Merge branch 'master' of github.com:Faerbit/swp

This commit is contained in:
Steffen Fündgens 2015-02-13 17:14:38 +01:00
commit 9e987fdbdf
21 changed files with 291 additions and 86 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ CMakeLists.txt.user
*.zip
*.db
*.blend1
*.swp

View File

@ -69,7 +69,7 @@
</object>
<light>
<xOffset>0.0</xOffset>
<yOffset>3</yOffset>
<yOffset>2</yOffset>
<zOffset>0.0</zOffset>
<rColour>1.0</rColour>
<gColour>1.0</gColour>

View File

@ -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.

View File

@ -1,7 +1,7 @@
#version 150
out float fragmentDepth;
out float gl_FragDepth;
void main() {
fragmentDepth = gl_FragCoord.z;
gl_FragDepth = gl_FragCoord.z;
}

16
Shader/depth_cube.fsh Normal file
View File

@ -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;
}

15
Shader/depth_cube.vsh Normal file
View File

@ -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);
}

View File

@ -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<lightCount; i++) {
vec3 lightDirection = vec3(fragPosition) - lightSources[i];
float distance = length(lightDirection);
float pointVisibility = 1.0f;
// only take lights into account with meaningful contribution
if (distance > 0.001f) {
if (distance < farPlane) {
if (i == 0 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube0, lightDirection);
}
if (i == 1 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube1, lightDirection);
}
if (i == 2 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube2, lightDirection);
}
if (i == 3 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube3, lightDirection);
}
if (i == 4 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube4, lightDirection);
}
if (i == 5 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube5, lightDirection);
}
if (i == 6 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube6, lightDirection);
}
if (i == 7 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube7, lightDirection);
}
if (i == 8 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube8, lightDirection);
}
if (i == 9 && i<maxShadowRenderCount) {
pointVisibility = samplePointShadow(shadowMap_cube9, lightDirection);
}
vec3 lightVector = normalize(lightSources[i]-vec3(fragPosition));
float intensity = clamp(exp(-(1/lightIntensities[i])*distance), 0.0, 1.0);
diffuseColor += clamp(dot(normalize(vNormal), lightVector)
*diffuseFactor*intensity*lightColors[i], 0.0, 1.0);
*diffuseFactor*intensity*lightColors[i], 0.0, 1.0)*pointVisibility;
vec3 cameraVector = normalize(camera - vec3(fragPosition));
specularColor += clamp(pow((dot((cameraVector+lightVector),normalize(vNormal))/(length(cameraVector+lightVector)*length(normalize(vNormal)))),shininess), 0.0, 1.0)
*specularFactor*intensity*lightColors[i];
visibility = samplePointShadow(shadowMap_cube, lightDirection);
specularColor += clamp(pow((dot((cameraVector+lightVector),normalize(vNormal))/
(length(cameraVector+lightVector)*length(normalize(vNormal)))),shininess), 0.0, 1.0)
*specularFactor*intensity*lightColors[i]*pointVisibility;
}
}
// shadows
visibility *= sampleDirectionalShadow(shadowMap, shadowCoord);
specularColor *= visibility;
diffuseColor *= visibility;
vec3 finalColor = specularColor + diffuseColor + ambientColor;
float distanceCameraCenter = distance(cameraCenter, vec3(fragPosition));

View File

@ -5,7 +5,7 @@ Application::Application() {
Loader loader = Loader();
//load the config.xml
loader.loadConfig(this);
graphics = Graphics(glm::uvec2(windowWidth, windowHeight), 0.1f, farPlane, shadowCubeSize);
graphics = Graphics(glm::uvec2(windowWidth, windowHeight), 0.1f, farPlane, shadowCubeSize, maxShadowRenderCount);
}
void Application::init()
@ -123,3 +123,7 @@ void Application::setHeightmapPath(std::string heightmapPath) {
void Application::setLevelXmlPath(std::string levelXmlPath) {
this->levelXmlPath = levelXmlPath;
}
void Application::setMaxShadowRenderCount(int count) {
this->maxShadowRenderCount = count;
}

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -7,6 +7,8 @@
<farPlane>150.0</farPlane>
<maxShadowRenderCount>10</maxShadowRenderCount>
<compositionsPath>../Levels/ObjectSetups/Compositions.xml</compositionsPath>
<shaderPath>Shader/</shaderPath>

View File

@ -1,7 +1,9 @@
#include "graphics.hh"
#include "lodepng.h"
#include <iomanip>
#include <sstream>
#include <functional>
#include <ACGL/OpenGL/Creator/ShaderProgramCreator.hh>
@ -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() {
@ -41,7 +46,10 @@ 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);
@ -52,11 +60,18 @@ void Graphics::init(Level* level) {
framebuffer->setDepthTexture(depthTexture);
framebuffer->validate();
/*depth_cubeMaps = std::vector<ACGL::OpenGL::SharedTextureCubeMap>(level->getLights()->size());
for (unsigned int i = 0; i<depth_cubeMaps.size(); i++) {*/
depth_cubeMaps = std::vector<ACGL::OpenGL::SharedTextureCubeMap>(std::min(int(level->getLights()->size()), 1));
for (unsigned int i = 0; i<1 && i<depth_cubeMaps.size(); i++) {
depth_cubeMaps.at(i) = SharedTextureCubeMap(new TextureCubeMap(glm::vec2(cube_size, cube_size), GL_DEPTH_COMPONENT16));
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 < 12) {
printf("You need at least 12 texture units to run this application. Exiting\n");
exit(-1);
}
// always generate and bind 32 cube maps, because otherwise the shader won't work
depth_cubeMaps = std::vector<ACGL::OpenGL::SharedTextureCubeMap>(10);
for (unsigned int i = 0; i<depth_cubeMaps.size(); i++) {
depth_cubeMaps.at(i) = SharedTextureCubeMap(new TextureCubeMap(glm::vec2(cube_size, cube_size), GL_DEPTH_COMPONENT24));
depth_cubeMaps.at(i)->setMinFilter(GL_NEAREST);
depth_cubeMaps.at(i)->setMagFilter(GL_NEAREST);
depth_cubeMaps.at(i)->setWrapS(GL_CLAMP_TO_EDGE);
@ -66,12 +81,17 @@ 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; i<depth_cubeMaps.size(); i++){
// 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);
}
}
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_pointlight<level->getLights()->size(); i_pointlight++) {
for (unsigned int i_pointlight = 0; i_pointlight<1 && i_pointlight<level->getLights()->size(); i_pointlight++) {
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 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<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 texture for sun
depthShader->use();
glViewport(0, 0, windowSize.x, windowSize.y);
// far pass
@ -123,18 +149,15 @@ void Graphics::render(double time)
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<Light>(*level->getLights());
std::sort(closestLights.begin(),
closestLights.end(),
[this](Light a, Light b) {return compareLightDistances(a, b); });
closestLights = std::vector<Light>(&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; i<level->getLights()->size(); i++) {
lightSources[i] = level->getLights()->at(i).getPosition();
glm::vec3 lightSources[closestLights.size()];
for(unsigned int i = 0; i<closestLights.size(); i++) {
lightSources[i] = closestLights.at(i).getPosition();
}
glUniform3fv(lightingShader->getUniformLocation("lightSources"),
sizeof(lightSources), (GLfloat*) lightSources);
// Build light colour array
glm::vec3 lightColours[level->getLights()->size()];
for(unsigned int i = 0; i<level->getLights()->size(); i++) {
lightColours[i] = level->getLights()->at(i).getColour();
glm::vec3 lightColours[closestLights.size()];
for(unsigned int i = 0; i<closestLights.size(); i++) {
lightColours[i] = closestLights.at(i).getColour();
}
glUniform3fv(lightingShader->getUniformLocation("lightColors"),
sizeof(lightColours), (GLfloat*) lightColours);
// Build light attenuation array
float lightIntensities[level->getLights()->size()];
for(unsigned int i = 0; i<level->getLights()->size(); i++) {
lightIntensities[i] = level->getLights()->at(i).getIntensity();
float lightIntensities[closestLights.size()];
for(unsigned int i = 0; i<closestLights.size(); i++) {
lightIntensities[i] = closestLights.at(i).getIntensity();
}
glUniform1fv(lightingShader->getUniformLocation("lightIntensities"),
sizeof(lightIntensities), (GLfloat*) lightIntensities);
@ -213,6 +254,7 @@ void Graphics::resize(glm::uvec2 windowSize) {
glm::mat4 Graphics::buildViewMatrix(Level* level) {
//construct lookAt (cameraPosition = cameraCenter + cameraVector)
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()),
@ -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<unsigned char> 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;
}

View File

@ -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<Light> closestLights;
ACGL::OpenGL::SharedShaderProgram lightingShader;
ACGL::OpenGL::SharedShaderProgram depthCubeShader;
ACGL::OpenGL::SharedShaderProgram depthShader;
ACGL::OpenGL::SharedTexture2D depthTexture;
ACGL::OpenGL::SharedFrameBufferObject framebuffer;
std::vector<ACGL::OpenGL::SharedTextureCubeMap> 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

View File

@ -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));

View File

@ -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<glm::mat4>* shadowVPs=0);
glm::vec3 getAmbientLight();

View File

@ -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);

View File

@ -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();
}

View File

@ -14,7 +14,7 @@ Object::~Object() {
}
void Object::render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass,
glm::mat4* viewProjectionMatrix, std::vector<glm::mat4>* shadowVPs) {
glm::mat4* viewProjectionMatrix, std::vector<glm::mat4>* 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; (i<shadowVPs->size() && i<5); i++) {
shadowMVPs[i] = shadowVPs->at(i) * modelMatrix;
for(unsigned int i = 0; (i<additionalMatrices->size() && 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

View File

@ -16,7 +16,7 @@ class Object : public Entity {
Object();
~Object();
void render(ACGL::OpenGL::SharedShaderProgram shader, bool lightingPass,
glm::mat4* viewProjcetionMatrix, std::vector<glm::mat4>* shadowVPs);
glm::mat4* viewProjcetionMatrix, std::vector<glm::mat4>* additionalMatrices);
private:
Model model;
Material material;

View File

@ -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));