From 0f297734f38348668357b33952245f6b2c539d84 Mon Sep 17 00:00:00 2001 From: baldurk Date: Sun, 25 Jan 2015 20:30:03 +0000 Subject: [PATCH] Add geometry-shader calculated face normals for lit mesh view * Also fix up the depth buffer part of output windows (since it wasn't used for anything else) --- renderdoc/data/glsl/mesh.frag | 7 +-- renderdoc/data/glsl/mesh.geom | 40 +++++++++++++++ renderdoc/driver/gl/gl_debug.cpp | 66 ++++++++++++++++++++----- renderdoc/driver/gl/gl_replay.cpp | 37 +++++++++++--- renderdoc/driver/gl/gl_replay.h | 8 +-- renderdoc/driver/gl/gl_replay_linux.cpp | 2 +- renderdoc/driver/gl/gl_replay_win32.cpp | 2 +- 7 files changed, 131 insertions(+), 31 deletions(-) diff --git a/renderdoc/data/glsl/mesh.frag b/renderdoc/data/glsl/mesh.frag index 156de3def..0e040147c 100644 --- a/renderdoc/data/glsl/mesh.frag +++ b/renderdoc/data/glsl/mesh.frag @@ -48,12 +48,9 @@ void main(void) } else if(type == MESHDISPLAY_FACELIT) { - color_out = vec4(0, 1, 0, 1); - /* - float3 lightDir = normalize(float3(0, -0.3f, -1)); + vec3 lightDir = normalize(vec3(0, -0.3f, -1)); - return float4(WireframeColour.xyz*saturate(dot(lightDir, IN.norm)), 1); - */ + color_out = vec4(RENDERDOC_GenericFS_Color.xyz*clamp(dot(lightDir, IN.norm.xyz), 0.0f, 1.0f), 1); } else //if(type == MESHDISPLAY_SOLID) { diff --git a/renderdoc/data/glsl/mesh.geom b/renderdoc/data/glsl/mesh.geom index 494c5da04..eabd9fac1 100644 --- a/renderdoc/data/glsl/mesh.geom +++ b/renderdoc/data/glsl/mesh.geom @@ -23,3 +23,43 @@ ******************************************************************************/ #version 420 core + +layout(triangles, invocations = 1) in; +layout(triangle_strip, max_vertices = 3) out; + +in v2f +{ + vec4 secondary; + vec4 norm; +} IN[]; + +out v2f +{ + vec4 secondary; + vec4 norm; +} OUT; + +uniform mat4 InvProj; + +out gl_PerVertex +{ + vec4 gl_Position; + float gl_PointSize; + float gl_ClipDistance[]; +}; + +void main() +{ + vec4 faceEdgeA = (InvProj * gl_in[1].gl_Position) - (InvProj * gl_in[0].gl_Position); + vec4 faceEdgeB = (InvProj * gl_in[2].gl_Position) - (InvProj * gl_in[0].gl_Position); + vec3 faceNormal = normalize( cross(faceEdgeA.xyz, faceEdgeB.xyz) ); + + for(int i=0; i < 3; i++) + { + gl_Position = gl_in[i].gl_Position; + OUT.secondary = IN[i].secondary; + OUT.norm = vec4(faceNormal.xyz, 1); + EmitVertex(); + } + EndPrimitive(); +} diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 907d7cc40..073bb5387 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -76,7 +76,7 @@ GLuint GLReplay::CreateCShaderProgram(const char *csSrc) return ret; } -GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *psSrc) +GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *psSrc, const char *gsSrc) { if(m_pDriver == NULL) return 0; @@ -86,14 +86,23 @@ GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *psSrc) GLuint vs = gl.glCreateShader(eGL_VERTEX_SHADER); GLuint fs = gl.glCreateShader(eGL_FRAGMENT_SHADER); + GLuint gs = 0; const char *src = vsSrc; gl.glShaderSource(vs, 1, &src, NULL); src = psSrc; gl.glShaderSource(fs, 1, &src, NULL); + if(gsSrc) + { + gs = gl.glCreateShader(eGL_GEOMETRY_SHADER); + src = gsSrc; + gl.glShaderSource(gs, 1, &src, NULL); + } + gl.glCompileShader(vs); gl.glCompileShader(fs); + if(gs) gl.glCompileShader(gs); char buffer[1024]; GLint status = 0; @@ -112,18 +121,31 @@ GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *psSrc) RDCERR("Shader error: %s", buffer); } + if(gs) + { + gl.glGetShaderiv(gs, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + gl.glGetShaderInfoLog(gs, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } + } + GLuint ret = gl.glCreateProgram(); gl.glAttachShader(ret, vs); gl.glAttachShader(ret, fs); + if(gs) gl.glAttachShader(ret, gs); gl.glLinkProgram(ret); gl.glDetachShader(ret, vs); gl.glDetachShader(ret, fs); + if(gs) gl.glDetachShader(ret, gs); gl.glDeleteShader(vs); gl.glDeleteShader(fs); + if(gs) gl.glDeleteShader(gs); return ret; } @@ -173,10 +195,12 @@ void GLReplay::InitDebugData() DebugData.genericProg = CreateShaderProgram(DebugData.genericvsSource.c_str(), DebugData.genericfsSource.c_str()); string meshvs = GetEmbeddedResource(mesh_vert); + string meshgs = GetEmbeddedResource(mesh_geom); string meshfs = GetEmbeddedResource(mesh_frag); meshfs = glslheader + meshfs; DebugData.meshProg = CreateShaderProgram(meshvs.c_str(), meshfs.c_str()); + DebugData.meshgsProg = CreateShaderProgram(meshvs.c_str(), meshfs.c_str(), meshgs.c_str()); WrappedOpenGL &gl = *m_pDriver; @@ -339,6 +363,7 @@ void GLReplay::DeleteDebugData() gl.glDeleteProgram(DebugData.checkerProg); gl.glDeleteProgram(DebugData.genericProg); gl.glDeleteProgram(DebugData.meshProg); + gl.glDeleteProgram(DebugData.meshgsProg); gl.glDeleteBuffers(1, &DebugData.outlineStripVB); gl.glDeleteVertexArrays(1, &DebugData.outlineStripVAO); @@ -1036,6 +1061,8 @@ void GLReplay::RenderCheckerboard(Vec3f light, Vec3f dark) gl.glUseProgram(DebugData.checkerProg); + gl.glDisable(eGL_DEPTH_TEST); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]); Vec4f *ubo = (Vec4f *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(Vec4f)*2, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); @@ -1074,6 +1101,8 @@ void GLReplay::RenderHighlightBox(float w, float h, float scale) gl.glUniform4fv(offsetLoc, 1, &offsetVal.x); gl.glUniform4fv(scaleLoc, 1, &scaleVal.x); gl.glUniform4fv(colLoc, 1, &colVal.x); + + gl.glDisable(eGL_DEPTH_TEST); gl.glBindVertexArray(DebugData.outlineStripVAO); gl.glDrawArrays(eGL_LINE_LOOP, 0, 4); @@ -1563,13 +1592,12 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vectorGetSerialiser()->GetCallstackResolver(); } -void GLReplay::CreateOutputWindowBackbuffer(OutputWindow &outwin) +void GLReplay::CreateOutputWindowBackbuffer(OutputWindow &outwin, bool depth) { if(m_pDriver == NULL) return; @@ -164,6 +164,22 @@ void GLReplay::CreateOutputWindowBackbuffer(OutputWindow &outwin) gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, outwin.BlitData.backbuffer, 0); + if(depth) + { + gl.glGenTextures(1, &outwin.BlitData.depthstencil); + gl.glBindTexture(eGL_TEXTURE_2D, outwin.BlitData.depthstencil); + + gl.glTexStorage2D(eGL_TEXTURE_2D, 1, eGL_DEPTH_COMPONENT24, outwin.width, outwin.height); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + } + else + { + outwin.BlitData.depthstencil = 0; + } + outwin.BlitData.replayFBO = 0; } @@ -200,11 +216,18 @@ bool GLReplay::CheckResizeOutputWindow(uint64_t id) MakeCurrentReplayContext(m_DebugCtx); WrappedOpenGL &gl = *m_pDriver; + + bool haddepth = false; gl.glDeleteTextures(1, &outw.BlitData.backbuffer); + if(outw.BlitData.depthstencil) + { + haddepth = true; + gl.glDeleteTextures(1, &outw.BlitData.depthstencil); + } gl.glDeleteFramebuffers(1, &outw.BlitData.windowFBO); - CreateOutputWindowBackbuffer(outw); + CreateOutputWindowBackbuffer(outw, haddepth); return true; } @@ -224,6 +247,8 @@ void GLReplay::BindOutputWindow(uint64_t id, bool depth) m_pDriver->glBindFramebuffer(eGL_FRAMEBUFFER, outw.BlitData.windowFBO); m_pDriver->glViewport(0, 0, outw.width, outw.height); + m_pDriver->glFramebufferTexture(eGL_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, depth && outw.BlitData.depthstencil ? outw.BlitData.depthstencil : 0, 0); + DebugData.outWidth = float(outw.width); DebugData.outHeight = float(outw.height); } @@ -232,8 +257,6 @@ void GLReplay::ClearOutputWindowColour(uint64_t id, float col[4]) if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) return; - OutputWindow &outw = m_OutputWindows[id]; - MakeCurrentReplayContext(m_DebugCtx); m_pDriver->glClearBufferfv(eGL_COLOR, 0, col); @@ -244,11 +267,9 @@ void GLReplay::ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) return; - OutputWindow &outw = m_OutputWindows[id]; - - MakeCurrentReplayContext(&outw); + MakeCurrentReplayContext(m_DebugCtx); - m_pDriver->glClearBufferfv(eGL_DEPTH, 0, &depth); + m_pDriver->glClearBufferfi(eGL_DEPTH_STENCIL, 0, depth, (GLint)stencil); } void GLReplay::FlipOutputWindow(uint64_t id) diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index dfa70964d..1b3be4f6d 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -146,8 +146,9 @@ class GLReplay : public IReplayDriver // used to blit from defined FBO (VAOs not shared) GLuint emptyVAO; - // texture for the below FBO. Resizes with the window + // textures for the below FBO. Resize with the window GLuint backbuffer; + GLuint depthstencil; // this FBO is on the debug GL context, not the window's GL context // when rendering a texture or mesh etc, we render onto this FBO on @@ -202,6 +203,7 @@ class GLReplay : public IReplayDriver GLuint genericProg; GLuint meshProg; + GLuint meshgsProg; GLuint meshVAO; GLuint outlineStripVB; @@ -222,11 +224,11 @@ class GLReplay : public IReplayDriver void InitDebugData(); void DeleteDebugData(); - GLuint CreateShaderProgram(const char *vs, const char *ps); + GLuint CreateShaderProgram(const char *vs, const char *ps, const char *gs = NULL); GLuint CreateCShaderProgram(const char *cs); void InitOutputWindow(OutputWindow &outwin); - void CreateOutputWindowBackbuffer(OutputWindow &outwin); + void CreateOutputWindowBackbuffer(OutputWindow &outwin, bool depth); GLWindowingData m_ReplayCtx; int64_t m_DebugID; diff --git a/renderdoc/driver/gl/gl_replay_linux.cpp b/renderdoc/driver/gl/gl_replay_linux.cpp index 1fdc517d7..3df589656 100644 --- a/renderdoc/driver/gl/gl_replay_linux.cpp +++ b/renderdoc/driver/gl/gl_replay_linux.cpp @@ -154,7 +154,7 @@ uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth) MakeCurrentReplayContext(&win); InitOutputWindow(win); - CreateOutputWindowBackbuffer(win); + CreateOutputWindowBackbuffer(win, depth); uint64_t ret = m_OutputWindowID++; diff --git a/renderdoc/driver/gl/gl_replay_win32.cpp b/renderdoc/driver/gl/gl_replay_win32.cpp index 86f5ab99b..54f5d2aca 100644 --- a/renderdoc/driver/gl/gl_replay_win32.cpp +++ b/renderdoc/driver/gl/gl_replay_win32.cpp @@ -183,7 +183,7 @@ uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth) win.height = rect.bottom-rect.top; InitOutputWindow(win); - CreateOutputWindowBackbuffer(win); + CreateOutputWindowBackbuffer(win, depth); uint64_t ret = m_OutputWindowID++;