Now only using the 32 closest light sources.
This commit is contained in:
parent
91dbc280e0
commit
d6d934277f
73
graphics.cc
73
graphics.cc
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <ACGL/OpenGL/Creator/ShaderProgramCreator.hh>
|
#include <ACGL/OpenGL/Creator/ShaderProgramCreator.hh>
|
||||||
|
|
||||||
@ -56,6 +57,14 @@ void Graphics::init(Level* level) {
|
|||||||
framebuffer->setDepthTexture(depthTexture);
|
framebuffer->setDepthTexture(depthTexture);
|
||||||
framebuffer->validate();
|
framebuffer->validate();
|
||||||
|
|
||||||
|
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &number_of_texture_units);
|
||||||
|
printf("Your graphics card supports %d texture units.\n", number_of_texture_units);
|
||||||
|
// Exit if we need more texture units
|
||||||
|
if (number_of_texture_units < 34) {
|
||||||
|
printf("You need at least 34 texture units to run this application. Exiting\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
// always generate and bind 32 cube maps, because otherwise the shader won't work
|
// always generate and bind 32 cube maps, because otherwise the shader won't work
|
||||||
depth_cubeMaps = std::vector<ACGL::OpenGL::SharedTextureCubeMap>(32);
|
depth_cubeMaps = std::vector<ACGL::OpenGL::SharedTextureCubeMap>(32);
|
||||||
for (unsigned int i = 0; i<depth_cubeMaps.size(); i++) {
|
for (unsigned int i = 0; i<depth_cubeMaps.size(); i++) {
|
||||||
@ -69,19 +78,18 @@ void Graphics::init(Level* level) {
|
|||||||
|
|
||||||
framebuffer_cube = SharedFrameBufferObject(new FrameBufferObject());
|
framebuffer_cube = SharedFrameBufferObject(new FrameBufferObject());
|
||||||
|
|
||||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &number_of_texture_units);
|
|
||||||
printf("Your graphics card supports %d texture units.\n", number_of_texture_units);
|
|
||||||
|
|
||||||
lightingShader->use();
|
lightingShader->use();
|
||||||
|
|
||||||
lightingShader->setTexture("shadowMap", depthTexture, 1);
|
lightingShader->setTexture("shadowMap", depthTexture, 1);
|
||||||
|
|
||||||
if (level->getLights()->size() > 0) {
|
if (level->getLights()->size() > 0) {
|
||||||
for(unsigned int i = 0; i<32; i++){
|
for(unsigned int i = 0; i<depth_cubeMaps.size(); i++){
|
||||||
// start with texture unit 2 because the first two are used by the texture and the directional shadow map
|
// start with texture unit 2 because the first two are used by the texture and the directional shadow map
|
||||||
lightingShader->setTexture("shadowMap_cube" + std::to_string(i), depth_cubeMaps.at(i), i+2);
|
lightingShader->setTexture("shadowMap_cube" + std::to_string(i), depth_cubeMaps.at(i), i+2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateClosestLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::uvec2 Graphics::getWindowSize() {
|
glm::uvec2 Graphics::getWindowSize() {
|
||||||
@ -102,13 +110,13 @@ void Graphics::render(double time)
|
|||||||
glm::vec3(0.0f, 0.0f, -1.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, -1.0f, 0.0f),glm::vec3(0.0f, -1.0f, 0.0f)};
|
||||||
|
|
||||||
framebuffer_cube->bind();
|
framebuffer_cube->bind();
|
||||||
for (unsigned int i_pointlight = 0; i_pointlight<level->getLights()->size(); i_pointlight++) {
|
for (unsigned int i_pointlight = 0; i_pointlight<closestLights->size(); i_pointlight++) {
|
||||||
// render each side of the cube
|
// render each side of the cube
|
||||||
for (int i_face = 0; i_face<6; i_face++) {
|
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);
|
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);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
glm::mat4 viewMatrix = glm::lookAt(level->getLights()->at(i_pointlight).getPosition(),
|
glm::mat4 viewMatrix = glm::lookAt(closestLights->at(i_pointlight).getPosition(),
|
||||||
level->getLights()->at(i_pointlight).getPosition() + looking_directions[i_face], upvectors[i_face]);
|
closestLights->at(i_pointlight).getPosition() + looking_directions[i_face], upvectors[i_face]);
|
||||||
glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * viewMatrix;
|
glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * viewMatrix;
|
||||||
std::vector<glm::mat4> viewMatrixVector = std::vector<glm::mat4>();
|
std::vector<glm::mat4> viewMatrixVector = std::vector<glm::mat4>();
|
||||||
viewMatrixVector.push_back(viewMatrix);
|
viewMatrixVector.push_back(viewMatrix);
|
||||||
@ -143,10 +151,11 @@ void Graphics::render(double time)
|
|||||||
|
|
||||||
// TODO look into doing this less often, offload to another thread?
|
// 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?
|
// TODO figure out how to deal with bigger numbers of lights. load the nearest on demand?
|
||||||
|
|
||||||
double nextUpdate = lastUpdate + lightUpdateDelay;
|
double nextUpdate = lastUpdate + lightUpdateDelay;
|
||||||
if (time >= nextUpdate)
|
if (time >= nextUpdate)
|
||||||
{
|
{
|
||||||
updateLights();
|
updateShaderLights();
|
||||||
lastUpdate = time;
|
lastUpdate = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,28 +188,54 @@ void Graphics::render(double time)
|
|||||||
level->render(lightingShader, true, &lightingViewProjectionMatrix, &shadowVPs);
|
level->render(lightingShader, true, &lightingViewProjectionMatrix, &shadowVPs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::updateLights() {
|
bool Graphics::compareLightDistances(Light a, Light b) {
|
||||||
if (level->getLights()->size() > 0) {
|
if (glm::distance(this->level->getCameraCenter()->getPosition(), a.getPosition()) <
|
||||||
lightingShader->setUniform("lightCount", (int) level->getLights()->size());
|
glm::distance(this->level->getCameraCenter()->getPosition(), b.getPosition())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::updateClosestLights() {
|
||||||
|
if (level->getLights()->size() <= 32) {
|
||||||
|
this->closestLights = level->getLights();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
closestLightsVector = std::vector<Light>(*level->getLights());
|
||||||
|
std::sort(closestLightsVector.begin(),
|
||||||
|
closestLightsVector.end(),
|
||||||
|
[this](Light a, Light b) {return compareLightDistances(a, b); });
|
||||||
|
closestLightsVector = std::vector<Light>(&closestLightsVector[0],
|
||||||
|
&closestLightsVector[31]);
|
||||||
|
closestLights = &closestLightsVector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::updateShaderLights() {
|
||||||
|
updateClosestLights();
|
||||||
|
if (closestLights->size() > 0) {
|
||||||
|
lightingShader->setUniform("lightCount", (int) closestLights->size());
|
||||||
|
|
||||||
// Build light position array
|
// Build light position array
|
||||||
glm::vec3 lightSources[level->getLights()->size()];
|
glm::vec3 lightSources[closestLights->size()];
|
||||||
for(unsigned int i = 0; i<level->getLights()->size(); i++) {
|
for(unsigned int i = 0; i<closestLights->size(); i++) {
|
||||||
lightSources[i] = level->getLights()->at(i).getPosition();
|
lightSources[i] = closestLights->at(i).getPosition();
|
||||||
}
|
}
|
||||||
glUniform3fv(lightingShader->getUniformLocation("lightSources"),
|
glUniform3fv(lightingShader->getUniformLocation("lightSources"),
|
||||||
sizeof(lightSources), (GLfloat*) lightSources);
|
sizeof(lightSources), (GLfloat*) lightSources);
|
||||||
// Build light colour array
|
// Build light colour array
|
||||||
glm::vec3 lightColours[level->getLights()->size()];
|
glm::vec3 lightColours[closestLights->size()];
|
||||||
for(unsigned int i = 0; i<level->getLights()->size(); i++) {
|
for(unsigned int i = 0; i<closestLights->size(); i++) {
|
||||||
lightColours[i] = level->getLights()->at(i).getColour();
|
lightColours[i] = closestLights->at(i).getColour();
|
||||||
}
|
}
|
||||||
glUniform3fv(lightingShader->getUniformLocation("lightColors"),
|
glUniform3fv(lightingShader->getUniformLocation("lightColors"),
|
||||||
sizeof(lightColours), (GLfloat*) lightColours);
|
sizeof(lightColours), (GLfloat*) lightColours);
|
||||||
// Build light attenuation array
|
// Build light attenuation array
|
||||||
float lightIntensities[level->getLights()->size()];
|
float lightIntensities[closestLights->size()];
|
||||||
for(unsigned int i = 0; i<level->getLights()->size(); i++) {
|
for(unsigned int i = 0; i<closestLights->size(); i++) {
|
||||||
lightIntensities[i] = level->getLights()->at(i).getIntensity();
|
lightIntensities[i] = closestLights->at(i).getIntensity();
|
||||||
}
|
}
|
||||||
glUniform1fv(lightingShader->getUniformLocation("lightIntensities"),
|
glUniform1fv(lightingShader->getUniformLocation("lightIntensities"),
|
||||||
sizeof(lightIntensities), (GLfloat*) lightIntensities);
|
sizeof(lightIntensities), (GLfloat*) lightIntensities);
|
||||||
|
@ -19,12 +19,17 @@ class Graphics {
|
|||||||
void resize(glm::uvec2 windowSize);
|
void resize(glm::uvec2 windowSize);
|
||||||
float getFarPlane();
|
float getFarPlane();
|
||||||
private:
|
private:
|
||||||
void updateLights();
|
void updateShaderLights();
|
||||||
|
void updateClosestLights();
|
||||||
|
bool compareLightDistances(Light a, Light b);
|
||||||
void saveDepthBufferToDisk(int face, std::string);
|
void saveDepthBufferToDisk(int face, std::string);
|
||||||
double lastUpdate;
|
double lastUpdate;
|
||||||
glm::uvec2 windowSize;
|
glm::uvec2 windowSize;
|
||||||
float nearPlane;
|
float nearPlane;
|
||||||
float farPlane;
|
float farPlane;
|
||||||
|
// pointer to either use the vector from the level or from here
|
||||||
|
std::vector<Light>* closestLights;
|
||||||
|
std::vector<Light> closestLightsVector; // contains the 32 closest lights
|
||||||
ACGL::OpenGL::SharedShaderProgram lightingShader;
|
ACGL::OpenGL::SharedShaderProgram lightingShader;
|
||||||
ACGL::OpenGL::SharedShaderProgram depthCubeShader;
|
ACGL::OpenGL::SharedShaderProgram depthCubeShader;
|
||||||
ACGL::OpenGL::SharedShaderProgram depthShader;
|
ACGL::OpenGL::SharedShaderProgram depthShader;
|
||||||
|
Loading…
Reference in New Issue
Block a user