From 819584ef1553a64acd43c233a099edd4d48f2e78 Mon Sep 17 00:00:00 2001 From: Faerbit Date: Tue, 2 Jun 2015 00:18:22 +0200 Subject: [PATCH] Implemented updating of shadow render queue. Doesn't work satisfactory right now. (#10) --- CMakeLists.txt | 4 +- game/graphics.cc | 116 ++++++++++++++++++++++++++++++++--------------- game/level.cc | 2 + 3 files changed, 83 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d72a5b9..ead39d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,8 +56,8 @@ ADD_DEFINITIONS(-DNO_SPACE_NAVIGATOR_SUPPORT) SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -DSAXUM_DEBUG -g") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -DSAXUM_DEBUG -g") -SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O2") -SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O2") +SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O2 -DNDEBUG") +SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O2 -DNDEBUG") set(dir ${CMAKE_CURRENT_SOURCE_DIR}/binaries) set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE) diff --git a/game/graphics.cc b/game/graphics.cc index 54e124d..71cb56f 100644 --- a/game/graphics.cc +++ b/game/graphics.cc @@ -180,8 +180,6 @@ void Graphics::init(Level* level) { bindTextureUnits(); - updateLights(); - // set shader variables that stay the same across the runtime of the application skydomeShader->use(); skydomeShader->setUniform("farPlane", farPlane); @@ -211,12 +209,14 @@ void Graphics::init(Level* level) { depthCubeShader->setUniform("farPlane", farPlane); level->sortObjects(Material::getAllTextures()->size()); + #ifdef SAXUM_DEBUG std::cout << "There were " << Material::getAllTextures()->size() << " materials used in this level." << std::endl; #endif initShadowRenderQueue(); + updateLights(); } void Graphics::bindTextureUnits(){ @@ -334,7 +334,7 @@ void Graphics::render(double time) double nextLightUpdate = lastLightUpdate + lightUpdateDelay; if (time >= nextLightUpdate) { - //updateLights(); + updateLights(); lastLightUpdate = time; } @@ -375,26 +375,29 @@ void Graphics::render(double time) framebuffer_cube->bind(); for (unsigned int i_pointlight = 0; i_pointlight < renderQueue.size(); i_pointlight++) { - // render each side of the cube - glm::vec3 position = glm::vec3(0.0f); - if (std::get<0>(renderQueue.at(i_pointlight))->isFlame()) { - position = std::get<0>(renderQueue.at(i_pointlight))->getPosition(); - position = glm::vec3(position.x + 0.75f*wind.x, position.y, position.z + 0.75f*wind.y); - } - else { - position = std::get<0>(renderQueue.at(i_pointlight))->getPosition(); - } - for (int i_face = 0; i_face<6; i_face++) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i_face, - depth_cubeMaps.at(std::get<2>(renderQueue.at(i_pointlight)))->getObjectName(), 0); - glClear(GL_DEPTH_BUFFER_BIT); - glm::mat4 viewMatrix = glm::lookAt(position, position + looking_directions[i_face], upvectors[i_face]); - glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * viewMatrix; - std::vector viewMatrixVector = std::vector(1); - viewMatrixVector.at(0) = viewMatrix; - level->render(depthCubeShader, false, std::get<0>(renderQueue.at(i_pointlight))->getPosition(), 1, &depthViewProjectionMatrix_face, &viewMatrixVector); - if (!framebuffer_cube->isFrameBufferObjectComplete()) { - printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); + // check if queue points to a existing light + if (std::get<0>(renderQueue.at(i_pointlight))) { + // render each side of the cube + glm::vec3 position = glm::vec3(0.0f); + if (std::get<0>(renderQueue.at(i_pointlight))->isFlame()) { + position = std::get<0>(renderQueue.at(i_pointlight))->getPosition(); + position = glm::vec3(position.x + 0.75f*wind.x, position.y, position.z + 0.75f*wind.y); + } + else { + position = std::get<0>(renderQueue.at(i_pointlight))->getPosition(); + } + for (int i_face = 0; i_face<6; i_face++) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i_face, + depth_cubeMaps.at(std::get<2>(renderQueue.at(i_pointlight)))->getObjectName(), 0); + glClear(GL_DEPTH_BUFFER_BIT); + glm::mat4 viewMatrix = glm::lookAt(position, position + looking_directions[i_face], upvectors[i_face]); + glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * viewMatrix; + std::vector viewMatrixVector = std::vector(1); + viewMatrixVector.at(0) = viewMatrix; + level->render(depthCubeShader, false, std::get<0>(renderQueue.at(i_pointlight))->getPosition(), 1, &depthViewProjectionMatrix_face, &viewMatrixVector); + if (!framebuffer_cube->isFrameBufferObjectComplete()) { + printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); + } } } } @@ -627,12 +630,52 @@ void Graphics::render(double time) } void Graphics::updateLights() { + std::vector> oldClosestLights = std::vector>(*closestLights); closestLights = level->getClosestLights(); if (closestLights->size() > 0) { lightingShader->use(); lightingShader->setUniform("lightCount", (int) closestLights->size()); lightingShader->setUniform("maxShadowRenderCount", min((int)closestLights->size(), maxShadowSampleCount)); + // find new closest lights for the shadow render queue + unsigned int i = 0; + std::vector> compareClosestLights = std::vector>(*closestLights); + while(igetCameraCenter()->getPosition(), shadowRenderQueue.at(i).light->getPosition()); + shadowRenderQueue.at(i).priority = (int) 100*std::exp(5.0f - 0.1f * distance); + } + // Build light position array glm::vec3 lightSources[closestLights->size()]; for(unsigned int i = 0; isize(); i++) { @@ -654,20 +697,20 @@ void Graphics::updateLights() { } glUniform1fv(lightingShader->getUniformLocation("lightIntensities"), sizeof(lightIntensities), (GLfloat*) lightIntensities); - } - // set directional Light - bool isFlame[closestLights->size()]; - closestFlames = std::vector(); - for (unsigned int i = 0; isize(); i++) { - if (closestLights->at(i)->isFlame()) { - closestFlames.push_back(closestLights->at(i)->getFlame()); - isFlame[i] = true; - } - else { - isFlame[i] = false; + + bool isFlame[closestLights->size()]; + closestFlames = std::vector(); + for (unsigned int i = 0; isize(); i++) { + if (closestLights->at(i)->isFlame()) { + closestFlames.push_back(closestLights->at(i)->getFlame()); + isFlame[i] = true; + } + else { + isFlame[i] = false; + } } + glUniform1iv(lightingShader->getUniformLocation("isFlame"), sizeof(isFlame), (GLint*) isFlame); } - glUniform1iv(lightingShader->getUniformLocation("isFlame"), sizeof(isFlame), (GLint*) isFlame); } void Graphics::saveWindowSize(glm::uvec2 windowSize) { @@ -812,6 +855,7 @@ void Graphics::enqueueObjects(std::vector>* queue){ } void Graphics::initShadowRenderQueue() { + closestLights = level->getClosestLights(); int maxLights = min((int)closestLights->size(), maxShadowSampleCount); shadowRenderQueue = std::vector(maxLights); glViewport(0, 0, cube_size, cube_size); @@ -825,8 +869,6 @@ void Graphics::initShadowRenderQueue() { for(unsigned int i = 0; iat(i); - float distance = glm::distance(level->getCameraCenter()->getPosition(), closestLights->at(i)->getPosition()); - shadowRenderQueue.at(i).priority = (int) 100*std::exp(5.0f - 0.1f * distance); shadowRenderQueue.at(i).currentPriority = 0; // render depth textures for point lights depthCubeShader->use(); diff --git a/game/level.cc b/game/level.cc index 6d51bc1..3497ce7 100644 --- a/game/level.cc +++ b/game/level.cc @@ -462,5 +462,7 @@ std::vector>* Level::getClosestLights() { closestLights = std::vector>(&closestLights[0], &closestLights[15]); } + // sort pointers for faster comparisons + std::sort(closestLights.begin(), closestLights.end()); return &closestLights; }