diff --git a/game/graphics.cc b/game/graphics.cc index 8c7b72b..e0123db 100644 --- a/game/graphics.cc +++ b/game/graphics.cc @@ -25,6 +25,8 @@ Graphics::Graphics(glm::uvec2 windowSize, float nearPlane, this->loadingScreenPath = screenPath; this->loadingScreenContinuePath = screenContinuePath; gameStart = false; + renderShadows = true; + renderFlames = true; } Graphics::Graphics() { @@ -307,66 +309,70 @@ void Graphics::render(double time) updateLights(); lastLightUpdate = time; } + // At first render shadows - depthCubeShader->use(); - depthCubeShader->setUniform("farPlane", farPlane); - // render depth textures for point lights - glViewport(0, 0, cube_size, cube_size); - glm::mat4 depthProjectionMatrix_pointlights = glm::perspective(1.571f, (float)cube_size/(float)cube_size, 0.1f, farPlane); - glm::vec3 looking_directions[6] = {glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), - glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, -1.0f)}; - glm::vec3 upvectors[6] = {glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, 0.0f, -1.0f), - glm::vec3(0.0f, 0.0f, -1.0f),glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, -1.0f, 0.0f)}; - - - framebuffer_cube->bind(); - for (unsigned int i_pointlight = 0; i_pointlightgetObjectName(), 0); - glClear(GL_DEPTH_BUFFER_BIT); - glm::mat4 viewMatrix = glm::lookAt(closestLights.at(i_pointlight).getPosition(), - closestLights.at(i_pointlight).getPosition() + looking_directions[i_face], upvectors[i_face]); - glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * viewMatrix; - std::vector viewMatrixVector = std::vector(); - viewMatrixVector.push_back(viewMatrix); - level->render(depthCubeShader, false, &depthViewProjectionMatrix_face, &viewMatrixVector); - if (!framebuffer_cube->isFrameBufferObjectComplete()) { - printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); - } - } - } - - // render depth textures for sun - depthShader->use(); - glViewport(0, 0, windowSize.x, windowSize.y); - std::vector depthViewProjectionMatrices = std::vector(framebuffer_directional.size()); - float sunAngle = glm::dot(glm::vec3(0.0f, 1.0f, 0.0f), glm::normalize(level->getDirectionalLight()->getPosition())); - glm::vec3 sunVector = (level->getCameraCenter()->getPosition() + level->getDirectionalLight()->getPosition()); + if (renderShadows) { + depthCubeShader->use(); + depthCubeShader->setUniform("farPlane", farPlane); + // render depth textures for point lights + glViewport(0, 0, cube_size, cube_size); + glm::mat4 depthProjectionMatrix_pointlights = glm::perspective(1.571f, (float)cube_size/(float)cube_size, 0.1f, farPlane); + glm::vec3 looking_directions[6] = {glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, -1.0f)}; + glm::vec3 upvectors[6] = {glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, 0.0f, -1.0f), + glm::vec3(0.0f, 0.0f, -1.0f),glm::vec3(0.0f, -1.0f, 0.0f),glm::vec3(0.0f, -1.0f, 0.0f)}; - for (unsigned int i = 0; ibind(); - glClear(GL_DEPTH_BUFFER_BIT); - if (sunAngle > -0.6f) { - float projection_size = 0.0f; - switch(i) { - case 0: - projection_size = 10.0f; - break; - case 1: - projection_size = 30.0f; - break; - case 2: - projection_size = farPlane/1.5f; - break; + + framebuffer_cube->bind(); + for (unsigned int i_pointlight = 0; i_pointlightgetObjectName(), 0); + glClear(GL_DEPTH_BUFFER_BIT); + glm::mat4 viewMatrix = glm::lookAt(closestLights.at(i_pointlight).getPosition(), + closestLights.at(i_pointlight).getPosition() + looking_directions[i_face], upvectors[i_face]); + glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * viewMatrix; + std::vector viewMatrixVector = std::vector(); + viewMatrixVector.push_back(viewMatrix); + level->render(depthCubeShader, false, &depthViewProjectionMatrix_face, &viewMatrixVector); + if (!framebuffer_cube->isFrameBufferObjectComplete()) { + printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); + } } - depthViewProjectionMatrices.at(i) = glm::ortho(-projection_size, projection_size, -projection_size, projection_size, -farPlane/1.5f, farPlane/1.5f) * - glm::lookAt(sunVector, level->getCameraCenter()->getPosition(), glm::vec3(0,1,0)); - level->render(depthShader, false, &depthViewProjectionMatrices.at(i)); } - if (!framebuffer_directional.at(i)->isFrameBufferObjectComplete()) { - printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); + + // render depth textures for sun + depthShader->use(); + glViewport(0, 0, windowSize.x, windowSize.y); + + + float sunAngle = glm::dot(glm::vec3(0.0f, 1.0f, 0.0f), glm::normalize(level->getDirectionalLight()->getPosition())); + glm::vec3 sunVector = (level->getCameraCenter()->getPosition() + level->getDirectionalLight()->getPosition()); + + for (unsigned int i = 0; ibind(); + glClear(GL_DEPTH_BUFFER_BIT); + if (sunAngle > -0.6f) { + float projection_size = 0.0f; + switch(i) { + case 0: + projection_size = 10.0f; + break; + case 1: + projection_size = 30.0f; + break; + case 2: + projection_size = farPlane/1.5f; + break; + } + depthViewProjectionMatrices.at(i) = glm::ortho(-projection_size, projection_size, -projection_size, projection_size, -farPlane/1.5f, farPlane/1.5f) * + glm::lookAt(sunVector, level->getCameraCenter()->getPosition(), glm::vec3(0,1,0)); + level->render(depthShader, false, &depthViewProjectionMatrices.at(i)); + if (!framebuffer_directional.at(i)->isFrameBufferObjectComplete()) { + printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); + } + } } } @@ -421,12 +427,6 @@ void Graphics::render(double time) level->getSkydome()->render(skydomeShader, false, true, &lightingViewProjectionMatrix); lightingShader->use(); - - //set lighting parameters - - // TODO look into doing this less often, offload to another thread? - // TODO figure out how to deal with bigger numbers of lights. load the nearest on demand? - // convert texture to homogenouse coordinates glm::mat4 biasMatrix( @@ -462,50 +462,52 @@ void Graphics::render(double time) level->render(lightingShader, true, &lightingViewProjectionMatrix, &depthBiasVPs); // draw flames on top - flameShader->use(); - // cull faces to get consistent color while using alpha - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); + if (renderFlames) { + flameShader->use(); + // cull faces to get consistent color while using alpha + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); - // draw with colors - for(unsigned int i = 0; irender(flameShader, lightingViewProjectionMatrix, float(time), true, wind); + // draw with colors + for(unsigned int i = 0; irender(flameShader, lightingViewProjectionMatrix, float(time), true, wind); + } + glDisable(GL_CULL_FACE); + + framebuffer_light->bind(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_light->getObjectName()); + glBlitFramebuffer(0, 0, windowSize.x, windowSize.y, 0, 0, windowSize.x, windowSize.y, + GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); + + // draw slightly larger only for stencil buffer to blur edges + glEnable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 1, 0xFF); //Set any stencil to 1 + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilMask(0xFF);//write to stencil buffer + glClear(GL_STENCIL_BUFFER_BIT);//clear stencil buffer + + for(unsigned int i = 0; irender(flameShader, lightingViewProjectionMatrix, float(time), false, wind); + } + + glStencilFunc(GL_EQUAL, 1, 0xFF); //Pass test if stencil value is 1 + glStencilMask(0x00);// don't write to stencil buffer + + flamePostShader->use(); + fullscreen_quad->render(); + glDepthMask(GL_TRUE); + + glDisable(GL_STENCIL_TEST); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer_light->getObjectName()); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, windowSize.x, windowSize.y, 0, 0, windowSize.x, windowSize.y, + GL_COLOR_BUFFER_BIT, GL_NEAREST); } - glDisable(GL_CULL_FACE); - - framebuffer_light->bind(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_light->getObjectName()); - glBlitFramebuffer(0, 0, windowSize.x, windowSize.y, 0, 0, windowSize.x, windowSize.y, - GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); - - // draw slightly larger only for stencil buffer to blur edges - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_ALWAYS, 1, 0xFF); //Set any stencil to 1 - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glStencilMask(0xFF);//write to stencil buffer - glClear(GL_STENCIL_BUFFER_BIT);//clear stencil buffer - - for(unsigned int i = 0; irender(flameShader, lightingViewProjectionMatrix, float(time), false, wind); - } - - glStencilFunc(GL_EQUAL, 1, 0xFF); //Pass test if stencil value is 1 - glStencilMask(0x00);// don't write to stencil buffer - - flamePostShader->use(); - fullscreen_quad->render(); - glDepthMask(GL_TRUE); - - glDisable(GL_STENCIL_TEST); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer_light->getObjectName()); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glBlitFramebuffer(0, 0, windowSize.x, windowSize.y, 0, 0, windowSize.x, windowSize.y, - GL_COLOR_BUFFER_BIT, GL_NEAREST); } } @@ -632,3 +634,31 @@ void Graphics::saveDepthBufferToDisk(int face, std::string filename) { void Graphics::startGame() { gameStart = true; } + +void Graphics::setRenderShadows(bool state) { + if(!state) { + for(unsigned int i = 0; ibind(); + glClear(GL_DEPTH_BUFFER_BIT); + } + for(unsigned int i_pointlight = 0; i_pointlightgetObjectName(), 0); + glClear(GL_DEPTH_BUFFER_BIT); + } + } + } + renderShadows = state; +} + +void Graphics::setRenderFlames(bool state) { + renderFlames = state; +} + +bool Graphics::getRenderShadows() { + return renderShadows; +} + +bool Graphics::getRenderFlames() { + return renderFlames; +} diff --git a/game/graphics.hh b/game/graphics.hh index cad8070..2b642a2 100644 --- a/game/graphics.hh +++ b/game/graphics.hh @@ -24,6 +24,10 @@ class Graphics { float getFarPlane(); void startGame(); void renderLoadingScreen(); + void setRenderShadows(bool state); + void setRenderFlames(bool state); + bool getRenderShadows(); + bool getRenderFlames(); private: void bindTextureUnits(); void updateLights(); @@ -71,6 +75,8 @@ class Graphics { bool gameStart; float loadingScreenWidth; float loadingScreenHeight; + bool renderShadows; + bool renderFlames; }; #endif diff --git a/game/main.cc b/game/main.cc index a569950..2396c5d 100644 --- a/game/main.cc +++ b/game/main.cc @@ -23,6 +23,12 @@ static void keyCallback(GLFWwindow* _window, int _key, int, int _action, int) glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); app.setCameraLock(false); } + if (_key == GLFW_KEY_F5 && _action == GLFW_PRESS) { + app.getGraphics()->setRenderShadows(!app.getGraphics()->getRenderShadows()); + } + if (_key == GLFW_KEY_F6 && _action == GLFW_PRESS) { + app.getGraphics()->setRenderFlames(!app.getGraphics()->getRenderFlames()); + } } static void mouseCallback(GLFWwindow* window, int button, int action, int) {