diff --git a/.gitignore b/.gitignore index b3bbf0c..e30bed8 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ CMakeLists.txt.user *.zip *.db *.blend1 +*.swp diff --git a/Levels/ObjectSetups/Compositions.xml b/Levels/ObjectSetups/Compositions.xml index 14e78d0..756ec55 100644 --- a/Levels/ObjectSetups/Compositions.xml +++ b/Levels/ObjectSetups/Compositions.xml @@ -69,7 +69,7 @@ 0.0 - 3 + 2 0.0 1.0 1.0 diff --git a/Readme.md b/Readme.md index 78890de..8da28f9 100644 --- a/Readme.md +++ b/Readme.md @@ -5,3 +5,8 @@ This will be a Marble Race Game developed for the Softwarepraktikum at the RWTH ##Building Currently only tested on Linux. To build execute build.sh. Resulting binary will be in binaries. You can also use the run.sh script to directly start the binary after building it. + +##Control + +You can control the camera by moving the mouse. You can zoom with the mouse wheel. +The marble is controlled via the W,A,S and D keys. diff --git a/Shader/depth.fsh b/Shader/depth.fsh index b236c6a..4e98194 100644 --- a/Shader/depth.fsh +++ b/Shader/depth.fsh @@ -1,7 +1,7 @@ #version 150 -out float fragmentDepth; +out float gl_FragDepth; void main() { - fragmentDepth = gl_FragCoord.z; + gl_FragDepth = gl_FragCoord.z; } diff --git a/Shader/depth_cube.fsh b/Shader/depth_cube.fsh new file mode 100644 index 0000000..d7beeb7 --- /dev/null +++ b/Shader/depth_cube.fsh @@ -0,0 +1,16 @@ +#version 150 + +in vec4 fragPosition; + +uniform float farPlane; + +out float gl_FragDepth; + +void main() { + float nearPlane = 0.1; + float A = -(farPlane+nearPlane)/(farPlane-nearPlane); + float B = -2*(farPlane*nearPlane)/(farPlane - nearPlane); + float value = 0.5*(-A*length(fragPosition) + B)/length(fragPosition) + 0.5; + gl_FragDepth = value; + //gl_FragDepth = length(fragPosition)/farPlane; +} diff --git a/Shader/depth_cube.vsh b/Shader/depth_cube.vsh new file mode 100644 index 0000000..2618bfa --- /dev/null +++ b/Shader/depth_cube.vsh @@ -0,0 +1,15 @@ +#version 150 + +in vec3 aPosition; +in vec3 aNormal; +in vec3 aTexcoord; + +uniform mat4 modelViewProjectionMatrix; +uniform mat4 modelViewMatrix; + +out vec4 fragPosition; + +void main() { + fragPosition = modelViewMatrix * vec4(aPosition, 1.0); + gl_Position = modelViewProjectionMatrix * vec4(aPosition, 1.0); +} diff --git a/Shader/phong.fsh b/Shader/phong.fsh index 447b1fe..08a6bf0 100644 --- a/Shader/phong.fsh +++ b/Shader/phong.fsh @@ -9,7 +9,16 @@ out vec4 oColor; uniform sampler2D uTexture; uniform sampler2DShadow shadowMap; -uniform samplerCubeShadow shadowMap_cube; +uniform samplerCubeShadow shadowMap_cube0; +uniform samplerCubeShadow shadowMap_cube1; +uniform samplerCubeShadow shadowMap_cube2; +uniform samplerCubeShadow shadowMap_cube3; +uniform samplerCubeShadow shadowMap_cube4; +uniform samplerCubeShadow shadowMap_cube5; +uniform samplerCubeShadow shadowMap_cube6; +uniform samplerCubeShadow shadowMap_cube7; +uniform samplerCubeShadow shadowMap_cube8; +uniform samplerCubeShadow shadowMap_cube9; uniform vec3 ambientColor; uniform float ambientFactor; uniform float diffuseFactor; @@ -17,6 +26,7 @@ uniform float specularFactor; uniform vec3 camera; uniform float shininess; uniform int lightCount; +uniform int maxShadowRenderCount; uniform vec3 directionalLightVector; uniform vec3 directionalColor; uniform float directionalIntensity; @@ -70,9 +80,10 @@ float samplePointShadow(samplerCubeShadow shadowMap, vec3 lightDirection) { float A = -(farPlane+nearPlane)/(farPlane-nearPlane); float B = -2*(farPlane*nearPlane)/(farPlane - nearPlane); float compValue = 0.5*(-A*length(lightDirection) + B)/length(lightDirection) + 0.5; - float bias = 0.005; - vec3 vector = vec3(-lightDirection.x, -lightDirection.y, lightDirection.z); - return texture(shadowMap, vec4(vector , compValue - bias)); + float bias = 0.001*tan(acos(clamp(dot(vNormal, -directionalLightVector), 0.0, 1.0))); + bias = clamp(bias, 0.0, 0.01); + //return texture(shadowMap, vec4(lightDirection , length(lightDirection)/farPlane - bias)); + return texture(shadowMap, vec4(lightDirection , compValue - bias)); } float distanceToBorder(vec2 vector) { @@ -91,11 +102,13 @@ void main() // direction lighting if(length(directionalLightVector)>0.0f) { vec3 directionalVector = normalize(directionalLightVector); + float directionalVisibility = sampleDirectionalShadow(shadowMap, shadowCoord); diffuseColor += clamp(dot(normalize(vNormal), directionalVector) - *diffuseFactor*directionalIntensity*directionalColor, 0.0, 1.0); + *diffuseFactor*directionalIntensity*directionalColor, 0.0, 1.0)*directionalVisibility; vec3 cameraVector = normalize(camera - vec3(fragPosition)); - specularColor += clamp(pow((dot((cameraVector+directionalVector),normalize(vNormal))/(length(cameraVector+directionalVector)*length(normalize(vNormal)))),shininess), 0.0, 1.0) - *specularFactor*directionalIntensity*directionalColor; + specularColor += clamp(pow((dot((cameraVector+directionalVector),normalize(vNormal))/ + (length(cameraVector+directionalVector)*length(normalize(vNormal)))),shininess), 0.0, 1.0) + *specularFactor*directionalIntensity*directionalColor*directionalVisibility; } // point lights @@ -103,24 +116,50 @@ void main() for(int i = 0; i 0.001f) { + if (distance < farPlane) { + if (i == 0 && ilevelXmlPath = levelXmlPath; } + +void Application::setMaxShadowRenderCount(int count) { + this->maxShadowRenderCount = count; +} diff --git a/application.hh b/application.hh index 0a58d84..169a664 100644 --- a/application.hh +++ b/application.hh @@ -22,6 +22,7 @@ class Application { void setWindowHeight(int windowHeight); void setShadowCubeSize(int shadowCubeSize); void setFarPlane(float farPlane); + void setMaxShadowRenderCount(int count); void setCompositionsPath(std::string compositionsPath); void setShaderPath(std::string shaderPath); void setGeometryPath(std::string geometryPath); @@ -38,6 +39,7 @@ class Application { int windowWidth; int windowHeight; int shadowCubeSize; + int maxShadowRenderCount; float farPlane; std::string compositionsPath; std::string shaderPath; diff --git a/camera.cc b/camera.cc index 181ece4..218eeac 100644 --- a/camera.cc +++ b/camera.cc @@ -3,6 +3,7 @@ Camera::Camera(glm::vec2 rotation, float distance) { this->rotation = rotation; this->distance = distance; + this->setIsPhysicsCamera(true); } Camera::Camera() { @@ -31,6 +32,15 @@ void Camera::setRotation(glm::vec2 rotation) { updatePosition(); } + +bool Camera::getIsPhysicsCamera() +{ + return usePhysicsCamera; +} +void Camera::setIsPhysicsCamera(bool val) +{ + usePhysicsCamera = val; +} void Camera::updateRotation(glm::vec2 rotation) { this->rotation += rotation; if((this->rotation.x + rotation.x) >= 1.57f) { diff --git a/camera.hh b/camera.hh index 71b6b86..e0bea51 100644 --- a/camera.hh +++ b/camera.hh @@ -19,7 +19,8 @@ class Camera { glm::vec3 getPosition(); void setDirection(glm::vec3 dir); glm::vec3 getDirection(); - + bool getIsPhysicsCamera(); + void setIsPhysicsCamera(bool val); private: void updatePosition(); float distance; @@ -27,6 +28,7 @@ class Camera { glm::vec3 vector; glm::vec3 position; glm::vec3 direction; + bool usePhysicsCamera; }; #endif diff --git a/data/config.xml b/data/config.xml index fd1c30f..fc95c9d 100644 --- a/data/config.xml +++ b/data/config.xml @@ -7,6 +7,8 @@ 150.0 +10 + ../Levels/ObjectSetups/Compositions.xml Shader/ diff --git a/graphics.cc b/graphics.cc index d51ecb6..66a6397 100644 --- a/graphics.cc +++ b/graphics.cc @@ -1,7 +1,9 @@ #include "graphics.hh" +#include "lodepng.h" #include #include +#include #include @@ -9,11 +11,14 @@ using namespace ACGL::OpenGL; const double lightUpdateDelay = 0.5f; -Graphics::Graphics(glm::uvec2 windowSize, float nearPlane, float farPlane, int cube_size) { +Graphics::Graphics(glm::uvec2 windowSize, float nearPlane, + float farPlane, int cube_size, + unsigned int maxShadowRenderCount) { this->windowSize = windowSize; this->nearPlane = nearPlane; this->farPlane = farPlane; this->cube_size = cube_size; + this->maxShadowRenderCount = maxShadowRenderCount; } Graphics::Graphics() { @@ -40,8 +45,11 @@ void Graphics::init(Level* level) { depthShader = ShaderProgramCreator("depth") .attributeLocations(vao->getAttributeLocations()).create(); - - depthTexture = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH_COMPONENT16)); + + depthCubeShader = ShaderProgramCreator("depth_cube") + .attributeLocations(vao->getAttributeLocations()).create(); + + depthTexture = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH_COMPONENT24)); depthTexture->setMinFilter(GL_NEAREST); depthTexture->setMagFilter(GL_NEAREST); depthTexture->setWrapS(GL_CLAMP_TO_EDGE); @@ -51,12 +59,19 @@ void Graphics::init(Level* level) { framebuffer = SharedFrameBufferObject(new FrameBufferObject()); framebuffer->setDepthTexture(depthTexture); framebuffer->validate(); - - /*depth_cubeMaps = std::vector(level->getLights()->size()); - for (unsigned int i = 0; i(std::min(int(level->getLights()->size()), 1)); - for (unsigned int i = 0; i<1 && i(10); + for (unsigned int i = 0; isetMinFilter(GL_NEAREST); depth_cubeMaps.at(i)->setMagFilter(GL_NEAREST); depth_cubeMaps.at(i)->setWrapS(GL_CLAMP_TO_EDGE); @@ -65,13 +80,18 @@ void Graphics::init(Level* level) { } framebuffer_cube = SharedFrameBufferObject(new FrameBufferObject()); - - depthTexture_cube = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH_COMPONENT16)); - depthTexture_cube->setMinFilter(GL_NEAREST); - depthTexture_cube->setMagFilter(GL_NEAREST); - depthTexture_cube->setWrapS(GL_CLAMP_TO_EDGE); - depthTexture_cube->setWrapT(GL_CLAMP_TO_EDGE); - depthTexture_cube->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); + + lightingShader->use(); + + lightingShader->setTexture("shadowMap", depthTexture, 1); + + if (level->getLights()->size() > 0) { + for(unsigned int i = 0; isetTexture("shadowMap_cube" + std::to_string(i), depth_cubeMaps.at(i), i+2); + } + } + updateClosestLights(); } glm::uvec2 Graphics::getWindowSize() { @@ -81,29 +101,35 @@ glm::uvec2 Graphics::getWindowSize() { void Graphics::render(double time) { // At first render shadows - depthShader->use(); + 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 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_pointlightgetLights()->size(); i_pointlight++) { - for (unsigned int i_pointlight = 0; i_pointlight<1 && i_pointlightgetLights()->size(); i_pointlight++) { + for (unsigned int i_pointlight = 0; i_pointlightgetObjectName(), 0); glClear(GL_DEPTH_BUFFER_BIT); - glm::mat4 depthViewProjectionMatrix_face = depthProjectionMatrix_pointlights * glm::lookAt(level->getLights()->at(i_pointlight).getPosition(), - level->getLights()->at(i_pointlight).getPosition() + looking_directions[i_face], glm::vec3(0.0f, 1.0f, 0.0f)); - level->render(depthShader, false, &depthViewProjectionMatrix_face); + 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 texture for sun + depthShader->use(); glViewport(0, 0, windowSize.x, windowSize.y); // far pass @@ -122,19 +148,16 @@ void Graphics::render(double time) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); lightingShader->use(); - - if (level->getLights()->size() > 0) { - lightingShader->setTexture("shadowMap_cube", depth_cubeMaps.at(0), 4); - } - + //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? + double nextUpdate = lastUpdate + lightUpdateDelay; if (time >= nextUpdate) { - updateLights(); + updateShaderLights(); lastUpdate = time; } @@ -146,9 +169,6 @@ void Graphics::render(double time) 0.5, 0.5, 0.5, 1.0 ); glm::mat4 depthBiasVP = biasMatrix*depthViewProjectionMatrix; - - lightingShader->setTexture("shadowMap", depthTexture, 1); - lightingShader->setUniform("farPlane", farPlane); // set fog Parameters @@ -157,7 +177,7 @@ void Graphics::render(double time) // set Material Parameters lightingShader->setUniform("ambientColor", level->getAmbientLight()); - lightingShader->setUniform("camera", level->getCameraPosition()); + lightingShader->setUniform("camera", level->getPhysics()->getCameraPosition()); //set view and projection matrix glm::mat4 lightingViewProjectionMatrix = glm::perspective(1.571f, (float)windowSize.x/(float)windowSize.y, 0.1f, farPlane) * buildViewMatrix(level); @@ -169,28 +189,49 @@ void Graphics::render(double time) level->render(lightingShader, true, &lightingViewProjectionMatrix, &shadowVPs); } -void Graphics::updateLights() { - if (level->getLights()->size() > 0) { - lightingShader->setUniform("lightCount", (int) level->getLights()->size()); - +bool Graphics::compareLightDistances(Light a, Light b) { + if (glm::distance(this->level->getCameraCenter()->getPosition(), a.getPosition()) < + glm::distance(this->level->getCameraCenter()->getPosition(), b.getPosition())) { + return true; + } + else { + return false; + } +} + +void Graphics::updateClosestLights() { + closestLights = std::vector(*level->getLights()); + std::sort(closestLights.begin(), + closestLights.end(), + [this](Light a, Light b) {return compareLightDistances(a, b); }); + closestLights = std::vector(&closestLights[0], + &closestLights[31]); +} + +void Graphics::updateShaderLights() { + updateClosestLights(); + if (closestLights.size() > 0) { + lightingShader->setUniform("lightCount", (int) closestLights.size()); + lightingShader->setUniform("maxShadowRenderCount", std::min((int) closestLights.size(), (int)maxShadowRenderCount)); + // Build light position array - glm::vec3 lightSources[level->getLights()->size()]; - for(unsigned int i = 0; igetLights()->size(); i++) { - lightSources[i] = level->getLights()->at(i).getPosition(); + glm::vec3 lightSources[closestLights.size()]; + for(unsigned int i = 0; igetUniformLocation("lightSources"), sizeof(lightSources), (GLfloat*) lightSources); // Build light colour array - glm::vec3 lightColours[level->getLights()->size()]; - for(unsigned int i = 0; igetLights()->size(); i++) { - lightColours[i] = level->getLights()->at(i).getColour(); + glm::vec3 lightColours[closestLights.size()]; + for(unsigned int i = 0; igetUniformLocation("lightColors"), sizeof(lightColours), (GLfloat*) lightColours); // Build light attenuation array - float lightIntensities[level->getLights()->size()]; - for(unsigned int i = 0; igetLights()->size(); i++) { - lightIntensities[i] = level->getLights()->at(i).getIntensity(); + float lightIntensities[closestLights.size()]; + for(unsigned int i = 0; igetUniformLocation("lightIntensities"), sizeof(lightIntensities), (GLfloat*) lightIntensities); @@ -213,7 +254,8 @@ void Graphics::resize(glm::uvec2 windowSize) { glm::mat4 Graphics::buildViewMatrix(Level* level) { //construct lookAt (cameraPosition = cameraCenter + cameraVector) - return glm::lookAt(level->getCamera()->getPosition(), level->getCamera()->getPosition() + level->getCamera()->getDirection(), glm::vec3(0.0f, 1.0f, 0.0f)); + if(level->getCamera()->getIsPhysicsCamera()) + return glm::lookAt(level->getCamera()->getPosition(), level->getCamera()->getPosition() + level->getCamera()->getDirection(), glm::vec3(0.0f, 1.0f, 0.0f)); return glm::lookAt((level->getCameraCenter()->getPosition() + level->getCamera()->getVector()), level->getCameraCenter()->getPosition(), glm::vec3(0.0f, 1.0f, 0.0f)); @@ -222,3 +264,25 @@ glm::mat4 Graphics::buildViewMatrix(Level* level) { float Graphics::getFarPlane() { return farPlane; } + +void Graphics::saveDepthBufferToDisk(int face, std::string filename) { + printf("Starting saving of depth buffer...\n"); + float *depthbuffer = new float[1024*1024]; + std::vector image (1024 * 1024 * 4); + + glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_DEPTH_COMPONENT, GL_FLOAT, depthbuffer); + for (unsigned int i = 0; i<1024*1024; i++) { + image[i * 4 + 0] = depthbuffer[i] * 255; + image[i * 4 + 1] = depthbuffer[i] * 255; + image[i * 4 + 2] = depthbuffer[i] * 255; + image[i * 4 + 3] = 255; + } + unsigned error = lodepng::encode(filename.c_str(), image, 1024, 1024); + if (error) { + std::cout << "Encoder error " << error << ": " << lodepng_error_text(error) << std::endl; + } + else { + printf("Saving complete!\n"); + } + delete [] depthbuffer; +} diff --git a/graphics.hh b/graphics.hh index 96259cd..ec348f2 100644 --- a/graphics.hh +++ b/graphics.hh @@ -10,7 +10,7 @@ class Graphics { public: - Graphics(glm::uvec2 windowSize, float nearPlane, float farPlane, int cube_size); + Graphics(glm::uvec2 windowSize, float nearPlane, float farPlane, int cube_size, unsigned int maxShadowRenderCount); Graphics(); void init(Level* level); void render(double time); @@ -19,20 +19,27 @@ class Graphics { void resize(glm::uvec2 windowSize); float getFarPlane(); private: - void updateLights(); + void updateShaderLights(); + void updateClosestLights(); + bool compareLightDistances(Light a, Light b); + void saveDepthBufferToDisk(int face, std::string); double lastUpdate; glm::uvec2 windowSize; float nearPlane; float farPlane; + // pointer to either use the vector from the level or from here + std::vector closestLights; ACGL::OpenGL::SharedShaderProgram lightingShader; + ACGL::OpenGL::SharedShaderProgram depthCubeShader; ACGL::OpenGL::SharedShaderProgram depthShader; ACGL::OpenGL::SharedTexture2D depthTexture; ACGL::OpenGL::SharedFrameBufferObject framebuffer; std::vector depth_cubeMaps; ACGL::OpenGL::SharedFrameBufferObject framebuffer_cube; - ACGL::OpenGL::SharedTexture2D depthTexture_cube; int cube_size; + unsigned int maxShadowRenderCount; Level* level; + int number_of_texture_units = 0; }; #endif diff --git a/level.cc b/level.cc index 3437f42..233890c 100644 --- a/level.cc +++ b/level.cc @@ -56,7 +56,7 @@ void Level::render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass, } } -void Level::update(float runTime, glm::vec2 mouseDelta, bool wPressed, bool aPressed, bool sPressed, bool dPressed) { +void Level::update(float runTime, glm::vec2 mouseDelta, bool wPressed, bool aPressed, bool sPressed, bool dPressed,bool kPressed, bool lPressed) { // Ignore first two mouse updates, because they are incorrect // DON'T try to move this functionallity elsewhere static int i = 0; @@ -84,6 +84,11 @@ void Level::update(float runTime, glm::vec2 mouseDelta, bool wPressed, bool aPre physics.rollRight(camera.getVector(),strength); } + if(kPressed) + camera.setIsPhysicsCamera(true); + if(lPressed) + camera.setIsPhysicsCamera(false); + physics.takeUpdateStep(runTime); cameraCenter->setPosition(physics.getPos(0)); diff --git a/level.hh b/level.hh index 4cbdf34..93d11fa 100644 --- a/level.hh +++ b/level.hh @@ -24,7 +24,7 @@ class Level { Level(); ~Level(); void load(); - void update(float runTime, glm::vec2 mouseDelta,bool wPressed, bool aPressed,bool sPressed, bool dPressed); + void update(float runTime, glm::vec2 mouseDelta,bool wPressed, bool aPressed,bool sPressed, bool dPressed, bool kPressed, bool lPressed); void render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass, glm::mat4* viewProjectionMatrix, std::vector* shadowVPs=0); glm::vec3 getAmbientLight(); diff --git a/loader.cc b/loader.cc index 0dd03e9..ca515ab 100644 --- a/loader.cc +++ b/loader.cc @@ -5,7 +5,7 @@ Loader::Loader() { } void Loader::loadConfig(Application* application) { - int windowWidth, windowHeight, shadowCubeSize; + int windowWidth, windowHeight, shadowCubeSize, maxShadowRenderCount; float farPlane; std::string compositionsPath, shaderPath, geometryPath, texturePath, scriptPath, heightmapPath, levelXmlPath; XMLDocument* config = new XMLDocument(); @@ -20,6 +20,7 @@ void Loader::loadConfig(Application* application) { errorCheck(resolution->FirstChildElement("height")->QueryIntText(&windowHeight)); errorCheck(config->FirstChildElement("shadowCubeSize")->QueryIntText(&shadowCubeSize)); errorCheck(config->FirstChildElement("farPlane")->QueryFloatText(&farPlane)); + errorCheck(config->FirstChildElement("maxShadowRenderCount")->QueryIntText(&maxShadowRenderCount)); const char* charCompositionsPath = config->FirstChildElement("compositionsPath")->GetText(); if(charCompositionsPath == NULL){ @@ -74,6 +75,7 @@ void Loader::loadConfig(Application* application) { application->setWindowHeight(windowHeight); application->setShadowCubeSize(shadowCubeSize); application->setFarPlane(farPlane); + application->setMaxShadowRenderCount(maxShadowRenderCount); application->setCompositionsPath(compositionsPath); application->setShaderPath(shaderPath); application->setGeometryPath(geometryPath); diff --git a/main.cc b/main.cc index 2cfb0a5..08ddf72 100644 --- a/main.cc +++ b/main.cc @@ -161,16 +161,19 @@ int main( int argc, char *argv[] ) int stateA = glfwGetKey(window, GLFW_KEY_A); int stateS = glfwGetKey(window, GLFW_KEY_S); int stateD = glfwGetKey(window, GLFW_KEY_D); + int stateK = glfwGetKey(window, GLFW_KEY_K); + int stateL = glfwGetKey(window, GLFW_KEY_L); + double xpos, ypos; glfwGetCursorPos(window, &xpos, &ypos); glfwSetCursorPos(window, app.getGraphics()->getWindowSize().x/2, app.getGraphics()->getWindowSize().y/2); app.getLevel()->update(now - lastUpdate, glm::vec2((float)ypos-app.getGraphics()->getWindowSize().y/2, (float)xpos-app.getGraphics()->getWindowSize().x/2), - stateW == GLFW_PRESS,stateA == GLFW_PRESS,stateS == GLFW_PRESS,stateD == GLFW_PRESS); + stateW == GLFW_PRESS,stateA == GLFW_PRESS,stateS == GLFW_PRESS,stateD == GLFW_PRESS,stateK == GLFW_PRESS,stateL == GLFW_PRESS); } else { - app.getLevel()->update(now - lastUpdate, glm::vec2(0.0f, 0.0f), false, false, false, false); + app.getLevel()->update(now - lastUpdate, glm::vec2(0.0f, 0.0f), false, false, false, false,false,false); if (app.isLocked()) { app.ignoredOneMouseUpdate(); } diff --git a/object.cc b/object.cc index 70acd47..3419786 100644 --- a/object.cc +++ b/object.cc @@ -14,7 +14,7 @@ Object::~Object() { } void Object::render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass, - glm::mat4* viewProjectionMatrix, std::vector* shadowVPs) { + glm::mat4* viewProjectionMatrix, std::vector* additionalMatrices) { if (!renderable) { return; } @@ -27,15 +27,20 @@ void Object::render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass, shader->setUniform("shininess", material.getShininess()); shader->setTexture("uTexture", material.getReference(), 0); // set model matrix - shader->setUniform( "modelMatrix", modelMatrix); + shader->setUniform("modelMatrix", modelMatrix); // set shadowMVPs glm::mat4 shadowMVPs[5]; - for(unsigned int i = 0; (isize() && i<5); i++) { - shadowMVPs[i] = shadowVPs->at(i) * modelMatrix; + for(unsigned int i = 0; (isize() && i<5); i++) { + shadowMVPs[i] = additionalMatrices->at(i) * modelMatrix; } glUniformMatrix4fv(shader->getUniformLocation("shadowMVPs"), sizeof(shadowMVPs), false, (GLfloat*) shadowMVPs); } + else { + if (additionalMatrices) { + shader->setUniform("modelViewMatrix", additionalMatrices->at(0) * modelMatrix); + } + } glm::mat4 mvp = (*viewProjectionMatrix) * modelMatrix; shader->setUniform("modelViewProjectionMatrix", mvp); // draw diff --git a/object.hh b/object.hh index 7d21956..3b80f2b 100644 --- a/object.hh +++ b/object.hh @@ -16,7 +16,7 @@ class Object : public Entity { Object(); ~Object(); void render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass, - glm::mat4* viewProjcetionMatrix, std::vector* shadowVPs); + glm::mat4* viewProjcetionMatrix, std::vector* additionalMatrices); private: Model model; Material material; diff --git a/physics.cc b/physics.cc index 0f5cd42..60a28b6 100644 --- a/physics.cc +++ b/physics.cc @@ -204,7 +204,7 @@ void Physics::addTriangleMeshBody(Entity entity, std::string path, float mass, f btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); btVector3 inertia(0,0,0); - if(mass != 0.0 && rotate) //&& rotate lets certain objects get inertia (0,0,0) (not rotateable) + if(mass != 0.0) { shape->calculateLocalInertia((btScalar)mass,inertia); } @@ -219,6 +219,10 @@ void Physics::addTriangleMeshBody(Entity entity, std::string path, float mass, f world->addRigidBody(body,COL_OBJECTS, objectsPhysicsCollision); + if(!rotate)//rotate lets certain objects get inertia (0,0,0) (not rotateable) + { + body->setAngularFactor(btVector3(0,0,0)); + } if(bodies.size() != indice) throw std::invalid_argument( "Bodies out of Sync" ); @@ -237,7 +241,7 @@ void Physics::addButton(float width, float height, float length, Entity entity, btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); btVector3 inertia(0,0,0); - if(mass != 0.0 && rotate) //&& rotate lets certain objects get inertia (0,0,0) (not rotateable) + if(mass != 0.0) //&& rotate lets certain objects get inertia (0,0,0) (not rotateable) { box->calculateLocalInertia((btScalar)mass,inertia); } @@ -251,6 +255,11 @@ void Physics::addButton(float width, float height, float length, Entity entity, bodies.push_back(body); + if(!rotate) + { + body->setAngularFactor(btVector3(0,0,0)); + } + if(bodies.size() != indice) throw std::invalid_argument( "Bodies out of Sync" ); } @@ -266,11 +275,12 @@ void Physics::addBox(float width, float height, float length, Entity entity, flo btDefaultMotionState* motion = new btDefaultMotionState(btTransform(btQuaternion(glmQuat.x,glmQuat.y,glmQuat.z,glmQuat.w),btVector3(entity.getPosition().x,entity.getPosition().y,entity.getPosition().z))); btVector3 inertia(0,0,0); - if(mass != 0.0 && rotate) //&& rotate lets certain objects get inertia (0,0,0) (not rotateable) + if(mass != 0.0) //&& rotate lets certain objects get inertia (0,0,0) (not rotateable) { box->calculateLocalInertia((btScalar)mass,inertia); } + btRigidBody::btRigidBodyConstructionInfo info(mass,motion,box,inertia); btRigidBody* body = new btRigidBody(info); @@ -281,6 +291,11 @@ void Physics::addBox(float width, float height, float length, Entity entity, flo bodies.push_back(body); + if(!rotate) + { + body->setAngularFactor(btVector3(0,0,0)); + } + if(bodies.size() != indice) throw std::invalid_argument( "Bodies out of Sync" ); } @@ -311,6 +326,11 @@ void Physics::addSphere(float rad, Entity entity, float mass, float dampningL, f bodies.push_back(body); + if(!rotate)//rotate lets certain objects get inertia (0,0,0) (not rotateable) + { + body->setAngularFactor(btVector3(0,0,0)); + } + body->setSleepingThresholds(0,0); if(bodies.size() != indice) @@ -334,6 +354,9 @@ void Physics::addCamera() //Camera Creator automatically called when player is c cameraBody->setDamping(0.9,0.5); //this damping factor leaves a relativly smoothe system + info.m_friction = 0; + info.m_restitution = 0; + world->addRigidBody(cameraBody,COL_OBJECTS, objectsPhysicsCollision); cameraBody->setGravity(btVector3(0,0,0));