initial commit
This commit is contained in:
commit
739d8f55b7
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.vs/
|
||||||
|
[Oo]ut/
|
||||||
|
[Bb]uild/
|
||||||
|
|
||||||
|
*.json
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "vendor/glm"]
|
||||||
|
path = vendor/glm
|
||||||
|
url = git@github.com:g-truc/glm.git
|
35
CMakeLists.txt
Normal file
35
CMakeLists.txt
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
cmake_minimum_required (VERSION 3.8)
|
||||||
|
|
||||||
|
project("lol")
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
|
find_package(GLM)
|
||||||
|
if(NOT GLM_FOUND)
|
||||||
|
message(STATUS "Could not find GLM on system, including from source instead")
|
||||||
|
add_subdirectory("vendor/glm")
|
||||||
|
|
||||||
|
set(GLM_INCLUDE_DIRS glm)
|
||||||
|
set(GLM_LIBRARIES glm)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(lol STATIC
|
||||||
|
"src/Drawable.cpp"
|
||||||
|
"src/Transformable.cpp"
|
||||||
|
"src/Shader.cpp"
|
||||||
|
"src/VertexArrayObject.cpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_sources(lol PUBLIC
|
||||||
|
vendor/glad/src/glad.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(lol PUBLIC
|
||||||
|
${GLM_INCLUDE_DIRS}
|
||||||
|
vendor/glad/include
|
||||||
|
include
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(lol PUBLIC
|
||||||
|
${GLM_LIBRARIES}
|
||||||
|
)
|
15
include/backend/BoundingBox.hpp
Normal file
15
include/backend/BoundingBox.hpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct Rect
|
||||||
|
{
|
||||||
|
float x, y;
|
||||||
|
float w, h;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoundingBox
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
float w, h, d;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef BoundingBox BBox;
|
67
include/backend/Camera.hpp
Normal file
67
include/backend/Camera.hpp
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "Transformable.hpp"
|
||||||
|
#include "Drawable.hpp"
|
||||||
|
|
||||||
|
// TODO: Find better name
|
||||||
|
class CameraBase : public Transformable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// "Scaling" doesn't really makes sense for a camera
|
||||||
|
void GetScale() = delete;
|
||||||
|
void SetScale(const glm::vec3&) = delete;
|
||||||
|
void Scale(const glm::vec3&) = delete;
|
||||||
|
|
||||||
|
inline void LookAt(const glm::vec3& target)
|
||||||
|
{
|
||||||
|
transformation = glm::lookAt(position, target, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const glm::mat4& GetView() const
|
||||||
|
{
|
||||||
|
return transformation;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const glm::mat4& GetProjection() const
|
||||||
|
{
|
||||||
|
return projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Draw(const Drawable& drawable) const
|
||||||
|
{
|
||||||
|
drawable.Draw(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
glm::mat4 projection;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Camera : public CameraBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Camera(float fov = 90.0f, float aspect = 1.0f, float zNear = 0.01f, float zFar = 100.0f)
|
||||||
|
{
|
||||||
|
projection = glm::perspective(glm::radians(fov), aspect, zNear, zFar);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Update(float fov, float aspect, float zNear, float zFar)
|
||||||
|
{
|
||||||
|
projection = glm::perspective(glm::radians(fov), aspect, zNear, zFar);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class OrthogonalCamera : public CameraBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OrthogonalCamera(float left = -1.0f, float right = 1.0f, float bottom = -1.0f, float top = 1.0f, float zNear = -100.0f, float zFar = 100.0f)
|
||||||
|
{
|
||||||
|
projection = glm::ortho(left, right, bottom, top, zNear, zFar);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Update(float left, float right, float bottom, float top, float zNear, float zFar)
|
||||||
|
{
|
||||||
|
projection = glm::ortho(left, right, bottom, top, zNear, zFar);
|
||||||
|
}
|
||||||
|
};
|
38
include/backend/Drawable.hpp
Normal file
38
include/backend/Drawable.hpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include "VertexArrayObject.hpp"
|
||||||
|
#include "Shader.hpp"
|
||||||
|
|
||||||
|
class CameraBase;
|
||||||
|
|
||||||
|
enum class PrimitiveType
|
||||||
|
{
|
||||||
|
Lines = GL_LINES,
|
||||||
|
LineStrip = GL_LINE_STRIP,
|
||||||
|
LineLoop = GL_LINE_LOOP,
|
||||||
|
|
||||||
|
Triangles = GL_TRIANGLES,
|
||||||
|
TriangleStrip = GL_TRIANGLE_STRIP,
|
||||||
|
TriangleFan = GL_TRIANGLE_FAN
|
||||||
|
};
|
||||||
|
|
||||||
|
class Drawable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Drawable(const Drawable& other) = delete;
|
||||||
|
void operator=(const Drawable& other) = delete;
|
||||||
|
|
||||||
|
virtual void PreRender(const CameraBase& camera) const { };
|
||||||
|
void Draw(const CameraBase& camera) const;
|
||||||
|
void SetPrimitiveType(PrimitiveType type);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Drawable() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
VertexArrayObject vao;
|
||||||
|
Shader shader;
|
||||||
|
|
||||||
|
PrimitiveType type = PrimitiveType::Triangles;
|
||||||
|
};
|
16
include/backend/NonCopyable.hpp
Normal file
16
include/backend/NonCopyable.hpp
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace lol
|
||||||
|
{
|
||||||
|
class NonCopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NonCopyable(const NonCopyable& other) = delete;
|
||||||
|
void operator=(const NonCopyable& other) = delete;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
NonCopyable() {}
|
||||||
|
~NonCopyable() {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
71
include/backend/ObjectManager.hpp
Normal file
71
include/backend/ObjectManager.hpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some objects should only exist once but be available to multiple objects (e.g. multiple
|
||||||
|
* models sharing the same VAO and shaders. Any object can register objects here and other
|
||||||
|
* objects can then retrieve them if they have the ID.
|
||||||
|
*
|
||||||
|
* Objects are stored and returned as shared_ptr's, so even if a part of the program deletes
|
||||||
|
* an object from the manager, any part of the program that has the objects stored in them will
|
||||||
|
* not break and still work. But realistically this shouldn't happen in the first place.
|
||||||
|
* As a consequence, even if no objects are using an object stored in here it will continue to
|
||||||
|
* exist.
|
||||||
|
*/
|
||||||
|
template<typename Type>
|
||||||
|
class ObjectManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static ObjectManager<Type>& GetInstance()
|
||||||
|
{
|
||||||
|
static ObjectManager<Type> instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ObjectManager(const ObjectManager<Type>&) = delete;
|
||||||
|
void operator=(const ObjectManager<Type>&) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new (existing) object to manager
|
||||||
|
*/
|
||||||
|
inline void Register(unsigned int id, std::shared_ptr<Type> obj)
|
||||||
|
{
|
||||||
|
objects.insert(std::make_pair(id, obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove object from manager
|
||||||
|
*/
|
||||||
|
inline void Delete(unsigned int id)
|
||||||
|
{
|
||||||
|
objects.erase(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve object from manager
|
||||||
|
*/
|
||||||
|
inline std::shared_ptr<Type> Get(unsigned int id)
|
||||||
|
{
|
||||||
|
auto it = objects.find(id);
|
||||||
|
|
||||||
|
if (it == objects.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ObjectManager() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<unsigned int, std::shared_ptr<Type>> objects;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AbstractShader;
|
||||||
|
class AbstractVertexArrayObject;
|
||||||
|
|
||||||
|
typedef ObjectManager<AbstractVertexArrayObject> VAOManager;
|
||||||
|
typedef ObjectManager<AbstractShader> ShaderManager;
|
39
include/backend/Shader.hpp
Normal file
39
include/backend/Shader.hpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class AbstractShader
|
||||||
|
{
|
||||||
|
friend class ShaderFactory;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AbstractShader(const std::string& vertexShader, const std::string& fragmentShader);
|
||||||
|
AbstractShader(const AbstractShader& other) = delete;
|
||||||
|
~AbstractShader();
|
||||||
|
|
||||||
|
inline bool Good() { return id != 0; }
|
||||||
|
void Use();
|
||||||
|
|
||||||
|
void SetUniform(const std::string& name, const glm::mat4& value);
|
||||||
|
void SetUniform(const std::string& name, const glm::vec4& value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
|
bool recording = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<AbstractShader> Shader;
|
||||||
|
|
||||||
|
class ShaderFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline static Shader Produce(const std::string& vertexShader, const std::string& fragmentShader)
|
||||||
|
{
|
||||||
|
return std::make_shared<AbstractShader>(vertexShader, fragmentShader);
|
||||||
|
}
|
||||||
|
};
|
33
include/backend/Transformable.hpp
Normal file
33
include/backend/Transformable.hpp
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
|
||||||
|
class Transformable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Transformable();
|
||||||
|
|
||||||
|
const glm::vec3& GetPosition() const;
|
||||||
|
void SetPosition(const glm::vec3& pos);
|
||||||
|
void Move(const glm::vec3& direction);
|
||||||
|
|
||||||
|
const glm::vec3 GetRotation() const;
|
||||||
|
const glm::quat& GetQuaternion() const;
|
||||||
|
void SetRotation(const glm::vec3& axis, float angle);
|
||||||
|
void SetRotation(const glm::vec3& eulerAngles);
|
||||||
|
void Rotate(const glm::vec3& axis, float angle);
|
||||||
|
|
||||||
|
const glm::vec3& GetScale() const;
|
||||||
|
void SetScale(const glm::vec3& scale);
|
||||||
|
void Scale(const glm::vec3& factor);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void CalculateTransformationMatrix();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
glm::mat4 transformation;
|
||||||
|
|
||||||
|
glm::vec3 position, scale;
|
||||||
|
glm::quat orientation;
|
||||||
|
};
|
58
include/backend/VertexArrayObject.hpp
Normal file
58
include/backend/VertexArrayObject.hpp
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
// struct representing an OpenGL attribute pointer
|
||||||
|
struct VertexAttribute
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
unsigned int type;
|
||||||
|
bool normalized;
|
||||||
|
unsigned int stride;
|
||||||
|
const void* pointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Useful abbreviations
|
||||||
|
typedef std::vector<float> VertexArray;
|
||||||
|
typedef std::vector<unsigned int> IndexArray;
|
||||||
|
typedef std::vector<VertexAttribute> Layout;
|
||||||
|
|
||||||
|
// OpenGL Buffer usages (I turned them into an enum so it's easier to know what options exist)
|
||||||
|
enum class Usage
|
||||||
|
{
|
||||||
|
Static, Stream, Dynamic
|
||||||
|
};
|
||||||
|
|
||||||
|
// VAO structure that sets up the buffers and deletes them at the end of the lifecycle
|
||||||
|
class AbstractVertexArrayObject
|
||||||
|
{
|
||||||
|
friend class VAOFactory;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AbstractVertexArrayObject() = delete;
|
||||||
|
AbstractVertexArrayObject(const VertexArray& vertices, const IndexArray& indices, const Layout& layout, Usage usage);
|
||||||
|
~AbstractVertexArrayObject();
|
||||||
|
|
||||||
|
void Render(unsigned int mode = 4);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int vao, vbo, ebo;
|
||||||
|
size_t indexCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
// You cannot actually create this VAO, you are forced to use a shared pointer
|
||||||
|
// so the buffers dont get accidentally deleted while another obejct is potentially still using it.
|
||||||
|
// I find this to be very important since VAOs are supposed to be shared between copies of objects
|
||||||
|
// if they have the same model.
|
||||||
|
typedef std::shared_ptr<AbstractVertexArrayObject> VertexArrayObject;
|
||||||
|
|
||||||
|
// Factory for creating said shared pointers.
|
||||||
|
class VAOFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static VertexArrayObject Produce(const VertexArray& vertices, const IndexArray& indices, const Layout& layout, Usage usage = Usage::Static)
|
||||||
|
{
|
||||||
|
return std::make_shared<AbstractVertexArrayObject>(vertices, indices, layout, usage);
|
||||||
|
}
|
||||||
|
};
|
13
src/Drawable.cpp
Normal file
13
src/Drawable.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "backend/Drawable.hpp"
|
||||||
|
|
||||||
|
void Drawable::Draw(const CameraBase& camera) const
|
||||||
|
{
|
||||||
|
shader->Use();
|
||||||
|
PreRender(camera);
|
||||||
|
vao->Render(static_cast<unsigned int>(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Drawable::SetPrimitiveType(PrimitiveType type)
|
||||||
|
{
|
||||||
|
this->type = type;
|
||||||
|
}
|
97
src/Shader.cpp
Normal file
97
src/Shader.cpp
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
#include "backend/Shader.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
#define IMPLEMENT_UNIFORM_FUNCTION(type, func) \
|
||||||
|
inline
|
||||||
|
|
||||||
|
AbstractShader::AbstractShader(const std::string& vertexShader, const std::string& fragmentShader) :
|
||||||
|
id(0)
|
||||||
|
{
|
||||||
|
GLint success;
|
||||||
|
GLchar infoLog[512];
|
||||||
|
|
||||||
|
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
const char* vertexShaderSource = vertexShader.c_str();
|
||||||
|
glShaderSource(vertexShaderID, 1, &vertexShaderSource, NULL);
|
||||||
|
glCompileShader(vertexShaderID);
|
||||||
|
|
||||||
|
glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &success);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(vertexShaderID, 512, NULL, infoLog);
|
||||||
|
std::cerr << "Vertex shader creation failed: \n" << infoLog << std::endl;
|
||||||
|
|
||||||
|
glDeleteShader(vertexShaderID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
const char* fragmentShaderSource = fragmentShader.c_str();
|
||||||
|
glShaderSource(fragmentShaderID, 1, &fragmentShaderSource, NULL);
|
||||||
|
glCompileShader(fragmentShaderID);
|
||||||
|
|
||||||
|
glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &success);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(fragmentShaderID, 512, NULL, infoLog);
|
||||||
|
std::cerr << "Fragment shader creation failed: \n" << infoLog << std::endl;
|
||||||
|
|
||||||
|
glDeleteShader(fragmentShaderID);
|
||||||
|
glDeleteShader(vertexShaderID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = glCreateProgram();
|
||||||
|
glAttachShader(id, vertexShaderID);
|
||||||
|
glAttachShader(id, fragmentShaderID);
|
||||||
|
glLinkProgram(id);
|
||||||
|
|
||||||
|
glGetProgramiv(id, GL_LINK_STATUS, &success);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
glGetProgramInfoLog(fragmentShaderID, 512, NULL, infoLog);
|
||||||
|
std::cerr << "Shader program linking failed: \n" << infoLog << std::endl;
|
||||||
|
|
||||||
|
glDeleteShader(fragmentShaderID);
|
||||||
|
glDeleteShader(vertexShaderID);
|
||||||
|
|
||||||
|
id = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteShader(fragmentShaderID);
|
||||||
|
glDeleteShader(vertexShaderID);
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractShader::~AbstractShader()
|
||||||
|
{
|
||||||
|
glDeleteProgram(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractShader::Use()
|
||||||
|
{
|
||||||
|
glUseProgram(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractShader::SetUniform(const std::string& name, const glm::mat4& value)
|
||||||
|
{
|
||||||
|
GLint location = glGetUniformLocation(id, name.c_str());
|
||||||
|
if (location == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractShader::SetUniform(const std::string& name, const glm::vec4& value)
|
||||||
|
{
|
||||||
|
GLint location = glGetUniformLocation(id, name.c_str());
|
||||||
|
if (location == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glUniform4fv(location, 1, glm::value_ptr(value));
|
||||||
|
}
|
82
src/Transformable.cpp
Normal file
82
src/Transformable.cpp
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#include "backend/Transformable.hpp"
|
||||||
|
|
||||||
|
Transformable::Transformable() :
|
||||||
|
position(0.0f), scale(1.0f), orientation(glm::vec3(0.0, 0.0, 0.0))
|
||||||
|
{
|
||||||
|
CalculateTransformationMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
const glm::vec3& Transformable::GetPosition() const
|
||||||
|
{
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transformable::SetPosition(const glm::vec3& pos)
|
||||||
|
{
|
||||||
|
position = pos;
|
||||||
|
CalculateTransformationMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transformable::Move(const glm::vec3& direction)
|
||||||
|
{
|
||||||
|
position += direction;
|
||||||
|
CalculateTransformationMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
const glm::vec3 Transformable::GetRotation() const
|
||||||
|
{
|
||||||
|
return glm::eulerAngles(orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
const glm::quat& Transformable::GetQuaternion() const
|
||||||
|
{
|
||||||
|
return orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transformable::SetRotation(const glm::vec3& axis, float angle)
|
||||||
|
{
|
||||||
|
orientation = glm::quat(glm::radians(angle), axis);
|
||||||
|
CalculateTransformationMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transformable::SetRotation(const glm::vec3& eulerAngles)
|
||||||
|
{
|
||||||
|
/*orientation = glm::quat(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
orientation = glm::rotate(orientation, eulerAngles.x, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
orientation = glm::rotate(orientation, eulerAngles.y, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
orientation = glm::rotate(orientation, eulerAngles.z, glm::vec3(0.0f, 0.0f, 1.0f));*/
|
||||||
|
|
||||||
|
orientation = glm::quat(eulerAngles);
|
||||||
|
CalculateTransformationMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transformable::Rotate(const glm::vec3& axis, float angle)
|
||||||
|
{
|
||||||
|
orientation = glm::rotate(orientation, glm::radians(angle), axis);
|
||||||
|
CalculateTransformationMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
const glm::vec3& Transformable::GetScale() const
|
||||||
|
{
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transformable::SetScale(const glm::vec3& scale)
|
||||||
|
{
|
||||||
|
this->scale = scale;
|
||||||
|
CalculateTransformationMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transformable::Scale(const glm::vec3& factor)
|
||||||
|
{
|
||||||
|
this->scale *= scale; // I pray this is component-wise multiplication
|
||||||
|
CalculateTransformationMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Transformable::CalculateTransformationMatrix()
|
||||||
|
{
|
||||||
|
transformation = glm::mat4(1.0f);
|
||||||
|
transformation = glm::translate(transformation, position);
|
||||||
|
transformation *= glm::mat4(orientation);
|
||||||
|
transformation = glm::scale(transformation, scale);
|
||||||
|
}
|
60
src/VertexArrayObject.cpp
Normal file
60
src/VertexArrayObject.cpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#include "backend/VertexArrayObject.hpp"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
AbstractVertexArrayObject::~AbstractVertexArrayObject()
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, &ebo);
|
||||||
|
glDeleteBuffers(1, &vbo);
|
||||||
|
glDeleteVertexArrays(1, &vao);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractVertexArrayObject::Render(GLenum mode)
|
||||||
|
{
|
||||||
|
assert(vao != 0);
|
||||||
|
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
// GLenum result = glGetError();
|
||||||
|
glDrawElements(mode, indexCount, GL_UNSIGNED_INT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractVertexArrayObject::AbstractVertexArrayObject(const VertexArray& vertices, const IndexArray& indices, const Layout& layout, Usage usage) :
|
||||||
|
vao(0), vbo(0), ebo(0), indexCount(indices.size())
|
||||||
|
{
|
||||||
|
glGenVertexArrays(1, &vao);
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
glGenBuffers(1, &vbo);
|
||||||
|
glGenBuffers(1, &ebo);
|
||||||
|
|
||||||
|
// Determing native OpenGL GLenum depending on specified usage
|
||||||
|
GLenum bufferUsage;
|
||||||
|
switch (usage)
|
||||||
|
{
|
||||||
|
case Usage::Static: bufferUsage = GL_STATIC_DRAW; break;
|
||||||
|
case Usage::Dynamic: bufferUsage = GL_DYNAMIC_DRAW; break;
|
||||||
|
case Usage::Stream: bufferUsage = GL_STREAM_DRAW; break;
|
||||||
|
|
||||||
|
default: // Forgot to add a usage case to this switch
|
||||||
|
assert("Unknown buffer usage" == "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create VBO
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), (const void*)(vertices.data()), bufferUsage);
|
||||||
|
|
||||||
|
// Create EBO
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), (const void*)(indices.data()), bufferUsage);
|
||||||
|
|
||||||
|
// Set up pipeline layout
|
||||||
|
unsigned int index = 0;
|
||||||
|
for (const VertexAttribute& attribute : layout)
|
||||||
|
{
|
||||||
|
glVertexAttribPointer(index, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.pointer);
|
||||||
|
glEnableVertexAttribArray(index);
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
311
vendor/glad/include/KHR/khrplatform.h
vendored
Normal file
311
vendor/glad/include/KHR/khrplatform.h
vendored
Normal file
|
@ -0,0 +1,311 @@
|
||||||
|
#ifndef __khrplatform_h_
|
||||||
|
#define __khrplatform_h_
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
** copy of this software and/or associated documentation files (the
|
||||||
|
** "Materials"), to deal in the Materials without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
** permit persons to whom the Materials are furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included
|
||||||
|
** in all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Khronos platform-specific types and definitions.
|
||||||
|
*
|
||||||
|
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||||
|
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||||
|
* The last semantic modification to khrplatform.h was at commit ID:
|
||||||
|
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||||
|
*
|
||||||
|
* Adopters may modify this file to suit their platform. Adopters are
|
||||||
|
* encouraged to submit platform specific modifications to the Khronos
|
||||||
|
* group so that they can be included in future versions of this file.
|
||||||
|
* Please submit changes by filing pull requests or issues on
|
||||||
|
* the EGL Registry repository linked above.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* See the Implementer's Guidelines for information about where this file
|
||||||
|
* should be located on your system and for more details of its use:
|
||||||
|
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||||
|
*
|
||||||
|
* This file should be included as
|
||||||
|
* #include <KHR/khrplatform.h>
|
||||||
|
* by Khronos client API header files that use its types and defines.
|
||||||
|
*
|
||||||
|
* The types in khrplatform.h should only be used to define API-specific types.
|
||||||
|
*
|
||||||
|
* Types defined in khrplatform.h:
|
||||||
|
* khronos_int8_t signed 8 bit
|
||||||
|
* khronos_uint8_t unsigned 8 bit
|
||||||
|
* khronos_int16_t signed 16 bit
|
||||||
|
* khronos_uint16_t unsigned 16 bit
|
||||||
|
* khronos_int32_t signed 32 bit
|
||||||
|
* khronos_uint32_t unsigned 32 bit
|
||||||
|
* khronos_int64_t signed 64 bit
|
||||||
|
* khronos_uint64_t unsigned 64 bit
|
||||||
|
* khronos_intptr_t signed same number of bits as a pointer
|
||||||
|
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||||
|
* khronos_ssize_t signed size
|
||||||
|
* khronos_usize_t unsigned size
|
||||||
|
* khronos_float_t signed 32 bit floating point
|
||||||
|
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||||
|
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||||
|
* nanoseconds
|
||||||
|
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||||
|
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||||
|
* only be used as a base type when a client API's boolean type is
|
||||||
|
* an enum. Client APIs which use an integer or other type for
|
||||||
|
* booleans cannot use this as the base type for their boolean.
|
||||||
|
*
|
||||||
|
* Tokens defined in khrplatform.h:
|
||||||
|
*
|
||||||
|
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||||
|
*
|
||||||
|
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||||
|
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||||
|
*
|
||||||
|
* Calling convention macros defined in this file:
|
||||||
|
* KHRONOS_APICALL
|
||||||
|
* KHRONOS_APIENTRY
|
||||||
|
* KHRONOS_APIATTRIBUTES
|
||||||
|
*
|
||||||
|
* These may be used in function prototypes as:
|
||||||
|
*
|
||||||
|
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||||
|
* int arg1,
|
||||||
|
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||||
|
# define KHRONOS_STATIC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APICALL
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This precedes the return type of the function in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(KHRONOS_STATIC)
|
||||||
|
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||||
|
* header compatible with static linking. */
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
# define KHRONOS_APICALL __declspec(dllimport)
|
||||||
|
#elif defined (__SYMBIAN32__)
|
||||||
|
# define KHRONOS_APICALL IMPORT_C
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIENTRY
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the return type of the function and precedes the function
|
||||||
|
* name in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||||
|
/* Win32 but not WinCE */
|
||||||
|
# define KHRONOS_APIENTRY __stdcall
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIATTRIBUTES
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the closing parenthesis of the function prototype arguments.
|
||||||
|
*/
|
||||||
|
#if defined (__ARMCC_2__)
|
||||||
|
#define KHRONOS_APIATTRIBUTES __softfp
|
||||||
|
#else
|
||||||
|
#define KHRONOS_APIATTRIBUTES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* basic type definitions
|
||||||
|
*-----------------------------------------------------------------------*/
|
||||||
|
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <stdint.h>
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
/*
|
||||||
|
* To support platform where unsigned long cannot be used interchangeably with
|
||||||
|
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||||
|
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||||
|
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||||
|
* unsigned long long or similar (this results in different C++ name mangling).
|
||||||
|
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||||
|
* platforms where the size of a pointer is larger than the size of long.
|
||||||
|
*/
|
||||||
|
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||||
|
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||||
|
#define KHRONOS_USE_INTPTR_T
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__VMS ) || defined(__sgi)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <inttypes.h>
|
||||||
|
*/
|
||||||
|
#include <inttypes.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Win32
|
||||||
|
*/
|
||||||
|
typedef __int32 khronos_int32_t;
|
||||||
|
typedef unsigned __int32 khronos_uint32_t;
|
||||||
|
typedef __int64 khronos_int64_t;
|
||||||
|
typedef unsigned __int64 khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(__sun__) || defined(__digital__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sun or Digital
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#if defined(__arch64__) || defined(_LP64)
|
||||||
|
typedef long int khronos_int64_t;
|
||||||
|
typedef unsigned long int khronos_uint64_t;
|
||||||
|
#else
|
||||||
|
typedef long long int khronos_int64_t;
|
||||||
|
typedef unsigned long long int khronos_uint64_t;
|
||||||
|
#endif /* __arch64__ */
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hypothetical platform with no float or int64 support
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 0
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 0
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic fallback
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that are (so far) the same on all platforms
|
||||||
|
*/
|
||||||
|
typedef signed char khronos_int8_t;
|
||||||
|
typedef unsigned char khronos_uint8_t;
|
||||||
|
typedef signed short int khronos_int16_t;
|
||||||
|
typedef unsigned short int khronos_uint16_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||||
|
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||||
|
* to be the only LLP64 architecture in current use.
|
||||||
|
*/
|
||||||
|
#ifdef KHRONOS_USE_INTPTR_T
|
||||||
|
typedef intptr_t khronos_intptr_t;
|
||||||
|
typedef uintptr_t khronos_uintptr_t;
|
||||||
|
#elif defined(_WIN64)
|
||||||
|
typedef signed long long int khronos_intptr_t;
|
||||||
|
typedef unsigned long long int khronos_uintptr_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_intptr_t;
|
||||||
|
typedef unsigned long int khronos_uintptr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
typedef signed long long int khronos_ssize_t;
|
||||||
|
typedef unsigned long long int khronos_usize_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_ssize_t;
|
||||||
|
typedef unsigned long int khronos_usize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_FLOAT
|
||||||
|
/*
|
||||||
|
* Float type
|
||||||
|
*/
|
||||||
|
typedef float khronos_float_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_INT64
|
||||||
|
/* Time types
|
||||||
|
*
|
||||||
|
* These types can be used to represent a time interval in nanoseconds or
|
||||||
|
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||||
|
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||||
|
* time the system booted). The Unadjusted System Time is an unsigned
|
||||||
|
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||||
|
* may be either signed or unsigned.
|
||||||
|
*/
|
||||||
|
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||||
|
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dummy value used to pad enum types to 32 bits.
|
||||||
|
*/
|
||||||
|
#ifndef KHRONOS_MAX_ENUM
|
||||||
|
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enumerated boolean type
|
||||||
|
*
|
||||||
|
* Values other than zero should be considered to be true. Therefore
|
||||||
|
* comparisons should not be made against KHRONOS_TRUE.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
KHRONOS_FALSE = 0,
|
||||||
|
KHRONOS_TRUE = 1,
|
||||||
|
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||||
|
} khronos_boolean_enum_t;
|
||||||
|
|
||||||
|
#endif /* __khrplatform_h_ */
|
3694
vendor/glad/include/glad/glad.h
vendored
Normal file
3694
vendor/glad/include/glad/glad.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
1833
vendor/glad/src/glad.c
vendored
Normal file
1833
vendor/glad/src/glad.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
vendor/glm
vendored
Submodule
1
vendor/glm
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 6ad79aae3eb5bf809c30bf1168171e9e55857e45
|
Loading…
Reference in a new issue