Adding debug switchtes for flames and shadows.
This commit is contained in:
parent
9a54c033c0
commit
e2e343db1a
236
game/graphics.cc
236
game/graphics.cc
@ -25,6 +25,8 @@ Graphics::Graphics(glm::uvec2 windowSize, float nearPlane,
|
|||||||
this->loadingScreenPath = screenPath;
|
this->loadingScreenPath = screenPath;
|
||||||
this->loadingScreenContinuePath = screenContinuePath;
|
this->loadingScreenContinuePath = screenContinuePath;
|
||||||
gameStart = false;
|
gameStart = false;
|
||||||
|
renderShadows = true;
|
||||||
|
renderFlames = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics::Graphics() {
|
Graphics::Graphics() {
|
||||||
@ -307,66 +309,70 @@ void Graphics::render(double time)
|
|||||||
updateLights();
|
updateLights();
|
||||||
lastLightUpdate = time;
|
lastLightUpdate = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
// At first render shadows
|
// 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_pointlight<closestLights.size() && i_pointlight < maxShadowRenderCount; i_pointlight++) {
|
|
||||||
// render each side of the cube
|
|
||||||
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(i_pointlight)->getObjectName(), 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<glm::mat4> viewMatrixVector = std::vector<glm::mat4>();
|
|
||||||
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<glm::mat4> depthViewProjectionMatrices = std::vector<glm::mat4>(framebuffer_directional.size());
|
std::vector<glm::mat4> depthViewProjectionMatrices = std::vector<glm::mat4>(framebuffer_directional.size());
|
||||||
float sunAngle = glm::dot(glm::vec3(0.0f, 1.0f, 0.0f), glm::normalize(level->getDirectionalLight()->getPosition()));
|
if (renderShadows) {
|
||||||
glm::vec3 sunVector = (level->getCameraCenter()->getPosition() + level->getDirectionalLight()->getPosition());
|
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; i<framebuffer_directional.size(); i++) {
|
|
||||||
framebuffer_directional.at(i)->bind();
|
framebuffer_cube->bind();
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
for (unsigned int i_pointlight = 0; i_pointlight<closestLights.size() && i_pointlight < maxShadowRenderCount; i_pointlight++) {
|
||||||
if (sunAngle > -0.6f) {
|
// render each side of the cube
|
||||||
float projection_size = 0.0f;
|
for (int i_face = 0; i_face<6; i_face++) {
|
||||||
switch(i) {
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i_face, depth_cubeMaps.at(i_pointlight)->getObjectName(), 0);
|
||||||
case 0:
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
projection_size = 10.0f;
|
glm::mat4 viewMatrix = glm::lookAt(closestLights.at(i_pointlight).getPosition(),
|
||||||
break;
|
closestLights.at(i_pointlight).getPosition() + looking_directions[i_face], upvectors[i_face]);
|
||||||
case 1:
|
glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * viewMatrix;
|
||||||
projection_size = 30.0f;
|
std::vector<glm::mat4> viewMatrixVector = std::vector<glm::mat4>();
|
||||||
break;
|
viewMatrixVector.push_back(viewMatrix);
|
||||||
case 2:
|
level->render(depthCubeShader, false, &depthViewProjectionMatrix_face, &viewMatrixVector);
|
||||||
projection_size = farPlane/1.5f;
|
if (!framebuffer_cube->isFrameBufferObjectComplete()) {
|
||||||
break;
|
printf("Framebuffer incomplete, unknown error occured during shadow generation!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
depthViewProjectionMatrices.at(i) = glm::ortho<float>(-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; i<framebuffer_directional.size(); i++) {
|
||||||
|
framebuffer_directional.at(i)->bind();
|
||||||
|
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<float>(-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);
|
level->getSkydome()->render(skydomeShader, false, true, &lightingViewProjectionMatrix);
|
||||||
|
|
||||||
lightingShader->use();
|
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
|
// convert texture to homogenouse coordinates
|
||||||
glm::mat4 biasMatrix(
|
glm::mat4 biasMatrix(
|
||||||
@ -462,50 +462,52 @@ void Graphics::render(double time)
|
|||||||
level->render(lightingShader, true, &lightingViewProjectionMatrix, &depthBiasVPs);
|
level->render(lightingShader, true, &lightingViewProjectionMatrix, &depthBiasVPs);
|
||||||
|
|
||||||
// draw flames on top
|
// draw flames on top
|
||||||
flameShader->use();
|
if (renderFlames) {
|
||||||
// cull faces to get consistent color while using alpha
|
flameShader->use();
|
||||||
glEnable(GL_CULL_FACE);
|
// cull faces to get consistent color while using alpha
|
||||||
glCullFace(GL_BACK);
|
glEnable(GL_CULL_FACE);
|
||||||
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
// draw with colors
|
// draw with colors
|
||||||
for(unsigned int i = 0; i<closestFlames.size(); i++) {
|
for(unsigned int i = 0; i<closestFlames.size(); i++) {
|
||||||
closestFlames.at(i)->render(flameShader, lightingViewProjectionMatrix, float(time), true, wind);
|
closestFlames.at(i)->render(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; i<closestFlames.size(); i++) {
|
||||||
|
closestFlames.at(i)->render(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; i<closestFlames.size(); i++) {
|
|
||||||
closestFlames.at(i)->render(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() {
|
void Graphics::startGame() {
|
||||||
gameStart = true;
|
gameStart = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::setRenderShadows(bool state) {
|
||||||
|
if(!state) {
|
||||||
|
for(unsigned int i = 0; i<framebuffer_directional.size(); i++) {
|
||||||
|
framebuffer_directional.at(i)->bind();
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
for(unsigned int i_pointlight = 0; i_pointlight<depth_cubeMaps.size(); i_pointlight++) {
|
||||||
|
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(i_pointlight)->getObjectName(), 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;
|
||||||
|
}
|
||||||
|
@ -24,6 +24,10 @@ class Graphics {
|
|||||||
float getFarPlane();
|
float getFarPlane();
|
||||||
void startGame();
|
void startGame();
|
||||||
void renderLoadingScreen();
|
void renderLoadingScreen();
|
||||||
|
void setRenderShadows(bool state);
|
||||||
|
void setRenderFlames(bool state);
|
||||||
|
bool getRenderShadows();
|
||||||
|
bool getRenderFlames();
|
||||||
private:
|
private:
|
||||||
void bindTextureUnits();
|
void bindTextureUnits();
|
||||||
void updateLights();
|
void updateLights();
|
||||||
@ -71,6 +75,8 @@ class Graphics {
|
|||||||
bool gameStart;
|
bool gameStart;
|
||||||
float loadingScreenWidth;
|
float loadingScreenWidth;
|
||||||
float loadingScreenHeight;
|
float loadingScreenHeight;
|
||||||
|
bool renderShadows;
|
||||||
|
bool renderFlames;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,6 +23,12 @@ static void keyCallback(GLFWwindow* _window, int _key, int, int _action, int)
|
|||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
app.setCameraLock(false);
|
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) {
|
static void mouseCallback(GLFWwindow* window, int button, int action, int) {
|
||||||
|
Loading…
Reference in New Issue
Block a user