Encapsulate frame buffers
This commit is contained in:
parent
f568e2186f
commit
5bc1703b2c
@ -23,6 +23,8 @@ target_sources(couchlib PUBLIC
|
|||||||
CollisionShape.h
|
CollisionShape.h
|
||||||
CollisionShape.cpp
|
CollisionShape.cpp
|
||||||
constants.h
|
constants.h
|
||||||
|
Framebuffer.h
|
||||||
|
Framebuffer.cpp
|
||||||
Index.h
|
Index.h
|
||||||
Index.cpp
|
Index.cpp
|
||||||
Input.h
|
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);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
// Setup frame buffers
|
// Setup frame buffers
|
||||||
glGenFramebuffers(1, &framebuffer);
|
framebuffer.clearColor = Vector3(1.0f, 0.0f, 0.0f);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
framebuffer.clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
|
||||||
|
framebuffer.depthTest = true;
|
||||||
|
framebuffer.Bind();
|
||||||
|
|
||||||
tex.width = width;
|
tex.width = width;
|
||||||
tex.height = height;
|
tex.height = height;
|
||||||
@ -59,14 +61,17 @@ Screen::Screen() {
|
|||||||
std::cerr << "Error setting up screen framebuffer." << std::endl;
|
std::cerr << "Error setting up screen framebuffer." << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
FramebufferStack::GetStack()->curr->Bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::Enable() {
|
void Screen::Enable() {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
FramebufferStack::GetStack()->Save(&framebuffer);
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
framebuffer.Enable();
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
framebuffer.Clear();
|
||||||
glEnable(GL_DEPTH_TEST);
|
}
|
||||||
|
|
||||||
|
void Screen::Disable() {
|
||||||
|
FramebufferStack::GetStack()->Restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::Draw() {
|
void Screen::Draw() {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "Framebuffer.h"
|
||||||
#include "Vertex.h"
|
#include "Vertex.h"
|
||||||
#include "Material.h"
|
#include "Material.h"
|
||||||
|
|
||||||
@ -14,13 +15,14 @@ class Screen {
|
|||||||
public:
|
public:
|
||||||
Screen();
|
Screen();
|
||||||
void Enable();
|
void Enable();
|
||||||
|
void Disable();
|
||||||
void Draw();
|
void Draw();
|
||||||
const int width = 640;
|
const int width = 640;
|
||||||
const int height = 480;
|
const int height = 480;
|
||||||
Texture tex;
|
Texture tex;
|
||||||
private:
|
private:
|
||||||
Id quad;
|
Id quad;
|
||||||
Id framebuffer;
|
Framebuffer framebuffer;
|
||||||
Id renderbuffer;
|
Id renderbuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,14 +32,6 @@ bool Window::ShouldClose() {
|
|||||||
return glfwWindowShouldClose(glfwWindow);
|
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() {
|
void Window::Update() {
|
||||||
glfwSwapBuffers(glfwWindow);
|
glfwSwapBuffers(glfwWindow);
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "Framebuffer.h"
|
||||||
|
|
||||||
class Window {
|
class Window {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -37,10 +39,6 @@ public:
|
|||||||
@returns whether or not the user tried to close the window
|
@returns whether or not the user tried to close the window
|
||||||
*/
|
*/
|
||||||
bool ShouldClose();
|
bool ShouldClose();
|
||||||
/**
|
|
||||||
Begin rendering to the window
|
|
||||||
*/
|
|
||||||
void Enable();
|
|
||||||
/**
|
/**
|
||||||
Swap the buffers and poll for events
|
Swap the buffers and poll for events
|
||||||
*/
|
*/
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "Shaders/SkyboxShader.h"
|
#include "Shaders/SkyboxShader.h"
|
||||||
|
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
|
#include "Framebuffer.h"
|
||||||
|
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "Input.h"
|
#include "Input.h"
|
||||||
@ -84,17 +85,21 @@ int main() {
|
|||||||
double delta = 0.0;
|
double delta = 0.0;
|
||||||
|
|
||||||
while(!window.ShouldClose()) {
|
while(!window.ShouldClose()) {
|
||||||
// Physics update()
|
// Physics update
|
||||||
world->Step(delta);
|
world->Step(delta);
|
||||||
|
|
||||||
// Start rendering to texture;
|
// Script update
|
||||||
screen.Enable();
|
|
||||||
|
|
||||||
// Call update function
|
|
||||||
lua->Update(delta);
|
lua->Update(delta);
|
||||||
|
|
||||||
// Delete freed nodes
|
// Delete freed nodes
|
||||||
root->DoFree();
|
root->DoFree();
|
||||||
|
|
||||||
|
// Clear the default shader
|
||||||
|
FramebufferStack::GetStack()->curr->Clear();
|
||||||
|
|
||||||
|
// Start rendering to screen
|
||||||
|
screen.Enable();
|
||||||
|
|
||||||
shader->Use();
|
shader->Use();
|
||||||
shader->UpdateProjection(projection);
|
shader->UpdateProjection(projection);
|
||||||
Matrix view(1.0f);
|
Matrix view(1.0f);
|
||||||
@ -133,11 +138,12 @@ int main() {
|
|||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render to the window
|
// Stop rendering to texture
|
||||||
window.Enable();
|
screen.Disable();
|
||||||
|
|
||||||
screenShader->Use();
|
screenShader->Use();
|
||||||
screenShader->UpdateTex(screen.tex);
|
screenShader->UpdateTex(screen.tex);
|
||||||
|
|
||||||
screen.Draw();
|
screen.Draw();
|
||||||
|
|
||||||
window.Update();
|
window.Update();
|
||||||
|
Loading…
Reference in New Issue
Block a user