Repository navigation
Implement IRenderer3D on the OpenGL backend - #599
Merged
Merged
Conversation
ImGuiController now implements IRenderer3D through GLRenderer3D: a render target is a framebuffer with an RGBA8 colour texture and an optional D24 renderbuffer, drawn with a second shader program created on first use. TryGetRenderer3D therefore answers true in a desktop application. - A target's handle is its colour texture's name, so it can never collide with a CreateTexture name. DeleteTexture refuses a target and DeleteRenderTarget refuses anything else, freeing nothing either way. - The shader maps clip z from [0, w] onto OpenGL's [-w, w] and flips y, so one Matrix4x4.CreatePerspectiveFieldOfView matrix draws the same upright picture as the software renderer; front faces are GL_CW while drawing. - Clear and Draw restore every piece of state they touch, including both framebuffer bindings, depth test/mask/func, culling and winding, the viewport, scissor and clear values. - Empty index spans are a no-op; an out-of-range index throws ArgumentOutOfRangeException before anything reaches the driver. The calls go through an internal IGL3D seam, and GLRenderer3DTests covers allocation, release, both delete guards, resize, and state restore against a stateful stand-in. Fixes #414 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012BGwLwAUhH4nnCmtfec9ob
…om coverage GL3DWrapper only forwards to a live OpenGL context, which unit tests do not have, so it follows the ExcludeFromCodeCoverage precedent for native interop. The controller's IRenderer3D members and the uninitialised guard are now exercised, as is a second Dispose. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012BGwLwAUhH4nnCmtfec9ob
|
This was referenced Oct 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Requested by Matt · project thread
Before:
ImGuiApp.TryGetRenderer3Dansweredfalsein a real desktop app, because only the software renderer implementedIRenderer3D. The Viewport3D demo fell back to a CPU wireframe outside the test harness.After: the OpenGL backend implements it.
TryGetRenderer3Danswerstrueon desktop, and a caller can draw depth-tested, culled, textured geometry into offscreen targets and show them withImGui.Image. The same matrix draws the same upright picture on OpenGL and on the software renderer.How
GLRenderer3D(new, internal) does the work behind an internalIGL3Dseam.GL3DWrappercarries it to Silk.NET, andImGuiControllerdelegates its newIRenderer3Dmembers to it.IGL3Dis separate from the publicIGLso that no existing implementer breaks.depth: true, a D24 renderbuffer. The handle is the colour texture's name. That is the only value that cannot collide with a liveCreateTexturename, so both crossover guards hold:DeleteTexturethrows on a target, andDeleteRenderTargetthrows on anything else. Neither one frees anything when it refuses.Matrix4x4.CreatePerspectiveFieldOfViewproduces and what the software renderer'sDepthBufferuses. The vertex shader remaps z onto OpenGL's [-w, w]. It also negates y so that row 0 is the top, which is howImGui.Imageshows it. Because that flips winding, front faces areGL_CWwhile drawing.ClearandDrawrestore everything they touch: both draw and read framebuffer bindings (restored to their previous values, not to 0), program, active texture with its unit-0 texture and sampler, VAO, array buffer, depth test/mask/func, cull enable/mode/front face, blend enable/equations/funcs, scissor, viewport and clear values.ArgumentOutOfRangeExceptionbefore anything reaches the driver.ResizeRenderTargetrespecifies storage in place and keeps the handle. The program and buffers are created lazily on the first draw.Tests
GLRenderer3DTestshas 26 tests that run against a stateful stand-in for the context. They cover allocation and release, an incomplete framebuffer, both delete guards (including throughImGuiController.DeleteTexture), resize, line lists, matrix upload order, theVertex3Dbyte layout, and state restore. The restore tests start from a context left in deliberately unusual state and compare a full snapshot before and after. To check the tests can fail, I removed the depth-test restore, the y flip and the index check one at a time, and each change failed a test. The fullImGui.App.Testssuite passes (523 passed, 2 skipped), and the solution builds clean in Release with the ktsu analyzers on.I also checked it on a real context (Mesa llvmpipe, GL 4.5, under Xvfb) with a scratch program that is not committed. It cleared a 64×64 target, drew overlapping quads with depth, a back-wound quad and a perspective triangle, then read the texture back. The output was upright, the depth test worked, the back-wound quad was culled, the perspective triangle passed clipping, there was no GL error, and the depth test and culling were off again afterwards.
CLAUDE.md's Backend-agnostic 3D section now describes the OpenGL implementation. Metal (#413 sub-issue 3) andViewport3D(sub-issue 4) are still open.Fixes #414
🤖 Generated with Claude Code
https://claude.ai/code/session_012BGwLwAUhH4nnCmtfec9ob
Generated by Claude Code