From 9c56d3f061072c0e8c85d7d343e5bfb91d22cea5 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sat, 17 Feb 2018 23:49:56 +0100 Subject: [PATCH] Rendering linearized depth buffer by rendering it to another RGB texture --- data/shaders/fs_depthbuffer.glsl | 22 +----- src/modules/RenderModule.cc | 118 +++++++++++++++++-------------- src/modules/RenderModule.h | 4 ++ src/modules/RenderUtils.cc | 25 ++++++- src/modules/RenderUtils.h | 8 ++- 5 files changed, 101 insertions(+), 76 deletions(-) diff --git a/data/shaders/fs_depthbuffer.glsl b/data/shaders/fs_depthbuffer.glsl index 1228392..e3c7cda 100644 --- a/data/shaders/fs_depthbuffer.glsl +++ b/data/shaders/fs_depthbuffer.glsl @@ -10,27 +10,7 @@ uniform float uFar; void main() { float z = texture(uTexture, ioUV).r; - float c = (2.0 * uNear) / (uFar + uNear - z * (uFar - uNear)); -// c = 2.0 * uNear * uFar / (uFar + uNear - z * (uFar - uNear)); -// c = (uNear + (z - uNear) / (uFar - uNear); - - c = (z - uNear) / (uFar - uNear); + float c = (z - uNear) / (uFar - uNear); outColor = vec3(c); - - if (abs(c + 1) < 0.2) - outColor = vec3(1, 0, 0); -// if (abs(c - 0.1) < 0.1) -// outColor = vec3(0, 0, 1); -// if (abs(c - 0.8) < 0.1) -// outColor = vec3(1, 0, 0); - - -// n ---- z ------- f -// 0 1 -// -// (n + (z - n)) (f - n) -// -// (f - n) -// outColor = vec3(z); } diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index 27b29d2..04f698e 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -2,6 +2,7 @@ #include "Globals.h" #include "RenderModule.h" #include +#include "Serializer.h" #include "imgui/imgui.h" #include "imgui_dock.h" @@ -10,10 +11,16 @@ using namespace SimpleMath::GL; struct Renderer; +struct RendererSettings { + bool DrawDepth = false; +}; + +static RendererSettings sRendererSettings; + static const GLfloat g_vertex_buffer_data[] = { -0.9f, -0.9f, 0.0f, 0.9f, -0.9f, 0.0f, - 0.0f, 0.9f, 1.0f + 0.0f, 0.9f, 4.0f }; static const GLfloat g_quad_vertex_buffer_data[] = { @@ -47,6 +54,7 @@ template static void module_serialize ( struct module_state *state, Serializer* serializer) { + SerializeBool(*serializer, "protot.RenderModule.DrawDepth", sRendererSettings.DrawDepth); // // get the state from the serializer // Camera* camera = &gRenderer->cameras[gRenderer->activeCameraIndex]; // assert (camera != nullptr); @@ -74,6 +82,7 @@ static void module_reload(struct module_state *state, void *read_serializer) { gLog ("Renderer initialize"); assert (state != nullptr); state->renderer->Initialize(100, 100); + state->renderer->mSettings = &sRendererSettings; gRenderer = state->renderer; @@ -147,7 +156,10 @@ glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data muDefaultColor = mDefaultProgram.GetUniformLocation("uColor"); // Render Target - mRenderTarget = RenderTarget (width, height, RenderTarget::EnableColor | RenderTarget::EnableDepthTexture); + mRenderTarget = RenderTarget (width, height, + RenderTarget::EnableColor + | RenderTarget::EnableDepthTexture + | RenderTarget::EnableLinearizedDepthTexture); // Render Target Quad glGenVertexArrays(1, &mRenderQuadVertexArrayId); @@ -186,11 +198,11 @@ void Renderer::RenderGl() { if (width != mWidth || height != mHeight) Resize(width, height); - mCamera.eye = Vector3f (0.0f, 0.0f, 1.0f); + mCamera.eye = Vector3f (0.0f, 0.0f, 4.0f); mCamera.poi = Vector3f (0.0f, 0.0f, 0.0f); mCamera.up = Vector3f (0.0f, 1.0f, 0.0f); mCamera.near = 0.0f; - mCamera.far = 1.0f; + mCamera.far = 4.0f; mCamera.orthographic = true; mCamera.UpdateMatrices(); @@ -230,23 +242,63 @@ void Renderer::RenderGl() { ); glDrawArrays(GL_TRIANGLES, 0, 3); // starting from vertex 0; 3 vertices total + + if (mSettings->DrawDepth) { + mRenderTarget.RenderToLinearizedDepth(true); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_DEPTH_TEST); + + Matrix44f model_view_projection = Matrix44f::Identity(); + + // render depth texture + glUseProgram(mRenderQuadProgramDepth.mProgramId); + glUniformMatrix4fv(muRenderQuadModelViewProj, 1, GL_FALSE, model_view_projection.data()); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mRenderTarget.mDepthTexture); + glUniform1i(muRenderQuadTexture, 0); + + // TODO: adjust for perspective + glUniform1f(muRenderQuadDepthNear, mCamera.near); + // TODO: why do I have to divide by depth range? + glUniform1f(muRenderQuadDepthFar, mCamera.far / (mCamera.far - mCamera.near)); + + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, mRenderQuadVertexBufferId); + glVertexAttribPointer( + 0, // attribute 0 + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized? + 0, // stride + (void*)0 // offset + ); + + glDrawArrays(GL_TRIANGLES, 0, 6); // starting from vertex 0; 3 vertices total + + mRenderTarget.RenderToLinearizedDepth(false); + } + glDisableVertexAttribArray(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } void Renderer::RenderGui() { - bool render_color = true; - - GLuint texture; - if (render_color) { - texture = mRenderTarget.mColorTexture; - } else { - texture = mRenderTarget.mDepthTexture; - } - if (ImGui::BeginDock("Scene")) { + ImGui::Checkbox("Draw Depth", &mSettings->DrawDepth); + + GLuint texture; + if (mSettings->DrawDepth) { + texture = mRenderTarget.mLinearizedDepthTexture; + } else { + texture = mRenderTarget.mColorTexture; + } + ImGui::Text("Scene"); const ImVec2 content_avail = ImGui::GetContentRegionAvail(); + +// mRenderTarget.Resize(content_avail.x, content_avail.y); + ImGui::Image((void*) texture, content_avail, ImVec2(0.0f, 1.0f), @@ -254,46 +306,6 @@ void Renderer::RenderGui() { ); } ImGui::EndDock(); - - return; - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glActiveTexture(GL_TEXTURE0); - - Matrix44f model_view_projection = Matrix44f::Identity(); - - if (render_color) { - // Render the full screen quad - glUseProgram(mRenderQuadProgramColor.mProgramId); - glBindTexture(GL_TEXTURE_2D, mRenderTarget.mColorTexture); - glUniformMatrix4fv(muRenderQuadModelViewProj, 1, GL_FALSE, model_view_projection.data()); - glUniform1i(muRenderQuadTexture, 0); - glUniform1f(muRenderQuadTime, (float)(glfwGetTime() * 10.0f)); - } else { - // render depth texture - glUseProgram(mRenderQuadProgramDepth.mProgramId); - glBindTexture(GL_TEXTURE_2D, mRenderTarget.mDepthTexture); - glUniformMatrix4fv(muRenderQuadModelViewProj, 1, GL_FALSE, model_view_projection.data()); - glUniform1i(muRenderQuadTexture, 0); - glUniform1f(muRenderQuadDepthNear, mCamera.near); - glUniform1f(muRenderQuadDepthFar, mCamera.far); - } - - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, mRenderQuadVertexBufferId); - glVertexAttribPointer( - 0, // attribute 0 - 3, // size - GL_FLOAT, // type - GL_FALSE, // normalized? - 0, // stride - (void*)0 // offset - ); - - glDrawArrays(GL_TRIANGLES, 0, 6); // starting from vertex 0; 3 vertices total - glDisableVertexAttribArray(0); } void Renderer::Resize (int width, int height) { diff --git a/src/modules/RenderModule.h b/src/modules/RenderModule.h index 4135b96..12110ff 100644 --- a/src/modules/RenderModule.h +++ b/src/modules/RenderModule.h @@ -106,7 +106,11 @@ struct Mesh { GLuint mVertexBuffer = -1; }; +struct RendererSettings; + struct Renderer { + RendererSettings* mSettings = nullptr; + bool mInitialized = false; uint32_t mWidth = 1; uint32_t mHeight = 1; diff --git a/src/modules/RenderUtils.cc b/src/modules/RenderUtils.cc index 0202923..0832e81 100644 --- a/src/modules/RenderUtils.cc +++ b/src/modules/RenderUtils.cc @@ -170,6 +170,11 @@ void RenderTarget::Cleanup() { glDeleteRenderbuffers(1, &mDepthBuffer); mDepthBuffer = -1; } + + if (mLinearizedDepthTexture != -1) { + glDeleteTextures(1, &mLinearizedDepthTexture); + mLinearizedDepthTexture = -1; + } } void RenderTarget::Resize(int width, int height) { @@ -210,6 +215,17 @@ void RenderTarget::Resize(int width, int height) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, mDepthTexture, 0); + + if (mFlags & EnableLinearizedDepthTexture) { + glGenTextures(1, &mLinearizedDepthTexture); + glBindTexture(GL_TEXTURE_2D, mLinearizedDepthTexture); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, mWidth, mHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } } else if (mFlags & EnableDepth) { assert((mFlags & EnableDepthTexture) == false); glGenRenderbuffers(1, &mDepthBuffer); @@ -219,4 +235,11 @@ void RenderTarget::Resize(int width, int height) { } } - +void RenderTarget::RenderToLinearizedDepth(bool render_to_depth) { + if (render_to_depth) { + assert(mFlags & EnableLinearizedDepthTexture); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mLinearizedDepthTexture, 0); + } else { + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mColorTexture, 0); + } +} diff --git a/src/modules/RenderUtils.h b/src/modules/RenderUtils.h index a81072e..f327f79 100644 --- a/src/modules/RenderUtils.h +++ b/src/modules/RenderUtils.h @@ -146,6 +146,9 @@ struct RenderProgram { bool Load(); }; +struct RenderSettings; + + struct RenderTarget { int mWidth = 0; int mHeight = 0; @@ -153,11 +156,13 @@ struct RenderTarget { GLuint mColorTexture = -1; GLuint mDepthBuffer = -1; GLuint mDepthTexture = -1; + GLuint mLinearizedDepthTexture = -1; typedef enum { EnableColor = 1, EnableDepth = 2, - EnableDepthTexture = 4 + EnableDepthTexture = 4, + EnableLinearizedDepthTexture = 8 } Flags; int mFlags = 0; @@ -168,6 +173,7 @@ struct RenderTarget { void Cleanup(); void Resize(int width, int height); + void RenderToLinearizedDepth(bool render_to_depth); }; #endif