From f4e71649ad7363f78092c14cf947914eab98e87f Mon Sep 17 00:00:00 2001 From: Anselme Date: Fri, 25 Aug 2017 14:16:44 +0200 Subject: [PATCH] stencil buffer is working, no more skybox artifacts + wireframe mode is unexpectedly interesting --- shaders/debug.frag.glsl | 8 ++++--- shaders/lighting.frag.glsl | 3 --- src/deferredpipeline.cpp | 48 +++++++++++++++++++++++--------------- src/deferredpipeline.h | 7 +++--- src/framebuffer.cpp | 9 +++++++ src/framebuffer.h | 2 ++ src/mesh.cpp | 4 ++-- src/skybox.cpp | 1 - 8 files changed, 51 insertions(+), 31 deletions(-) diff --git a/shaders/debug.frag.glsl b/shaders/debug.frag.glsl index 8f7e61c..7a5c432 100644 --- a/shaders/debug.frag.glsl +++ b/shaders/debug.frag.glsl @@ -2,11 +2,13 @@ in vec2 varTexCoord; -// LIGHT BUFFER - +#ifdef COLOR +uniform vec3 color; +#else uniform sampler2DRect debuggedBuffer; +#endif -// OUTPUT LIGHT +// OUTPUT layout(location = 0)out vec4 outColor; diff --git a/shaders/lighting.frag.glsl b/shaders/lighting.frag.glsl index b65d590..9db8fa0 100644 --- a/shaders/lighting.frag.glsl +++ b/shaders/lighting.frag.glsl @@ -7,8 +7,6 @@ uniform sampler2DRect positionBuffer; uniform sampler2DRect albedoBuffer; // - Normal buffer uniform sampler2DRect normalBuffer; -// - depth buffer -uniform sampler2DRect depthBuffer; #endif // - Emission + Metallic uniform sampler2DRect emissionBuffer; @@ -170,7 +168,6 @@ void main(void) { vec3 emission = emissionTexel.rgb; float metallic = emissionTexel.a; vec4 fragPos = texelFetch(positionBuffer, texCoord); - float depth = texelFetch(depthBuffer, texCoord).r; // compute shadow #ifdef SHADOWMAP diff --git a/src/deferredpipeline.cpp b/src/deferredpipeline.cpp index 1538acf..e1686cf 100644 --- a/src/deferredpipeline.cpp +++ b/src/deferredpipeline.cpp @@ -26,7 +26,7 @@ RESOURCE_PACK(shaders) -GBuffer::GBuffer(int width, int height) : FrameBuffer() +GBuffer::GBuffer(int width, int height, GLuint renderBuffer) : FrameBuffer() { Texture* tex; @@ -54,11 +54,8 @@ GBuffer::GBuffer(int width, int height) : FrameBuffer() tex->setUnit(EMISSION); addTexture(tex, GL_COLOR_ATTACHMENT3); - // - depth and stencil buffer - tex = new Texture(GL_DEPTH_STENCIL, GL_DEPTH24_STENCIL8, width, height, GL_UNSIGNED_INT_24_8, GL_TEXTURE_RECTANGLE); - tex->setFiltering(GL_NEAREST); - tex->setUnit(DEPTH); - addTexture(tex, GL_DEPTH_STENCIL_ATTACHMENT); + addRenderBuffer(renderBuffer, GL_DEPTH_ATTACHMENT); + addRenderBuffer(renderBuffer, GL_STENCIL_ATTACHMENT); initColorAttachments(); } @@ -75,13 +72,16 @@ void GBuffer::unbindTextures() getTexture(i)->unbind(); } -LightingBuffer::LightingBuffer(int width, int height) : FrameBuffer() +LightingBuffer::LightingBuffer(int width, int height, GLuint renderBuffer) : FrameBuffer() { // colors are encoded in float to allow tonemapping Texture* tex = new Texture(GL_RGBA, GL_RGBA16F, width, height, GL_FLOAT, GL_TEXTURE_RECTANGLE); tex->setFiltering(GL_NEAREST); addTexture(tex, GL_COLOR_ATTACHMENT0); + addRenderBuffer(renderBuffer, GL_DEPTH_ATTACHMENT); + addRenderBuffer(renderBuffer, GL_STENCIL_ATTACHMENT); + initColorAttachments(); } @@ -90,6 +90,7 @@ DeferredPipeline::DeferredPipeline() : m_skybox(nullptr), m_width(512), m_height(512), + m_depth_stencil_renderBuffer(0), m_gBuffer(nullptr), m_lightingBuffer(nullptr), m_renderTarget(nullptr), @@ -137,13 +138,14 @@ void DeferredPipeline::renderGL(Scene *scene) glDisable(GL_BLEND); glClearColor(0.0f, 0.0f, 0.0f, 1.f); glClearDepth(1.0f); - glClearStencil(1); + glClearStencil(0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glStencilMask(0xFF); - glStencilFunc(GL_ALWAYS, 1, 0xFF); // always draw fragments (ignore the stencil buffer values for now) + glStencilMask(0x01); + glStencilFunc(GL_ALWAYS, 0x01, 0x01); // always draw fragments (ignore the stencil buffer values for now) // draw skybox if(m_skybox != nullptr) { + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); m_skybox->renderGL(m_camera); glClear(GL_DEPTH_BUFFER_BIT); } @@ -180,24 +182,25 @@ void DeferredPipeline::renderGL(Scene *scene) glDepthFunc(GL_LEQUAL); glEnable(GL_BLEND); + glEnable(GL_STENCIL_TEST); glBlendFunc(GL_ONE, GL_ONE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); m_gBuffer->bindTextures(); // draw unlit fragments -/* + Shader *shader = m_lightShaders[1 << Light::UNLIT_FLAG]; if(shader != nullptr) { shader->bind(); shader->bindInteger(shader->getLocation("emissionBuffer"), GBuffer::EMISSION); - //glStencilFunc(GL_EQUAL, 1, 0xFF); + glStencilFunc(GL_EQUAL, 1, 0x01); SparrowRenderer::drawQuad(); } -*/ + // loop on light sources - //glStencilFunc(GL_EQUAL, 0, 0xFF); + glStencilFunc(GL_EQUAL, 0, 0x01); for(SceneIterator* lightIt = scene->getLights(); lightIt->isValid(); lightIt->next()) { @@ -215,7 +218,6 @@ void DeferredPipeline::renderGL(Scene *scene) shader->bindInteger(shader->getLocation("albedoBuffer"), GBuffer::ALBEDO); shader->bindInteger(shader->getLocation("normalBuffer"), GBuffer::NORMAL); shader->bindInteger(shader->getLocation("emissionBuffer"), GBuffer::EMISSION); - shader->bindInteger(shader->getLocation("depthBuffer"), GBuffer::DEPTH); // bind light light->bindAttributes(shader, m_camera); @@ -229,6 +231,7 @@ void DeferredPipeline::renderGL(Scene *scene) m_renderTarget->bindFBO(); glDisable(GL_BLEND); glDisable(GL_STENCIL_TEST); + glStencilMask(0); m_lightingBuffer->getTexture(0)->bind(0); m_postEffectsShader->bind(); m_postEffectsShader->bindInteger(m_postEffectsShader->getLocation("lightBuffer"), 0); @@ -344,14 +347,22 @@ void DeferredPipeline::resizeGL(int w, int h) if(m_skybox != nullptr) m_skybox->resizeGL(w, h); + if(m_depth_stencil_renderBuffer != 0) + glDeleteRenderbuffers(1, &m_depth_stencil_renderBuffer); + // rebuilding FrameBuffers if(m_gBuffer != NULL) { delete m_gBuffer; delete m_lightingBuffer; } - m_gBuffer = new GBuffer(w, h); - m_lightingBuffer = new LightingBuffer(w, h); + + glGenRenderbuffers(1, &m_depth_stencil_renderBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_depth_stencil_renderBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); + + m_gBuffer = new GBuffer(w, h, m_depth_stencil_renderBuffer); + m_lightingBuffer = new LightingBuffer(w, h, m_depth_stencil_renderBuffer); m_orthoMatrix = glm::ortho(0.f, float(m_width), float(m_height), 0.f); m_guiMesh->resizeGL(w, h); } @@ -403,8 +414,7 @@ void DeferredPipeline::refreshScene(Scene *scene) glm::vec4 DeferredPipeline::pick(int x, int y) { m_gBuffer->setTarget(GL_READ_FRAMEBUFFER); - m_gBuffer->bindFBO(); - //m_gBuffer->getTexture(0)-> + m_gBuffer->bindFBO(); float values[4] = {1}; glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, values); GLenum err = glGetError(); diff --git a/src/deferredpipeline.h b/src/deferredpipeline.h index dc69b7d..5dc8753 100644 --- a/src/deferredpipeline.h +++ b/src/deferredpipeline.h @@ -14,8 +14,8 @@ class GuiMesh; class GBuffer : public FrameBuffer { public: - enum Buffers { POSITION, ALBEDO, NORMAL, EMISSION, DEPTH, NB_BUFFERS }; - GBuffer(int width, int height); + enum Buffers { POSITION, ALBEDO, NORMAL, EMISSION, NB_BUFFERS }; + GBuffer(int width, int height, GLuint renderBuffer); void bindTextures(); void unbindTextures(); }; @@ -23,7 +23,7 @@ public: class LightingBuffer : public FrameBuffer { public: - LightingBuffer(int width, int height); + LightingBuffer(int width, int height, GLuint renderBuffer); }; class DeferredPipeline : public Pipeline @@ -54,6 +54,7 @@ class DeferredPipeline : public Pipeline GuiMesh * m_guiMesh; // framebuffers + GLuint m_depth_stencil_renderBuffer; GBuffer *m_gBuffer; LightingBuffer *m_lightingBuffer; const FrameBuffer *m_renderTarget; diff --git a/src/framebuffer.cpp b/src/framebuffer.cpp index 78ed02d..91111ec 100644 --- a/src/framebuffer.cpp +++ b/src/framebuffer.cpp @@ -38,6 +38,15 @@ void FrameBuffer::addTexture(Texture* tex, GLenum attachment) } } +void FrameBuffer::addRenderBuffer(GLuint renderBufferId, GLenum attachment) +{ + if(m_frameBufferId != 0) + { + bindFBO(); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, renderBufferId); + } +} + void FrameBuffer::initColorAttachments() { if(m_frameBufferId != 0 && m_attachments.size() != 0) diff --git a/src/framebuffer.h b/src/framebuffer.h index 381ce62..8805224 100644 --- a/src/framebuffer.h +++ b/src/framebuffer.h @@ -40,6 +40,8 @@ public: void addTexture(Texture* tex, GLenum attachment); + void addRenderBuffer(GLuint renderBufferId, GLenum attachment); + void initColorAttachments(); void deleteTextures(); diff --git a/src/mesh.cpp b/src/mesh.cpp index d84fb77..9347929 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -174,9 +174,9 @@ void Mesh::initGL() void Mesh::draw(Shader* shader) { if(isWireframe) - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); else - glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); if(isDoubleSided) glDisable(GL_CULL_FACE); if(material != NULL) diff --git a/src/skybox.cpp b/src/skybox.cpp index 6798754..6039b75 100644 --- a/src/skybox.cpp +++ b/src/skybox.cpp @@ -54,7 +54,6 @@ void Skybox::renderGL(Camera* myCamera) cubeMap->bind(0); glBindVertexArray(vao); - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbos[0]); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, NULL); glBindVertexArray(0);