Encapsulate frame buffers
This commit is contained in:
parent
ccd69afc2e
commit
a899135e6f
@ -23,6 +23,8 @@ target_sources(couchlib PUBLIC
|
||||
CollisionShape.h
|
||||
CollisionShape.cpp
|
||||
constants.h
|
||||
Framebuffer.h
|
||||
Framebuffer.cpp
|
||||
Index.h
|
||||
Index.cpp
|
||||
Input.h
|
||||
|
79
core/Framebuffer.cpp
Normal file
79
core/Framebuffer.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
Dane Johnson <dane@danejohnson.org>
|
||||
|
||||
LICENSE
|
||||
|
||||
Couch Copyright (C) 2021 Dane Johnson
|
||||
|
||||
This program comes with ABSOLUTELY NO WARRANTY; without event the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for details at
|
||||
https://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
Framebuffers are essentially just things that can be drawn to. They have
|
||||
a number of settings that are set via stateful calls to OpenGL, so they
|
||||
are wrapped here so they can be saved and restored in a stateless fashion.
|
||||
*/
|
||||
|
||||
#include "Framebuffer.h"
|
||||
|
||||
Framebuffer::Framebuffer() {
|
||||
glGenFramebuffers(1, &fbo);
|
||||
}
|
||||
|
||||
Framebuffer::Framebuffer(Id fbo) {
|
||||
this->fbo = fbo;
|
||||
}
|
||||
|
||||
Framebuffer::~Framebuffer() {
|
||||
// If this isn't the default framebuffer.
|
||||
if (fbo != 0) {
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::Enable() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
if (depthTest) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
} else {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Framebuffer::Clear() {
|
||||
glClearColor(clearColor.x, clearColor.y, clearColor.z, 1.0f);
|
||||
glClear(clearFlags);
|
||||
}
|
||||
|
||||
void Framebuffer::Bind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
}
|
||||
|
||||
// Gotta initialize static members here so DLLs will
|
||||
// only create one instance.
|
||||
static FramebufferStack static_stack;
|
||||
|
||||
void FramebufferStack::Save(Framebuffer *buffer) {
|
||||
stack.push_back(curr);
|
||||
curr = buffer;
|
||||
}
|
||||
|
||||
void FramebufferStack::Restore() {
|
||||
curr = stack.back();
|
||||
stack.pop_back();
|
||||
|
||||
curr->Enable();
|
||||
}
|
||||
|
||||
FramebufferStack *FramebufferStack::GetStack() {
|
||||
return &static_stack;
|
||||
}
|
81
core/Framebuffer.h
Normal file
81
core/Framebuffer.h
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
@file
|
||||
@author Dane Johnson <dane@danejohnson.org>
|
||||
|
||||
@section LICENSE
|
||||
|
||||
Couch Copyright (C) 2021 Dane Johnson
|
||||
|
||||
This program comes with ABSOLUTELY NO WARRANTY; without event the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for details at
|
||||
https://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
@section DESCRIPTION
|
||||
|
||||
Framebuffers are essentially just things that can be drawn to. They have
|
||||
a number of settings that are set via stateful calls to OpenGL, so they
|
||||
are wrapped here so they can be saved and restored in a stateless fashion.
|
||||
*/
|
||||
|
||||
#ifndef FRAMEBUFFER_H
|
||||
#define FRAMEBUFFER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
class Framebuffer {
|
||||
public:
|
||||
Framebuffer();
|
||||
/**
|
||||
If the frame buffer has already been initialized, you can pass it
|
||||
in with this constructor
|
||||
@param fbo the frame buffer object handle.
|
||||
*/
|
||||
Framebuffer(Id fbo);
|
||||
/**
|
||||
Apply the configuration for this framebuffer to the OpenGL state.
|
||||
*/
|
||||
~Framebuffer();
|
||||
void Enable();
|
||||
/**
|
||||
Clear out this framebuffer.
|
||||
*/
|
||||
void Clear();
|
||||
/**
|
||||
Bind the texture without applying configuration.
|
||||
*/
|
||||
void Bind();
|
||||
/**
|
||||
What clear color to draw to this frame buffer
|
||||
*/
|
||||
Vector3 clearColor = Vector3(0.0f, 0.0f, 1.0f);
|
||||
/**
|
||||
What bit(s) to clear in this buffer.
|
||||
*/
|
||||
int clearFlags = GL_COLOR_BUFFER_BIT;
|
||||
/**
|
||||
Should we enable depth testing?
|
||||
*/
|
||||
bool depthTest = false;
|
||||
private:
|
||||
Id fbo;
|
||||
};
|
||||
|
||||
class FramebufferStack {
|
||||
public:
|
||||
void Save(Framebuffer *buffer);
|
||||
void Restore();
|
||||
Framebuffer *curr = new Framebuffer(0); // Start with the default framebuffer
|
||||
static FramebufferStack *GetStack();
|
||||
private:
|
||||
std::vector<Framebuffer *> stack;
|
||||
};
|
||||
|
||||
#endif /* FRAMEBUFFER_H */
|
@ -33,8 +33,10 @@ Screen::Screen() {
|
||||
glBindVertexArray(0);
|
||||
|
||||
// Setup frame buffers
|
||||
glGenFramebuffers(1, &framebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
framebuffer.clearColor = Vector3(1.0f, 0.0f, 0.0f);
|
||||
framebuffer.clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
|
||||
framebuffer.depthTest = true;
|
||||
framebuffer.Bind();
|
||||
|
||||
tex.width = width;
|
||||
tex.height = height;
|
||||
@ -59,14 +61,17 @@ Screen::Screen() {
|
||||
std::cerr << "Error setting up screen framebuffer." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
FramebufferStack::GetStack()->curr->Bind();
|
||||
}
|
||||
|
||||
void Screen::Enable() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
FramebufferStack::GetStack()->Save(&framebuffer);
|
||||
framebuffer.Enable();
|
||||
framebuffer.Clear();
|
||||
}
|
||||
|
||||
void Screen::Disable() {
|
||||
FramebufferStack::GetStack()->Restore();
|
||||
}
|
||||
|
||||
void Screen::Draw() {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "Vertex.h"
|
||||
#include "Material.h"
|
||||
|
||||
@ -14,13 +15,14 @@ class Screen {
|
||||
public:
|
||||
Screen();
|
||||
void Enable();
|
||||
void Disable();
|
||||
void Draw();
|
||||
const int width = 640;
|
||||
const int height = 480;
|
||||
Texture tex;
|
||||
private:
|
||||
Id quad;
|
||||
Id framebuffer;
|
||||
Framebuffer framebuffer;
|
||||
Id renderbuffer;
|
||||
};
|
||||
|
||||
|
@ -32,14 +32,6 @@ bool Window::ShouldClose() {
|
||||
return glfwWindowShouldClose(glfwWindow);
|
||||
}
|
||||
|
||||
void Window::Enable() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void Window::Update() {
|
||||
glfwSwapBuffers(glfwWindow);
|
||||
glfwPollEvents();
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "Framebuffer.h"
|
||||
|
||||
class Window {
|
||||
public:
|
||||
/**
|
||||
@ -37,10 +39,6 @@ public:
|
||||
@returns whether or not the user tried to close the window
|
||||
*/
|
||||
bool ShouldClose();
|
||||
/**
|
||||
Begin rendering to the window
|
||||
*/
|
||||
void Enable();
|
||||
/**
|
||||
Swap the buffers and poll for events
|
||||
*/
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "Shaders/SkyboxShader.h"
|
||||
|
||||
#include "Screen.h"
|
||||
#include "Framebuffer.h"
|
||||
|
||||
#include "Camera.h"
|
||||
#include "Input.h"
|
||||
@ -84,17 +85,21 @@ int main() {
|
||||
double delta = 0.0;
|
||||
|
||||
while(!window.ShouldClose()) {
|
||||
// Physics update()
|
||||
// Physics update
|
||||
world->Step(delta);
|
||||
|
||||
// Start rendering to texture;
|
||||
screen.Enable();
|
||||
|
||||
// Call update function
|
||||
// Script update
|
||||
lua->Update(delta);
|
||||
|
||||
// Delete freed nodes
|
||||
root->DoFree();
|
||||
|
||||
// Clear the default shader
|
||||
FramebufferStack::GetStack()->curr->Clear();
|
||||
|
||||
// Start rendering to screen
|
||||
screen.Enable();
|
||||
|
||||
shader->Use();
|
||||
shader->UpdateProjection(projection);
|
||||
Matrix view(1.0f);
|
||||
@ -133,11 +138,12 @@ int main() {
|
||||
glDepthFunc(GL_LESS);
|
||||
}
|
||||
|
||||
// Render to the window
|
||||
window.Enable();
|
||||
|
||||
// Stop rendering to texture
|
||||
screen.Disable();
|
||||
|
||||
screenShader->Use();
|
||||
screenShader->UpdateTex(screen.tex);
|
||||
|
||||
screen.Draw();
|
||||
|
||||
window.Update();
|
||||
|
Loading…
Reference in New Issue
Block a user