ex1 done
This commit is contained in:
parent
4645e40b62
commit
4247ae3659
|
@ -30,3 +30,5 @@
|
||||||
*.exe
|
*.exe
|
||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
|
build/
|
||||||
|
|
|
@ -1,12 +1,67 @@
|
||||||
#version 430 core
|
#version 430 core
|
||||||
|
|
||||||
in layout(location = 0) vec3 normal;
|
in layout(location = 0) vec3 normal;
|
||||||
|
in layout(location = 1) vec3 vertex;
|
||||||
|
|
||||||
|
// point lights
|
||||||
|
struct Light {
|
||||||
|
vec3 position;
|
||||||
|
mat4 MV;
|
||||||
|
bool is_spot;
|
||||||
|
vec3 spot_target; // MV space coordinates
|
||||||
|
};
|
||||||
|
|
||||||
|
#define N_LIGHTS 3
|
||||||
|
|
||||||
|
uniform Light light[N_LIGHTS];
|
||||||
|
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
|
// constants
|
||||||
|
float shininess = 15;
|
||||||
|
vec3 c_diffuse = vec3(0.75390625, 0.4296875, 0.4375);
|
||||||
|
vec3 c_emissive = vec3(0.01171875, 0.0, 0.15234375);
|
||||||
|
vec3 c_specular = vec3(0.9453125, 0.94921875, 0.84765625);
|
||||||
|
|
||||||
|
float spot_cuttof_angle = cos(4 / 180.0 * 3.1415926535);
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
float intensity = dot(normalize(normal), vec3(0, 0, 1));
|
vec3 nnormal = normalize(normal);
|
||||||
color = vec4(0.5 * normal + 0.5, 1.0);
|
|
||||||
//color = vec4(intensity, intensity, intensity, 1.0f);
|
float diffuse_intensity = 0.0;
|
||||||
|
float specular_intensity = 0.0;
|
||||||
|
|
||||||
|
for (int i = 0; i<3; i++) {
|
||||||
|
vec3 L = vec3(light[i].MV * vec4(light[i].position, 1.0f)) - vertex;
|
||||||
|
float attenuation = clamp(1000/(1 + 40*length(L) + 0.1*length(L)*length(L)), 0.0, 1.25);
|
||||||
|
L = normalize(L);
|
||||||
|
|
||||||
|
if (light[i].is_spot) {
|
||||||
|
vec3 L2 = normalize(vec3(light[i].MV * vec4(light[i].position, 1.0f)) - light[i].spot_target);
|
||||||
|
if (dot(L2, L) < spot_cuttof_angle) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
attenuation *= 70;
|
||||||
|
}
|
||||||
|
|
||||||
|
float diffuse_i = dot(nnormal, L);
|
||||||
|
|
||||||
|
float specular_i = pow(dot(reflect(-L, nnormal), normalize(vec3(0,0,0) - vertex)), shininess);
|
||||||
|
|
||||||
|
|
||||||
|
if (diffuse_i > 0) diffuse_intensity += attenuation*diffuse_i;
|
||||||
|
if (specular_i > 0) specular_intensity += attenuation*specular_i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//diffuse_intensity *= 1.0 / N_LIGHTS;
|
||||||
|
//specular_intensity *= 1.0 / N_LIGHTS;
|
||||||
|
|
||||||
|
|
||||||
|
//float intensity = dot(normalize(normal), normalize(light_pos_2));
|
||||||
|
//color = vec4(0.5 * normal + 0.5, 1.0);
|
||||||
|
|
||||||
|
color = vec4(c_emissive
|
||||||
|
+ c_diffuse*diffuse_intensity
|
||||||
|
+ c_specular*specular_intensity, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,16 @@ in layout(location = 0) vec3 position;
|
||||||
in layout(location = 1) vec3 normal_in;
|
in layout(location = 1) vec3 normal_in;
|
||||||
|
|
||||||
uniform layout(location = 3) mat4 MVP;
|
uniform layout(location = 3) mat4 MVP;
|
||||||
|
uniform layout(location = 4) mat4 MV;
|
||||||
|
uniform layout(location = 5) mat4 MVnormal;
|
||||||
|
|
||||||
|
|
||||||
out layout(location = 0) vec3 normal_out;
|
out layout(location = 0) vec3 normal_out;
|
||||||
|
out layout(location = 1) vec3 vertex_out;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
normal_out = normal_in;
|
normal_out = normalize(vec3(MVnormal * vec4(normal_in, 1.0f)));
|
||||||
|
vertex_out = vec3(MV*vec4(position, 1.0f));
|
||||||
gl_Position = MVP * vec4(position, 1.0f);
|
gl_Position = MVP * vec4(position, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <SFML/Audio/Sound.hpp>
|
#include <SFML/Audio/Sound.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include <string>
|
||||||
#include "gamelogic.h"
|
#include "gamelogic.h"
|
||||||
#include "sceneGraph.hpp"
|
#include "sceneGraph.hpp"
|
||||||
|
|
||||||
|
@ -33,6 +34,8 @@ SceneNode* boxNode;
|
||||||
SceneNode* ballNode;
|
SceneNode* ballNode;
|
||||||
SceneNode* padNode;
|
SceneNode* padNode;
|
||||||
|
|
||||||
|
SceneNode* lightNode[3];
|
||||||
|
|
||||||
double ballRadius = 3.0f;
|
double ballRadius = 3.0f;
|
||||||
|
|
||||||
// These are heap allocated, because they should not be initialised at the start of the program
|
// These are heap allocated, because they should not be initialised at the start of the program
|
||||||
|
@ -55,7 +58,7 @@ bool hasLost = false;
|
||||||
bool jumpedToNextFrame = false;
|
bool jumpedToNextFrame = false;
|
||||||
|
|
||||||
// Modify if you want the music to start further on in the track. Measured in seconds.
|
// Modify if you want the music to start further on in the track. Measured in seconds.
|
||||||
const float debug_startTime = 0;
|
const float debug_startTime = 45;
|
||||||
double totalElapsedTime = debug_startTime;
|
double totalElapsedTime = debug_startTime;
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,12 +128,28 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) {
|
||||||
ballNode->vertexArrayObjectID = ballVAO;
|
ballNode->vertexArrayObjectID = ballVAO;
|
||||||
ballNode->VAOIndexCount = sphere.indices.size();
|
ballNode->VAOIndexCount = sphere.indices.size();
|
||||||
|
|
||||||
|
// task 1a, add point lights
|
||||||
|
for (int i = 0; i<3; i++) {
|
||||||
|
lightNode[i] = createSceneNode();
|
||||||
|
lightNode[i]->nodeType = SceneNodeType::POINT_LIGHT;
|
||||||
|
lightNode[i]->lightID = i;
|
||||||
|
}
|
||||||
|
rootNode->children.push_back(lightNode[0]);
|
||||||
|
rootNode->children.push_back(lightNode[1]);
|
||||||
|
ballNode->children.push_back(lightNode[2]);
|
||||||
|
lightNode[0]->position = {boxDimensions.x/2 - 10, boxDimensions.y/2 - 10, boxDimensions.z/2 - 10};
|
||||||
|
lightNode[1]->position = {300,300,400};
|
||||||
|
lightNode[2]->position = {0, 0, 0};
|
||||||
|
|
||||||
|
lightNode[1]->nodeType = SPOT_LIGHT;
|
||||||
|
padNode->targeted_by = lightNode[1];
|
||||||
|
|
||||||
getTimeDeltaSeconds();
|
getTimeDeltaSeconds();
|
||||||
|
|
||||||
std::cout << "Ready. Click to start!" << std::endl;
|
std::cout << "Ready. Click to start!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateNodeTransformations(SceneNode* node, glm::mat4 transformationThusFar) {
|
void updateNodeTransformations(SceneNode* node, glm::mat4 transformationThusFar, glm::mat4 V, glm::mat4 P) {
|
||||||
|
|
||||||
glm::mat4 transformationMatrix(1.0);
|
glm::mat4 transformationMatrix(1.0);
|
||||||
|
|
||||||
|
@ -146,17 +165,30 @@ void updateNodeTransformations(SceneNode* node, glm::mat4 transformationThusFar)
|
||||||
* glm::scale(glm::mat4(1.0), node->scale);
|
* glm::scale(glm::mat4(1.0), node->scale);
|
||||||
break;
|
break;
|
||||||
case POINT_LIGHT:
|
case POINT_LIGHT:
|
||||||
|
|
||||||
break;
|
|
||||||
case SPOT_LIGHT:
|
case SPOT_LIGHT:
|
||||||
|
transformationMatrix =
|
||||||
|
glm::translate(glm::mat4(1.0), node->position);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
glm::mat4 M = transformationThusFar * transformationMatrix;
|
||||||
|
glm::mat4 MV = V*M;
|
||||||
|
|
||||||
node->currentTransformationMatrix = transformationThusFar * transformationMatrix;
|
node->currentTransformationMatrixMV = MV;
|
||||||
|
node->currentTransformationMatrix = P*MV;
|
||||||
|
node->currentTransformationMatrixMVnormal = glm::inverse(glm::transpose(MV));
|
||||||
|
|
||||||
for(SceneNode* child : node->children) {
|
for(SceneNode* child : node->children) {
|
||||||
updateNodeTransformations(child, node->currentTransformationMatrix);
|
updateNodeTransformations(child, M, V, P);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->targeted_by != nullptr) {
|
||||||
|
assert(node->targeted_by->nodeType == SPOT_LIGHT);
|
||||||
|
node->targeted_by->rotation = glm::vec3(MV*glm::vec4(node->position, 1.0));
|
||||||
|
|
||||||
|
//std::cout << node->targeted_by->rotation[0]
|
||||||
|
// << " " << node->targeted_by->rotation[1]
|
||||||
|
// << " " << node->targeted_by->rotation[2]
|
||||||
|
// << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,9 +327,7 @@ void updateFrame(GLFWwindow* window) {
|
||||||
* glm::rotate(glm::mat4(1.0), 0.2f, glm::vec3(1, 0, 0))
|
* glm::rotate(glm::mat4(1.0), 0.2f, glm::vec3(1, 0, 0))
|
||||||
* glm::rotate(glm::mat4(1.0), float(M_PI), glm::vec3(0, 1, 0));
|
* glm::rotate(glm::mat4(1.0), float(M_PI), glm::vec3(0, 1, 0));
|
||||||
|
|
||||||
glm::mat4 VP = projection * cameraTransform;
|
updateNodeTransformations(rootNode, glm::mat4(1.0), cameraTransform, projection);
|
||||||
|
|
||||||
updateNodeTransformations(rootNode, VP);
|
|
||||||
|
|
||||||
boxNode->position = {-boxDimensions.x / 2, -boxDimensions.y / 2 - 15, boxDimensions.z - 10};
|
boxNode->position = {-boxDimensions.x / 2, -boxDimensions.y / 2 - 15, boxDimensions.z - 10};
|
||||||
padNode->position = {-boxDimensions.x / 2 + (1 - padPositionX) * (boxDimensions.x - padDimensions.x),
|
padNode->position = {-boxDimensions.x / 2 + (1 - padPositionX) * (boxDimensions.x - padDimensions.x),
|
||||||
|
@ -313,6 +343,8 @@ void updateFrame(GLFWwindow* window) {
|
||||||
|
|
||||||
void renderNode(SceneNode* node) {
|
void renderNode(SceneNode* node) {
|
||||||
glUniformMatrix4fv(3, 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrix));
|
glUniformMatrix4fv(3, 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrix));
|
||||||
|
glUniformMatrix4fv(4, 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrixMV));
|
||||||
|
glUniformMatrix4fv(5, 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrixMVnormal));
|
||||||
|
|
||||||
switch(node->nodeType) {
|
switch(node->nodeType) {
|
||||||
case GEOMETRY:
|
case GEOMETRY:
|
||||||
|
@ -320,14 +352,20 @@ void renderNode(SceneNode* node) {
|
||||||
glBindVertexArray(node->vertexArrayObjectID);
|
glBindVertexArray(node->vertexArrayObjectID);
|
||||||
glDrawElements(GL_TRIANGLES, node->VAOIndexCount, GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, node->VAOIndexCount, GL_UNSIGNED_INT, nullptr);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case POINT_LIGHT:
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SPOT_LIGHT:
|
case SPOT_LIGHT:
|
||||||
|
case POINT_LIGHT: {
|
||||||
|
std::string pre = "light[" + std::to_string(node->lightID) + "]";
|
||||||
|
|
||||||
|
glUniform3fv(shader->location(pre+".position"), 1, glm::value_ptr(node->position));
|
||||||
|
glUniformMatrix4fv(shader->location(pre+".MV"), 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrixMV));
|
||||||
|
|
||||||
|
glUniform1i(shader->location(pre+".is_spot"), node->nodeType == SPOT_LIGHT);
|
||||||
|
glUniform3fv(shader->location(pre+".spot_target"), 1, glm::value_ptr(node->rotation));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(SceneNode* child : node->children) {
|
for(SceneNode* child : node->children) {
|
||||||
renderNode(child);
|
renderNode(child);
|
||||||
|
|
|
@ -57,7 +57,8 @@ void runProgram(GLFWwindow* window, CommandLineOptions options)
|
||||||
void handleKeyboardInput(GLFWwindow* window)
|
void handleKeyboardInput(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
// Use escape key for terminating the GLFW window
|
// Use escape key for terminating the GLFW window
|
||||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS
|
||||||
|
|| glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
|
||||||
{
|
{
|
||||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ struct SceneNode {
|
||||||
VAOIndexCount = 0;
|
VAOIndexCount = 0;
|
||||||
|
|
||||||
nodeType = GEOMETRY;
|
nodeType = GEOMETRY;
|
||||||
|
targeted_by = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A list of all children that belong to this node.
|
// A list of all children that belong to this node.
|
||||||
|
@ -44,7 +45,9 @@ struct SceneNode {
|
||||||
glm::vec3 scale;
|
glm::vec3 scale;
|
||||||
|
|
||||||
// A transformation matrix representing the transformation of the node's location relative to its parent. This matrix is updated every frame.
|
// A transformation matrix representing the transformation of the node's location relative to its parent. This matrix is updated every frame.
|
||||||
glm::mat4 currentTransformationMatrix;
|
glm::mat4 currentTransformationMatrix; // MVP
|
||||||
|
glm::mat4 currentTransformationMatrixMV; // MV
|
||||||
|
glm::mat4 currentTransformationMatrixMVnormal; // transpose(inverse(MV))
|
||||||
|
|
||||||
// The location of the node's reference point
|
// The location of the node's reference point
|
||||||
glm::vec3 referencePoint;
|
glm::vec3 referencePoint;
|
||||||
|
@ -55,6 +58,10 @@ struct SceneNode {
|
||||||
|
|
||||||
// Node type is used to determine how to handle the contents of a node
|
// Node type is used to determine how to handle the contents of a node
|
||||||
SceneNodeType nodeType;
|
SceneNodeType nodeType;
|
||||||
|
|
||||||
|
// for lights:
|
||||||
|
unsigned int lightID;
|
||||||
|
SceneNode* targeted_by; // spot
|
||||||
};
|
};
|
||||||
|
|
||||||
// Struct for keeping track of 2D coordinates
|
// Struct for keeping track of 2D coordinates
|
||||||
|
|
|
@ -19,6 +19,11 @@ namespace Gloom
|
||||||
public:
|
public:
|
||||||
Shader() { mProgram = glCreateProgram(); }
|
Shader() { mProgram = glCreateProgram(); }
|
||||||
|
|
||||||
|
// hack?:
|
||||||
|
GLint location(std::string const& name) {
|
||||||
|
return glGetUniformLocation(mProgram, name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
// Public member functions
|
// Public member functions
|
||||||
void activate() { glUseProgram(mProgram); }
|
void activate() { glUseProgram(mProgram); }
|
||||||
void deactivate() { glUseProgram(0); }
|
void deactivate() { glUseProgram(0); }
|
||||||
|
|
Loading…
Reference in New Issue