[ADD] custom rendering system

This commit is contained in:
Menno
2021-05-18 11:20:57 +02:00
parent e46e26c729
commit 0bb4cc5e1d
29 changed files with 8840 additions and 805 deletions

BIN
res/TreeTexture.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -1,57 +0,0 @@
#include "FpsCam.h"
#include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp>
FpsCam::FpsCam(GLFWwindow* window)
{
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
if (glfwRawMouseMotionSupported())
glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
}
glm::mat4 FpsCam::getMatrix()
{
glm::mat4 ret(1.0f);
ret = glm::rotate(ret, rotation.x, glm::vec3(1, 0, 0));
ret = glm::rotate(ret, rotation.y, glm::vec3(0, 1, 0));
ret = glm::translate(ret, position);
return ret;
}
void FpsCam::move(float angle, float fac)
{
position.x += (float)cos(rotation.y + glm::radians(angle)) * fac;
position.z += (float)sin(rotation.y + glm::radians(angle)) * fac;
}
void FpsCam::update(GLFWwindow* window)
{
double currentTime = glfwGetTime();
static double lastFrameTime = 0;
double deltaTime = currentTime - lastFrameTime;
lastFrameTime = currentTime;
double x, y;
glfwGetCursorPos(window, &x, &y);
static double lastX = x;
static double lastY = y;
rotation.x -= (float)(lastY - y) / 100.0f;
rotation.y -= (float)(lastX - x) / 100.0f;
lastX = x;
lastY = y;
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
move(0, 4.0f * deltaTime);
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
move(180, 4.0f * deltaTime);
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
move(90, 4.0f * deltaTime);
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
move(-90, 4.0f * deltaTime);
}

View File

@@ -1,21 +0,0 @@
#pragma once
#include <glm/glm.hpp>
struct GLFWwindow;
class FpsCam
{
public:
FpsCam(GLFWwindow*);
glm::mat4 getMatrix();
void update(GLFWwindow*);
private:
glm::vec3 position = glm::vec3(0, 0, 0);
glm::vec2 rotation = glm::vec2(0, 0);
void move(float angle, float fac);
};

95
src/MainManager.cpp Normal file
View File

@@ -0,0 +1,95 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp>
#include <vector>
#define STB_IMAGE_IMPLEMENTATION
#include <ostream>
#include "stb_image.h"
#include "models/Model.h"
#include "renderEngine/Loader.h"
#include "renderEngine/ObjLoader.h"
#include "renderEngine/Renderer.h"
#include "shaders/StaticShader.h"
#include "toolbox/Toolbox.h"
#pragma comment(lib, "glfw3.lib")
#pragma comment(lib, "glew32s.lib")
#pragma comment(lib, "opengl32.lib")
static double updateDelta();
static GLFWwindow* window;
int main(void)
{
#pragma region OPENGL_SETTINGS
if (!glfwInit())
throw "Could not inditialize glwf";
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGT, "Eindopdracht - Menno Bil", NULL, NULL);
if (!window)
{
glfwTerminate();
throw "Could not initialize glwf";
}
glfwMakeContextCurrent(window);
glewInit();
glGetError();
#pragma endregion
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE)
glfwSetWindowShouldClose(window, true);
});
models::RawModel rawModel = LoadObjModel("res/Tree.obj");
models::ModelTexture texture = { renderEngine::loader::LoadTexture("res/TreeTexture.png") };
models::TexturedModel model = { rawModel, texture };
entities::Entity entity(model, glm::vec3(0, -5, -20), glm::vec3(0, 0, 0), 1);
shaders::StaticShader shader;
shader.init();
renderEngine::renderer::Init(shader);
entities::Camera camera(glm::vec3(0, 0, 0), glm::vec3(0, 0, 0));
// Main game loop
while (!glfwWindowShouldClose(window))
{
// Update
const double delta = updateDelta();
entity.increaseRotation(glm::vec3(0, 1, 0));
camera.move(window);
// Render
renderEngine::renderer::Prepare();
shader.start();
shader.loadViewMatrix(camera);
renderEngine::renderer::Render(entity, shader);
// Finish up
shader.stop();
glfwSwapBuffers(window);
glfwPollEvents();
}
// Clean up
shader.cleanUp();
renderEngine::loader::CleanUp();
glfwTerminate();
return 0;
}
static double updateDelta()
{
double currentTime = glfwGetTime();
static double lastFrameTime = currentTime;
double deltaTime = currentTime - lastFrameTime;
lastFrameTime = currentTime;
return deltaTime;
}

32
src/entities/Camera.cpp Normal file
View File

@@ -0,0 +1,32 @@
#include "Camera.h"
namespace entities
{
Camera::Camera(const ::glm::vec3& position, const ::glm::vec3& rotation)
: position(position),
rotation(rotation)
{}
void Camera::move(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
{
position.z -= speed;
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
{
position.z += speed;
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
{
position.x += speed;
}
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
{
position.x -= speed;
}
}
}

24
src/entities/Camera.h Normal file
View File

@@ -0,0 +1,24 @@
#pragma once
#include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp>
namespace entities
{
class Camera
{
private:
float speed = 0.02f;
glm::vec3 position;
glm::vec3 rotation;
public:
Camera(const ::glm::vec3& position, const ::glm::vec3& rotation);
void move(GLFWwindow* window);
inline glm::vec3 getPosition() const{ return position; }
inline glm::vec3 getRotation() const{ return rotation; }
};
}

29
src/entities/Entity.cpp Normal file
View File

@@ -0,0 +1,29 @@
#include "Entity.h"
#include <iostream>
namespace entities
{
Entity::Entity(const models::TexturedModel& model, const glm::vec3& position, const glm::vec3& rotation, float scale)
: model(model),
position(position),
rotation(rotation),
scale(scale)
{
}
void Entity::increasePosition(const glm::vec3& distance)
{
position.x += distance.x;
position.y += distance.y;
position.z += distance.z;
}
void Entity::increaseRotation(const glm::vec3& rotation)
{
this->rotation.x += rotation.x;
this->rotation.y += rotation.y;
this->rotation.z += rotation.z;
}
}

31
src/entities/Entity.h Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
#include <glm/gtc/matrix_transform.hpp>
#include "../models/Model.h"
namespace entities
{
class Entity
{
private:
models::TexturedModel model;
glm::vec3 position;
glm::vec3 rotation;
float scale;
public:
Entity(const models::TexturedModel& model, const glm::vec3& position, const glm::vec3& rotation, float scale);
void increasePosition(const glm::vec3& distance);
void increaseRotation(const glm::vec3& rotation);
inline models::TexturedModel getModel() const{return model;}
inline void set_model(const ::models::TexturedModel& model) { this->model = model; }
inline glm::vec3 getPosition() const { return position; }
inline void set_position(const ::glm::vec3& position) { this->position = position; }
inline glm::vec3 getRotation() const { return rotation; }
inline void set_rotation(const ::glm::vec3& rotation) { this->rotation = rotation; }
inline float getScale() const { return scale; }
inline void set_scale(const float scale) { this->scale = scale; }
};
}

View File

@@ -1,100 +0,0 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "tigl.h"
#include "FpsCam.h"
#include <iostream>
#include <glm/gtc/matrix_transform.hpp>
using tigl::Vertex;
#pragma comment(lib, "glfw3.lib")
#pragma comment(lib, "glew32s.lib")
#pragma comment(lib, "opengl32.lib")
GLFWwindow* window;
void init();
void update();
void draw();
int main(void)
{
if (!glfwInit())
throw "Could not initialize glwf";
window = glfwCreateWindow(1400, 800, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
throw "Could not initialize glwf";
}
glfwMakeContextCurrent(window);
tigl::init();
init();
while (!glfwWindowShouldClose(window))
{
update();
draw();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
FpsCam* camera;
void init()
{
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE)
glfwSetWindowShouldClose(window, true);
});
camera = new FpsCam(window);
}
void update()
{
camera->update(window);
}
void draw()
{
glClearColor(0.3f, 0.4f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glm::mat4 projection = glm::perspective(glm::radians(75.0f), viewport[2] / (float)viewport[3], 0.01f, 100.0f);
tigl::shader->setProjectionMatrix(projection);
tigl::shader->setViewMatrix(camera->getMatrix());
tigl::shader->setModelMatrix(glm::mat4(1.0f));
tigl::shader->enableColor(true);
glEnable(GL_DEPTH_TEST);
tigl::begin(GL_TRIANGLES);
tigl::addVertex(Vertex::PC(glm::vec3(-2, -1, -4), glm::vec4(1, 0, 0, 1)));
tigl::addVertex(Vertex::PC(glm::vec3(2, -1, -4), glm::vec4(0, 1, 0, 1)));
tigl::addVertex(Vertex::PC(glm::vec3(0, 1, -4), glm::vec4(0, 0, 1, 1)));
tigl::addVertex(Vertex::PC(glm::vec3(-10, -1, -10), glm::vec4(1, 1, 1, 1)));
tigl::addVertex(Vertex::PC(glm::vec3(-10, -1, 10), glm::vec4(1, 1, 1, 1)));
tigl::addVertex(Vertex::PC(glm::vec3(10, -1, 10), glm::vec4(1, 1, 1, 1)));
tigl::addVertex(Vertex::PC(glm::vec3(-10, -1, -10), glm::vec4(1, 1, 1, 1)));
tigl::addVertex(Vertex::PC(glm::vec3(10, -1, -10), glm::vec4(1, 1, 1, 1)));
tigl::addVertex(Vertex::PC(glm::vec3(10, -1, 10), glm::vec4(1, 1, 1, 1)));
tigl::end();
}

38
src/models/Model.h Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
#include <GL/glew.h>
namespace models
{
/*
Structure for storing a vboID and vertexCount.
This structure represents a Bare bones Model (A mesh without a texture).
The vaoID, points to an ID stored by openGL and the
vertexCount is how many triangles in the mesh there are.
*/
struct RawModel
{
GLuint vaoID;
int vertexCount;
};
/*
Structure for storing a texture (textureID) to apply to a RawModel.
*/
struct ModelTexture
{
GLuint textureID;
};
/*
Structure for storing a RawModel and a Texure.
This struct represents a model with a texture.
*/
struct TexturedModel
{
RawModel rawModel;
ModelTexture texture;
};
}

118
src/renderEngine/Loader.cpp Normal file
View File

@@ -0,0 +1,118 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "../stb_image.h"
#include "Loader.h"
namespace renderEngine
{
namespace loader
{
static GLuint createVAO();
static void storeDataInAttributeList(int attributeNumber, int coordinateSize, std::vector<float>& data);
static void bindIndicesBuffer(std::vector<unsigned int>& indices);
static std::vector<GLuint> vaos;
static std::vector<GLuint> vbos;
static std::vector<GLuint> textures;
/*
This function will generate a Model from vertex positions, textureCoordinates and indices.
*/
struct models::RawModel LoadToVAO(std::vector<float>& positions, std::vector<float>& textureCoords, std::vector<unsigned int>& indices)
{
GLuint vaoID = createVAO();
bindIndicesBuffer(indices);
storeDataInAttributeList(0, 3, positions);
storeDataInAttributeList(1, 2, textureCoords);
glBindVertexArray(0);
return { vaoID, static_cast<int>(indices.size()) };
}
/*
Loads an image as texture into openGL
*/
GLuint LoadTexture(std::string fileName)
{
int width, height, bpp;
unsigned char* imgData = stbi_load(fileName.c_str(), &width, &height, &bpp, 4);
GLuint textureID;
glGenTextures(1, &textureID);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
stbi_image_free(imgData);
textures.push_back(textureID);
return textureID;
}
/*
This function will delete all the vectors declared at the top of this file from openGL.
*/
void CleanUp()
{
glDeleteVertexArrays(static_cast<GLsizei>(vaos.size()), &vaos[0]);
glDeleteBuffers(static_cast<GLsizei>(vbos.size()), &vbos[0]);
glDeleteTextures(static_cast<GLsizei>(textures.size()), &textures[0]);
}
/*
This function will create a new VAO for a new mesh.
*/
static GLuint createVAO()
{
GLuint vaoID;
glGenVertexArrays(1, &vaoID);
vaos.push_back(vaoID);
glBindVertexArray(vaoID);
return vaoID;
}
/*
This function can store data (vbo) in a vao.
*/
static void storeDataInAttributeList(int attributeNumber, int coordinateSize, std::vector<float>& data)
{
GLuint vboID;
glGenBuffers(1, &vboID);
vbos.push_back(vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * data.size(), &data[0], GL_STATIC_DRAW);
glVertexAttribPointer(attributeNumber, coordinateSize, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
/*
This functions loads a indices buffer and binds it to a vao.
(Using this method of rendering is way more effici<63>nt with large/complex meshes.
This way you won't have to specify double or more occuring vertices. You just use sort of a lookup table
to choose which vertex to get)
Example:
std::vector<float> vertices =
{
-0.5f, 0.5f, 0,
-0.5f, -0.5f, 0,
0.5f, -0.5f, 0,
0.5f, 0.5f, 0
};
std::vector<int> indices =
{
0,1,3,
3,1,2
};
*/
static void bindIndicesBuffer(std::vector<unsigned int>& indices)
{
GLuint vboID;
glGenBuffers(1, &vboID);
vbos.push_back(vboID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * indices.size(), &indices[0], GL_STATIC_DRAW);
}
}
}

26
src/renderEngine/Loader.h Normal file
View File

@@ -0,0 +1,26 @@
#pragma once
#include <string>
#include <vector>
#include "../models/Model.h"
namespace renderEngine
{
namespace loader
{
/*
This function generates a model from model data.
*/
struct models::RawModel LoadToVAO(std::vector<float>& positions, std::vector<float>& textureCoords, std::vector<unsigned int>& indices);
/*
Loads a texture from a file into openGL using stb_image.h
*/
GLuint LoadTexture(std::string fileName);
/*
Call this function when cleaning up all the meshes (when exiting the program).
*/
void CleanUp();
}
}

View File

@@ -0,0 +1,134 @@
#include <fstream>
#include <iostream>
#include <vector>
#include <sstream>
#include <glm/gtc/matrix_transform.hpp>
#include "Loader.h"
#include "ObjLoader.h"
/*
* Grotendeels van deze functies zijn gemaakt door:
* https://github.com/Hopson97/ThinMatrix-OpenGL-Engine/blob/master/Source/Render_Engine/OBJLoader.cpp
*/
static void split(const std::string& s, char delim, std::vector<std::string>& elems)
{
std::stringstream ss;
ss.str(s);
std::string item;
while (getline(ss, item, delim)) {
elems.push_back(item);
}
}
static std::vector<std::string> split(const std::string& s, char delim)
{
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
static void processVertex(const std::vector<std::string>& vertexData,
const std::vector<glm::vec3>& normals,
const std::vector<glm::vec2>& textures,
std::vector<GLuint>& indices,
std::vector<GLfloat>& textureArray,
std::vector<GLfloat>& normalArray)
{
GLuint currentVertexPointer = std::stoi(vertexData.at(0)) - 1;
indices.push_back(currentVertexPointer);
glm::vec2 currentTexture = textures.at(std::stoi(vertexData.at(1)) - 1);
textureArray[(currentVertexPointer * 2) % textureArray.size()] = currentTexture.x;
textureArray[(currentVertexPointer * 2 + 1) % textureArray.size()] = 1 - currentTexture.y;
glm::vec3 currentNorm = normals.at(std::stoi(vertexData.at(2)) - 1);
normalArray[currentVertexPointer * 3] = currentNorm.x;
normalArray[currentVertexPointer * 3 + 1] = currentNorm.y;
normalArray[currentVertexPointer * 3 + 2] = currentNorm.z;
}
models::RawModel LoadObjModel(std::string fileName)
{
std::ifstream inFile (fileName);
if ( !inFile.is_open() )
{
throw std::runtime_error ( "Could not open model file " + fileName + ".obj!" );
}
std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> textures;
std::vector<GLuint> indices;
std::vector<GLfloat> vertexArray;
std::vector<GLfloat> normalArray;
std::vector<GLfloat> textureArray;
std::string line;
try
{
while (std::getline(inFile, line))
{
std::vector<std::string> splitline = split(line, ' ');
if (splitline.at(0) == "v")
{
glm::vec3 vertex;
vertex.x = std::stof(splitline.at(1));
vertex.y = std::stof(splitline.at(2));
vertex.z = std::stof(splitline.at(3));
vertices.push_back(vertex);
}
else if (splitline.at(0) == "vt")
{
glm::vec2 texture;
texture.x = std::stof(splitline.at(1));
texture.y = std::stof(splitline.at(2));
textures.push_back(texture);
}
else if (splitline.at(0) == "vn")
{
glm::vec3 normal;
normal.x = std::stof(splitline.at(1));
normal.y = std::stof(splitline.at(2));
normal.z = std::stof(splitline.at(3));
normals.push_back(normal);
}
else if (splitline.at(0) == "f")
{
normalArray = std::vector<GLfloat>(vertices.size() * 3);
textureArray = std::vector<GLfloat>(textures.size() * 2);
break;
}
}
while (true)
{
std::vector<std::string> splitline = split(line, ' ');
std::vector<std::string> vertex1 = split(splitline.at(1), '/');
std::vector<std::string> vertex2 = split(splitline.at(2), '/');
std::vector<std::string> vertex3 = split(splitline.at(3), '/');
processVertex(vertex1, normals, textures, indices, textureArray, normalArray);
processVertex(vertex2, normals, textures, indices, textureArray, normalArray);
processVertex(vertex3, normals, textures, indices, textureArray, normalArray);
if (!std::getline(inFile, line))
{
break;
}
}
} catch (const std::exception& e)
{
// Always go in here
}
inFile.close();
vertexArray = std::vector<GLfloat>( vertices.size() * 3 );
int p = 0;
for ( auto& vertex : vertices )
{
vertexArray[p++] = vertex.x;
vertexArray[p++] = vertex.y;
vertexArray[p++] = vertex.z;
}
return renderEngine::loader::LoadToVAO( vertexArray, textureArray, indices);
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include <string>
#include "../models/Model.h"
models::RawModel LoadObjModel(std::string fileName);

View File

@@ -0,0 +1,68 @@
#include <GL/glew.h>
#include <glm/gtc/matrix_transform.hpp>
#include <iostream>
#include "../models/Model.h"
#include "Renderer.h"
#include "../toolbox/Toolbox.h"
namespace renderEngine
{
namespace renderer
{
static const float FOV = 70.0f;
static const float NEAR_PLANE = 0.01f;
static const float FAR_PLANE = 1000.0f;
/*
This function will load the projectionMatrix into the shader
*/
void Init(shaders::StaticShader& shader)
{
const glm::mat4 projectionMatrix =
glm::perspective(glm::radians(FOV), (WINDOW_WIDTH / WINDOW_HEIGT), NEAR_PLANE, FAR_PLANE);
shader.start();
shader.loadProjectionMatrix(projectionMatrix);
shader.stop();
}
/*
This function will clear the screen.
*/
void Prepare()
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.3f, 0.4f, 0.6f, 1.0f);
}
/*
This function will Render a Model on the screen.
*/
void Render(entities::Entity& entity, shaders::StaticShader& shader)
{
const models::TexturedModel model = entity.getModel();
const models::RawModel rawModel = model.rawModel;
// Enable the model
glBindVertexArray(rawModel.vaoID);
// Enable the inputs for the vertexShader
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
// Load the transformation of the model into the shader
const glm::mat4 modelMatrix = toolbox::createModelMatrix(entity.getPosition(), entity.getRotation(), entity.getScale());
shader.loadModelMatrix(modelMatrix);
// Draw the model
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, model.texture.textureID);
glDrawElements(GL_TRIANGLES, rawModel.vertexCount, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindVertexArray(0);
}
}
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include "../entities/Entity.h"
#include "../shaders/StaticShader.h"
namespace renderEngine
{
namespace renderer
{
/*
Call this function when starting the program
*/
void Init(shaders::StaticShader& shader);
/*
Call this function before rendering.
*/
void Prepare();
/*
Call this function when wanting to Render a mesh to the screen.
*/
void Render(entities::Entity& entity, shaders::StaticShader& shader);
}
}

View File

@@ -0,0 +1,129 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "ShaderProgram.h"
namespace shaders
{
ShaderProgram::ShaderProgram(std::string& vertexShader, std::string& fragmentShader)
{
vertexShaderID = loadShader(vertexShader, GL_VERTEX_SHADER);
fragmentShaderID = loadShader(fragmentShader, GL_FRAGMENT_SHADER);
programID = glCreateProgram();
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
}
void ShaderProgram::init()
{
setAttributes();
glLinkProgram(programID);
glValidateProgram(programID);
getAllUniformLocations();
}
// This method will start the shaders
void ShaderProgram::start() const
{
glUseProgram(programID);
}
// This method will stop the shaders
void ShaderProgram::stop() const
{
glUseProgram(0);
}
// This method will clean up all the shaders
void ShaderProgram::cleanUp() const
{
stop();
glDetachShader(programID, vertexShaderID);
glDetachShader(programID, fragmentShaderID);
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
glDeleteProgram(programID);
}
// This method sets an input variabele into the shaders
void ShaderProgram::setAttribute(const GLuint attribute, const char* variableName) const
{
glBindAttribLocation(programID, attribute, variableName);
}
void ShaderProgram::loadFloat(GLuint location, GLfloat value) const
{
glUniform1f(location, value);
}
void ShaderProgram::loadVector(GLuint location, glm::vec3 vector) const
{
// glUniform3f(location, vector.x, vector.y, vector.z);
glUniform3fv(location, 1, glm::value_ptr(vector));
}
void ShaderProgram::loadMatrix(GLuint location, glm::mat4 matrix) const
{
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(matrix));
}
GLuint ShaderProgram::getUniformLocation(const GLchar* uniformName) const
{
return glGetUniformLocation(programID, uniformName);
}
// This method loads a shader into openGL
GLuint ShaderProgram::loadShader(const std::string& shaderString, const GLuint type) const
{
const char* shaderText = shaderString.c_str();
const GLuint shaderID = glCreateShader(type);
glShaderSource(shaderID, 1, &shaderText, NULL);
glCompileShader(shaderID);
GLint succes = 0;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &succes);
if (succes == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(shaderID, maxLength, &maxLength, &errorLog[0]);
for (std::vector<GLchar>::const_iterator i = errorLog.begin(); i != errorLog.end(); ++i)
{
std::cout << *i;
}
std::cout << std::endl;
std::cerr << "Could not compile shader" << std::endl;
cleanUp();
std::exit(-1);
}
return shaderID;
}
//// This method reads a shader from a file into a string
//std::string ShaderProgram::readFromFile(const std::string& file) const
//{
// std::string content;
// std::ifstream fileStream(file, std::ios::in);
// if (!fileStream.is_open()) {
// std::cerr << "Could not read file " << file << ". File does not exist." << std::endl;
// std::exit(-1);
// }
// std::string line;
// while (!fileStream.eof()) {
// std::getline(fileStream, line);
// content.append(line + "\n");
// }
// fileStream.close();
// return content;
//}
}

View File

@@ -0,0 +1,51 @@
#pragma once
#include <GL/glew.h>
#include <glm/gtc/matrix_transform.hpp>
#include <string>
/*
This abstract class represents a generic shader program.
*/
namespace shaders
{
class ShaderProgram
{
private:
GLuint programID;
GLuint vertexShaderID;
GLuint fragmentShaderID;
public:
ShaderProgram(std::string& vertexShader, std::string& fragmentShader);
virtual ~ShaderProgram() = default;
// Call this function after making the shaderprogram (sets all the attributes of the shader)
void init();
// Call this function before rendering
void start() const;
// Call this function after rendering
void stop() const;
// Call this function when closing the application
void cleanUp() const;
protected:
// Set the inputs of the vertex shader
virtual void setAttributes() const = 0;
void setAttribute(const GLuint attribute, const char* variableName) const;
// Loads value's (uniform variables) into the shader
void loadFloat(GLuint location, GLfloat value) const;
void loadVector(GLuint location, glm::vec3 vector) const;
void loadMatrix(GLuint location, glm::mat4 matrix) const;
virtual void getAllUniformLocations() = 0;
GLuint getUniformLocation(const GLchar* uniformName) const;
private:
GLuint loadShader(const std::string& shaderString, GLuint type) const;
//std::string readFromFile(const std::string& file) const;
};
}

View File

@@ -0,0 +1,88 @@
#include "StaticShader.h"
#include "../toolbox/Toolbox.h"
namespace shaders
{
static std::string vertexShader = R"(
#version 400 core
// The VertexShader is run for each vertex on the screen.
// Position of the vertex
in vec3 position;
// Coordinates of the texture
in vec2 textureCoords;
// Equal to the textureCoords
out vec2 passTextureCoords;
uniform mat4 modelMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
void main(void)
{
// Tell OpenGL where to render the vertex
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
// Pass the textureCoords directly to the fragment shader
passTextureCoords = textureCoords;
}
)";
static std::string fragmentShader = R"(
#version 400 core
// The FragmentShader is run for each pixel in a face on the screen.
// Interpolated textureCoordinates of the vertex (relative to the distance to each vertex)
in vec2 passTextureCoords;
// Final color of the pixel
out vec4 outColor;
// The texture of the model
uniform sampler2D textureSampler;
void main(void)
{
outColor = texture(textureSampler, passTextureCoords);
}
)";
StaticShader::StaticShader(): ShaderProgram(vertexShader, fragmentShader)
{
}
void StaticShader::loadModelMatrix(const glm::mat4& matrix) const
{
loadMatrix(location_modelMatrix, matrix);
}
void StaticShader::loadProjectionMatrix(const glm::mat4& projection) const
{
loadMatrix(location_projectionMatrix, projection);
}
void StaticShader::loadViewMatrix(entities::Camera& camera) const
{
const glm::mat4 viewMatrix = toolbox::createViewMatrix(camera);
loadMatrix(location_viewMatrix, viewMatrix);
}
void StaticShader::setAttributes() const
{
setAttribute(0, "position");
setAttribute(1, "textureCoords");
}
void StaticShader::getAllUniformLocations()
{
location_modelMatrix = getUniformLocation("modelMatrix");
location_projectionMatrix = getUniformLocation("projectionMatrix");
location_viewMatrix = getUniformLocation("viewMatrix");
}
}

View File

@@ -0,0 +1,32 @@
#pragma once
#include <string>
#include <glm/gtc/matrix_transform.hpp>
#include "ShaderProgram.h"
#include "../entities/Camera.h"
/*
This class does represents the shaders for the models.
*/
namespace shaders
{
class StaticShader : public ShaderProgram
{
private:
GLuint location_modelMatrix;
GLuint location_projectionMatrix;
GLuint location_viewMatrix;
public:
StaticShader();
void loadModelMatrix(const glm::mat4& matrix) const;
void loadProjectionMatrix(const glm::mat4& projection) const;
void loadViewMatrix(entities::Camera& camera) const;
protected:
void setAttributes() const override;
void getAllUniformLocations() override;
};
}

View File

@@ -0,0 +1,17 @@
#version 400 core
// The FragmentShader is run for each pixel in a face on the screen.
// Interpolated textureCoordinates of the vertex (relative to the distance to each vertex)
in vec2 passTextureCoords;
// Final color of the pixel
out vec4 outColor;
// The texture of the model
uniform sampler2D textureSampler;
void main(void)
{
outColor = texture(textureSampler, passTextureCoords);
}

View File

@@ -0,0 +1,25 @@
#version 400 core
// The VertexShader is run for each vertex on the screen.
// Position of the vertex
in vec3 position;
// Coordinates of the texture
in vec2 textureCoords;
// Equal to the textureCoords
out vec2 passTextureCoords;
uniform mat4 modelMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
void main(void)
{
// Tell OpenGL where to render the vertex
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
// Pass the textureCoords directly to the fragment shader
passTextureCoords = textureCoords;
}

7762
src/stb_image.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,465 +0,0 @@
#include "tigl.h"
#include <glm/gtc/type_ptr.hpp>
#include <string>
#include <iostream>
namespace tigl
{
class ShaderImpl : public internal::Shader
{
public:
ShaderImpl();
~ShaderImpl();
void use();
void setProjectionMatrix(const glm::mat4& matrix);
void setViewMatrix(const glm::mat4& matrix);
void setModelMatrix(const glm::mat4& matrix);
void enableColor(bool enabled) { setUniform(Uniform::useColor, enabled); }
void enableTexture(bool enabled) { setUniform(Uniform::useTexture, enabled); }
void enableLighting(bool enabled) { setUniform(Uniform::useLighting, enabled); }
void setLightCount(int count) { setUniform(Uniform::lightCount, count); }
void setLightDirectional(int lightNr, bool isDirectional) { setUniform("lights[" + std::to_string(lightNr) + "].directional", isDirectional); }
void setLightPosition(int lightNr, const glm::vec3& position) { setUniform("lights[" + std::to_string(lightNr) + "].position", position); }
void setLightAmbient(int lightNr, const glm::vec3& color) { setUniform("lights[" + std::to_string(lightNr) + "].ambient", color); }
void setLightDiffuse(int lightNr, const glm::vec3& color) { setUniform("lights[" + std::to_string(lightNr) + "].diffuse", color); }
void setLightSpecular(int lightNr, const glm::vec3& color) { setUniform("lights[" + std::to_string(lightNr) + "].specular", color); }
void setShinyness(float shinyness) { setUniform(Uniform::shinyness, shinyness); }
void enableColorMult(bool enabled) { setUniform(Uniform::useColorMult, enabled); }
void setColorMult(const glm::vec4& color) { setUniform(Uniform::colorMult, color); }
void enableAlphaTest(bool enabled) { setUniform(Uniform::useAlphaTest, enabled); }
void enableFog(bool enabled) { setUniform(Uniform::useFog, enabled); }
void setFogLinear(float begin, float end) {
setUniform(Uniform::fogType, 0);
setUniform(Uniform::fogLinNear, begin);
setUniform(Uniform::fogLinFar, end);
}
void setFogExp(float density) {
setUniform(Uniform::fogType, 1);
setUniform(Uniform::fogExpDensity, density);
}
void setFogExp2(float density) {
setUniform(Uniform::fogType, 2);
setUniform(Uniform::fogExpDensity, density);
}
private:
void addShader(int shaderProgram, GLenum shaderType, const std::string& shader);
GLuint programId;
enum Uniform
{
//matrices
ProjectionMatrix,
ViewMatrix,
ModelMatrix,
NormalMatrix,
//flags
useColor,
useColorMult,
useTexture,
useLighting,
useAlphaTest,
useFog,
//parameters
colorMult,
lightCount,
shinyness,
cameraPosition,
fogType,
fogLinNear,
fogLinFar,
fogExpDensity,
UniformMax
};
int uniforms[UniformMax];
void setUniform(Uniform uniform, const glm::mat4& value);
void setUniform(Uniform uniform, const glm::mat3& value);
void setUniform(Uniform uniform, const glm::vec4& value);
void setUniform(Uniform uniform, const glm::vec3& value);
void setUniform(Uniform uniform, const glm::vec2& value);
void setUniform(Uniform uniform, float value);
void setUniform(Uniform uniform, int value);
void setUniform(Uniform uniform, bool value);
//slower
void setUniform(const std::string& uniform, const glm::mat4& value);
void setUniform(const std::string& uniform, const glm::mat3& value);
void setUniform(const std::string& uniform, const glm::vec4& value);
void setUniform(const std::string& uniform, const glm::vec3& value);
void setUniform(const std::string& uniform, const glm::vec2& value);
void setUniform(const std::string& uniform, float value);
void setUniform(const std::string& uniform, int value);
void setUniform(const std::string& uniform, bool value);
glm::mat4 modelMatrix;
glm::mat4 projectionMatrix;
glm::mat4 viewMatrix;
};
std::unique_ptr<internal::Shader> shader;
int attributePosition = 0;
int attributeColor = 1;
int attributeTexcoord = 2;
int attributeNormal = 3;
// Initializes shader used
void init()
{
glewInit();
shader.reset(new ShaderImpl());
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
}
std::vector<Vertex> vertices;
GLenum shape = 0;
void begin(GLenum shape)
{
assert(tigl::shape == 0);
tigl::shape = shape;
vertices.clear();
}
void addVertex(const Vertex& vertex)
{
vertices.push_back(vertex);
}
void end()
{
assert(shape != 0);
drawVertices(shape, vertices);
shape = 0;
}
void drawVertices(GLenum shape, const std::vector<Vertex>& vertices)
{
if (vertices.size() > 0)
{
glVertexAttribPointer(tigl::attributePosition, 3, GL_FLOAT, false, sizeof(Vertex), &vertices[0].position);
glVertexAttribPointer(tigl::attributeColor, 4, GL_FLOAT, false, sizeof(Vertex), &vertices[0].color);
glVertexAttribPointer(tigl::attributeTexcoord, 2, GL_FLOAT, false, sizeof(Vertex), &vertices[0].texcoord);
glVertexAttribPointer(tigl::attributeNormal, 3, GL_FLOAT, false, sizeof(Vertex), &vertices[0].normal);
glDrawArrays(shape, 0, (GLsizei)vertices.size());
}
}
ShaderImpl::ShaderImpl()
{
this->programId = glCreateProgram();
addShader(this->programId, GL_VERTEX_SHADER, R"ESC(#version 330
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec4 a_color;
layout (location = 2) in vec2 a_texcoord;
layout (location = 3) in vec3 a_normal;
uniform mat4 modelMatrix = mat4(1.0);
uniform mat4 viewMatrix = mat4(1.0);
uniform mat4 projectionMatrix = mat4(1.0);
uniform mat3 normalMatrix = mat3(1.0);
out vec4 color;
out vec2 texCoord;
out vec3 normal;
out vec3 position;
void main()
{
texCoord = a_texcoord;
color = a_color;
normal = normalMatrix * a_normal;
position = vec3(modelMatrix * vec4(a_position,1));
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(a_position,1);
}
)ESC");
addShader(this->programId, GL_FRAGMENT_SHADER, R"ESC(#version 330
layout(location = 0) out vec4 fragColor;
uniform sampler2D s_texture;
//flags
uniform bool useColor = false;
uniform bool useColorMult = false;
uniform bool useTexture = false;
uniform bool useLighting = false;
uniform bool useAlphaTest = false;
uniform bool useFog = false;
//parameters
uniform vec4 colorMult = vec4(1,1,1,1);
uniform vec3 fogColor = vec3(1.0);
uniform vec3 cameraPosition;
uniform int fogType = 0;
uniform float fogLinNear = 0;
uniform float fogLinFar = 100;
uniform float fogExpDensity = 0;
uniform float shinyness = 0;
struct Light
{
bool directional;
vec3 position;
vec3 diffuse;
vec3 ambient;
vec3 specular;
};
uniform Light lights[5];
uniform int lightCount = 1;
in vec4 color;
in vec2 texCoord;
in vec3 normal;
in vec3 position;
float fogFactorLinear(const float dist, const float start, const float end) {
return 1.0 - clamp((end - dist) / (end - start), 0.0, 1.0);
}
float fogFactorExp2(const float dist, const float density) {
const float LOG2 = -1.442695;
float d = density * dist;
return 1.0 - clamp(exp2(d * d * LOG2), 0.0, 1.0);
}
float fogFactorExp(const float dist, const float density) {
return 1.0 - clamp(exp(-density * dist), 0.0, 1.0);
}
void main()
{
vec4 outputColor = vec4(1,1,1,1);
if(useColor)
outputColor *= color;
if(useColorMult)
outputColor *= colorMult;
if(useTexture)
outputColor *= texture2D(s_texture, texCoord);
if(useLighting) {
vec3 ambient;
vec3 specular;
vec3 diffuse;
for(int i = 0; i < lightCount; i++) {
vec3 lightDir = normalize(lights[i].position - position);
ambient += lights[i].ambient;
float diffuseFactor = max(0, dot(lightDir, normalize(normal)));
diffuse += diffuseFactor * lights[i].diffuse;
vec3 reflectDir = reflect(-lightDir, normalize(normal));
float specularFactor = pow(max(dot(normalize(cameraPosition-position), reflectDir), 0.0), shinyness);
specular += specularFactor * lights[i].specular;
}
outputColor.rgb = (ambient + specular + diffuse) * outputColor.rgb;
}
if(useFog) {
float fogDistance = gl_FragCoord.z / gl_FragCoord.w;
if(fogType == 0)
outputColor.rgb = mix(outputColor.rgb, fogColor, fogFactorLinear(fogDistance, fogLinNear,fogLinFar));
else if(fogType == 1)
outputColor.rgb = mix(outputColor.rgb, fogColor, fogFactorExp(fogDistance, fogExpDensity));
else if(fogType == 2)
outputColor.rgb = mix(outputColor.rgb, fogColor, fogFactorExp2(fogDistance, fogExpDensity));
}
if(useAlphaTest && outputColor.a < 0.01)
discard;
fragColor = outputColor;
}
)ESC");
glLinkProgram(programId);
GLint status;
glGetProgramiv(programId, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
int length, charsWritten;
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &length);
char* infolog = new char[length + 1];
memset(infolog, 0, length + 1);
glGetProgramInfoLog(programId, length, &charsWritten, infolog);
std::cout << "Error compiling shader:\n" << infolog << std::endl;
delete[] infolog;
return;
}
uniforms[Uniform::ModelMatrix] = glGetUniformLocation(programId, "modelMatrix");
uniforms[Uniform::ViewMatrix] = glGetUniformLocation(programId, "viewMatrix");
uniforms[Uniform::ProjectionMatrix] = glGetUniformLocation(programId, "projectionMatrix");
uniforms[Uniform::NormalMatrix] = glGetUniformLocation(programId, "normalMatrix");
uniforms[Uniform::useColor] = glGetUniformLocation(programId, "useColor");
uniforms[Uniform::useColorMult] = glGetUniformLocation(programId, "useColorMult");
uniforms[Uniform::useTexture] = glGetUniformLocation(programId, "useTexture");
uniforms[Uniform::useLighting] = glGetUniformLocation(programId, "useLighting");
uniforms[Uniform::useAlphaTest] = glGetUniformLocation(programId, "useAlphaTest");
uniforms[Uniform::useFog] = glGetUniformLocation(programId, "useFog");
uniforms[Uniform::colorMult] = glGetUniformLocation(programId, "colorMult");
uniforms[Uniform::cameraPosition] = glGetUniformLocation(programId, "cameraPosition");
uniforms[Uniform::shinyness] = glGetUniformLocation(programId, "shinyness");
uniforms[Uniform::fogType] = glGetUniformLocation(programId, "fogType");
uniforms[Uniform::fogLinNear] = glGetUniformLocation(programId, "fogLinNear");
uniforms[Uniform::fogLinFar] = glGetUniformLocation(programId, "fogLinFar");
uniforms[Uniform::fogExpDensity] = glGetUniformLocation(programId, "fogExpDensity");
use();
}
ShaderImpl::~ShaderImpl()
{
}
void ShaderImpl::use()
{
glUseProgram(programId);
}
void ShaderImpl::addShader(int shaderProgram, GLenum shaderType, const std::string& shader)
{
GLuint shaderId = glCreateShader(shaderType);
const char* shaderSource = shader.c_str();
glShaderSource(shaderId, 1, &shaderSource, NULL);
glCompileShader(shaderId);
GLint status;
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
int length, charsWritten;
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length);
char* infolog = new char[length + 1];
memset(infolog, 0, length + 1);
glGetShaderInfoLog(shaderId, length, &charsWritten, infolog);
std::cout << "Error compiling shader:\n" << infolog << std::endl;
delete[] infolog;
return;
}
glAttachShader(programId, shaderId);
}
void ShaderImpl::setProjectionMatrix(const glm::mat4& matrix)
{
this->projectionMatrix = matrix;
setUniform(Uniform::ProjectionMatrix, matrix);
}
void ShaderImpl::setViewMatrix(const glm::mat4& matrix)
{
this->viewMatrix = matrix;
setUniform(Uniform::ViewMatrix, matrix);
glm::vec4 cameraPosition = glm::inverse(matrix) * glm::vec4(0, 0, 0, 1);
setUniform(Uniform::cameraPosition, glm::vec3(cameraPosition));
}
void ShaderImpl::setModelMatrix(const glm::mat4& matrix)
{
this->modelMatrix = matrix;
setUniform(Uniform::ModelMatrix, matrix);
setUniform(Uniform::NormalMatrix, glm::mat3(glm::transpose(glm::inverse(modelMatrix))));
}
void ShaderImpl::setUniform(Uniform uniform, const glm::mat4& value)
{
glUniformMatrix4fv(uniforms[uniform], 1, false, glm::value_ptr(value));
}
void ShaderImpl::setUniform(Uniform uniform, const glm::mat3& value)
{
glUniformMatrix3fv(uniforms[uniform], 1, false, glm::value_ptr(value));
}
void ShaderImpl::setUniform(Uniform uniform, const glm::vec4& value)
{
glUniform4fv(uniforms[uniform], 1, glm::value_ptr(value));
}
void ShaderImpl::setUniform(Uniform uniform, const glm::vec3& value)
{
glUniform3fv(uniforms[uniform], 1, glm::value_ptr(value));
}
void ShaderImpl::setUniform(Uniform uniform, const glm::vec2& value)
{
glUniform2fv(uniforms[uniform], 1, glm::value_ptr(value));
}
void ShaderImpl::setUniform(Uniform uniform, bool value)
{
glUniform1i(uniforms[uniform], value ? GL_TRUE : GL_FALSE);
}
void ShaderImpl::setUniform(Uniform uniform, int value)
{
glUniform1i(uniforms[uniform], value);
}
void ShaderImpl::setUniform(Uniform uniform, float value)
{
glUniform1f(uniforms[uniform], value);
}
void ShaderImpl::setUniform(const std::string& uniform, const glm::mat4& value)
{
glUniformMatrix4fv(glGetUniformLocation(programId, uniform.c_str()), 1, false, glm::value_ptr(value));
}
void ShaderImpl::setUniform(const std::string& uniform, const glm::mat3& value)
{
glUniformMatrix3fv(glGetUniformLocation(programId, uniform.c_str()), 1, false, glm::value_ptr(value));
}
void ShaderImpl::setUniform(const std::string& uniform, const glm::vec4& value)
{
glUniform4fv(glGetUniformLocation(programId, uniform.c_str()), 1, glm::value_ptr(value));
}
void ShaderImpl::setUniform(const std::string& uniform, const glm::vec3& value)
{
glUniform3fv(glGetUniformLocation(programId, uniform.c_str()), 1, glm::value_ptr(value));
}
void ShaderImpl::setUniform(const std::string& uniform, const glm::vec2& value)
{
glUniform2fv(glGetUniformLocation(programId, uniform.c_str()), 1, glm::value_ptr(value));
}
void ShaderImpl::setUniform(const std::string& uniform, bool value)
{
glUniform1i(glGetUniformLocation(programId, uniform.c_str()), value ? GL_TRUE : GL_FALSE);
}
void ShaderImpl::setUniform(const std::string& uniform, int value)
{
glUniform1i(glGetUniformLocation(programId, uniform.c_str()), value);
}
void ShaderImpl::setUniform(const std::string& uniform, float value)
{
glUniform1f(glGetUniformLocation(programId, uniform.c_str()), value);
}
}

View File

@@ -1,148 +0,0 @@
#pragma once
#include <GL/glew.h>
#include <memory>
#include <glm/glm.hpp>
#include <vector>
namespace tigl
{
namespace internal
{
class Shader
{
public:
virtual ~Shader() {};
// Sets the projection matrix
virtual void setProjectionMatrix(const glm::mat4& matrix) = 0;
// Sets the view (camera) matrix
virtual void setViewMatrix(const glm::mat4& matrix) = 0;
// Sets the model matrix
virtual void setModelMatrix(const glm::mat4& matrix) = 0;
// enables the use of the colors set in vertices
virtual void enableColor(bool enabled) = 0;
// enables the use of texture coordinats set in vertices, and uses textures set in texture sampler
virtual void enableTexture(bool enabled) = 0;
// enables the lighting
virtual void enableLighting(bool enabled) = 0;
// sets the number of lights
virtual void setLightCount(int count) = 0;
// sets the light as directional or positional
virtual void setLightDirectional(int lightNr, bool isDirectional) = 0;
// sets the position of the light. If the light is a directional light, the position is interpreted as a direction
virtual void setLightPosition(int lightNr, const glm::vec3& position) = 0;
// sets the ambient color of a light
virtual void setLightAmbient(int lightNr, const glm::vec3& color) = 0;
// sets the diffuse color of a light
virtual void setLightDiffuse(int lightNr, const glm::vec3& color) = 0;
// sets the specular color of a light
virtual void setLightSpecular(int lightNr, const glm::vec3& color) = 0;
// sets the shinyness of the material drawn. Used for specular calculations
virtual void setShinyness(float shinyness) = 0;
// Enables color multiplication. If enabled, all colors (texture and vertex colors) will be multiplied by the color set by the setColorMult method
virtual void enableColorMult(bool enabled) = 0;
// Changes the color that output will be multiplied with when enableColorMult is enabled
virtual void setColorMult(const glm::vec4& color) = 0;
// Enables alpha testing. Will stop rendering everything with a low alpha value
virtual void enableAlphaTest(bool enabled) = 0;
// Enables fog
virtual void enableFog(bool enabled) = 0;
// Sets the fog to linear
virtual void setFogLinear(float begin, float end) = 0;
// Sets the fog to Exponential
virtual void setFogExp(float density) = 0;
// Sets the fog to Exponential
virtual void setFogExp2(float density) = 0;
};
}
// A simple structure to store vertices. Can store positions, normals, colors and texture coordinats
struct Vertex
{
public:
glm::vec3 position;
glm::vec3 normal;
glm::vec4 color;
glm::vec2 texcoord;
// Creates a vertex with a position
static Vertex P(const glm::vec3& position) {
return { position, glm::vec3(0,1,0), glm::vec4(1,1,1,1), glm::vec2(0,0) };
}
// Creates a vertex with a position and a color
static Vertex PC(const glm::vec3& position, const glm::vec4& color) {
return { position, glm::vec3(0,1,0), color, glm::vec2(0,0) };
}
// Creates a vertex with a position and a texture coordinat
static Vertex PT(const glm::vec3& position, const glm::vec2& texcoord) {
return { position, glm::vec3(0,1,0), glm::vec4(1,1,1,1), texcoord };
}
// Creates a vertex with a position and a normal
static Vertex PN(const glm::vec3& position, const glm::vec3& normal) {
return { position, normal, glm::vec4(1,1,1,1), glm::vec2(0,0) };
}
// Creates a vertex with a position, a texture coordinat and a color
static Vertex PTC(const glm::vec3& position, const glm::vec2& texcoord, const glm::vec4 &color) {
return { position, glm::vec3(0,1,0), color, texcoord };
}
// Creates a vertex with a position, color and normal
static Vertex PCN(const glm::vec3& position, const glm::vec4& color, const glm::vec3& normal) {
return { position, normal, color, glm::vec2(0,0) };
}
// Creates a vertex with a position, texture coordinat and normal
static Vertex PTN(const glm::vec3& position, const glm::vec2& texcoord, const glm::vec3& normal) {
return { position, normal, glm::vec4(1,1,1,1), texcoord };
}
// Creates a vertex with a position, color, texture coordinat and normal
static Vertex PCTN(const glm::vec3& position, const glm::vec4& color, const glm::vec2& texcoord, const glm::vec3& normal) {
return { position, normal, color, texcoord };
}
};
// Access point for the shader
extern std::unique_ptr<internal::Shader> shader;
// Call to initialize. Loads the shader
void init();
// Call to start a set of OpenGL primitives
void begin(GLenum shape);
// Adds a single vertex to the set
void addVertex(const Vertex& vertex);
// Finishes and draws the vertices given
void end();
// Draws a full array of vertices
void drawVertices(GLenum shape, const std::vector<Vertex> &vertices);
}

26
src/toolbox/Toolbox.cpp Normal file
View File

@@ -0,0 +1,26 @@
#include "Toolbox.h"
namespace toolbox
{
glm::mat4 createModelMatrix(glm::vec3 translation, glm::vec3 rotation, float scale)
{
glm::mat4 matrix(1.0f);
matrix = glm::translate(matrix, translation);
matrix = glm::rotate(matrix, glm::radians(rotation.x), glm::vec3(1, 0, 0));
matrix = glm::rotate(matrix, glm::radians(rotation.y), glm::vec3(0, 1, 0));
matrix = glm::rotate(matrix, glm::radians(rotation.z), glm::vec3(0, 0, 1));
matrix = glm::scale(matrix, glm::vec3(scale, scale, scale));
return matrix;
}
glm::mat4 createViewMatrix(entities::Camera& camera)
{
glm::mat4 matrix(1.0f);
matrix = glm::rotate(matrix, glm::radians(camera.getRotation().x), glm::vec3(1, 0, 0));
matrix = glm::rotate(matrix, glm::radians(camera.getRotation().y), glm::vec3(0, 1, 0));
matrix = glm::rotate(matrix, glm::radians(camera.getRotation().z), glm::vec3(0, 0, 1));
const glm::vec3 negativeCamPos = glm::vec3(-camera.getPosition().x, -camera.getPosition().y, -camera.getPosition().z);
matrix = glm::translate(matrix, negativeCamPos);
return matrix;
}
}

14
src/toolbox/Toolbox.h Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#include "../entities/Camera.h"
#include <glm/gtc/matrix_transform.hpp>
namespace toolbox
{
#define WINDOW_WIDTH 1400.0f
#define WINDOW_HEIGT 800.0f
glm::mat4 createModelMatrix(glm::vec3 translation, glm::vec3 rotation, float scale);
glm::mat4 createViewMatrix(entities::Camera& camera);
}

View File

@@ -18,6 +18,29 @@
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\entities\Camera.cpp" />
<ClCompile Include="src\entities\Entity.cpp" />
<ClCompile Include="src\MainManager.cpp" />
<ClCompile Include="src\renderEngine\Loader.cpp" />
<ClCompile Include="src\renderEngine\ObjLoader.cpp" />
<ClCompile Include="src\renderEngine\Renderer.cpp" />
<ClCompile Include="src\shaders\ShaderProgram.cpp" />
<ClCompile Include="src\shaders\StaticShader.cpp" />
<ClCompile Include="src\toolbox\Toolbox.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\entities\Camera.h" />
<ClInclude Include="src\entities\Entity.h" />
<ClInclude Include="src\models\Model.h" />
<ClInclude Include="src\renderEngine\Loader.h" />
<ClInclude Include="src\renderEngine\ObjLoader.h" />
<ClInclude Include="src\renderEngine\Renderer.h" />
<ClInclude Include="src\shaders\ShaderProgram.h" />
<ClInclude Include="src\shaders\StaticShader.h" />
<ClInclude Include="src\stb_image.h" />
<ClInclude Include="src\toolbox\Toolbox.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{A7ECF1BE-DB22-4BF7-BFF6-E3BF72691EE6}</ProjectGuid>
@@ -155,15 +178,6 @@
<AdditionalLibraryDirectories>$(SolutionDir)lib\glfw-3.3.2\$(Platform);$(SolutionDir)lib\glew-2.1.0\lib\Release\$(Platform);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\FpsCam.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\tigl.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\FpsCam.h" />
<ClInclude Include="src\tigl.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@@ -15,21 +15,63 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\tigl.cpp">
<ClCompile Include="src\entities\Camera.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\main.cpp">
<ClCompile Include="src\entities\Entity.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\FpsCam.cpp">
<ClCompile Include="src\renderEngine\Loader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\renderEngine\ObjLoader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\renderEngine\Renderer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\shaders\ShaderProgram.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\shaders\StaticShader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\toolbox\Toolbox.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\MainManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\tigl.h">
<ClInclude Include="src\entities\Camera.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\FpsCam.h">
<ClInclude Include="src\entities\Entity.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\models\Model.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\renderEngine\Loader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\renderEngine\ObjLoader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\renderEngine\Renderer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\shaders\ShaderProgram.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\shaders\StaticShader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\toolbox\Toolbox.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\stb_image.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>