mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-25 07:56:33 +00:00
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)
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 vector<MeshF
|
||||
|
||||
GLenum topo = MakeGLPrimitiveTopology(cfg.position.topo);
|
||||
|
||||
gl.glDisable(eGL_DEPTH_TEST);
|
||||
|
||||
GLuint prog = DebugData.meshProg;
|
||||
|
||||
if(cfg.solidShadeMode == eShade_Lit)
|
||||
{
|
||||
// pick program with GS for per-face lighting
|
||||
prog = DebugData.meshgsProg;
|
||||
}
|
||||
|
||||
GLint colLoc = gl.glGetUniformLocation(prog, "RENDERDOC_GenericFS_Color");
|
||||
@@ -1584,13 +1612,20 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshF
|
||||
}
|
||||
|
||||
gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data());
|
||||
|
||||
|
||||
// solid render
|
||||
if(cfg.solidShadeMode != eShade_None && topo != eGL_PATCHES)
|
||||
{
|
||||
gl.glEnable(eGL_DEPTH_TEST);
|
||||
gl.glDepthFunc(eGL_LESS);
|
||||
|
||||
if(cfg.solidShadeMode == eShade_Lit)
|
||||
{
|
||||
// set GS-specific uniform
|
||||
GLint invProjLoc = gl.glGetUniformLocation(prog, "InvProj");
|
||||
|
||||
Matrix4f InvProj = projMat.Inverse();
|
||||
|
||||
gl.glUniformMatrix4fv(invProjLoc, 1, GL_FALSE, InvProj.Data());
|
||||
}
|
||||
|
||||
gl.glEnableVertexAttribArray(1);
|
||||
@@ -1622,16 +1657,21 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector<MeshF
|
||||
}
|
||||
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
}
|
||||
|
||||
if(cfg.solidShadeMode == eShade_Lit)
|
||||
{
|
||||
colLoc = gl.glGetUniformLocation(prog, "RENDERDOC_GenericFS_Color");
|
||||
mvpLoc = gl.glGetUniformLocation(prog, "ModelViewProj");
|
||||
fmtLoc = gl.glGetUniformLocation(prog, "Mesh_DisplayFormat");
|
||||
|
||||
colLoc = gl.glGetUniformLocation(prog, "RENDERDOC_GenericFS_Color");
|
||||
mvpLoc = gl.glGetUniformLocation(prog, "ModelViewProj");
|
||||
fmtLoc = gl.glGetUniformLocation(prog, "Mesh_DisplayFormat");
|
||||
|
||||
gl.glUseProgram(prog);
|
||||
|
||||
gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data());
|
||||
gl.glUseProgram(prog);
|
||||
|
||||
gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data());
|
||||
}
|
||||
}
|
||||
|
||||
gl.glDisable(eGL_DEPTH_TEST);
|
||||
|
||||
// wireframe render
|
||||
if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw || topo == eGL_PATCHES)
|
||||
{
|
||||
|
||||
@@ -139,7 +139,7 @@ Callstack::StackResolver *GLReplay::GetCallstackResolver()
|
||||
return m_pDriver->GetSerialiser()->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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++;
|
||||
|
||||
|
||||
@@ -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++;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user