summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gfx/gl/billboardPainter.cpp10
-rw-r--r--gfx/gl/billboardPainter.h6
-rw-r--r--gfx/gl/glFramebuffer.cpp28
-rw-r--r--gfx/gl/glFramebuffer.h40
-rw-r--r--gfx/gl/sceneRenderer.cpp78
-rw-r--r--gfx/gl/sceneRenderer.h7
-rw-r--r--gfx/gl/shadowMapper.cpp11
-rw-r--r--gfx/gl/shadowMapper.h2
-rw-r--r--gfx/gl/shadowStenciller.cpp6
-rw-r--r--gfx/gl/shadowStenciller.h6
-rw-r--r--lib/glArrays.h6
-rw-r--r--test/testRenderOutput.cpp23
-rw-r--r--test/testRenderOutput.h6
13 files changed, 131 insertions, 98 deletions
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<GL_TEXTURE_2D_ARRAY, 3> & 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<GL_TEXTURE_2D_ARRAY, 3> &, 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 <stdexcept>
+
+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<const GLenum> buffers)
+{
+ glNamedFramebufferDrawBuffers(name, static_cast<GLsizei>(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<GLenum Target>
+ void
+ texture(GLenum attachment, const glTexture<Target> & texture)
+ {
+ glNamedFramebufferTexture(name, attachment, texture, 0);
+ }
+
+ void drawBuffers(std::span<const GLenum> buffers);
+
+ template<std::convertible_to<GLenum>... Buffers>
+ void
+ drawBuffers(Buffers... buffers)
+ {
+ drawBuffers(std::array {static_cast<GLenum>(buffers)...});
+ }
+
+ void buffer(GLenum attachment, const glRenderbuffer &);
+ void assertComplete() const;
+ };
+}
+
+template<size_t N>
+using glFramebuffers = glManagedArray<Impl::glFramebuffer, N, &glCreateFramebuffers, &glDeleteFramebuffers>;
+using glFramebuffer = glManagedSingle<Impl::glFramebuffer, &glCreateFramebuffers, &glDeleteFramebuffers>;
+
+template<size_t N>
+using glRenderbuffers = glManagedArray<Impl::glRenderbuffer, N, &glCreateRenderbuffers, &glDeleteRenderbuffers>;
+using glRenderbuffer = glManagedSingle<Impl::glRenderbuffer, &glCreateRenderbuffers, &glDeleteRenderbuffers>;
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 <gfx/gl/shaders/directionalLight-frag.h>
#include <gfx/gl/shaders/lighting-frag.h>
#include <gfx/gl/shaders/lighting-vert.h>
@@ -23,35 +24,9 @@ SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o, glDebugScope) :
shader.setViewPort({0, 0, size.x, size.y});
displayVAO.configure().addAttribs<glm::i8vec4>(0, displayVBO, displayVAOdata);
- const auto configuregdata = [this](glTexture<GL_TEXTURE_2D> & 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<GLenum, 3> 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<GL_TEXTURE_2D> & data, const GLenum iformat, const GLenum attachment) {
- data = {};
+
+ depth = {};
+ gPosition = {};
+ gNormal = {};
+ gAlbedoSpec = {};
+ gIllumination = {};
+ configureBuffers();
+}
+
+void
+SceneRenderer::configureBuffers()
+{
+ const auto configureAttachment = [this](glFramebuffer & fbo, glTexture<GL_TEXTURE_2D> & 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<GL_TEXTURE_2D> 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<RGBA::value_type>::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<std::array<RelativePosition3D, 4>, SHADOW_BANDS + 1>;
[[nodiscard]] static size_t getBandViewExtents(BandViewExtents &, const Camera &, const glm::mat4 & lightView);
- glFrameBuffer depthMapFBO;
+ glFramebuffer depthMapFBO;
glTexture<GL_TEXTURE_2D_ARRAY> 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<GL_TEXTURE_2D_ARRAY> &, const MeshBase &, Texture::AnyPtr texture) const;
private:
- glFrameBuffer fbo;
+ mutable glFramebuffer fbo;
Program shadowCaster;
Program::RequiredUniformLocation viewProjectionLoc {shadowCaster, "viewProjection"};
diff --git a/lib/glArrays.h b/lib/glArrays.h
index 93ea992..7f5a10b 100644
--- a/lib/glArrays.h
+++ b/lib/glArrays.h
@@ -110,9 +110,3 @@ template<Detail::IsglNamed Named, size_t N, auto Gen, auto Del> struct glManaged
return N;
}
};
-
-template<size_t N> using glFrameBuffers = glManagedArray<Detail::glNamed, N, &glGenFramebuffers, &glDeleteFramebuffers>;
-using glFrameBuffer = glManagedSingle<Detail::glNamed, &glGenFramebuffers, &glDeleteFramebuffers>;
-template<size_t N>
-using glRenderBuffers = glManagedArray<Detail::glNamed, N, &glGenRenderbuffers, &glDeleteRenderbuffers>;
-using glRenderBuffer = glManagedSingle<Detail::glNamed, &glGenRenderbuffers, &glDeleteRenderbuffers>;
diff --git a/test/testRenderOutput.cpp b/test/testRenderOutput.cpp
index b86469a..e2cc437 100644
--- a/test/testRenderOutput.cpp
+++ b/test/testRenderOutput.cpp
@@ -1,25 +1,20 @@
#include "testRenderOutput.h"
#include <gl_traits.h>
-#include <stdexcept>
TestRenderOutput::TestRenderOutput(TextureAbsCoord outputSize) : size {outputSize}
{
- glBindFramebuffer(GL_FRAMEBUFFER, output);
- const auto configuregdata = [this](glTexture<GL_TEXTURE_2D> & data, const GLenum format, const GLenum attachment) {
- data.storage(1, format, size);
+ const auto configureAttachment = [this](glFramebuffer & fbo, glTexture<GL_TEXTURE_2D> & 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);
};
- configuregdata(outImage, GL_RGBA8, GL_COLOR_ATTACHMENT0);
- glDrawBuffer(GL_COLOR_ATTACHMENT0);
+ configureAttachment(output, outImage, GL_RGBA8, GL_COLOR_ATTACHMENT0);
+ output.drawBuffers(GL_COLOR_ATTACHMENT0);
- glBindRenderbuffer(GL_RENDERBUFFER, depth);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.x, size.y);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
+ depth.storage(GL_DEPTH_COMPONENT, size);
+ output.buffer(GL_DEPTH_ATTACHMENT, depth);
- // finally check if framebuffer is complete
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
- throw std::runtime_error("Framebuffer not complete!");
- }
+ output.assertComplete();
}
diff --git a/test/testRenderOutput.h b/test/testRenderOutput.h
index 248485c..e68d1f3 100644
--- a/test/testRenderOutput.h
+++ b/test/testRenderOutput.h
@@ -2,7 +2,7 @@
#include "config/types.h"
#include "game/gamestate.h"
-#include "glArrays.h"
+#include "gfx/gl/glFramebuffer.h"
#include <glm/vec2.hpp>
#include <special_members.h>
@@ -15,8 +15,8 @@ public:
NO_COPY(TestRenderOutput);
const TextureAbsCoord size;
- glFrameBuffer output;
- glRenderBuffer depth;
+ glFramebuffer output;
+ glRenderbuffer depth;
glTexture<GL_TEXTURE_2D> outImage;
GameState gameState;
};