Render `vertCount` world-space triangle vertices from the light into the depth FBO; optionally read the depth back. Depth state goes through the Core bundles so the GL-state audits stay green; ApplyPipeline re-owns depth/cull on the next draw, so only bindings (FBO / program / VAO / buffer / viewport) are restored.
| 265 | // so the GL-state audits stay green; ApplyPipeline re-owns depth/cull on the next |
| 266 | // draw, so only bindings (FBO / program / VAO / buffer / viewport) are restored. |
| 267 | bool RenderDepthFBO(void* glContext, const float* lightVP16, const float* triXYZ, int vertCount, int res, |
| 268 | float* outDepthOrNull) |
| 269 | { |
| 270 | if (!glContext || !lightVP16 || !triXYZ || vertCount < 3 || res <= 0) |
| 271 | return false; |
| 272 | if (!EnsureProgram() || !EnsureTarget(res) || !EnsureMesh()) |
| 273 | return false; |
| 274 | |
| 275 | GLint prevFBO = 0, prevProg = 0, prevVAO = 0, prevArrayBuf = 0; |
| 276 | GLint prevVP[4] = {0, 0, 0, 0}; |
| 277 | glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFBO); |
| 278 | glGetIntegerv(GL_CURRENT_PROGRAM, &prevProg); |
| 279 | glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &prevVAO); |
| 280 | glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prevArrayBuf); |
| 281 | glGetIntegerv(GL_VIEWPORT, prevVP); |
| 282 | glBindFramebuffer(GL_FRAMEBUFFER, s_fbo); |
| 283 | glViewport(0, 0, res, res); |
| 284 | Poseidon::render::depthstencil::Normal(/*hasStencil*/ false); // test on, LEQUAL, write on |
| 285 | Poseidon::render::cull::None(); // single-map probe: capture both faces |
| 286 | glClearDepth(1.0); |
| 287 | Poseidon::render::clear::WithMask(GL_DEPTH_BUFFER_BIT); |
| 288 | |
| 289 | glUseProgram(s_prog); |
| 290 | glUniformMatrix4fv(s_locVP, 1, GL_FALSE, lightVP16); |
| 291 | |
| 292 | GL33Bind::Vao(s_vao); |
| 293 | glBindBuffer(GL_ARRAY_BUFFER, s_vbo); |
| 294 | glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(vertCount) * 3 * sizeof(float), triXYZ, GL_DYNAMIC_DRAW); |
| 295 | glDrawArrays(GL_TRIANGLES, 0, vertCount); |
| 296 | |
| 297 | // GL_DEPTH_COMPONENT float == window-space depth in [0,1]; with ZERO_TO_ONE |
| 298 | // clip control window z == NDC z, matching the CPU oracle. Origin bottom-left. |
| 299 | if (outDepthOrNull) |
| 300 | glReadPixels(0, 0, res, res, GL_DEPTH_COMPONENT, GL_FLOAT, outDepthOrNull); |
| 301 | |
| 302 | glBindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(prevFBO)); |
| 303 | glViewport(prevVP[0], prevVP[1], prevVP[2], prevVP[3]); |
| 304 | glUseProgram(static_cast<GLuint>(prevProg)); |
| 305 | glBindBuffer(GL_ARRAY_BUFFER, static_cast<GLuint>(prevArrayBuf)); |
| 306 | GL33Bind::Vao(static_cast<GLuint>(prevVAO)); |
| 307 | return true; |
| 308 | } |
| 309 | |
| 310 | // Render the casters into each cascade layer of the depth array, once per cascade |
| 311 | // with that cascade's light-VP: solid triangles with the depth-only program, then |
no test coverage detected