added namespace
This commit is contained in:
parent
8c789f57cb
commit
de7cbdabbd
|
@ -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;
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
139
src/Shader.cpp
139
src/Shader.cpp
|
@ -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));
|
|
||||||
}
|
}
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue