Fixed blurring of flames with stencil buffer.
This commit is contained in:
parent
a88112d639
commit
fa47c93b46
@ -6,5 +6,5 @@ out vec4 oColor;
|
||||
|
||||
|
||||
void main() {
|
||||
oColor = vec4(fColor, 1.0);
|
||||
oColor = vec4(fColor, 0.6);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
in vec2 vTexCoord;
|
||||
|
||||
uniform sampler2D flame_fbo;
|
||||
uniform sampler2D light_fbo;
|
||||
uniform int windowSizeX;
|
||||
uniform int windowSizeY;
|
||||
@ -12,24 +11,11 @@ out vec4 oColor;
|
||||
const float lookup_offset = 4.0;
|
||||
|
||||
void main() {
|
||||
vec4 color = texture(flame_fbo, vTexCoord).rgba;
|
||||
if (color == vec4(0.0, 0.0, 0.0, 1.0)) {
|
||||
oColor = texture(light_fbo, vTexCoord).rgba;
|
||||
}
|
||||
else {
|
||||
vec4 sum = vec4(0.0);
|
||||
for(float i = -lookup_offset; i<=lookup_offset; i+=1.0) {
|
||||
for(float j = -lookup_offset; j<=lookup_offset; j+=1.0) {
|
||||
vec4 flame_pixel = texture(flame_fbo, vec2(vTexCoord.x + i * 1.0/(windowSizeX/2.0), vTexCoord.y + j * 1.0/(windowSizeY/2.0)))/pow(lookup_offset*2+1, 2.0);
|
||||
vec4 light_pixel = texture(light_fbo, vec2(vTexCoord.x + i * 1.0/(windowSizeX/2.0), vTexCoord.y + j * 1.0/(windowSizeY/2.0)))/pow(lookup_offset*2+1, 2.0);
|
||||
if (flame_pixel == vec4(0.0, 0.0, 0.0, 1.0)) {
|
||||
sum += light_pixel;
|
||||
}
|
||||
else {
|
||||
sum += mix(flame_pixel, light_pixel, 0.7);
|
||||
}
|
||||
}
|
||||
vec4 sum = vec4(0.0);
|
||||
for(float i = -lookup_offset; i<=lookup_offset; i+=1.0) {
|
||||
for(float j = -lookup_offset; j<=lookup_offset; j+=1.0) {
|
||||
sum += texture(light_fbo, vec2(vTexCoord.x + i * 1.0/(windowSizeX/2.0), vTexCoord.y + j * 1.0/(windowSizeY/2.0)))/pow(lookup_offset*2+1, 2.0);
|
||||
}
|
||||
oColor = sum;
|
||||
}
|
||||
oColor = sum;
|
||||
}
|
||||
|
54
graphics.cc
54
graphics.cc
@ -92,8 +92,8 @@ void Graphics::init(Level* level) {
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &number_of_texture_units);
|
||||
printf("Your graphics card supports %d texture units.\n", number_of_texture_units);
|
||||
// Exit if we need more texture units
|
||||
if (number_of_texture_units < 16) {
|
||||
printf("You need at least 16 texture units to run this application. Exiting\n");
|
||||
if (number_of_texture_units < 15) {
|
||||
printf("You need at least 15 texture units to run this application. Exiting\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@ -142,28 +142,12 @@ void Graphics::init(Level* level) {
|
||||
}
|
||||
}
|
||||
|
||||
flame_fbo_color_texture = SharedTexture2D(new Texture2D(windowSize, GL_RGBA8));
|
||||
flame_fbo_color_texture->setMinFilter(GL_NEAREST);
|
||||
flame_fbo_color_texture->setMagFilter(GL_NEAREST);
|
||||
flame_fbo_color_texture->setWrapS(GL_CLAMP_TO_BORDER);
|
||||
flame_fbo_color_texture->setWrapT(GL_CLAMP_TO_BORDER);
|
||||
flame_fbo_depth_texture = SharedTexture2D(new Texture2D(windowSize, GL_DEPTH_COMPONENT24));
|
||||
flame_fbo_depth_texture->setMinFilter(GL_NEAREST);
|
||||
flame_fbo_depth_texture->setMagFilter(GL_NEAREST);
|
||||
flame_fbo_depth_texture->setWrapS(GL_CLAMP_TO_BORDER);
|
||||
flame_fbo_depth_texture->setWrapT(GL_CLAMP_TO_BORDER);
|
||||
framebuffer_flames = SharedFrameBufferObject(new FrameBufferObject());
|
||||
framebuffer_flames->attachColorTexture("oColor", flame_fbo_color_texture);
|
||||
framebuffer_flames->setDepthTexture(flame_fbo_depth_texture);
|
||||
framebuffer_flames->setClearColor(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
framebuffer_flames->validate();
|
||||
|
||||
light_fbo_color_texture = SharedTexture2D(new Texture2D(windowSize, GL_RGBA8));
|
||||
light_fbo_color_texture->setMinFilter(GL_NEAREST);
|
||||
light_fbo_color_texture->setMagFilter(GL_NEAREST);
|
||||
light_fbo_color_texture->setWrapS(GL_CLAMP_TO_BORDER);
|
||||
light_fbo_color_texture->setWrapT(GL_CLAMP_TO_BORDER);
|
||||
light_fbo_depth_texture = SharedTexture2D(new Texture2D(windowSize, GL_DEPTH_COMPONENT24));
|
||||
light_fbo_depth_texture = SharedTexture2D(new Texture2D(windowSize, GL_DEPTH24_STENCIL8));
|
||||
light_fbo_depth_texture->setMinFilter(GL_NEAREST);
|
||||
light_fbo_depth_texture->setMagFilter(GL_NEAREST);
|
||||
light_fbo_depth_texture->setWrapS(GL_CLAMP_TO_BORDER);
|
||||
@ -175,8 +159,7 @@ void Graphics::init(Level* level) {
|
||||
framebuffer_light->validate();
|
||||
|
||||
flamePostShader->use();
|
||||
flamePostShader->setTexture("flame_fbo", flame_fbo_color_texture, 15);
|
||||
flamePostShader->setTexture("light_fbo", light_fbo_color_texture, 16);
|
||||
flamePostShader->setTexture("light_fbo", light_fbo_color_texture, 15);
|
||||
flamePostShader->setUniform("windowSizeX", int(windowSize.x));
|
||||
flamePostShader->setUniform("windowSizeY", int(windowSize.y));
|
||||
|
||||
@ -294,14 +277,16 @@ void Graphics::render(double time)
|
||||
// render the level
|
||||
level->render(lightingShader, true, &lightingViewProjectionMatrix, &depthBiasVPs);
|
||||
|
||||
// draw flames on top
|
||||
// cull faces to get consistent color while using alpha
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
// draw flames on top
|
||||
|
||||
framebuffer_flames->bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF); //Set any stencil to 1
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glStencilMask(0xFF);//write to stencil buffer
|
||||
glClear(GL_STENCIL_BUFFER_BIT);//clear stencil buffer
|
||||
|
||||
flameShader->use();
|
||||
flameShader->setUniform("viewProjectionMatrix", lightingViewProjectionMatrix);
|
||||
@ -319,11 +304,20 @@ void Graphics::render(double time)
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glStencilFunc(GL_EQUAL, 1, 0xFF); //Pass test if stencil value is 1
|
||||
glStencilMask(0x00); //don't write to stencil buffer
|
||||
|
||||
flamePostShader->use();
|
||||
fullscreen_quad->render();
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer_light->getObjectName());
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBlitFramebuffer(0, 0, windowSize.x, windowSize.y, 0, 0, windowSize.x, windowSize.y,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
|
||||
bool Graphics::compareLightDistances(Light a, Light b) {
|
||||
@ -406,8 +400,8 @@ void Graphics::resize(glm::uvec2 windowSize) {
|
||||
for (unsigned int i = 0; i<depth_directionalMaps.size(); i++) {
|
||||
depth_directionalMaps.at(i)->resize(glm::vec2(windowSize.x, windowSize.y));
|
||||
}
|
||||
flame_fbo_color_texture->resize(windowSize);
|
||||
flame_fbo_depth_texture->resize(windowSize);
|
||||
light_fbo_color_texture->resize(windowSize);
|
||||
light_fbo_depth_texture->resize(windowSize);
|
||||
flamePostShader->setUniform("windowSizeX", int(windowSize.x));
|
||||
flamePostShader->setUniform("windowSizeY", int(windowSize.y));
|
||||
}
|
||||
|
@ -39,9 +39,6 @@ class Graphics {
|
||||
std::vector<SharedFrameBufferObject> framebuffer_directional;
|
||||
std::vector<SharedTextureCubeMap> depth_cubeMaps;
|
||||
SharedFrameBufferObject framebuffer_cube;
|
||||
SharedFrameBufferObject framebuffer_flames;
|
||||
SharedTexture2D flame_fbo_color_texture;
|
||||
SharedTexture2D flame_fbo_depth_texture;
|
||||
SharedFrameBufferObject framebuffer_light;
|
||||
SharedTexture2D light_fbo_color_texture;
|
||||
SharedTexture2D light_fbo_depth_texture;
|
||||
|
Loading…
Reference in New Issue
Block a user