protot/src/modules/RenderModule.cc

248 lines
6.9 KiB
C++
Raw Normal View History

#include "RuntimeModule.h"
#include "Globals.h"
#include "RenderModule.h"
2018-02-13 14:27:16 +01:00
#include <GLFW/glfw3.h>
struct Renderer;
2018-02-13 12:05:07 +01:00
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
2018-02-14 13:14:10 +01:00
1.0f, -1.0f, -1.2f,
2018-02-13 12:05:07 +01:00
0.0f, 1.0f, 0.0f
};
2018-02-13 14:27:16 +01:00
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
};
2018-02-12 21:35:44 +01:00
//
// Module
//
struct module_state {
Renderer *renderer;
};
static struct module_state *module_init() {
gLog ("%s %s called", __FILE__, __FUNCTION__);
assert (gWindow != nullptr && "Cannot initialize renderer module without gWindow!");
module_state *state = (module_state*) malloc(sizeof(*state));
state->renderer = new Renderer();
assert (state->renderer != nullptr);
return state;
}
template <typename Serializer>
static void module_serialize (
struct module_state *state,
Serializer* serializer) {
2018-02-12 21:35:44 +01:00
// // get the state from the serializer
// Camera* camera = &gRenderer->cameras[gRenderer->activeCameraIndex];
// assert (camera != nullptr);
2018-02-12 21:35:44 +01:00
// SerializeBool (*serializer, "protot.RenderModule.draw_floor", gRenderer->drawFloor);
// SerializeBool (*serializer, "protot.RenderModule.draw_skybox", gRenderer->drawSkybox);
// SerializeBool (*serializer, "protot.RenderModule.debug_enabled", gRenderer->drawDebug);
// SerializeVec3 (*serializer, "protot.RenderModule.camera.eye", camera->eye);
// SerializeVec3 (*serializer, "protot.RenderModule.camera.poi", camera->poi);
}
static void module_finalize(struct module_state *state) {
gLog ("%s %s called (state %p)", __FILE__, __FUNCTION__, state);
assert (state->renderer != nullptr);
delete state->renderer;
free(state);
}
static void module_reload(struct module_state *state, void *read_serializer) {
gLog ("%s %s called (state %p)", __FILE__, __FUNCTION__, state);
assert (gWindow != nullptr);
2017-02-05 10:36:37 +01:00
gLog ("Renderer initialize");
assert (state != nullptr);
2018-02-12 21:35:44 +01:00
state->renderer->Initialize(100, 100);
2018-02-13 12:05:07 +01:00
gRenderer = state->renderer;
// load the state of the module
if (read_serializer != nullptr) {
module_serialize(state, static_cast<ReadSerializer*>(read_serializer));
}
}
static void module_unload(struct module_state *state, void* write_serializer) {
// serialize the state of the module
if (write_serializer != nullptr) {
module_serialize(state, static_cast<WriteSerializer*>(write_serializer));
}
gRenderer = nullptr;
2018-02-12 21:35:44 +01:00
state->renderer->Shutdown();
2017-02-05 10:36:37 +01:00
gLog ("RenderModule unload called");
}
static bool module_step(struct module_state *state, float dt) {
int width, height;
assert (gWindow != nullptr);
2018-02-12 21:35:44 +01:00
state->renderer->RenderGui();
state->renderer->RenderGl();
2017-02-18 17:22:21 +01:00
return true;
}
extern "C" {
const struct module_api MODULE_API = {
.init = module_init,
.reload = module_reload,
.step = module_step,
.unload = module_unload,
.finalize = module_finalize
};
}
2016-12-17 23:04:50 +01:00
//
2018-02-12 21:35:44 +01:00
// Camera
//
void Camera::updateMatrices() {
}
//
2018-02-12 21:35:44 +01:00
// Camera
//
void Renderer::Initialize(int width, int height) {
2018-02-13 12:05:07 +01:00
glGenVertexArrays(1, &mMesh.mVertexArrayId);
glBindVertexArray(mMesh.mVertexArrayId);
glGenBuffers(1, &mMesh.mVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mMesh.mVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
2018-02-13 14:27:16 +01:00
// Shaders
2018-02-13 12:05:07 +01:00
mProgram = RenderProgram("data/shaders/vs_simple.glsl", "data/shaders/fs_simple.glsl");
bool load_result = mProgram.Load();
assert(load_result);
2018-02-13 14:27:16 +01:00
// Render Target
2018-02-14 13:14:10 +01:00
mRenderTarget = RenderTarget (width, height, RenderTarget::EnableColor | RenderTarget::EnableDepthTexture);
2018-02-13 14:27:16 +01:00
// 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);
2018-02-15 09:59:38 +01:00
// Program for color texture rendering
2018-02-13 14:27:16 +01:00
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");
2018-02-15 09:59:38 +01:00
// Program for depth texture rendering
mRenderQuadProgramDepth = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_depthbuffer.glsl");
load_result = mRenderQuadProgramDepth.Load();
assert(load_result);
muRenderQuadDepthNear = glGetUniformLocation(mRenderQuadProgramDepth.mProgramId, "near");
muRenderQuadDepthFar = glGetUniformLocation(mRenderQuadProgramDepth.mProgramId, "far");
}
2018-02-12 21:35:44 +01:00
void Renderer::Shutdown() {
2018-02-13 12:05:07 +01:00
glDeleteVertexArrays(1, &mMesh.mVertexArrayId);
2016-11-27 22:02:17 +01:00
}
2018-02-13 14:27:16 +01:00
2018-02-12 21:35:44 +01:00
void Renderer::RenderGl() {
2018-02-13 14:27:16 +01:00
int width, height;
glfwGetWindowSize(gWindow, &width, &height);
if (width != mWidth || height != mHeight)
Resize(width, height);
2018-02-13 14:27:16 +01:00
// enable the render target
glBindFramebuffer(GL_FRAMEBUFFER, mRenderTarget.mFrameBufferId);
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
gLog ("Cannot render: frame buffer invalid!");
}
// clear color and depth
2018-02-13 12:05:07 +01:00
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2018-02-14 13:14:10 +01:00
glEnable(GL_DEPTH_TEST);
2018-02-13 12:05:07 +01:00
glUseProgram(mProgram.mProgramId);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, mMesh.mVertexBuffer);
glVertexAttribPointer(
0, // attribute 0
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // offset
);
glDrawArrays(GL_TRIANGLES, 0, 3); // starting from vertex 0; 3 vertices total
glDisableVertexAttribArray(0);
}
2018-02-12 21:35:44 +01:00
void Renderer::RenderGui() {
2018-02-13 14:27:16 +01:00
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
2018-02-15 09:59:38 +01:00
bool render_color = false;
if (render_color) {
// Render the full screen quad
glUseProgram(mRenderQuadProgramColor.mProgramId);
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mColorTexture);
glUniform1i(muRenderQuadTexture, 0);
glUniform1f(muRenderQuadTime, (float)(glfwGetTime() * 10.0f));
} else {
// render depth texture
glUseProgram(mRenderQuadProgramDepth.mProgramId);
glBindTexture(GL_TEXTURE_2D, mRenderTarget.mDepthTexture);
glUniform1i(muRenderQuadTexture, 0);
glUniform1f(muRenderQuadDepthNear, 1.0);
glUniform1f(muRenderQuadDepthFar, -1.0);
}
2018-02-13 14:27:16 +01:00
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);
}
2018-02-12 21:35:44 +01:00
void Renderer::Resize (int width, int height) {
mWidth = width;
mHeight = height;
mRenderTarget.Resize(mWidth, mHeight);
glViewport(0, 0, mWidth, mHeight);
}