20 #include "ResourceManager.h" 21 #include "constants.h" 22 #include "GameObject.h" 23 #include "CubeMapTexture.h" 33 template <
typename T > std::string to_string(
const T& n )
35 std::ostringstream stm ;
50 void Renderer::initRenderer(
int width,
int height) {
52 resize(width, height);
55 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
58 void Renderer::resize(
unsigned int width,
unsigned int height) {
60 glViewport(0, 0, width, height);
62 postProcessFbo = createPostProcessFbo(width, height);
63 verticalBlurFbo = createPostProcessFbo(width, height);
64 horizontalBlurFbo = createPostProcessFbo(width, height);
65 cutOffFbo = createPostProcessFbo(width, height);
74 void Renderer::drawScene(
Camera *camera,
Scene *scene,
float currentTime)
76 Renderer::currentTime = currentTime;
78 chag::float4x4 viewMatrix = camera->getViewMatrix();
79 chag::float4x4 projectionMatrix = camera->getProjectionMatrix();
80 chag::float4x4 viewProjectionMatrix = projectionMatrix * viewMatrix;
85 glEnable(GL_CULL_FACE);
91 chag::float4x4 lightMatrix = chag::make_identity<chag::float4x4>();
93 if (scene->shadowMapCamera != NULL) {
94 chag::float4x4 lightViewMatrix = scene->shadowMapCamera->getViewMatrix();
95 chag::float4x4 lightProjectionMatrix = scene->shadowMapCamera->getProjectionMatrix();
96 chag::float4x4 lightViewProjectionMatrix = lightProjectionMatrix * lightViewMatrix;
98 lightMatrix = chag::make_translation(chag::make_vector( 0.5f, 0.5f, 0.5f ))
99 * chag::make_scale<chag::float4x4>(chag::make_vector(0.5f, 0.5f, 0.5f))
100 * lightViewProjectionMatrix
101 * inverse(viewMatrix);
103 drawShadowMap(sbo, lightViewProjectionMatrix, scene);
109 glBindFramebuffer(GL_FRAMEBUFFER, postProcessFbo.id);
110 glClearColor(0.2f, 0.2f, 0.8f, 1.0f);
112 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
113 int w = Globals::get(Globals::Key::WINDOW_WIDTH);
114 int h = Globals::get(Globals::Key::WINDOW_HEIGHT);
115 glViewport(0, 0, w, h);
117 shaderProgram->
use();
119 shaderProgram->setUniformBufferSubData( UNIFORM_BUFFER_OBJECT_MATRICES_NAME, 0 *
sizeof(chag::float4x4),
sizeof(chag::float4x4), &(viewMatrix.c1.x));
120 shaderProgram->setUniformBufferSubData( UNIFORM_BUFFER_OBJECT_MATRICES_NAME, 1 *
sizeof(chag::float4x4),
sizeof(chag::float4x4), &(projectionMatrix.c1.x));
121 shaderProgram->setUniformBufferSubData( UNIFORM_BUFFER_OBJECT_MATRICES_NAME, 2 *
sizeof(chag::float4x4),
sizeof(chag::float4x4), &(viewProjectionMatrix.c1.x));
124 shaderProgram->setUniformMatrix4fv(
"lightMatrix", lightMatrix);
125 shaderProgram->setUniformMatrix4fv(
"inverseViewNormalMatrix", transpose(viewMatrix));
126 shaderProgram->setUniform3f(
"viewPosition", camera->getPosition());
127 shaderProgram->setUniformMatrix4fv(
"viewMatrix", viewMatrix);
129 setLights(shaderProgram, scene);
131 setFog(shaderProgram);
134 if (scene->shadowMapCamera != NULL) {
135 shaderProgram->setUniform1i(
"has_shadow_map", 1);
136 shaderProgram->setUniform1i(
"shadowMap", 1);
137 glActiveTexture(GL_TEXTURE1);
138 glBindTexture(GL_TEXTURE_2D, sbo.texture);
142 if (scene->cubeMap !=
nullptr) {
143 shaderProgram->setUniform1i(
"hasCubeMap", 1);
144 shaderProgram->setUniform1i(
"cubeMap", 2);
145 glActiveTexture(GL_TEXTURE2);
146 scene->cubeMap->bind(GL_TEXTURE2);
148 shaderProgram->setUniform1i(
"hasCubeMap", 0);
149 shaderProgram->setUniform1i(
"cubeMap", 2);
152 drawShadowCasters(shaderProgram, scene);
155 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
156 drawTransparent(shaderProgram, scene);
168 shaderProgram->setUniform3f(
"directionalLight.colors.ambientColor", scene->directionalLight.ambientColor);
169 shaderProgram->setUniform3f(
"directionalLight.colors.diffuseColor", scene->directionalLight.diffuseColor);
170 shaderProgram->setUniform3f(
"directionalLight.colors.specularColor", scene->directionalLight.specularColor);
171 shaderProgram->setUniform3f(
"directionalLight.direction", scene->directionalLight.direction);
175 shaderProgram->setUniform1i(
"nrPointLights", (
int)scene->pointLights.size());
176 for (
int i = 0; i < (int)scene->pointLights.size(); i++) {
177 std::string name = std::string(
"pointLights[") + patch::to_string(i).c_str() +
"]";
178 shaderProgram->setUniform3f((name +
".position").c_str(), scene->pointLights[i].position);
179 shaderProgram->setUniform3f((name +
".colors.ambientColor").c_str(), scene->pointLights[i].ambientColor);
180 shaderProgram->setUniform3f((name +
".colors.diffuseColor").c_str(), scene->pointLights[i].diffuseColor);
181 shaderProgram->setUniform3f((name +
".colors.specularColor").c_str(), scene->pointLights[i].specularColor);
182 shaderProgram->setUniform1f((name +
".attenuation.constant").c_str(), scene->pointLights[i].attenuation.constant);
183 shaderProgram->setUniform1f((name +
".attenuation.linear").c_str(), scene->pointLights[i].attenuation.linear);
184 shaderProgram->setUniform1f((name +
".attenuation.exp").c_str(), scene->pointLights[i].attenuation.exp);
188 shaderProgram->setUniform1i(
"nrSpotLights", (
int)scene->spotLights.size());
189 for (
int i = 0; i < (int)scene->spotLights.size(); i++) {
190 std::string name = std::string(
"spotLights[") + patch::to_string(i).c_str() +
"]";
191 shaderProgram->setUniform3f((name +
".position").c_str(), scene->spotLights[i].position);
192 shaderProgram->setUniform3f((name +
".colors.ambientColor").c_str(), scene->spotLights[i].ambientColor);
193 shaderProgram->setUniform3f((name +
".colors.diffuseColor").c_str(), scene->spotLights[i].diffuseColor);
194 shaderProgram->setUniform3f((name +
".colors.specularColor").c_str(), scene->spotLights[i].specularColor);
195 shaderProgram->setUniform1f((name +
".attenuation.constant").c_str(), scene->spotLights[i].attenuation.constant);
196 shaderProgram->setUniform1f((name +
".attenuation.linear").c_str(), scene->spotLights[i].attenuation.linear);
197 shaderProgram->setUniform1f((name +
".attenuation.exp").c_str(), scene->spotLights[i].attenuation.exp);
198 shaderProgram->setUniform3f((name +
".direction").c_str(), scene->spotLights[i].direction);
199 shaderProgram->setUniform1f((name +
".cutoff").c_str(), scene->spotLights[i].cutOff);
200 shaderProgram->setUniform1f((name +
".cutoffOuter").c_str(), scene->spotLights[i].outerCutOff);
210 std::vector<GameObject*> shadowCasters = scene->getShadowCasters();
211 for (
unsigned int i = 0; i < scene->getShadowCasters().size(); i++) {
212 shaderProgram->setUniform1f(
"object_reflectiveness", (*shadowCasters[i]).shininess);
213 drawModel(*shadowCasters[i], shaderProgram);
219 std::vector<GameObject*> transparentObjects = scene->getTransparentObjects();
220 for (
unsigned int i = 0; i < transparentObjects.size(); i++) {
221 shaderProgram->setUniform1f(
"object_reflectiveness", (*transparentObjects[i]).shininess);
222 drawModel(*transparentObjects[i], shaderProgram);
226 void Renderer::drawShadowMap(
Fbo sbo, chag::float4x4 viewProjectionMatrix,
Scene *scene) {
227 glBindFramebuffer(GL_FRAMEBUFFER, sbo.id);
228 glViewport(0, 0, SHADOW_MAP_RESOLUTION, SHADOW_MAP_RESOLUTION);
230 glClearColor(1.0, 1.0, 1.0, 1.0);
232 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
234 glEnable(GL_POLYGON_OFFSET_FILL);
235 glPolygonOffset(2.5, 2.0);
237 GLint currentProgram;
238 glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram);
239 sbo.shaderProgram->
use();
240 sbo.shaderProgram->setUniformMatrix4fv(
"viewProjectionMatrix", viewProjectionMatrix);
242 std::vector<GameObject*> shadowCasters = scene->getShadowCasters();
243 for (
unsigned int i = 0; i < shadowCasters.size(); i++) {
244 sbo.shaderProgram->setUniform1f(
"object_reflectiveness", (*shadowCasters[i]).shininess);
245 (*shadowCasters[i]).renderShadow(sbo.shaderProgram);
249 glDisable(GL_POLYGON_OFFSET_FILL);
250 glBindFramebuffer(GL_FRAMEBUFFER, 0);
251 glUseProgram(currentProgram);
255 shaderProgram->setUniform1i(
"fog.iEquation", effects.fog.fEquation);
256 shaderProgram->setUniform1f(
"fog.fDensity", effects.fog.fDensity);
257 shaderProgram->setUniform1f(
"fog.fEnd", effects.fog.fEnd);
258 shaderProgram->setUniform1f(
"fog.fStart", effects.fog.fStart);
259 shaderProgram->setUniform3f(
"fog.vColor", effects.fog.vColor);
262 void Renderer::initGL()
267 if (!glBindFragDataLocation)
269 glBindFragDataLocation = glBindFragDataLocationEXT;
275 ResourceManager::loadShader(
"shaders/simple.vert",
"shaders/simple.frag", SIMPLE_SHADER_NAME);
277 shaderProgram = ResourceManager::getShader(SIMPLE_SHADER_NAME);
278 shaderProgram->setUniformBufferObjectBinding(UNIFORM_BUFFER_OBJECT_MATRICES_NAME, UNIFORM_BUFFER_OBJECT_MATRICES_INDEX);
279 shaderProgram->initUniformBufferObject(UNIFORM_BUFFER_OBJECT_MATRICES_NAME, 3 *
sizeof(chag::float4x4), UNIFORM_BUFFER_OBJECT_MATRICES_INDEX);
288 Logger::logInfo(
"Generating OpenGL data.");
290 ResourceManager::loadShader(
"shaders/shadowMap.vert",
"shaders/shadowMap.frag",
"SHADOW_SHADER");
291 sbo.shaderProgram = ResourceManager::getShader(
"SHADOW_SHADER");
293 sbo.width = SHADOW_MAP_RESOLUTION;
294 sbo.height = SHADOW_MAP_RESOLUTION;
296 glGenFramebuffers(1, &sbo.id);
297 glBindFramebuffer(GL_FRAMEBUFFER, sbo.id);
299 glGenTextures(1, &sbo.texture);
300 glBindTexture(GL_TEXTURE_2D, sbo.texture);
302 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, SHADOW_MAP_RESOLUTION, SHADOW_MAP_RESOLUTION, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
304 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
305 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
307 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
308 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
310 chag::float4 zeros = { 1.0f, 1.0f, 1.0f, 1.0f };
311 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &zeros.x);
313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
316 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, sbo.texture, 0);
319 glDrawBuffer(GL_NONE);
320 glReadBuffer(GL_NONE);
323 glBindFramebuffer(GL_FRAMEBUFFER, 0);
324 glBindTexture(GL_TEXTURE_2D, 0);
331 std::string post_fx =
"POST_FX_SHADER";
332 std::string vert_blur =
"VERTICAL_BLUR_SHADER";
333 std::string hor_blur =
"HORIZONTAL_BLUR_SHADER";
334 std::string cutoff =
"CUTOFF_SHADER";
336 ResourceManager::loadShader(
"shaders/postFx.vert",
"shaders/postFx.frag", post_fx);
337 ResourceManager::loadShader(
"shaders/postFx.vert",
"shaders/vertical_blur.frag", vert_blur);
338 ResourceManager::loadShader(
"shaders/postFx.vert",
"shaders/horizontal_blur.frag", hor_blur);
339 ResourceManager::loadShader(
"shaders/postFx.vert",
"shaders/cutoff.frag", cutoff);
341 postFxShader = ResourceManager::getShader(post_fx);
342 verticalBlurShader = ResourceManager::getShader(vert_blur);
343 horizontalBlurShader = ResourceManager::getShader(hor_blur);
344 cutoffShader = ResourceManager::getShader(cutoff);
348 glBindFramebuffer(GL_FRAMEBUFFER, 0);
349 glBindTexture(GL_TEXTURE_2D, 0);
351 glEnable(GL_DEPTH_TEST);
353 Logger::logInfo(
"Generating OpenGL data completed.");
356 Fbo Renderer::createPostProcessFbo(
int width,
int height) {
363 glGenFramebuffers(1, &fbo.id);
364 glBindFramebuffer(GL_FRAMEBUFFER, fbo.id);
366 glGenTextures(1, &fbo.texture);
367 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fbo.texture);
369 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
370 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
371 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
374 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, fbo.texture, 0);
376 glGenRenderbuffers(1, &fbo.depthbuffer);
377 glBindRenderbuffer(GL_RENDERBUFFER, fbo.depthbuffer);
378 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
379 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo.depthbuffer);
384 void Renderer::renderPostProcess() {
386 int w = Globals::get(Globals::WINDOW_WIDTH);
387 int h = Globals::get(Globals::WINDOW_HEIGHT);
391 glBindFramebuffer(GL_FRAMEBUFFER, 0);
392 glViewport(0, 0, w, h);
393 glClearColor(0.6f, 0.0f, 0.0f, 1.0f);
394 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
397 postFxShader->setUniform1i(
"frameBufferTexture", 0);
398 postFxShader->setUniform1i(
"blurredFrameBufferTexture", 1);
400 glActiveTexture(GL_TEXTURE0);
401 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, postProcessFbo.texture);
403 glActiveTexture(GL_TEXTURE1);
404 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, verticalBlurFbo.texture);
406 postFxShader->setUniform1f(
"time", currentTime);
408 drawFullScreenQuad();
411 void Renderer::blurImage() {
412 if (!effects.blur.active) {
return; }
415 int width = Globals::get(Globals::WINDOW_WIDTH);
416 int height = Globals::get(Globals::WINDOW_HEIGHT);
418 glBindFramebuffer(GL_FRAMEBUFFER, cutOffFbo.id);
419 glViewport(0, 0, width, height);
420 glClearColor(1.0, 1.0, 0.0, 1.0);
421 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
423 cutoffShader->setUniform1f(
"cutAt", effects.blur.cutOff);
424 glActiveTexture(GL_TEXTURE0);
425 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, postProcessFbo.texture);
427 drawFullScreenQuad();
430 glBindFramebuffer(GL_FRAMEBUFFER, horizontalBlurFbo.id);
431 glClearColor(0.0, 0.0, 0.0, 1.0);
432 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
434 horizontalBlurShader->use();
436 horizontalBlurShader->setUniform1i(
"frameBufferTexture", 0);
437 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, cutOffFbo.texture);
438 drawFullScreenQuad();
441 glBindFramebuffer(GL_FRAMEBUFFER, verticalBlurFbo.id);
442 glClearColor(0.0, 0.0, 0.0, 1.0);
443 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
445 verticalBlurShader->use();
447 verticalBlurShader->setUniform1i(
"frameBufferTexture", 0);
448 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, horizontalBlurFbo.texture);
449 drawFullScreenQuad();
452 void Renderer::drawFullScreenQuad()
454 static GLuint vertexArrayObject = 0;
457 if (vertexArrayObject == 0)
459 glGenVertexArrays(1, &vertexArrayObject);
460 static const chag::float2 positions[] = {{-1.0f, -1.0f},
468 createAddAttribBuffer(vertexArrayObject, positions,
sizeof(positions), 0, 2, GL_FLOAT);
470 glGenBuffers(1, &pos_vbo);
471 glBindBuffer(GL_ARRAY_BUFFER, pos_vbo);
472 glBufferData(GL_ARRAY_BUFFER,
sizeof(positions), positions, GL_STATIC_DRAW);
474 glBindVertexArray(vertexArrayObject);
475 glVertexAttribPointer(0, 2, GL_FLOAT,
false, 0, 0 );
476 glEnableVertexAttribArray(0);
480 glBindVertexArray(vertexArrayObject);
481 glDrawArrays(GL_TRIANGLES, 0, 6);
Class for maintaining OpenGL shader programs.