Merge branch 'feature/custom-rendering' into develop
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -10,7 +10,7 @@
|
|||||||
*.slo
|
*.slo
|
||||||
*.lo
|
*.lo
|
||||||
*.o
|
*.o
|
||||||
*.obj
|
x64/**/*.obj
|
||||||
|
|
||||||
# Precompiled Headers
|
# Precompiled Headers
|
||||||
*.gch
|
*.gch
|
||||||
|
|||||||
1488
res/Tree.obj
Normal file
1488
res/Tree.obj
Normal file
File diff suppressed because it is too large
Load Diff
BIN
res/TreeTexture.png
Normal file
BIN
res/TreeTexture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.8 KiB |
@@ -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);
|
|
||||||
}
|
|
||||||
21
src/FpsCam.h
21
src/FpsCam.h
@@ -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);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
32
src/entities/Camera.cpp
Normal file
32
src/entities/Camera.cpp
Normal 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
24
src/entities/Camera.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
namespace entities
|
||||||
|
{
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const 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; }
|
||||||
|
};
|
||||||
|
}
|
||||||
27
src/entities/Entity.cpp
Normal file
27
src/entities/Entity.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#include "entity.h"
|
||||||
|
|
||||||
|
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
31
src/entities/Entity.h
Normal 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 SetModel(const ::models::TexturedModel& model) { this->model = model; }
|
||||||
|
inline glm::vec3 GetPosition() const { return position; }
|
||||||
|
inline void SetPosition(const ::glm::vec3& position) { this->position = position; }
|
||||||
|
inline glm::vec3 GetRotation() const { return rotation; }
|
||||||
|
inline void SetRotation(const ::glm::vec3& rotation) { this->rotation = rotation; }
|
||||||
|
inline float GetScale() const { return scale; }
|
||||||
|
inline void SetScale(const float scale) { this->scale = scale; }
|
||||||
|
};
|
||||||
|
}
|
||||||
127
src/main.cpp
127
src/main.cpp
@@ -1,100 +1,93 @@
|
|||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include "tigl.h"
|
|
||||||
#include "FpsCam.h"
|
|
||||||
#include <iostream>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
using tigl::Vertex;
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "stb_image.h"
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
#include "models/model.h"
|
||||||
|
#include "renderEngine/loader.h"
|
||||||
|
#include "renderEngine/obj_loader.h"
|
||||||
|
#include "renderEngine/renderer.h"
|
||||||
|
#include "shaders/static_shader.h"
|
||||||
|
#include "toolbox/toolbox.h"
|
||||||
|
|
||||||
#pragma comment(lib, "glfw3.lib")
|
#pragma comment(lib, "glfw3.lib")
|
||||||
#pragma comment(lib, "glew32s.lib")
|
#pragma comment(lib, "glew32s.lib")
|
||||||
#pragma comment(lib, "opengl32.lib")
|
#pragma comment(lib, "opengl32.lib")
|
||||||
|
|
||||||
GLFWwindow* window;
|
static double UpdateDelta();
|
||||||
|
|
||||||
|
static GLFWwindow* window;
|
||||||
|
|
||||||
void init();
|
|
||||||
void update();
|
|
||||||
void draw();
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
#pragma region OPENGL_SETTINGS
|
||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
throw "Could not initialize glwf";
|
throw "Could not inditialize glwf";
|
||||||
window = glfwCreateWindow(1400, 800, "Hello World", NULL, NULL);
|
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGT, "SDBA", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
throw "Could not initialize glwf";
|
throw "Could not initialize glwf";
|
||||||
}
|
}
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
|
glewInit();
|
||||||
|
glGetError();
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
tigl::init();
|
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||||
|
{
|
||||||
init();
|
if (key == GLFW_KEY_ESCAPE)
|
||||||
|
glfwSetWindowShouldClose(window, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
models::RawModel raw_model = LoadObjModel("res/Tree.obj");
|
||||||
|
models::ModelTexture texture = { render_engine::loader::LoadTexture("res/TreeTexture.png") };
|
||||||
|
models::TexturedModel model = { raw_model, texture };
|
||||||
|
entities::Entity entity(model, glm::vec3(0, -5, -20), glm::vec3(0, 0, 0), 1);
|
||||||
|
|
||||||
|
shaders::StaticShader shader;
|
||||||
|
shader.Init();
|
||||||
|
render_engine::renderer::Init(shader);
|
||||||
|
|
||||||
|
entities::Camera camera(glm::vec3(0, 0, 0), glm::vec3(0, 0, 0));
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
update();
|
// Update
|
||||||
draw();
|
const double delta = UpdateDelta();
|
||||||
|
entity.IncreaseRotation(glm::vec3(0, 1, 0));
|
||||||
|
camera.Move(window);
|
||||||
|
|
||||||
|
// Render
|
||||||
|
render_engine::renderer::Prepare();
|
||||||
|
shader.Start();
|
||||||
|
shader.LoadViewMatrix(camera);
|
||||||
|
|
||||||
|
render_engine::renderer::Render(entity, shader);
|
||||||
|
|
||||||
|
// Finish up
|
||||||
|
shader.Stop();
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
shader.CleanUp();
|
||||||
|
render_engine::loader::CleanUp();
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FpsCam* camera;
|
static double UpdateDelta()
|
||||||
|
|
||||||
void init()
|
|
||||||
{
|
{
|
||||||
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods)
|
double current_time = glfwGetTime();
|
||||||
{
|
static double last_frame_time = current_time;
|
||||||
if (key == GLFW_KEY_ESCAPE)
|
double delt_time = current_time - last_frame_time;
|
||||||
glfwSetWindowShouldClose(window, true);
|
last_frame_time = current_time;
|
||||||
});
|
return delt_time;
|
||||||
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
38
src/models/Model.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
namespace models
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Structure for storing a vboID and vertex_count.
|
||||||
|
|
||||||
|
This structure represents a Bare bones Model (A mesh without a texture).
|
||||||
|
The vao_id, points to an ID stored by openGL and the
|
||||||
|
vertex_count is how many triangles in the mesh there are.
|
||||||
|
*/
|
||||||
|
struct RawModel
|
||||||
|
{
|
||||||
|
GLuint vao_id;
|
||||||
|
int vertex_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Structure for storing a texture (texture_id) to apply to a RawModel.
|
||||||
|
*/
|
||||||
|
struct ModelTexture
|
||||||
|
{
|
||||||
|
GLuint texture_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Structure for storing a RawModel and a Texure.
|
||||||
|
|
||||||
|
This struct represents a model with a texture.
|
||||||
|
*/
|
||||||
|
struct TexturedModel
|
||||||
|
{
|
||||||
|
RawModel raw_model;
|
||||||
|
ModelTexture texture;
|
||||||
|
};
|
||||||
|
}
|
||||||
117
src/renderEngine/Loader.cpp
Normal file
117
src/renderEngine/Loader.cpp
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
#include <GL/glew.h>
|
||||||
|
#include "../stb_image.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
|
namespace render_engine
|
||||||
|
{
|
||||||
|
namespace loader
|
||||||
|
{
|
||||||
|
static GLuint CreateVao();
|
||||||
|
static void StoreDataInAttributeList(int attribute_number, int coordinate_size, 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>& texture_coords, std::vector<unsigned int>& indices)
|
||||||
|
{
|
||||||
|
GLuint vao_id = CreateVao();
|
||||||
|
BindIndicesBuffer(indices);
|
||||||
|
StoreDataInAttributeList(0, 3, positions);
|
||||||
|
StoreDataInAttributeList(1, 2, texture_coords);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
return { vao_id, static_cast<int>(indices.size()) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Loads an image as texture into openGL
|
||||||
|
*/
|
||||||
|
GLuint LoadTexture(std::string file_name)
|
||||||
|
{
|
||||||
|
int width, height, bpp;
|
||||||
|
unsigned char* imgData = stbi_load(file_name.c_str(), &width, &height, &bpp, 4);
|
||||||
|
|
||||||
|
GLuint texture_id;
|
||||||
|
glGenTextures(1, &texture_id);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||||
|
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(texture_id);
|
||||||
|
return texture_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
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 vao_id;
|
||||||
|
glGenVertexArrays(1, &vao_id);
|
||||||
|
vaos.push_back(vao_id);
|
||||||
|
glBindVertexArray(vao_id);
|
||||||
|
return vao_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This function can store data (vbo) in a vao.
|
||||||
|
*/
|
||||||
|
static void StoreDataInAttributeList(int attribute_number, int coordinate_size, std::vector<float>& data)
|
||||||
|
{
|
||||||
|
GLuint vbo_id;
|
||||||
|
glGenBuffers(1, &vbo_id);
|
||||||
|
vbos.push_back(vbo_id);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * data.size(), &data[0], GL_STATIC_DRAW);
|
||||||
|
glVertexAttribPointer(attribute_number, coordinate_size, 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 vbo_id;
|
||||||
|
glGenBuffers(1, &vbo_id);
|
||||||
|
vbos.push_back(vbo_id);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_id);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * indices.size(), &indices[0], GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/renderEngine/Loader.h
Normal file
26
src/renderEngine/Loader.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "../models/model.h"
|
||||||
|
|
||||||
|
namespace render_engine
|
||||||
|
{
|
||||||
|
namespace loader
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This function generates a model from model data.
|
||||||
|
*/
|
||||||
|
struct models::RawModel LoadToVAO(std::vector<float>& positions, std::vector<float>& texture_coords, std::vector<unsigned int>& indices);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Loads a texture from a file into openGL using stb_image.h
|
||||||
|
*/
|
||||||
|
GLuint LoadTexture(std::string file_name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Call this function when cleaning up all the meshes (when exiting the program).
|
||||||
|
*/
|
||||||
|
void CleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
67
src/renderEngine/Renderer.cpp
Normal file
67
src/renderEngine/Renderer.cpp
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#include <GL/glew.h>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include "../models/model.h"
|
||||||
|
#include "renderer.h"
|
||||||
|
#include "../toolbox/toolbox.h"
|
||||||
|
|
||||||
|
namespace render_engine
|
||||||
|
{
|
||||||
|
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.raw_model;
|
||||||
|
|
||||||
|
// Enable the model
|
||||||
|
glBindVertexArray(rawModel.vao_id);
|
||||||
|
|
||||||
|
// 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.texture_id);
|
||||||
|
glDrawElements(GL_TRIANGLES, rawModel.vertex_count, GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
|
glDisableVertexAttribArray(0);
|
||||||
|
glDisableVertexAttribArray(1);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/renderEngine/Renderer.h
Normal file
25
src/renderEngine/Renderer.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../entities/entity.h"
|
||||||
|
#include "../shaders/static_shader.h"
|
||||||
|
|
||||||
|
namespace render_engine
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
129
src/renderEngine/obj_loader.cpp
Normal file
129
src/renderEngine/obj_loader.cpp
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include "loader.h"
|
||||||
|
#include "obj_loader.h"
|
||||||
|
|
||||||
|
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>& vertex_data,
|
||||||
|
const std::vector<glm::vec3>& normals,
|
||||||
|
const std::vector<glm::vec2>& textures,
|
||||||
|
std::vector<GLuint>& indices,
|
||||||
|
std::vector<GLfloat>& texture_array,
|
||||||
|
std::vector<GLfloat>& normal_array)
|
||||||
|
{
|
||||||
|
GLuint current_vertex_pointer = std::stoi(vertex_data.at(0)) - 1;
|
||||||
|
indices.push_back(current_vertex_pointer);
|
||||||
|
|
||||||
|
glm::vec2 current_texture = textures.at(std::stoi(vertex_data.at(1)) - 1);
|
||||||
|
texture_array[(current_vertex_pointer * 2) % texture_array.size()] = current_texture.x;
|
||||||
|
texture_array[(current_vertex_pointer * 2 + 1) % texture_array.size()] = 1 - current_texture.y;
|
||||||
|
|
||||||
|
glm::vec3 current_norm = normals.at(std::stoi(vertex_data.at(2)) - 1);
|
||||||
|
normal_array[current_vertex_pointer * 3] = current_norm.x;
|
||||||
|
normal_array[current_vertex_pointer * 3 + 1] = current_norm.y;
|
||||||
|
normal_array[current_vertex_pointer * 3 + 2] = current_norm.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
models::RawModel LoadObjModel(std::string file_name)
|
||||||
|
{
|
||||||
|
std::ifstream inFile (file_name);
|
||||||
|
if ( !inFile.is_open() )
|
||||||
|
{
|
||||||
|
throw std::runtime_error ( "Could not open model file " + file_name + ".obj!" );
|
||||||
|
}
|
||||||
|
std::vector<glm::vec3> vertices;
|
||||||
|
std::vector<glm::vec3> normals;
|
||||||
|
std::vector<glm::vec2> textures;
|
||||||
|
std::vector<GLuint> indices;
|
||||||
|
std::vector<GLfloat> vertex_array;
|
||||||
|
std::vector<GLfloat> normal_array;
|
||||||
|
std::vector<GLfloat> texture_array;
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (std::getline(inFile, line))
|
||||||
|
{
|
||||||
|
std::vector<std::string> split_line = Split(line, ' ');
|
||||||
|
if (split_line.at(0) == "v")
|
||||||
|
{
|
||||||
|
glm::vec3 vertex;
|
||||||
|
vertex.x = std::stof(split_line.at(1));
|
||||||
|
vertex.y = std::stof(split_line.at(2));
|
||||||
|
vertex.z = std::stof(split_line.at(3));
|
||||||
|
vertices.push_back(vertex);
|
||||||
|
}
|
||||||
|
else if (split_line.at(0) == "vt")
|
||||||
|
{
|
||||||
|
glm::vec2 texture;
|
||||||
|
texture.x = std::stof(split_line.at(1));
|
||||||
|
texture.y = std::stof(split_line.at(2));
|
||||||
|
textures.push_back(texture);
|
||||||
|
}
|
||||||
|
else if (split_line.at(0) == "vn")
|
||||||
|
{
|
||||||
|
glm::vec3 normal;
|
||||||
|
normal.x = std::stof(split_line.at(1));
|
||||||
|
normal.y = std::stof(split_line.at(2));
|
||||||
|
normal.z = std::stof(split_line.at(3));
|
||||||
|
normals.push_back(normal);
|
||||||
|
}
|
||||||
|
else if (split_line.at(0) == "f")
|
||||||
|
{
|
||||||
|
normal_array = std::vector<GLfloat>(vertices.size() * 3);
|
||||||
|
texture_array = std::vector<GLfloat>(textures.size() * 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
std::vector<std::string> split = Split(line, ' ');
|
||||||
|
std::vector<std::string> vertex1 = Split(split.at(1), '/');
|
||||||
|
std::vector<std::string> vertex2 = Split(split.at(2), '/');
|
||||||
|
std::vector<std::string> vertex3 = Split(split.at(3), '/');
|
||||||
|
ProcessVertex(vertex1, normals, textures, indices, texture_array, normal_array);
|
||||||
|
ProcessVertex(vertex2, normals, textures, indices, texture_array, normal_array);
|
||||||
|
ProcessVertex(vertex3, normals, textures, indices, texture_array, normal_array);
|
||||||
|
if (!std::getline(inFile, line))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
// Always go in here
|
||||||
|
}
|
||||||
|
|
||||||
|
inFile.close();
|
||||||
|
|
||||||
|
vertex_array = std::vector<GLfloat>( vertices.size() * 3 );
|
||||||
|
int p = 0;
|
||||||
|
for ( auto& vertex : vertices )
|
||||||
|
{
|
||||||
|
vertex_array[p++] = vertex.x;
|
||||||
|
vertex_array[p++] = vertex.y;
|
||||||
|
vertex_array[p++] = vertex.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
return render_engine::loader::LoadToVAO( vertex_array, texture_array, indices);
|
||||||
|
}
|
||||||
6
src/renderEngine/obj_loader.h
Normal file
6
src/renderEngine/obj_loader.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "../models/model.h"
|
||||||
|
|
||||||
|
models::RawModel LoadObjModel(std::string file_name);
|
||||||
106
src/shaders/shader_program.cpp
Normal file
106
src/shaders/shader_program.cpp
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#include <GL/glew.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include "shader_program.h"
|
||||||
|
|
||||||
|
namespace shaders
|
||||||
|
{
|
||||||
|
ShaderProgram::ShaderProgram(std::string& vertex_shader, std::string& fragment_shader)
|
||||||
|
{
|
||||||
|
vertex_shader_id = LoadShader(vertex_shader, GL_VERTEX_SHADER);
|
||||||
|
fragment_shader_id = LoadShader(fragment_shader, GL_FRAGMENT_SHADER);
|
||||||
|
program_id = glCreateProgram();
|
||||||
|
glAttachShader(program_id, vertex_shader_id);
|
||||||
|
glAttachShader(program_id, fragment_shader_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderProgram::Init()
|
||||||
|
{
|
||||||
|
SetAttributes();
|
||||||
|
glLinkProgram(program_id);
|
||||||
|
glValidateProgram(program_id);
|
||||||
|
GetAllUniformLocations();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method will Start the shaders
|
||||||
|
void ShaderProgram::Start() const
|
||||||
|
{
|
||||||
|
glUseProgram(program_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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(program_id, vertex_shader_id);
|
||||||
|
glDetachShader(program_id, fragment_shader_id);
|
||||||
|
glDeleteShader(vertex_shader_id);
|
||||||
|
glDeleteShader(fragment_shader_id);
|
||||||
|
glDeleteProgram(program_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method sets an input variabele into the shaders
|
||||||
|
void ShaderProgram::SetAttribute(const GLuint attribute, const char* variable_name) const
|
||||||
|
{
|
||||||
|
glBindAttribLocation(program_id, attribute, variable_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderProgram::LoadFloat(GLuint location, GLfloat value) const
|
||||||
|
{
|
||||||
|
glUniform1f(location, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderProgram::LoadVector(GLuint location, glm::vec3 vector) const
|
||||||
|
{
|
||||||
|
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* uniform_name) const
|
||||||
|
{
|
||||||
|
return glGetUniformLocation(program_id, uniform_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method loads a shader into openGL
|
||||||
|
GLuint ShaderProgram::LoadShader(const std::string& shader_string, const GLuint type) const
|
||||||
|
{
|
||||||
|
const char* shader_text = shader_string.c_str();
|
||||||
|
const GLuint shader_id = glCreateShader(type);
|
||||||
|
glShaderSource(shader_id, 1, &shader_text, NULL);
|
||||||
|
glCompileShader(shader_id);
|
||||||
|
|
||||||
|
GLint succes = 0;
|
||||||
|
glGetShaderiv(shader_id, GL_COMPILE_STATUS, &succes);
|
||||||
|
if (succes == GL_FALSE)
|
||||||
|
{
|
||||||
|
GLint max_length = 0;
|
||||||
|
glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &max_length);
|
||||||
|
|
||||||
|
std::vector<GLchar> error_log(max_length);
|
||||||
|
glGetShaderInfoLog(shader_id, max_length, &max_length, &error_log[0]);
|
||||||
|
for (std::vector<GLchar>::const_iterator i = error_log.begin(); i != error_log.end(); ++i)
|
||||||
|
{
|
||||||
|
std::cout << *i;
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cerr << "Could not compile shader" << std::endl;
|
||||||
|
CleanUp();
|
||||||
|
std::exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/shaders/shader_program.h
Normal file
49
src/shaders/shader_program.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This abstract class represents a generic shader program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace shaders
|
||||||
|
{
|
||||||
|
class ShaderProgram
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
GLuint program_id;
|
||||||
|
GLuint vertex_shader_id;
|
||||||
|
GLuint fragment_shader_id;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ShaderProgram(std::string& vertex_shader, std::string& fragment_shader);
|
||||||
|
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* variable_name) 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* uniform_name) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint LoadShader(const std::string& shader_string, GLuint type) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
87
src/shaders/static_shader.cpp
Normal file
87
src/shaders/static_shader.cpp
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
#include "static_shader.h"
|
||||||
|
#include "../toolbox/toolbox.h"
|
||||||
|
|
||||||
|
namespace shaders
|
||||||
|
{
|
||||||
|
static std::string vertex_shader = 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 texture_coords;
|
||||||
|
|
||||||
|
// Equal to the texture_coords
|
||||||
|
out vec2 pass_texture_coords;
|
||||||
|
|
||||||
|
uniform mat4 model_matrix;
|
||||||
|
uniform mat4 projection_matrix;
|
||||||
|
uniform mat4 view_matrix;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
// Tell OpenGL where to render the vertex
|
||||||
|
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(position, 1.0);
|
||||||
|
|
||||||
|
// Pass the texture_coords directly to the fragment shader
|
||||||
|
pass_texture_coords = texture_coords;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
|
||||||
|
static std::string fragment_shader = 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 pass_texture_coords;
|
||||||
|
|
||||||
|
// Final color of the pixel
|
||||||
|
out vec4 out_color;
|
||||||
|
|
||||||
|
// The texture of the model
|
||||||
|
uniform sampler2D texture_sampler;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
out_color = texture(texture_sampler, pass_texture_coords);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
|
||||||
|
StaticShader::StaticShader(): ShaderProgram(vertex_shader, fragment_shader)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticShader::LoadModelMatrix(const glm::mat4& matrix) const
|
||||||
|
{
|
||||||
|
LoadMatrix(location_model_matrix, matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticShader::LoadProjectionMatrix(const glm::mat4& projection) const
|
||||||
|
{
|
||||||
|
LoadMatrix(location_projection_matrix, projection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticShader::LoadViewMatrix(entities::Camera& camera) const
|
||||||
|
{
|
||||||
|
const glm::mat4 view_matrix = toolbox::CreateViewMatrix(camera);
|
||||||
|
LoadMatrix(location_view_matrix, view_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticShader::SetAttributes() const
|
||||||
|
{
|
||||||
|
SetAttribute(0, "position");
|
||||||
|
SetAttribute(1, "texture_coords");
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticShader::GetAllUniformLocations()
|
||||||
|
{
|
||||||
|
location_model_matrix = GetUniformLocation("model_matrix");
|
||||||
|
location_projection_matrix = GetUniformLocation("projection_matrix");
|
||||||
|
location_view_matrix = GetUniformLocation("view_matrix");
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/shaders/static_shader.h
Normal file
31
src/shaders/static_shader.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include "shader_program.h"
|
||||||
|
#include "../entities/camera.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
This class does represents the shaders for the models.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace shaders
|
||||||
|
{
|
||||||
|
class StaticShader : public ShaderProgram
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
GLuint location_model_matrix;
|
||||||
|
GLuint location_projection_matrix;
|
||||||
|
GLuint location_view_matrix;
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
}
|
||||||
7762
src/stb_image.h
Normal file
7762
src/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
465
src/tigl.cpp
465
src/tigl.cpp
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
148
src/tigl.h
148
src/tigl.h
@@ -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
26
src/toolbox/toolbox.cpp
Normal 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 negative_cam_pos = glm::vec3(-camera.GetPosition().x, -camera.GetPosition().y, -camera.GetPosition().z);
|
||||||
|
matrix = glm::translate(matrix, negative_cam_pos);
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/toolbox/toolbox.h
Normal file
14
src/toolbox/toolbox.h
Normal 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);
|
||||||
|
}
|
||||||
@@ -18,6 +18,29 @@
|
|||||||
<Platform>x64</Platform>
|
<Platform>x64</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\entities\camera.cpp" />
|
||||||
|
<ClCompile Include="src\entities\entity.cpp" />
|
||||||
|
<ClCompile Include="src\main.cpp" />
|
||||||
|
<ClCompile Include="src\renderEngine\loader.cpp" />
|
||||||
|
<ClCompile Include="src\renderEngine\obj_loader.cpp" />
|
||||||
|
<ClCompile Include="src\renderEngine\renderer.cpp" />
|
||||||
|
<ClCompile Include="src\shaders\shader_program.cpp" />
|
||||||
|
<ClCompile Include="src\shaders\static_shader.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\obj_loader.h" />
|
||||||
|
<ClInclude Include="src\renderEngine\renderer.h" />
|
||||||
|
<ClInclude Include="src\shaders\shader_program.h" />
|
||||||
|
<ClInclude Include="src\shaders\static_shader.h" />
|
||||||
|
<ClInclude Include="src\stb_image.h" />
|
||||||
|
<ClInclude Include="src\toolbox\toolbox.h" />
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<VCProjectVersion>16.0</VCProjectVersion>
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
<ProjectGuid>{A7ECF1BE-DB22-4BF7-BFF6-E3BF72691EE6}</ProjectGuid>
|
<ProjectGuid>{A7ECF1BE-DB22-4BF7-BFF6-E3BF72691EE6}</ProjectGuid>
|
||||||
@@ -158,15 +181,6 @@
|
|||||||
<AdditionalLibraryDirectories>$(SolutionDir)lib\glfw-3.3.2\$(Platform);$(SolutionDir)lib\glew-2.1.0\lib\Release\$(Platform);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>$(SolutionDir)lib\glfw-3.3.2\$(Platform);$(SolutionDir)lib\glew-2.1.0\lib\Release\$(Platform);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</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" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|||||||
@@ -15,21 +15,63 @@
|
|||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\tigl.cpp">
|
<ClCompile Include="src\entities\Camera.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\entities\Entity.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\renderEngine\Loader.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\renderEngine\Renderer.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="src\main.cpp">
|
<ClCompile Include="src\main.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="src\FpsCam.cpp">
|
<ClCompile Include="src\shaders\shader_program.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\shaders\static_shader.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\renderEngine\obj_loader.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\toolbox\toolbox.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\tigl.h">
|
<ClInclude Include="src\entities\Camera.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</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\Renderer.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\stb_image.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\shaders\shader_program.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\shaders\static_shader.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\renderEngine\obj_loader.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\toolbox\toolbox.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user