Я разместил этот вопрос также на en.sfml-dev.org ( здесь ) и fallahn показал мне правильный подход. Прежде чем заняться этим, вот результаты картины:
Люминесценция (порог = 0,24f): [1128]
]
Уууу! Решение состоит в том, чтобы установить все прозрачные пиксели в сплошной черный цвет vec4(0.0, 0.0, 0.0, 1.0)
, а затем после того, как они были размыты, просто добавьте их поверх сцены:
vec4 tex_color = texture2D(texture, gl_TexCoord[0].xy);
vec4 add_color = texture2D(add_texture, gl_TexCoord[0].xy);
gl_FragColor = tex_color + add_color;
Таким образом, если add_color
черный (" прозрачный "), мы добавляем tex_color + vec4(0.0, 0.0, 0.0, 1.0)
, что не приводит к изменениям!
Это здорово, потому что теперь вы можете полностью игнорировать альфа-канал.
Чтобы понять, почему я нахожу это таким замечательным, вы можете прочитать эту маленькую напыщенную речь здесь (не стесняйтесь ее пропустить):
Не беспокоясь об альфе, вы можете игнорировать любой sf::BlendMode
, как сбивающий с толку sf::BlendMode::OneMinusSrcAlpha
, который вызывал у меня головную боль в течение 2 дней. Попробуйте рассчитать любое разумное «истинное» альфа-значение, если вы знаете, что все они предварительно умножены. Конечно, вам также нужно умножить все значения rgb на альфа пикселя, чтобы обратить вспять умножение… формулы отсюда довольно быстро увеличиваются. Также вычтите 1 из альфы, потому что это OneMinusSrcAlpha
... и не забудьте проверить случаи, когда сумма всех альф (да, вам нужно сложить это) равна 0 (или в OneMinusSrcAlpha
вопрос, что-то еще) потому что в противном случае вы получите деление на 0 (или в OneMinusSrcAlpha
имеет значение деление на 0, когда все окружающие пиксели сплошные). Также иногда могут работать странные альфа-значения, но только для одного прохода размытия, но в моем случае у меня есть несколько проходов ... и т. Д. Sup>
Вот окончательный код:
luminescence.frag
#version 120
uniform sampler2D texture;
uniform float threshold;
void main(void){
vec3 current_color = texture2D(texture, gl_TexCoord[0].xy).rgb;
vec4 pixel = vec4(0.0, 0.0, 0.0, 1.0);
float brightness = dot(current_color.rgb, vec3(0.2126, 0.7152, 0.0722));
if (brightness >= threshold){
pixel = texture2D(texture, gl_TexCoord[0].xy);
}
gl_FragColor = pixel;
}
boxblur.frag
#version 120
uniform sampler2D texture;
uniform float texture_inverse;
uniform int blur_radius;
uniform vec2 blur_direction;
void main(void){
vec4 sum = texture2D(texture, gl_TexCoord[0].xy);
for (int i = 0; i < blur_radius; ++i){
sum += texture2D(texture, gl_TexCoord[0].xy + (i * texture_inverse) * blur_direction);
sum += texture2D(texture, gl_TexCoord[0].xy - (i * texture_inverse) * blur_direction);
}
gl_FragColor = sum / (blur_radius * 2 + 1);
}
[1148 ] multiply.frag
#version 120
uniform sampler2D texture;
uniform float multiply;
void main(void){
gl_FragColor = texture2D(texture, gl_TexCoord[0].xy) * multiply;
}
assembly.frag
#version 120
uniform sampler2D texture;
uniform sampler2D add_texture;
uniform float add_weight;
void main(void){
vec4 tex_color = texture2D(texture, gl_TexCoord[0].xy);
vec4 add_color = texture2D(add_texture, gl_TexCoord[0].xy) * add_weight;
gl_FragColor = tex_color + add_color;
}
[ 1127] main.cpp
#include
#include
#include
void run() {
const sf::Vector2f SIZE(1280, 720);
sf::Texture background_tex;
background_tex.loadFromFile("resources/background.jpg");
sf::Sprite background(background_tex);
sf::Shader luminescence_shader;
luminescence_shader.loadFromFile("resources/luminescence.frag", sf::Shader::Fragment);
luminescence_shader.setUniform("texture", sf::Shader::CurrentTexture);
luminescence_shader.setUniform("threshold", 0.24f);
sf::Shader blur_shader;
blur_shader.loadFromFile("resources/boxblur.frag", sf::Shader::Fragment);
blur_shader.setUniform("texture", sf::Shader::CurrentTexture);
blur_shader.setUniform("texture_inverse", 1.0f / SIZE.x);
sf::Shader assemble_shader;
assemble_shader.loadFromFile("resources/assemble.frag", sf::Shader::Fragment);
assemble_shader.setUniform("texture", sf::Shader::CurrentTexture);
sf::Shader multiply_shader;
multiply_shader.loadFromFile("resources/multiply.frag", sf::Shader::Fragment);
multiply_shader.setUniform("texture", sf::Shader::CurrentTexture);
sf::RenderStates shader_states;
//no blendmode! we make our own - assemble.frag
sf::ContextSettings context_settings;
context_settings.antialiasingLevel = 12;
//draws background
sf::RenderTexture scene_render;
scene_render.create(SIZE.x, SIZE.y, context_settings);
sf::RenderTexture luminescence_render;
luminescence_render.create(SIZE.x, SIZE.y, context_settings);
//draws luminescence and blur
sf::RenderTexture assemble_render;
assemble_render.create(SIZE.x, SIZE.y, context_settings);
//addding multiple boxblurs with different radii looks really nice! in this case 4 layers
std::array blur_renders;
for (int i = 0; i < blur_renders.size(); ++i) {
blur_renders[i].create(SIZE.x, SIZE.y, context_settings);
}
const int BLUR_RADIUS_VALUES[] = { 250, 180, 125, 55 };
float blur_weight = blur_renders.empty() ? 0.0 : 1.0 / blur_renders.size();
sf::RenderWindow window(sf::VideoMode(SIZE.x, SIZE.y), "glsl fun", sf::Style::Default, context_settings);
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
}
//first draw the scene
scene_render.clear();
scene_render.draw(background);
scene_render.display();
//apply luminescence
shader_states.shader = &luminescence_shader;
luminescence_render.clear();
luminescence_render.draw(sf::Sprite(scene_render.getTexture()), shader_states);
luminescence_render.display();
//apply two pass gaussian blur n times to simulate gaussian blur.
shader_states.shader = &blur_shader;
for (int i = 0; i < blur_renders.size(); ++i) {
blur_shader.setUniform("blur_radius", BLUR_RADIUS_VALUES[i]);
blur_renders[i].clear();
blur_renders[i].draw(sf::Sprite(luminescence_render.getTexture()));
blur_renders[i].display();
//vertical blur
blur_shader.setUniform("blur_direction", sf::Glsl::Vec2(1.0, 0.0));
blur_renders[i].draw(sf::Sprite(blur_renders[i].getTexture()), shader_states);
blur_renders[i].display();
//horizontal blur
blur_shader.setUniform("blur_direction", sf::Glsl::Vec2(0.0, 1.0));
blur_renders[i].draw(sf::Sprite(blur_renders[i].getTexture()), shader_states);
blur_renders[i].display();
}
//load blur_renders[0] into assemble_render so we can add the other blurs ontop of it
shader_states.shader = &multiply_shader;
multiply_shader.setUniform("multiply", blur_weight);
assemble_render.clear();
assemble_render.draw(sf::Sprite(blur_renders[0].getTexture()), shader_states);
assemble_render.display();
//adding the rest ontop creating a final blur
shader_states.shader = &assemble_shader;
assemble_shader.setUniform("add_weight", blur_weight);
for (int i = 1; i < blur_renders.size(); ++i) {
assemble_shader.setUniform("add_texture", blur_renders[i].getTexture());
assemble_render.draw(sf::Sprite(assemble_render.getTexture()), shader_states);
assemble_render.display();
}
//final result; scene + blur
assemble_shader.setUniform("add_weight", 1.0f);
assemble_shader.setUniform("add_texture", assemble_render.getTexture());
assemble_render.draw(sf::Sprite(scene_render.getTexture()), shader_states);
assemble_render.display();
window.clear();
window.draw(sf::Sprite(assemble_render.getTexture()));
window.display();
}
}
int main() {
try {
run();
}
catch (std::exception e) {
std::cerr << "caught exception - - - " << e.what() << '\n';
return 1;
}
return 0;
}
Я думаю, что необходимо пойти с FogBugz. Это онлайн, свободное для 2 разработчиков, это интегрируется с Вашим управлением исходным кодом. Я думаю, что bugtracking является вторым к управлению исходным кодом с точки зрения управления проектами специально для единственного разработчика. Необходимо смочь сказать, когда Вы исправили все ошибки, о которых сообщают, таким образом, можно предсказать дату поставки на функции и т.д. и т.д.
Автоматизированный процесс сборки снимет огромную нагрузку Вас, чтобы смочь создать Ваше программное обеспечение по требованию (в случае удалений и т.д.). Процесс CI может быть небольшим излишеством, но автоматизированным правилом сборок.
Если Вы волнуетесь по поводу помещения его на Вашем ноутбуке, но все еще хотите к самокрутке, можно перейти к slicehost и получить поле человечности для subversion/trac решения онлайн для 20 маркеров в месяц. Я делаю это для некоторых моих персональных проектов...
VCS важен, работаете ли Вы одни или нет.
Действительно, это должно быть там в течение тех моментов, когда Вы понимаете, что сделали ошибку и хотите откатывать, к какому Вы имели вчера или этим утром, или возможно Вы только что приняли другое решение в реализации и хотите перейти так, можно проверить вещи, не производя ядро того, что Вы записали до сих пор.
В целом, это - хорошая вещь иметь. И Вы более обеспечены быть безопасным, чем извините.
До средства отслеживания ошибки, которое является большим Вашим персональным предпочтением. Мне нравится Redmine, который интегрируется с SVN, мерзавцем, и т.д. Другие предпочитают Trac. Но так или иначе они смогут работать на Вашем ноутбуке при взятии минимальной суммы ресурсов. Особенно, когда Вы полагаете, что Вы - единственный с помощью них.
Я проверил бы http://bitnami.org/, который они предлагают упакованным Средствам отслеживания Ошибки, которые Вы просто выполняете, и это запустит свой собственный небольшой сервер на порте по Вашему выбору, и можно остановить его, когда Вы не используете его.
Вы могли бы хотеть рассмотреть репозиторий онлайн и/или средство отслеживания/планировщика в дополнение к Вашему локальному. Это - другой этап управления рисками и если в будущем кто-то еще присоединяется к Вашей команде, можно увеличиться только путем предоставления им доступа.
Некоторые опции:
Управление исходным кодом (онлайн):
Отслеживание ошибок / управление проектами
Subversion и Trac не поднимают многий Ваши системные ресурсы особенно, когда они просто находятся, там ожидая Вас для использования их.
Я работаю над маленьким проектом, всего 2 полностью занятых разработчика, но я нахожу, что использую наше программное обеспечение отслеживания ошибок (Jira в нашем случае, подобном Bugzilla), даже только для отслеживания мои собственные ошибки и проблемы. Легче, чем попытка помнить детали ошибки, когда Вы заставляете время работать над ним позже, и существует очень удовлетворяющее чувство к вычету проблем после разрешения их.
Я придерживался бы чего-то простого в Вашем случае, даже просто специализированное - делает список задач в Outlook был бы, вероятно, достаточен, не хотите ли Вы проводить слишком много времени разработки, настраивая специализированную систему. Важная вещь состоит в том, чтобы иметь способ знать наверняка, что Вы решили все ошибки, о которых сообщили.
Действительное значение средства отслеживания ошибки - то, что Вы не теряете след ничего, что должно быть зафиксировано. Это, вероятно, более важно, если существует только один из Вас, как будто существует больше, потому что нет никого больше для напоминания Вам о том, что Вы забыли. Я могу remeber проект в прошлом, где у нас были простая ошибка типа опечатки и только один разработчик приложений (я был разработчиком дб), и у него не было времени, чтобы сделать это день, генеральный директор поднял его и несколько месяцев спустя, когда генеральный директор заметил, что это было все еще там, он пошел баллистический. При манипулировании целым набором задач и возможных ошибок очень легко терять из виду что-то (особенно что-то, о чем Вы думаете как тривиальные). Тот инцидент привел к нам получающий средство отслеживания ошибки и помещающий все задачи не только ошибки в него, и это была одна из лучших вещей, которые мы когда-либо делали. Просто способность сказать клиенту, когда он хочет что-то новое, "Хорошо вот мой текущий список задач. Насколько важный это по сравнению с этими вещами?" делает это стоящим его веса в золоте особенно, когда Вы - единственный человек. Это поможет Вам разработать временные оценки к и дать Вам место для документирования обсуждений и решений относительно задачи, таким образом, никто не сможет возвратиться позже и сказать, что они не знали, что Вы собирались сделать это.
Упоминается, что у него есть подписка MSDN. Хотя это не моя любимая система управления версиями для использования, Sourcesafe очень легко создать и использовать, и не плохое решение, если он - единственный с помощью него (на который это походит).
И да, Вы хотите использовать что-то для отслеживания ошибок, даже если это - просто простой список в Excel (или) таким образом, можно отслеживать то, что, все еще повредился и что фиксируется. Я сделал это прежде на маленьких проектах, я продолжил работать.
Я согласился бы с JPunyon, что необходимо использовать Fogbugz для отслеживания ошибок. Я использую, если для моего персонального материала и это является блестящим. В то время как средство отслеживания ошибки не важно (хотя полезный), если Вы самостоятельно, Управление исходным кодом важно. Мой предпочтительный продукт теперь По необходимости, который предоставляет полностью функциональные 2 пользовательских копии, которые можно загрузить и использовать. Это поднимает очень мало ресурса и легко передаваемо при обновлении машин. Существует определенная кривая обучения, но стоящий того.
Хотя это и не является явным средством отслеживания ошибок, вы можете использовать tiddlywiki , который представляет собой отличную вики-страницу в автономном файле HTML, что упрощает управление версиями. .
Я упоминаю об этом потому, что рано или поздно вы захотите делать заметки в дополнение к спискам ошибок.
Надеюсь, это поможет
If you develop on your laptop, you probably work offline often (I do). Consider using bug tracker which doesn't require internet connection to operate. You may check Artifacts - simple, works offline and has Visual Studio integration.