diff --git a/data/shaders/fs_simpletexture.glsl b/data/shaders/fs_simpletexture.glsl new file mode 100644 index 0000000..83c035b --- /dev/null +++ b/data/shaders/fs_simpletexture.glsl @@ -0,0 +1,17 @@ +#version 330 core + +in vec2 uv; + +out vec3 color; + +uniform sampler2D rendered_texture; +uniform float time; + +void main() { + color = texture(rendered_texture, uv + + 0.00 * vec2( + sin(time + 1024.0 * uv.x), + cos(time + 768.0 * uv.y) + ) + ).xyz; +} diff --git a/data/shaders/vs_passthrough.glsl b/data/shaders/vs_passthrough.glsl new file mode 100644 index 0000000..29cf1a5 --- /dev/null +++ b/data/shaders/vs_passthrough.glsl @@ -0,0 +1,10 @@ +#version 330 core + +in vec3 vertex_position_modelspace; + +out vec2 uv; + +void main() { + gl_Position = vec4(vertex_position_modelspace, 1); + uv = (vertex_position_modelspace.xy + vec2(1,1)) / 2.0; +} diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index 212c180..fad207c 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -1,6 +1,7 @@ #include "RuntimeModule.h" #include "Globals.h" #include "RenderModule.h" +#include struct Renderer; @@ -10,6 +11,15 @@ static const GLfloat g_vertex_buffer_data[] = { 0.0f, 1.0f, 0.0f }; +static const GLfloat g_quad_vertex_buffer_data[] = { + -1.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, + 1.0f, -1.0f, 0.0f, + 1.0f, 1.0f, 0.0f +}; + // // Module // @@ -119,17 +129,39 @@ void Renderer::Initialize(int width, int height) { glBindBuffer(GL_ARRAY_BUFFER, mMesh.mVertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); + // Shaders mProgram = RenderProgram("data/shaders/vs_simple.glsl", "data/shaders/fs_simple.glsl"); bool load_result = mProgram.Load(); assert(load_result); + // Render Target mRenderTarget = RenderTarget (width, height, RenderTarget::EnableColor | RenderTarget::EnableDepth); + + // Render Target Quad + glGenVertexArrays(1, &mRenderQuadVertexArrayId); + glBindVertexArray(mRenderQuadVertexArrayId); + + glGenBuffers(1, &mRenderQuadVertexBufferId); + glBindBuffer(GL_ARRAY_BUFFER, mRenderQuadVertexBufferId); + glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW); + mRenderQuadProgramColor = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_simpletexture.glsl"); + load_result = mRenderQuadProgramColor.Load(); + assert(load_result); + + muRenderQuadTexture = glGetUniformLocation(mRenderQuadProgramColor.mProgramId, "rendered_texture"); + muRenderQuadTime = glGetUniformLocation(mRenderQuadProgramColor.mProgramId, "time"); } void Renderer::Shutdown() { glDeleteVertexArrays(1, &mMesh.mVertexArrayId); } + + void Renderer::RenderGl() { + int width, height; + glfwGetWindowSize(gWindow, &width, &height); + mRenderTarget.Resize(width, height); + // enable the render target glBindFramebuffer(GL_FRAMEBUFFER, mRenderTarget.mFrameBufferId); GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 }; @@ -160,6 +192,31 @@ void Renderer::RenderGl() { } void Renderer::RenderGui() { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Render the full screen quad + glUseProgram(mRenderQuadProgramColor.mProgramId); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mRenderTarget.mColorTexture); + glUniform1i(muRenderQuadTexture, 0); + glUniform1f(muRenderQuadTime, 0.0f * (float)(glfwGetTime() * 10.0f)); + + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, mRenderQuadVertexBufferId); + glVertexAttribPointer( + 0, // attribute 0 + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized? + 0, // stride + (void*)0 // offset + ); + + glDrawArrays(GL_TRIANGLES, 0, 6); // starting from vertex 0; 3 vertices total + glDisableVertexAttribArray(0); + } void Renderer::Resize (int width, int height) { diff --git a/src/modules/RenderModule.h b/src/modules/RenderModule.h index d20d44c..55dbc74 100644 --- a/src/modules/RenderModule.h +++ b/src/modules/RenderModule.h @@ -107,19 +107,26 @@ struct Mesh { }; struct Renderer { - bool initialized = false; - uint32_t view_width = 1; - uint32_t view_height = 1; + bool mInitialized = false; + uint32_t mWidth = 1; + uint32_t mHeight = 1; std::vector cameras; Mesh mMesh; RenderProgram mProgram; RenderTarget mRenderTarget; + GLuint mRenderQuadVertexArrayId; + GLuint mRenderQuadVertexBufferId; + RenderProgram mRenderQuadProgramColor; + RenderProgram mRenderQuadProgramDepth; + GLuint muRenderQuadTexture; + GLuint muRenderQuadTime; + Renderer() : - initialized(false), - view_width (0), - view_height (0) + mInitialized(false), + mWidth (0), + mHeight (0) { } void Initialize(int width, int height); diff --git a/src/modules/RenderUtils.cc b/src/modules/RenderUtils.cc index 6234dff..dc0c1d1 100644 --- a/src/modules/RenderUtils.cc +++ b/src/modules/RenderUtils.cc @@ -117,14 +117,50 @@ bool RenderProgram::Load() { // RenderTarget // RenderTarget::RenderTarget(int width, int height, int flags) { + mFlags = flags; + + Cleanup(); + Resize(width, height); +} + +RenderTarget::~RenderTarget() { + Cleanup(); +} + +void RenderTarget::Cleanup() { + if (mFrameBufferId != -1) { + glDeleteFramebuffers(1, &mFrameBufferId); + mFrameBufferId = -1; + } + + if (mColorTexture != -1) { + glDeleteTextures(1, &mColorTexture); + mColorTexture = -1; + } + + if (mDepthBuffer != -1) { + glDeleteRenderbuffers(1, &mDepthBuffer); + mDepthBuffer = -1; + } +} + +void RenderTarget::Resize(int width, int height) { + if (width == mWidth || height == mHeight) + return; + + Cleanup(); + + mWidth = width; + mHeight = height; + glGenFramebuffers(1, &mFrameBufferId); glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId); - if (flags & EnableColor) { + if (mFlags & EnableColor) { glGenTextures(1, &mColorTexture); glBindTexture(GL_TEXTURE_2D, mColorTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, mWidth, mHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -132,16 +168,13 @@ RenderTarget::RenderTarget(int width, int height, int flags) { glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mColorTexture, 0); } - if (flags & EnableDepth) { + if (mFlags & EnableDepth) { glGenRenderbuffers(1, &mDepthBuffer); glBindRenderbuffer(GL_RENDERBUFFER, mDepthBuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, mWidth, mHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBuffer); } -} -RenderTarget::~RenderTarget() { - // TODO: cleanup } diff --git a/src/modules/RenderUtils.h b/src/modules/RenderUtils.h index d645fcb..a834994 100644 --- a/src/modules/RenderUtils.h +++ b/src/modules/RenderUtils.h @@ -145,6 +145,8 @@ struct RenderProgram { }; struct RenderTarget { + int mWidth = 0; + int mHeight = 0; GLuint mFrameBufferId = -1; GLuint mColorTexture = -1; GLuint mDepthBuffer = -1; @@ -154,9 +156,14 @@ struct RenderTarget { EnableDepth = 2 } Flags; + int mFlags = 0; + RenderTarget() {}; RenderTarget(int width, int height, int flags); ~RenderTarget(); + + void Cleanup(); + void Resize(int width, int height); }; #endif