From 78b4b043a4fe6be84dd36717c832951a0a464f63 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 10 Mar 2026 01:51:38 +0000 Subject: Switch frame and render buffer to DSA helpers --- gfx/gl/billboardPainter.cpp | 10 +++--- gfx/gl/billboardPainter.h | 6 ++-- gfx/gl/glFramebuffer.cpp | 28 ++++++++++++++++ gfx/gl/glFramebuffer.h | 40 +++++++++++++++++++++++ gfx/gl/sceneRenderer.cpp | 78 ++++++++++++++++++--------------------------- gfx/gl/sceneRenderer.h | 7 ++-- gfx/gl/shadowMapper.cpp | 11 ++----- gfx/gl/shadowMapper.h | 2 +- gfx/gl/shadowStenciller.cpp | 6 ++-- gfx/gl/shadowStenciller.h | 6 ++-- 10 files changed, 119 insertions(+), 75 deletions(-) create mode 100644 gfx/gl/glFramebuffer.cpp create mode 100644 gfx/gl/glFramebuffer.h (limited to 'gfx') diff --git a/gfx/gl/billboardPainter.cpp b/gfx/gl/billboardPainter.cpp index 91d9168..878e950 100644 --- a/gfx/gl/billboardPainter.cpp +++ b/gfx/gl/billboardPainter.cpp @@ -67,12 +67,10 @@ BillboardPainter::renderBillBoard(const glTextures & bil glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glClearColor(0, 0, 0, 0); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, billboard[0], 0); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, billboard[1], 0); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, billboard[2], 0); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - throw std::runtime_error("Billboard framebuffer not complete!"); - } + fbo.texture(GL_DEPTH_ATTACHMENT, billboard[0]); + fbo.texture(GL_COLOR_ATTACHMENT0, billboard[1]); + fbo.texture(GL_COLOR_ATTACHMENT1, billboard[2]); + fbo.assertComplete(); if (texture) { texture->bind(0); } diff --git a/gfx/gl/billboardPainter.h b/gfx/gl/billboardPainter.h index 9f3a39a..617f431 100644 --- a/gfx/gl/billboardPainter.h +++ b/gfx/gl/billboardPainter.h @@ -1,9 +1,9 @@ #pragma once -#include "gfx/gl/program.h" #include "gfx/models/mesh.h" #include "gfx/models/texture.h" -#include "glArrays.h" +#include "glFramebuffer.h" +#include "program.h" class LightDirection; @@ -19,7 +19,7 @@ public: void renderBillBoard(const glTextures &, const MeshBase &, Texture::AnyPtr texture) const; private: - glFrameBuffer fbo; + mutable glFramebuffer fbo; Program program; Program::RequiredUniformLocation viewProjectionLoc {program, "viewProjection"}; Program::RequiredUniformLocation viewLoc {program, "view"}; diff --git a/gfx/gl/glFramebuffer.cpp b/gfx/gl/glFramebuffer.cpp new file mode 100644 index 0000000..fb3290f --- /dev/null +++ b/gfx/gl/glFramebuffer.cpp @@ -0,0 +1,28 @@ +#include "glFramebuffer.h" +#include + +void +Impl::glRenderbuffer::storage(const GLenum iformat, const ImageDimensions dims) +{ + glNamedRenderbufferStorage(name, iformat, dims.x, dims.y); +} + +void +Impl::glFramebuffer::buffer(const GLenum attachment, const Impl::glRenderbuffer & buffer) +{ + glNamedFramebufferRenderbuffer(name, attachment, GL_RENDERBUFFER, buffer); +} + +void +Impl::glFramebuffer::drawBuffers(const std::span buffers) +{ + glNamedFramebufferDrawBuffers(name, static_cast(buffers.size()), buffers.data()); +} + +void +Impl::glFramebuffer::assertComplete() const +{ + if (glCheckNamedFramebufferStatus(name, GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + throw std::runtime_error("Framebuffer not complete!"); + } +} diff --git a/gfx/gl/glFramebuffer.h b/gfx/gl/glFramebuffer.h new file mode 100644 index 0000000..0a4ec5a --- /dev/null +++ b/gfx/gl/glFramebuffer.h @@ -0,0 +1,40 @@ +#pragma once + +#include "config/types.h" +#include "glArrays.h" +#include "glTexture.h" + +namespace Impl { + struct glRenderbuffer : Detail::glNamed { + void storage(GLenum iformat, ImageDimensions); + }; + + struct glFramebuffer : Detail::glNamed { + template + void + texture(GLenum attachment, const glTexture & texture) + { + glNamedFramebufferTexture(name, attachment, texture, 0); + } + + void drawBuffers(std::span buffers); + + template... Buffers> + void + drawBuffers(Buffers... buffers) + { + drawBuffers(std::array {static_cast(buffers)...}); + } + + void buffer(GLenum attachment, const glRenderbuffer &); + void assertComplete() const; + }; +} + +template +using glFramebuffers = glManagedArray; +using glFramebuffer = glManagedSingle; + +template +using glRenderbuffers = glManagedArray; +using glRenderbuffer = glManagedSingle; diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp index 57802fa..ea11bea 100644 --- a/gfx/gl/sceneRenderer.cpp +++ b/gfx/gl/sceneRenderer.cpp @@ -1,5 +1,6 @@ #include "sceneRenderer.h" #include "maths.h" +#include "stream_support.h" #include #include #include @@ -23,35 +24,9 @@ SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o, glDebugScope) : shader.setViewPort({0, 0, size.x, size.y}); displayVAO.configure().addAttribs(0, displayVBO, displayVAOdata); - const auto configuregdata = [this](glTexture & data, const GLenum iformat, const GLenum attachment) { - data.storage(1, iformat, size); - data.parameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST); - data.parameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, data, 0); - }; - - glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); - configuregdata(gPosition, GL_RGB32F, GL_COLOR_ATTACHMENT0); - configuregdata(gNormal, GL_RGB8_SNORM, GL_COLOR_ATTACHMENT1); - configuregdata(gAlbedoSpec, GL_RGB8, GL_COLOR_ATTACHMENT2); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - throw std::runtime_error("Framebuffer could not be completed! (setup gBuffer)"); - } - constexpr std::array attachments {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2}; - glDrawBuffers(attachments.size(), attachments.data()); - - glBindRenderbuffer(GL_RENDERBUFFER, depth); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.x, size.y); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth); - - glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll); - configuregdata(gIllumination, GL_RGB8, GL_COLOR_ATTACHMENT0); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - throw std::runtime_error("Framebuffer could not be completed! (setup gBufferIll)"); - } - glDrawBuffer(GL_COLOR_ATTACHMENT0); - - glBindFramebuffer(GL_FRAMEBUFFER, output); + gBuffer.drawBuffers(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2); + gBufferIll.drawBuffers(GL_COLOR_ATTACHMENT0); + configureBuffers(); } void @@ -59,29 +34,38 @@ SceneRenderer::resize(ScreenAbsCoord newSize) { glDebugScope _ {output}; size = newSize; + shader.setViewPort({0, 0, size.x, size.y}); camera.setAspect(ratio(size)); - const auto configuregdata = [this](glTexture & data, const GLenum iformat, const GLenum attachment) { - data = {}; + + depth = {}; + gPosition = {}; + gNormal = {}; + gAlbedoSpec = {}; + gIllumination = {}; + configureBuffers(); +} + +void +SceneRenderer::configureBuffers() +{ + const auto configureAttachment = [this](glFramebuffer & fbo, glTexture & data, const GLenum iformat, + const GLenum attachment) { data.storage(1, iformat, size); data.parameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST); data.parameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, data, 0); + fbo.texture(attachment, data); }; - glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); - configuregdata(gPosition, GL_RGB32F, GL_COLOR_ATTACHMENT0); - configuregdata(gNormal, GL_RGB8_SNORM, GL_COLOR_ATTACHMENT1); - configuregdata(gAlbedoSpec, GL_RGB8, GL_COLOR_ATTACHMENT2); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.x, size.y); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - throw std::runtime_error("Framebuffer could not be completed! (resize gBuffer)"); - } - glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll); - configuregdata(gIllumination, GL_RGB8, GL_COLOR_ATTACHMENT0); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - throw std::runtime_error("Framebuffer could not be completed! (resize gBufferIll)"); - } - glDrawBuffer(GL_COLOR_ATTACHMENT0); - shader.setViewPort({0, 0, size.x, size.y}); + + configureAttachment(gBuffer, gPosition, GL_RGB32F, GL_COLOR_ATTACHMENT0); + configureAttachment(gBuffer, gNormal, GL_RGB8_SNORM, GL_COLOR_ATTACHMENT1); + configureAttachment(gBuffer, gAlbedoSpec, GL_RGB8, GL_COLOR_ATTACHMENT2); + + depth.storage(GL_DEPTH_COMPONENT, size); + gBuffer.buffer(GL_DEPTH_ATTACHMENT, depth); + gBuffer.assertComplete(); + + configureAttachment(gBufferIll, gIllumination, GL_RGB8, GL_COLOR_ATTACHMENT0); + gBufferIll.assertComplete(); } void diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h index 3de6000..2901dea 100644 --- a/gfx/gl/sceneRenderer.h +++ b/gfx/gl/sceneRenderer.h @@ -1,8 +1,8 @@ #pragma once #include "billboardPainter.h" +#include "gfx/gl/glFramebuffer.h" #include "gfx/lightDirection.h" -#include "glArrays.h" #include "gldebug.h" #include "program.h" #include "sceneProvider.h" @@ -27,12 +27,13 @@ public: protected: void renderQuad() const; + void configureBuffers(); ScreenAbsCoord size; GLuint output; - glFrameBuffer gBuffer, gBufferIll; + glFramebuffer gBuffer, gBufferIll; glTexture gPosition, gNormal, gAlbedoSpec, gIllumination; - glRenderBuffer depth; + glRenderbuffer depth; class DeferredLightProgram : public Program { public: diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index 28ab360..e01fd20 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -41,14 +41,9 @@ ShadowMapper::ShadowMapper(const TextureAbsCoord & s) : static constexpr RGBA border {std::numeric_limits::infinity()}; depthMap.parameter(GL_TEXTURE_BORDER_COLOR, border); - glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthMap, 0); - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - throw std::runtime_error("Framebuffer not complete!"); - } - glBindFramebuffer(GL_FRAMEBUFFER, 0); + depthMapFBO.texture(GL_DEPTH_ATTACHMENT, depthMap); + depthMapFBO.drawBuffers(GL_NONE); + depthMapFBO.assertComplete(); } constexpr GlobalDistance SHADOW_NEAR = 1; diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h index adae847..f0356b9 100644 --- a/gfx/gl/shadowMapper.h +++ b/gfx/gl/shadowMapper.h @@ -77,7 +77,7 @@ public: private: using BandViewExtents = std::array, SHADOW_BANDS + 1>; [[nodiscard]] static size_t getBandViewExtents(BandViewExtents &, const Camera &, const glm::mat4 & lightView); - glFrameBuffer depthMapFBO; + glFramebuffer depthMapFBO; glTexture depthMap; TextureAbsCoord size; diff --git a/gfx/gl/shadowStenciller.cpp b/gfx/gl/shadowStenciller.cpp index cafae02..9d43fdc 100644 --- a/gfx/gl/shadowStenciller.cpp +++ b/gfx/gl/shadowStenciller.cpp @@ -53,10 +53,8 @@ ShadowStenciller::renderStencil( { glDebugScope _ {fbo}; glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, stencil, 0); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - throw std::runtime_error("Stencil framebuffer not complete!"); - } + fbo.texture(GL_DEPTH_ATTACHMENT, stencil); + fbo.assertComplete(); if (texture) { texture->bind(0); } diff --git a/gfx/gl/shadowStenciller.h b/gfx/gl/shadowStenciller.h index 70dbca9..ff88ff7 100644 --- a/gfx/gl/shadowStenciller.h +++ b/gfx/gl/shadowStenciller.h @@ -1,9 +1,9 @@ #pragma once -#include "gfx/gl/program.h" #include "gfx/models/mesh.h" #include "gfx/models/texture.h" -#include "glArrays.h" +#include "glFramebuffer.h" +#include "program.h" class LightDirection; @@ -19,7 +19,7 @@ public: void renderStencil(const glTexture &, const MeshBase &, Texture::AnyPtr texture) const; private: - glFrameBuffer fbo; + mutable glFramebuffer fbo; Program shadowCaster; Program::RequiredUniformLocation viewProjectionLoc {shadowCaster, "viewProjection"}; -- cgit v1.3