added namespace

This commit is contained in:
Lauchmelder 2021-12-23 00:51:59 +01:00
parent 8c789f57cb
commit de7cbdabbd
11 changed files with 484 additions and 429 deletions

View file

@ -1,15 +1,20 @@
#pragma once #pragma once
struct Rect namespace lol
{ {
float x, y;
float w, h;
};
struct BoundingBox struct Rect
{ {
float x, y, z; float x, y;
float w, h, d; float w, h;
}; };
typedef BoundingBox BBox; struct BoundingBox
{
float x, y, z;
float w, h, d;
};
typedef BoundingBox BBox;
}

View file

@ -4,64 +4,69 @@
#include "Transformable.hpp" #include "Transformable.hpp"
#include "Drawable.hpp" #include "Drawable.hpp"
// TODO: Find better name namespace lol
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) // TODO: Find better name
class CameraBase : public Transformable
{ {
transformation = glm::lookAt(position, target, glm::vec3(0.0f, 1.0f, 0.0f)); 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 const glm::mat4& GetView() const 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
{ {
return transformation; 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 const glm::mat4& GetProjection() const inline void Update(float fov, float aspect, float zNear, float zFar)
{
projection = glm::perspective(glm::radians(fov), aspect, zNear, zFar);
}
};
class OrthogonalCamera : public CameraBase
{ {
return projection; 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 Draw(const Drawable& drawable) const inline void Update(float left, float right, float bottom, float top, float zNear, float zFar)
{ {
drawable.Draw(*this); projection = glm::ortho(left, right, bottom, top, zNear, zFar);
} }
};
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);
}
};

View file

@ -4,35 +4,40 @@
#include "VertexArrayObject.hpp" #include "VertexArrayObject.hpp"
#include "Shader.hpp" #include "Shader.hpp"
class CameraBase; namespace lol
enum class PrimitiveType
{ {
Lines = GL_LINES,
LineStrip = GL_LINE_STRIP,
LineLoop = GL_LINE_LOOP,
Triangles = GL_TRIANGLES, class CameraBase;
TriangleStrip = GL_TRIANGLE_STRIP,
TriangleFan = GL_TRIANGLE_FAN
};
class Drawable enum class PrimitiveType
{ {
public: Lines = GL_LINES,
Drawable(const Drawable& other) = delete; LineStrip = GL_LINE_STRIP,
void operator=(const Drawable& other) = delete; LineLoop = GL_LINE_LOOP,
virtual void PreRender(const CameraBase& camera) const { }; Triangles = GL_TRIANGLES,
void Draw(const CameraBase& camera) const; TriangleStrip = GL_TRIANGLE_STRIP,
void SetPrimitiveType(PrimitiveType type); TriangleFan = GL_TRIANGLE_FAN
};
protected: class Drawable
Drawable() {} {
public:
Drawable(const Drawable& other) = delete;
void operator=(const Drawable& other) = delete;
protected: virtual void PreRender(const CameraBase& camera) const { };
VertexArrayObject vao; void Draw(const CameraBase& camera) const;
Shader shader; void SetPrimitiveType(PrimitiveType type);
PrimitiveType type = PrimitiveType::Triangles; protected:
}; Drawable() {}
protected:
VertexArrayObject vao;
Shader shader;
PrimitiveType type = PrimitiveType::Triangles;
};
}

View file

@ -3,69 +3,74 @@
#include <map> #include <map>
#include <memory> #include <memory>
/** namespace lol
* 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 * 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.
*/ */
inline void Register(unsigned int id, std::shared_ptr<Type> obj) template<typename Type>
class ObjectManager
{ {
objects.insert(std::make_pair(id, obj)); public:
} static ObjectManager<Type>& GetInstance()
{
static ObjectManager<Type> instance;
return instance;
}
/** public:
* Remove object from manager ObjectManager(const ObjectManager<Type>&) = delete;
*/ void operator=(const ObjectManager<Type>&) = delete;
inline void Delete(unsigned int id)
{
objects.erase(id);
}
/** /**
* Retrieve object from manager * Add new (existing) object to manager
*/ */
inline std::shared_ptr<Type> Get(unsigned int id) inline void Register(unsigned int id, std::shared_ptr<Type> obj)
{ {
auto it = objects.find(id); objects.insert(std::make_pair(id, obj));
}
if (it == objects.end()) /**
return nullptr; * Remove object from manager
*/
inline void Delete(unsigned int id)
{
objects.erase(id);
}
return it->second; /**
} * Retrieve object from manager
*/
inline std::shared_ptr<Type> Get(unsigned int id)
{
auto it = objects.find(id);
private: if (it == objects.end())
ObjectManager() {} return nullptr;
private: return it->second;
std::map<unsigned int, std::shared_ptr<Type>> objects; }
};
class AbstractShader; private:
class AbstractVertexArrayObject; ObjectManager() {}
typedef ObjectManager<AbstractVertexArrayObject> VAOManager; private:
typedef ObjectManager<AbstractShader> ShaderManager; std::map<unsigned int, std::shared_ptr<Type>> objects;
};
class AbstractShader;
class AbstractVertexArrayObject;
typedef ObjectManager<AbstractVertexArrayObject> VAOManager;
typedef ObjectManager<AbstractShader> ShaderManager;
}

View file

@ -1,39 +1,44 @@
#pragma once #pragma once
#include <glm/glm.hpp>
#include <string> #include <string>
#include <memory> #include <memory>
#include <functional> #include <functional>
class AbstractShader #include <glm/glm.hpp>
namespace lol
{ {
friend class ShaderFactory;
public: class AbstractShader
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); 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);
}
};
}

View file

@ -3,31 +3,36 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp> #include <glm/gtx/quaternion.hpp>
class Transformable namespace lol
{ {
public:
Transformable();
const glm::vec3& GetPosition() const; class Transformable
void SetPosition(const glm::vec3& pos); {
void Move(const glm::vec3& direction); public:
Transformable();
const glm::vec3 GetRotation() const; const glm::vec3& GetPosition() const;
const glm::quat& GetQuaternion() const; void SetPosition(const glm::vec3& pos);
void SetRotation(const glm::vec3& axis, float angle); void Move(const glm::vec3& direction);
void SetRotation(const glm::vec3& eulerAngles);
void Rotate(const glm::vec3& axis, float angle);
const glm::vec3& GetScale() const; const glm::vec3 GetRotation() const;
void SetScale(const glm::vec3& scale); const glm::quat& GetQuaternion() const;
void Scale(const glm::vec3& factor); void SetRotation(const glm::vec3& axis, float angle);
void SetRotation(const glm::vec3& eulerAngles);
void Rotate(const glm::vec3& axis, float angle);
private: const glm::vec3& GetScale() const;
void CalculateTransformationMatrix(); void SetScale(const glm::vec3& scale);
void Scale(const glm::vec3& factor);
protected: private:
glm::mat4 transformation; void CalculateTransformationMatrix();
glm::vec3 position, scale; protected:
glm::quat orientation; glm::mat4 transformation;
};
glm::vec3 position, scale;
glm::quat orientation;
};
}

View file

@ -3,56 +3,61 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
// struct representing an OpenGL attribute pointer namespace lol
struct VertexAttribute
{ {
int size;
unsigned int type;
bool normalized;
unsigned int stride;
const void* pointer;
};
// Useful abbreviations // struct representing an OpenGL attribute pointer
typedef std::vector<float> VertexArray; struct VertexAttribute
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); 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);
}
};
}

View file

@ -1,13 +1,18 @@
#include <lol/Drawable.hpp> #include <lol/Drawable.hpp>
void Drawable::Draw(const CameraBase& camera) const namespace lol
{ {
shader->Use();
PreRender(camera);
vao->Render(static_cast<unsigned int>(type));
}
void Drawable::SetPrimitiveType(PrimitiveType type) void Drawable::Draw(const CameraBase& camera) const
{ {
this->type = type; shader->Use();
} PreRender(camera);
vao->Render(static_cast<unsigned int>(type));
}
void Drawable::SetPrimitiveType(PrimitiveType type)
{
this->type = type;
}
}

View file

@ -8,90 +8,95 @@
#define IMPLEMENT_UNIFORM_FUNCTION(type, func) \ #define IMPLEMENT_UNIFORM_FUNCTION(type, func) \
inline inline
AbstractShader::AbstractShader(const std::string& vertexShader, const std::string& fragmentShader) : namespace lol
id(0)
{ {
GLint success;
GLchar infoLog[512];
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); AbstractShader::AbstractShader(const std::string& vertexShader, const std::string& fragmentShader) :
const char* vertexShaderSource = vertexShader.c_str(); id(0)
glShaderSource(vertexShaderID, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShaderID);
glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &success);
if (!success)
{ {
glGetShaderInfoLog(vertexShaderID, 512, NULL, infoLog); GLint success;
std::cerr << "Vertex shader creation failed: \n" << infoLog << std::endl; GLchar infoLog[512];
glDeleteShader(vertexShaderID); GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
return; const char* vertexShaderSource = vertexShader.c_str();
} glShaderSource(vertexShaderID, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShaderID);
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &success);
const char* fragmentShaderSource = fragmentShader.c_str(); if (!success)
glShaderSource(fragmentShaderID, 1, &fragmentShaderSource, NULL); {
glCompileShader(fragmentShaderID); glGetShaderInfoLog(vertexShaderID, 512, NULL, infoLog);
std::cerr << "Vertex shader creation failed: \n" << infoLog << std::endl;
glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &success); glDeleteShader(vertexShaderID);
if (!success) return;
{ }
glGetShaderInfoLog(fragmentShaderID, 512, NULL, infoLog);
std::cerr << "Fragment shader creation failed: \n" << infoLog << std::endl; 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(fragmentShaderID);
glDeleteShader(vertexShaderID); glDeleteShader(vertexShaderID);
return;
} }
id = glCreateProgram(); AbstractShader::~AbstractShader()
glAttachShader(id, vertexShaderID);
glAttachShader(id, fragmentShaderID);
glLinkProgram(id);
glGetProgramiv(id, GL_LINK_STATUS, &success);
if (!success)
{ {
glGetProgramInfoLog(fragmentShaderID, 512, NULL, infoLog); glDeleteProgram(id);
std::cerr << "Shader program linking failed: \n" << infoLog << std::endl;
glDeleteShader(fragmentShaderID);
glDeleteShader(vertexShaderID);
id = 0;
return;
} }
glDeleteShader(fragmentShaderID); void AbstractShader::Use()
glDeleteShader(vertexShaderID); {
} glUseProgram(id);
}
AbstractShader::~AbstractShader() void AbstractShader::SetUniform(const std::string& name, const glm::mat4& value)
{ {
glDeleteProgram(id); GLint location = glGetUniformLocation(id, name.c_str());
} if (location == -1)
return;
void AbstractShader::Use() glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(value));
{ }
glUseProgram(id);
}
void AbstractShader::SetUniform(const std::string& name, const glm::mat4& value) void AbstractShader::SetUniform(const std::string& name, const glm::vec4& value)
{ {
GLint location = glGetUniformLocation(id, name.c_str()); GLint location = glGetUniformLocation(id, name.c_str());
if (location == -1) if (location == -1)
return; return;
glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(value)); glUniform4fv(location, 1, 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));
} }

View file

@ -1,82 +1,87 @@
#include <lol/Transformable.hpp> #include <lol/Transformable.hpp>
Transformable::Transformable() : namespace lol
position(0.0f), scale(1.0f), orientation(glm::vec3(0.0, 0.0, 0.0))
{ {
CalculateTransformationMatrix();
}
const glm::vec3& Transformable::GetPosition() const Transformable::Transformable() :
{ position(0.0f), scale(1.0f), orientation(glm::vec3(0.0, 0.0, 0.0))
return position; {
} CalculateTransformationMatrix();
}
void Transformable::SetPosition(const glm::vec3& pos) const glm::vec3& Transformable::GetPosition() const
{ {
position = pos; return position;
CalculateTransformationMatrix(); }
}
void Transformable::Move(const glm::vec3& direction) void Transformable::SetPosition(const glm::vec3& pos)
{ {
position += direction; position = pos;
CalculateTransformationMatrix(); CalculateTransformationMatrix();
} }
const glm::vec3 Transformable::GetRotation() const void Transformable::Move(const glm::vec3& direction)
{ {
return glm::eulerAngles(orientation); position += direction;
} CalculateTransformationMatrix();
}
const glm::quat& Transformable::GetQuaternion() const const glm::vec3 Transformable::GetRotation() const
{ {
return orientation; return glm::eulerAngles(orientation);
} }
void Transformable::SetRotation(const glm::vec3& axis, float angle) const glm::quat& Transformable::GetQuaternion() const
{ {
orientation = glm::quat(glm::radians(angle), axis); return orientation;
CalculateTransformationMatrix(); }
}
void Transformable::SetRotation(const glm::vec3& eulerAngles) void Transformable::SetRotation(const glm::vec3& axis, float angle)
{ {
/*orientation = glm::quat(0.0f, 0.0f, 0.0f, 1.0f); orientation = glm::quat(glm::radians(angle), axis);
orientation = glm::rotate(orientation, eulerAngles.x, glm::vec3(1.0f, 0.0f, 0.0f)); CalculateTransformationMatrix();
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); void Transformable::SetRotation(const glm::vec3& eulerAngles)
CalculateTransformationMatrix(); {
} /*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));*/
void Transformable::Rotate(const glm::vec3& axis, float angle) orientation = glm::quat(eulerAngles);
{ CalculateTransformationMatrix();
orientation = glm::rotate(orientation, glm::radians(angle), axis); }
CalculateTransformationMatrix();
}
const glm::vec3& Transformable::GetScale() const void Transformable::Rotate(const glm::vec3& axis, float angle)
{ {
return scale; orientation = glm::rotate(orientation, glm::radians(angle), axis);
} CalculateTransformationMatrix();
}
void Transformable::SetScale(const glm::vec3& scale) const glm::vec3& Transformable::GetScale() const
{ {
this->scale = scale; return scale;
CalculateTransformationMatrix(); }
}
void Transformable::Scale(const glm::vec3& factor) void Transformable::SetScale(const glm::vec3& scale)
{ {
this->scale *= scale; // I pray this is component-wise multiplication this->scale = scale;
CalculateTransformationMatrix(); 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);
}
void Transformable::CalculateTransformationMatrix()
{
transformation = glm::mat4(1.0f);
transformation = glm::translate(transformation, position);
transformation *= glm::mat4(orientation);
transformation = glm::scale(transformation, scale);
} }

View file

@ -3,58 +3,63 @@
#include <assert.h> #include <assert.h>
#include <glad/glad.h> #include <glad/glad.h>
AbstractVertexArrayObject::~AbstractVertexArrayObject() namespace lol
{ {
glDeleteBuffers(1, &ebo);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
}
void AbstractVertexArrayObject::Render(GLenum mode) AbstractVertexArrayObject::~AbstractVertexArrayObject()
{
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; glDeleteBuffers(1, &ebo);
case Usage::Dynamic: bufferUsage = GL_DYNAMIC_DRAW; break; glDeleteBuffers(1, &vbo);
case Usage::Stream: bufferUsage = GL_STREAM_DRAW; break; glDeleteVertexArrays(1, &vao);
default: // Forgot to add a usage case to this switch
assert("Unknown buffer usage" == "");
break;
} }
// Create VBO void AbstractVertexArrayObject::Render(GLenum mode)
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); assert(vao != 0);
glEnableVertexAttribArray(index);
index++; 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++;
}
}
}