void GLReplay::RenderMesh(int frameID, vector<int> eventID, MeshDisplay cfg) { WrappedOpenGL &gl = *m_pDriver; MakeCurrentReplayContext(m_DebugCtx); GLuint curFBO = 0; gl.glGetIntegerv(eGL_FRAMEBUFFER_BINDING, (GLint*)&curFBO); OutputWindow *outw = NULL; for(auto it = m_OutputWindows.begin(); it != m_OutputWindows.end(); ++it) { if(it->second.BlitData.windowFBO == curFBO) { outw = &it->second; break; } } if(!outw) return; const auto &attr = m_CurPipelineState.m_VtxIn.attributes[0]; const auto &vb = m_CurPipelineState.m_VtxIn.vbuffers[attr.BufferSlot]; if(vb.Buffer == ResourceId()) return; MakeCurrentReplayContext(&m_ReplayCtx); GLint viewport[4]; gl.glGetIntegerv(eGL_VIEWPORT, viewport); gl.glGetIntegerv(eGL_FRAMEBUFFER_BINDING, (GLint*)&curFBO); if(outw->BlitData.replayFBO == 0) { gl.glGenFramebuffers(1, &outw->BlitData.replayFBO); gl.glBindFramebuffer(eGL_FRAMEBUFFER, outw->BlitData.replayFBO); gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, outw->BlitData.backbuffer, 0); } else { gl.glBindFramebuffer(eGL_FRAMEBUFFER, outw->BlitData.replayFBO); } gl.glViewport(0, 0, (GLsizei)DebugData.outWidth, (GLsizei)DebugData.outHeight); GLuint curProg = 0; gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint*)&curProg); gl.glUseProgram(DebugData.meshProg); float wireCol[] = { 0.0f, 0.0f, 0.0f, 1.0f }; GLint colLoc = gl.glGetUniformLocation(DebugData.meshProg, "RENDERDOC_GenericFS_Color"); gl.glUniform4fv(colLoc, 1, wireCol); Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, DebugData.outWidth/DebugData.outHeight); Camera cam; if(cfg.arcballCamera) cam.Arcball(cfg.cameraPos.x, Vec3f(cfg.cameraRot.x, cfg.cameraRot.y, cfg.cameraRot.z)); else cam.fpsLook(Vec3f(cfg.cameraPos.x, cfg.cameraPos.y, cfg.cameraPos.z), Vec3f(cfg.cameraRot.x, cfg.cameraRot.y, cfg.cameraRot.z)); Matrix4f camMat = cam.GetMatrix(); Matrix4f ModelViewProj = projMat.Mul(camMat); GLint mvpLoc = gl.glGetUniformLocation(DebugData.meshProg, "ModelViewProj"); gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data()); GLuint curVAO = 0; gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint*)&curVAO); GLuint curArr = 0; gl.glGetIntegerv(eGL_ARRAY_BUFFER_BINDING, (GLint*)&curArr); gl.glBindVertexArray(DebugData.meshVAO); // TODO: we should probably use glBindVertexBuffer, glVertexAttribFormat, glVertexAttribBinding. // For now just assume things about the format and vbuffer. RDCASSERT(attr.Format.compType == eCompType_Float && attr.Format.compByteWidth == 4); gl.glBindBuffer(eGL_ARRAY_BUFFER, m_pDriver->GetResourceManager()->GetLiveResource(vb.Buffer).name); gl.glVertexAttribPointer(0, attr.Format.compCount, eGL_FLOAT, GL_FALSE, 0, (void *)intptr_t(vb.Offset + attr.RelativeOffset)); gl.glEnableVertexAttribArray(0); { GLint depthTest = GL_FALSE; gl.glGetIntegerv(eGL_DEPTH_TEST, (GLint*)&depthTest); GLenum polyMode = eGL_FILL; gl.glGetIntegerv(eGL_POLYGON_MODE, (GLint*)&polyMode); gl.glDisable(eGL_DEPTH_TEST); gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_LINE); ReplayLog(frameID, 0, eventID[0], eReplay_OnlyDraw); if(depthTest) gl.glEnable(eGL_DEPTH_TEST); if(polyMode != eGL_LINE) gl.glPolygonMode(eGL_FRONT_AND_BACK, polyMode); } gl.glBindVertexArray(curVAO); gl.glBindBuffer(eGL_ARRAY_BUFFER, curArr); gl.glUseProgram(curProg); gl.glViewport(viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]); gl.glBindFramebuffer(eGL_FRAMEBUFFER, curFBO); }