sdl_runtime_compiler git · main
SDL3 game for running and compiling code at runtime
C++ 72.3% C 26.2%git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gzFix aliasing a bit With Claude
src/rendering/gl_renderer.cpp | 63 ++++++++++++++++++++++++++++++------------- src/rendering/gl_renderer.hpp | 4 +++ 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/src/rendering/gl_renderer.cpp b/src/rendering/gl_renderer.cpp index 4d5c6ce..a0bffb4 100644 --- a/src/rendering/gl_renderer.cpp +++ b/src/rendering/gl_renderer.cpp @@ -539,7 +539,7 @@ GlRenderer::begin_Frame(int w, int h) else resize_FBO_(w, h); // Bind the FBO as the render target. - glBindFramebuffer(GL_FRAMEBUFFER, _scene_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, _scene_fbo_ms); glViewport(0, 0, w, h); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -559,6 +559,13 @@ GlRenderer::begin_Frame(int w, int h) void GlRenderer::end_Frame(SDL_Window* window) { + glBindFramebuffer(GL_READ_FRAMEBUFFER, _scene_fbo_ms); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _scene_fbo); + glBlitFramebuffer(0, 0, _fbo_w, _fbo_h, + 0, 0, _fbo_w, _fbo_h, + GL_COLOR_BUFFER_BIT, GL_NEAREST); // MS resolve requires NEAREST + glBindFramebuffer(GL_FRAMEBUFFER, 0); + // Run bloom passes (extract + blur). { FP_ZONE("end_Frame.bloom"); run_BloomPipeline_(); @@ -935,11 +942,35 @@ GlRenderer::create_BlitProgram_() void GlRenderer::create_FBO_(int w, int h) { + GLint max_samples = 0; + glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + if (_msaa_samples > max_samples) _msaa_samples = max_samples; + if (_msaa_samples < 1) _msaa_samples = 1; + + // ── Multisampled FBO: the scene renders here ──────────────────────── + glGenFramebuffers(1, &_scene_fbo_ms); + glBindFramebuffer(GL_FRAMEBUFFER, _scene_fbo_ms); + + glGenRenderbuffers(1, &_scene_color_rbo_ms); + glBindRenderbuffer(GL_RENDERBUFFER, _scene_color_rbo_ms); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, _msaa_samples, GL_RGBA8, w, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, _scene_color_rbo_ms); + + glGenRenderbuffers(1, &_scene_depth_rbo_ms); + glBindRenderbuffer(GL_RENDERBUFFER, _scene_depth_rbo_ms); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, _msaa_samples, + GL_DEPTH_COMPONENT24, w, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, _scene_depth_rbo_ms); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MSAA scene FBO incomplete"); + + // ── Single-sample resolve FBO: bloom + composite read this texture ── glGenFramebuffers(1, &_scene_fbo); glBindFramebuffer(GL_FRAMEBUFFER, _scene_fbo); - // Color attachment: RGBA8 texture (LDR for now; future HDR upgrade - // would use GL_RGBA16F here). glGenTextures(1, &_scene_color_tex); glBindTexture(GL_TEXTURE_2D, _scene_color_tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); @@ -949,22 +980,13 @@ GlRenderer::create_FBO_(int w, int h) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _scene_color_tex, 0); + // Depth now lives on the MS FBO, so the resolve target needs none. - // Depth attachment: renderbuffer (we don't sample depth in postprocess, - // so renderbuffer is fine and slightly cheaper than a depth texture). - glGenRenderbuffers(1, &_scene_depth_rbo); - glBindRenderbuffer(GL_RENDERBUFFER, _scene_depth_rbo); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, w, h); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, _scene_depth_rbo); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Scene FBO incomplete: 0x%x", status); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Resolve FBO incomplete"); glBindFramebuffer(GL_FRAMEBUFFER, 0); - _fbo_w = w; - _fbo_h = h; + _fbo_w = w; _fbo_h = h; } void @@ -1125,9 +1147,12 @@ GlRenderer::create_CompositeProgram_() void GlRenderer::destroy_FBO_() { - if (_scene_color_tex) { glDeleteTextures (1, &_scene_color_tex); _scene_color_tex = 0; } - if (_scene_depth_rbo) { glDeleteRenderbuffers(1, &_scene_depth_rbo); _scene_depth_rbo = 0; } - if (_scene_fbo) { glDeleteFramebuffers (1, &_scene_fbo); _scene_fbo = 0; } + if (_scene_color_tex) { glDeleteTextures(1, &_scene_color_tex); _scene_color_tex = 0; } + if (_scene_depth_rbo) { glDeleteRenderbuffers(1, &_scene_depth_rbo); _scene_depth_rbo = 0; } + if (_scene_fbo) { glDeleteFramebuffers(1, &_scene_fbo); _scene_fbo = 0; } + if (_scene_color_rbo_ms) { glDeleteRenderbuffers(1, &_scene_color_rbo_ms); _scene_color_rbo_ms = 0; } + if (_scene_depth_rbo_ms) { glDeleteRenderbuffers(1, &_scene_depth_rbo_ms); _scene_depth_rbo_ms = 0; } + if (_scene_fbo_ms) { glDeleteFramebuffers(1, &_scene_fbo_ms); _scene_fbo_ms = 0; } _fbo_w = 0; _fbo_h = 0; } diff --git a/src/rendering/gl_renderer.hpp b/src/rendering/gl_renderer.hpp index 3810468..0694851 100644 --- a/src/rendering/gl_renderer.hpp +++ b/src/rendering/gl_renderer.hpp @@ -86,6 +86,10 @@ class GlRenderer { GLuint _scene_fbo {0}; GLuint _scene_color_tex {0}; GLuint _scene_depth_rbo {0}; + GLuint _scene_fbo_ms {0}; + GLuint _scene_color_rbo_ms {0}; + GLuint _scene_depth_rbo_ms {0}; + int _msaa_samples {4}; int _fbo_w {0}; int _fbo_h {0};