Merge branch 'master' of github.com:Faerbit/swp
This commit is contained in:
commit
1492a312ed
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ CMakeLists.txt.user
|
||||
*.zip
|
||||
*.db
|
||||
*.blend1
|
||||
*.swp
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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
16
Shader/depth_cube.fsh
Normal 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
15
Shader/depth_cube.vsh
Normal 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);
|
||||
}
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
10
camera.cc
10
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) {
|
||||
|
@ -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
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
<farPlane>150.0</farPlane>
|
||||
|
||||
<maxShadowRenderCount>10</maxShadowRenderCount>
|
||||
|
||||
<compositionsPath>../Levels/ObjectSetups/Compositions.xml</compositionsPath>
|
||||
|
||||
<shaderPath>Shader/</shaderPath>
|
||||
|
146
graphics.cc
146
graphics.cc
@ -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;
|
||||
}
|
||||
|
13
graphics.hh
13
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<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
|
||||
|
7
level.cc
7
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));
|
||||
|
2
level.hh
2
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<glm::mat4>* shadowVPs=0);
|
||||
glm::vec3 getAmbientLight();
|
||||
|
@ -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);
|
||||
|
7
main.cc
7
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();
|
||||
}
|
||||
|
13
object.cc
13
object.cc
@ -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
|
||||
|
@ -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;
|
||||
|
29
physics.cc
29
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));
|
||||
|
Loading…
Reference in New Issue
Block a user