diff --git a/data/shader/flame.fsh b/data/shader/flame.fsh index 0bf4756..9ae570f 100644 --- a/data/shader/flame.fsh +++ b/data/shader/flame.fsh @@ -6,5 +6,5 @@ out vec4 oColor; void main() { - oColor = vec4(fColor, 1.0); + oColor = vec4(fColor, 0.6); } diff --git a/data/shader/flame_post.fsh b/data/shader/flame_post.fsh index 6518b0d..ea0bc2a 100644 --- a/data/shader/flame_post.fsh +++ b/data/shader/flame_post.fsh @@ -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; } diff --git a/graphics.cc b/graphics.cc index 7b4bc43..88db43e 100644 --- a/graphics.cc +++ b/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; iresize(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)); } diff --git a/graphics.hh b/graphics.hh index 4b5140a..0c48ac4 100644 --- a/graphics.hh +++ b/graphics.hh @@ -39,9 +39,6 @@ class Graphics { std::vector framebuffer_directional; std::vector 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;