Skip to content

Commit 0c3031f

Browse files
committed
feat: implement dynamic framebuffer resizing for postprocessing
1 parent 2baebca commit 0c3031f

4 files changed

Lines changed: 33 additions & 17 deletions

File tree

src/common/systems/forward-renderer.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,24 @@
55

66
namespace our {
77

8+
void ForwardRenderer::resizePostprocess(glm::ivec2 size) {
9+
if (!postprocessMaterial) return;
10+
11+
glBindFramebuffer(GL_FRAMEBUFFER, postprocessFrameBuffer);
12+
13+
colorTarget->bind();
14+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size.x, size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
15+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTarget->getOpenGLName(), 0);
16+
17+
depthTarget->bind();
18+
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, size.x, size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
19+
nullptr);
20+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTarget->getOpenGLName(), 0);
21+
22+
Texture2D::unbind();
23+
glBindFramebuffer(GL_FRAMEBUFFER, 0);
24+
}
25+
826
void ForwardRenderer::initialize(glm::ivec2 windowSize, const nlohmann::json& config) {
927
// First, we store the window size for later use
1028
this->windowSize = windowSize;
@@ -54,21 +72,8 @@ namespace our {
5472
// Then we check if there is a postprocessing shader in the configuration
5573
if (config.contains("postprocess")) {
5674
glGenFramebuffers(1, &postprocessFrameBuffer);
57-
glBindFramebuffer(GL_FRAMEBUFFER, postprocessFrameBuffer);
5875
colorTarget = new Texture2D();
59-
colorTarget->bind();
60-
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, windowSize.x, windowSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
61-
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTarget->getOpenGLName(),
62-
0);
63-
colorTarget->unbind();
64-
6576
depthTarget = new Texture2D();
66-
depthTarget->bind();
67-
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, windowSize.x, windowSize.y, 0, GL_DEPTH_COMPONENT,
68-
GL_UNSIGNED_INT, nullptr);
69-
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTarget->getOpenGLName(), 0);
70-
depthTarget->unbind();
71-
glBindFramebuffer(GL_FRAMEBUFFER, 0);
7277

7378
// Create a vertex array to use for drawing the texture
7479
glGenVertexArrays(1, &postProcessVertexArray);
@@ -94,6 +99,8 @@ namespace our {
9499
// The default options are fine but we don't need to interact with the depth buffer
95100
// so it is more performant to disable the depth mask
96101
postprocessMaterial->pipelineState.depthMask = false;
102+
103+
resizePostprocess(windowSize);
97104
}
98105
}
99106

@@ -125,7 +132,13 @@ namespace our {
125132
}
126133
}
127134

128-
void ForwardRenderer::render(World* world) {
135+
void ForwardRenderer::render(World* world, glm::ivec2 windowSize) {
136+
if (windowSize.x <= 0 || windowSize.y <= 0) return;
137+
if (this->windowSize != windowSize) {
138+
this->windowSize = windowSize;
139+
resizePostprocess(windowSize);
140+
}
141+
129142
// First of all, we search for a camera and for all the mesh renderers
130143
CameraComponent* camera = nullptr;
131144
opaqueCommands.clear();

src/common/systems/forward-renderer.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,16 @@ namespace our {
4242
Texture2D *colorTarget, *depthTarget;
4343
TexturedMaterial* postprocessMaterial;
4444

45+
void resizePostprocess(glm::ivec2 size);
46+
4547
public:
4648
// Initialize the renderer including the sky and the Postprocessing objects.
4749
// windowSize is the width & height of the window (in pixels).
4850
void initialize(glm::ivec2 windowSize, const nlohmann::json& config);
4951
// Clean up the renderer
5052
void destroy();
5153
// This function should be called every frame to draw the given world
52-
void render(World* world);
54+
void render(World* world, glm::ivec2 windowSize);
5355
};
5456

5557
} // namespace our

src/states/play-state.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class Playstate : public our::State {
101101
enemySpawner.update(&world, (float)deltaTime);
102102
// And finally we use the renderer system to draw the scene
103103
collisionSystem.update(&world);
104-
renderer.render(&world);
104+
renderer.render(&world, getApp()->getFrameBufferSize());
105105

106106
#ifdef COLLISION_DEBUG_DRAW
107107
// Toggle debug draw with F3

src/states/renderer-test-state.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ class RendererTestState : public our::State {
3131

3232
void onDraw(double deltaTime) override {
3333
// We simply call the renderer's "render" function and it should do all the rendering work
34-
renderer.render(&world);
34+
renderer.render(&world, getApp()->getFrameBufferSize());
3535
}
3636

3737
void onDestroy() override {
38+
renderer.destroy();
3839
world.clear();
3940
our::clearAllAssets();
4041
}

0 commit comments

Comments
 (0)