diff --git a/CMakeLists.txt b/CMakeLists.txt index fdead73..12272b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ add_library(lol STATIC "src/Shader.cpp" "src/VertexArrayObject.cpp" "vendor/glad/src/glad.c" - "include/lol/Texture.hpp" "src/Texture.cpp" ) + "include/lol/Texture.hpp" "src/Texture.cpp" "include/lol/util/Enums.hpp" "include/lol/Buffer.hpp" "src/Buffer.cpp" "include/lol/buffers/VertexBuffer.hpp" "src/buffers/VertexBuffer.cpp" "include/lol/buffers/ElementBuffer.hpp" "src/buffers/ElementBuffer.cpp") target_include_directories(lol PUBLIC ${GLM_INCLUDE_DIRS} diff --git a/include/lol/Buffer.hpp b/include/lol/Buffer.hpp new file mode 100644 index 0000000..9bf0f2b --- /dev/null +++ b/include/lol/Buffer.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include +#include + +#include +#include + +namespace lol +{ + /** + * @brief Represents a generic buffer object. The buffer is destroyed together with the object + */ + class Buffer : public NonCopyable + { + public: + void* Map(Access access); + void Unmap(); + + void Bind(); + void Unbind(); + + protected: + Buffer(BufferType target); + virtual ~Buffer(); + + protected: + unsigned int id; + BufferType type; + }; + +} \ No newline at end of file diff --git a/include/lol/Drawable.hpp b/include/lol/Drawable.hpp index d9d5846..9b9ea33 100644 --- a/include/lol/Drawable.hpp +++ b/include/lol/Drawable.hpp @@ -10,23 +10,14 @@ namespace lol 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 - }; - /** * A class that can be displayed on a screen. */ class Drawable { public: + virtual ~Drawable() {} + /** * @brief Called immediately after the shader is bound, and before the VAO is drawn. * @@ -44,16 +35,16 @@ namespace lol /** * @brief The VAO can be rendered as a mesh, a set of lines, loops, strips etc */ - void SetPrimitiveType(PrimitiveType type); + void SetDrawMode(DrawMode type); protected: Drawable() {} protected: - VertexArrayObject vao; - Shader shader; + std::shared_ptr vao; + std::shared_ptr shader; - PrimitiveType type = PrimitiveType::Triangles; + DrawMode type = DrawMode::Triangles; }; } \ No newline at end of file diff --git a/include/lol/Shader.hpp b/include/lol/Shader.hpp index 8428083..04e06f5 100644 --- a/include/lol/Shader.hpp +++ b/include/lol/Shader.hpp @@ -11,13 +11,10 @@ namespace lol { - class UniqueShader; - typedef std::shared_ptr Shader; - /** * Compiles shaders into a program and manages access to that program */ - class UniqueShader : public NonCopyable + class Shader : public NonCopyable { public: /** @@ -26,21 +23,8 @@ namespace lol * @param vertexShader Source code of the vertex shader * @param fragmentShader Source code of the fragment shader */ - UniqueShader(const std::string& vertexShader, const std::string& fragmentShader); - ~UniqueShader(); - - /** - * @brief Creates a shareable UniqueShader. Note that they're SHAREable, not COPYable - * - * @param vertexShader Source code of the vertex shader - * @param fragmentShader Source code of the fragment shader - * - * @returns Shared pointer to a UniqueShader - */ - inline static Shader Share(const std::string& vertexShader, const std::string& fragmentShader) - { - return std::make_shared(vertexShader, fragmentShader); - } + Shader(const std::string& vertexShader, const std::string& fragmentShader); + ~Shader(); /** * @brief Status of the program creation @@ -52,7 +36,8 @@ namespace lol /** * @brief Bind this shader program */ - void Use(); + void Bind(); + void Unbind(); /** * Set a 4x4 matrix uniform @@ -72,8 +57,6 @@ namespace lol private: unsigned int id; - - bool recording = false; }; typedef ObjectManager ShaderManager; diff --git a/include/lol/Texture.hpp b/include/lol/Texture.hpp index bf7e350..1219c18 100644 --- a/include/lol/Texture.hpp +++ b/include/lol/Texture.hpp @@ -5,6 +5,8 @@ namespace lol { + + class UniqueTexture; typedef std::shared_ptr Texture; @@ -12,6 +14,7 @@ namespace lol { public: UniqueTexture(); + ~UniqueTexture(); inline static Texture Share() { diff --git a/include/lol/Transformable.hpp b/include/lol/Transformable.hpp index 21a482c..158c87c 100644 --- a/include/lol/Transformable.hpp +++ b/include/lol/Transformable.hpp @@ -17,6 +17,8 @@ namespace lol */ Transformable(); + virtual ~Transformable() {} + /** * @brief Get position of the object * diff --git a/include/lol/VertexArrayObject.hpp b/include/lol/VertexArrayObject.hpp index 8d1e10e..1a99230 100644 --- a/include/lol/VertexArrayObject.hpp +++ b/include/lol/VertexArrayObject.hpp @@ -3,88 +3,40 @@ #include #include -#include +#include +#include #include namespace lol { - - /** - * 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 VertexArray; - typedef std::vector IndexArray; - typedef std::vector 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 - }; - - class UniqueVertexArrayObject; - // 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 VertexArrayObject; - /** * VAO structure that sets up the buffers and deletes them at the end of the lifecycle */ - class UniqueVertexArrayObject : public NonCopyable + class VertexArray : public NonCopyable { public: /** * @brief Creates new VAO from a set of vertices and indices and a layout/usage description - * - * @param vertices The vertices to go into the array buffer - * @param indices The indices to go into the element array buffer - * @param layout The layout of the VAO - * @param usage Usage of the VAO (static, dynamic, stream) */ - UniqueVertexArrayObject(const VertexArray& vertices, const IndexArray& indices, const Layout& layout, Usage usage = Usage::Static); - ~UniqueVertexArrayObject(); + VertexArray(); + VertexArray(const std::shared_ptr& vertexBuffer, const std::shared_ptr& elementBuffer); + virtual ~VertexArray(); - /** - * @brief Creates a shareable UniqueVertexArrayObject. Note that they're SHAREable, not COPYable - * - * @param vertices The vertices to go into the array buffer - * @param indices The indices to go into the element array buffer - * @param layout The layout of the VAO - * @param usage Usage of the VAO (static, dynamic, stream) - * - * @returns Shared pointer to a UniqueVertexArrayObject - */ - inline static VertexArrayObject Share(const VertexArray& vertices, const IndexArray& indices, const Layout& layout, Usage usage = Usage::Static) - { - return std::make_shared(vertices, indices, layout, usage); - } + void SetElementBuffer(const std::shared_ptr& buffer); + void SetVertexBuffer(const std::shared_ptr& buffer); - /** - * @brief Render the VAO - * - * @param mode The render mode (lines, triangles, ...) - */ - void Render(unsigned int mode = 4); + void Bind(); + void Unbind(); + + inline size_t GetIndexCount() { return elementBuffer->GetCount(); } private: - unsigned int vao, vbo, ebo; - size_t indexCount; + unsigned int id; + std::shared_ptr vertexBuffer; + std::shared_ptr elementBuffer; }; // Object manager for managing said shared pointers - typedef ObjectManager VAOManager; + typedef ObjectManager VAOManager; } \ No newline at end of file diff --git a/include/lol/buffers/ElementBuffer.hpp b/include/lol/buffers/ElementBuffer.hpp new file mode 100644 index 0000000..8e9a756 --- /dev/null +++ b/include/lol/buffers/ElementBuffer.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include + +namespace lol +{ + class ElementBuffer : public Buffer + { + public: + ElementBuffer(size_t count, unsigned int* elements, Usage usage = Usage::StaticDraw); + + inline size_t GetCount() const { return count; } + + private: + size_t count; + }; +} \ No newline at end of file diff --git a/include/lol/buffers/VertexBuffer.hpp b/include/lol/buffers/VertexBuffer.hpp new file mode 100644 index 0000000..fb8193f --- /dev/null +++ b/include/lol/buffers/VertexBuffer.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include + +namespace lol +{ + struct VertexAttribute + { + int size; + Type type; + bool normalized; + int offset; + + VertexAttribute(Type type, unsigned int count, bool normalized) : + type(type), size(count), normalized(normalized), offset(0) + { } + }; + + class BufferLayout + { + public: + BufferLayout(const std::initializer_list& attributes); + + inline const std::vector& GetLayout() const { return layout; } + inline int GetStride() const { return stride; } + + std::vector::const_iterator begin() const { return layout.begin(); } + std::vector::const_iterator end() const { return layout.end(); } + + private: + std::vector layout; + int stride; + }; + + class VertexBuffer : public Buffer + { + public: + VertexBuffer(size_t size, float* data, Usage usage = Usage::StaticDraw); + + inline void SetLayout(const BufferLayout& layout) { this->layout = layout; }; + inline const BufferLayout& GetLayout() { return layout; } + + private: + BufferLayout layout; + }; +} \ No newline at end of file diff --git a/include/lol/util/Enums.hpp b/include/lol/util/Enums.hpp new file mode 100644 index 0000000..ccc51ee --- /dev/null +++ b/include/lol/util/Enums.hpp @@ -0,0 +1,181 @@ +#pragma once + +#include +#include + +#define NATIVE(x) static_cast(x) + +namespace lol +{ + + /** + * @brief OpenGL datatypes + */ + enum class Type : GLenum + { + Byte = GL_BYTE, + UByte = GL_UNSIGNED_BYTE, + Short = GL_UNSIGNED_SHORT, + Int = GL_INT, + UInt = GL_UNSIGNED_INT, + Half = GL_HALF_FLOAT, + Float = GL_FLOAT, + Double = GL_DOUBLE, + Fixed = GL_FIXED + }; + + /** + * @brief Get size of OpenGL datatype in Bytes + */ + constexpr size_t SizeOf(Type type) + { + switch (type) + { + case Type::Byte: return sizeof(GLbyte); + case Type::UByte: return sizeof(GLubyte); + case Type::Short: return sizeof(GLshort); + case Type::Int: return sizeof(GLint); + case Type::UInt: return sizeof(GLuint); + case Type::Half: return sizeof(GLhalf); + case Type::Float: return sizeof(GLfloat); + case Type::Double: return sizeof(GLdouble); + case Type::Fixed: return sizeof(GLfixed); + + default: + assert(false && "lol::SizeOf did not implement every datatype"); + return 0; + } + } + + /** + * @brief Datatypes in GLSL + */ + enum class GLSLType : GLenum + { + Float = GL_FLOAT, Float2 = GL_FLOAT_VEC2, Float3 = GL_FLOAT_VEC3, Float4 = GL_FLOAT_VEC4, + Double = GL_DOUBLE, Double2 = GL_DOUBLE_VEC2, Double3 = GL_DOUBLE_VEC3, Double4 = GL_DOUBLE_VEC4, + Int = GL_INT, Int2 = GL_INT_VEC2, Int3 = GL_INT_VEC3, Int4 = GL_INT_VEC4, + UInt = GL_UNSIGNED_INT, UInt2 = GL_UNSIGNED_INT_VEC2, UInt3 = GL_UNSIGNED_INT_VEC3, UInt4 = GL_UNSIGNED_INT_VEC4, + Bool = GL_BOOL, Bool2 = GL_BOOL_VEC2, Bool3 = GL_BOOL_VEC3, Bool4 = GL_BOOL_VEC4, + + Mat2 = GL_FLOAT_MAT2, Mat3 = GL_FLOAT_MAT3, Mat4 = GL_FLOAT_MAT4, + Mat2x3 = GL_FLOAT_MAT2x3, Mat2x4 = GL_FLOAT_MAT2x4, Mat3x2 = GL_FLOAT_MAT3x2, + Mat3x4 = GL_FLOAT_MAT3x4, Mat4x2 = GL_FLOAT_MAT4x2, Mat4x3 = GL_FLOAT_MAT4x3, + + DMat2 = GL_DOUBLE_MAT2, DMat3 = GL_DOUBLE_MAT3, DMat4 = GL_DOUBLE_MAT4, + DMat2x3 = GL_DOUBLE_MAT2x3, DMat2x4 = GL_DOUBLE_MAT2x4, DMat3x2 = GL_DOUBLE_MAT3x2, + DMat3x4 = GL_DOUBLE_MAT3x4, DMat4x2 = GL_DOUBLE_MAT4x2, DMat4x3 = GL_DOUBLE_MAT4x3, + + Sampler1D = GL_SAMPLER_1D, Sampler2D = GL_SAMPLER_2D, + Sampler3D = GL_SAMPLER_3D, SamplerCube = GL_SAMPLER_CUBE, + Sampler1DShadow = GL_SAMPLER_1D_SHADOW, Sampler2DShadow = GL_SAMPLER_2D_SHADOW, + Sampler1DArray = GL_SAMPLER_1D_ARRAY, Sampler2DArray = GL_SAMPLER_2D_ARRAY, + Sampler1DArrayShadow = GL_SAMPLER_1D_ARRAY_SHADOW, Sampler2DArrayShadow = GL_SAMPLER_2D_ARRAY_SHADOW, + Sampler2DMS = GL_SAMPLER_2D_MULTISAMPLE, Sampler2DMSArray = GL_SAMPLER_2D_MULTISAMPLE_ARRAY, + SamplerCubeShadow = GL_SAMPLER_CUBE_SHADOW, SamplerBuffer = GL_SAMPLER_BUFFER, + Sampler2DRect = GL_SAMPLER_2D_RECT, Sampler2DRectShadow = GL_SAMPLER_2D_RECT_SHADOW, + + ISampler1D = GL_INT_SAMPLER_1D, ISampler2D = GL_INT_SAMPLER_2D, + ISampler3D = GL_INT_SAMPLER_3D, ISamplerCube = GL_INT_SAMPLER_CUBE, + ISampler1DArray = GL_INT_SAMPLER_1D_ARRAY, ISampler2DArray = GL_INT_SAMPLER_2D_ARRAY, + ISampler2DMS = GL_INT_SAMPLER_2D_MULTISAMPLE, ISampler2DMSArray = GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, + ISamplerBuffer = GL_INT_SAMPLER_BUFFER, ISampler2DRect = GL_INT_SAMPLER_2D_RECT, + + USampler1D = GL_UNSIGNED_INT_SAMPLER_1D, USampler2D = GL_UNSIGNED_INT_SAMPLER_2D, + USampler3D = GL_UNSIGNED_INT_SAMPLER_3D, USamplerCube = GL_UNSIGNED_INT_SAMPLER_CUBE, + USampler1DArray = GL_UNSIGNED_INT_SAMPLER_1D_ARRAY, USampler2DArray = GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, + USampler2DMS = GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, USampler2DMSArray = GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, + USamplerBuffer = GL_UNSIGNED_INT_SAMPLER_BUFFER, USampler2DRect = GL_UNSIGNED_INT_SAMPLER_2D_RECT, + + Image1D = GL_IMAGE_1D, Image2D = GL_IMAGE_2D, + Image3D = GL_IMAGE_3D, Image2DRect = GL_IMAGE_2D_RECT, + ImageCube = GL_IMAGE_CUBE, ImageBuffer = GL_IMAGE_BUFFER, + Image1DArray = GL_IMAGE_1D_ARRAY, Image2DArray = GL_IMAGE_2D_ARRAY, + Image2DMS = GL_IMAGE_2D_MULTISAMPLE, Image2DMSArray = GL_IMAGE_2D_MULTISAMPLE_ARRAY, + + IImage1D = GL_INT_IMAGE_1D, IImage2D = GL_INT_IMAGE_2D, + IImage3D = GL_INT_IMAGE_3D, IImage2DRect = GL_INT_IMAGE_2D_RECT, + IImageCube = GL_INT_IMAGE_CUBE, IImageBuffer = GL_INT_IMAGE_BUFFER, + IImage1DArray = GL_INT_IMAGE_1D_ARRAY, IImage2DArray = GL_INT_IMAGE_2D_ARRAY, + IImage2DMS = GL_INT_IMAGE_2D_MULTISAMPLE, IImage2DMSArray = GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY, + + UImage1D = GL_UNSIGNED_INT_IMAGE_1D, UImage2D = GL_UNSIGNED_INT_IMAGE_2D, + UImage3D = GL_UNSIGNED_INT_IMAGE_3D, UImage2DRect = GL_UNSIGNED_INT_IMAGE_2D_RECT, + UImageCube = GL_UNSIGNED_INT_IMAGE_CUBE, UImageBuffer = GL_UNSIGNED_INT_IMAGE_BUFFER, + UImage1DArray = GL_UNSIGNED_INT_IMAGE_1D_ARRAY, UImage2DArray = GL_UNSIGNED_INT_IMAGE_2D_ARRAY, + UImage2DMS = GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE, UImage2DMSArray = GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY, + + AtomicUnit = GL_UNSIGNED_INT_ATOMIC_COUNTER + }; + + /** + * @brief OpenGL buffer binding targets + */ + enum class BufferType : GLenum + { + Array = GL_ARRAY_BUFFER, + AtomicCounter = GL_ATOMIC_COUNTER_BUFFER, + CopyRead = GL_COPY_READ_BUFFER, + CopyWrite = GL_COPY_WRITE_BUFFER, + DispatchIndirect = GL_DISPATCH_INDIRECT_BUFFER, + DrawIndirect = GL_DRAW_INDIRECT_BUFFER, + ElementArray = GL_ELEMENT_ARRAY_BUFFER, + PixelPack = GL_PIXEL_PACK_BUFFER, + PixelUnpack = GL_PIXEL_UNPACK_BUFFER, + Query = GL_QUERY_BUFFER, + ShaderStorage = GL_SHADER_STORAGE_BUFFER, + Texture = GL_TEXTURE_BUFFER, + TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER, + Uniform = GL_UNIFORM_BUFFER + }; + + /** + * @brief OpenGL buffer usage types + */ + enum class Usage : GLenum + { + StaticDraw = GL_STATIC_DRAW, + StaticRead = GL_STATIC_READ, + StaticCopy = GL_STATIC_COPY, + + StreamDraw = GL_STREAM_DRAW, + StreamRead = GL_STREAM_READ, + StreamCopy = GL_STREAM_COPY, + + DynamicDraw = GL_DYNAMIC_DRAW, + DynamicRead = GL_DYNAMIC_READ, + DynamicCopy = GL_DYNAMIC_COPY + }; + + /** + * @brief OpenGL glDraw* modes. Primitives OpenGL can render + */ + enum class DrawMode : GLenum + { + Points = GL_POINTS, + + Lines = GL_LINES, + LineStrip = GL_LINE_STRIP, + LineLoop = GL_LINE_LOOP, + LineStripAdjacency = GL_LINE_STRIP_ADJACENCY, + LinesAdjacency = GL_LINES_ADJACENCY, + + Triangles = GL_TRIANGLES, + TriangleStrip = GL_TRIANGLE_STRIP, + TriangleFan = GL_TRIANGLE_FAN, + TriangleStripAdjacency = GL_TRIANGLE_STRIP_ADJACENCY, + TrianglesAdjacency = GL_TRIANGLES_ADJACENCY, + + Patches = GL_PATCHES + }; + + /** + * @brief OpenGL buffer access modes + */ + enum class Access : GLenum + { + ReadOnly = GL_READ_ONLY, + WriteOnly = GL_WRITE_ONLY, + ReadWrite = GL_READ_WRITE + }; +} \ No newline at end of file diff --git a/include/lol/util/ObjectManager.hpp b/include/lol/util/ObjectManager.hpp index fce0867..dfe6fa2 100644 --- a/include/lol/util/ObjectManager.hpp +++ b/include/lol/util/ObjectManager.hpp @@ -30,7 +30,7 @@ namespace lol /** * Add new (existing) object to manager */ - inline void Register(unsigned int id, Type obj) + inline void Register(unsigned int id, const std::shared_ptr& obj) { objects.insert(std::make_pair(id, obj)); } @@ -46,7 +46,7 @@ namespace lol /** * Retrieve object from manager */ - inline Type Get(unsigned int id) + inline std::shared_ptr Get(unsigned int id) { auto it = objects.find(id); @@ -60,7 +60,7 @@ namespace lol ObjectManager() {} private: - std::map objects; + std::map> objects; }; } \ No newline at end of file diff --git a/src/Buffer.cpp b/src/Buffer.cpp new file mode 100644 index 0000000..3de2d78 --- /dev/null +++ b/src/Buffer.cpp @@ -0,0 +1,37 @@ +#include "..\include\lol\Buffer.hpp" +#pragma once + +namespace lol +{ + Buffer::Buffer(BufferType type) : + id(0), type(type) + { + glGenBuffers(1, &id); + glBindBuffer(NATIVE(type), id); + } + + Buffer::~Buffer() + { + glDeleteBuffers(1, &id); + } + + void* Buffer::Map(Access access) + { + return glMapBuffer(NATIVE(type), NATIVE(access)); + } + + void Buffer::Unmap() + { + glUnmapBuffer(NATIVE(type)); + } + + void Buffer::Bind() + { + glBindBuffer(NATIVE(type), id); + } + + void Buffer::Unbind() + { + glBindBuffer(NATIVE(type), 0); + } +} \ No newline at end of file diff --git a/src/Drawable.cpp b/src/Drawable.cpp index 641a74a..e4dc50c 100644 --- a/src/Drawable.cpp +++ b/src/Drawable.cpp @@ -5,12 +5,14 @@ namespace lol void Drawable::Draw(const CameraBase& camera) const { - shader->Use(); + shader->Bind(); + vao->Bind(); PreRender(camera); - vao->Render(static_cast(type)); + + glDrawElements(NATIVE(type), vao->GetIndexCount(), GL_UNSIGNED_INT, nullptr); } - void Drawable::SetPrimitiveType(PrimitiveType type) + void Drawable::SetDrawMode(DrawMode type) { this->type = type; } diff --git a/src/Shader.cpp b/src/Shader.cpp index 74b8a53..4340c84 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -11,7 +11,7 @@ inline namespace lol { - UniqueShader::UniqueShader(const std::string& vertexShader, const std::string& fragmentShader) : + Shader::Shader(const std::string& vertexShader, const std::string& fragmentShader) : id(0) { GLint success; @@ -71,17 +71,22 @@ namespace lol glDeleteShader(vertexShaderID); } - UniqueShader::~UniqueShader() + Shader::~Shader() { glDeleteProgram(id); } - void UniqueShader::Use() + void Shader::Bind() { glUseProgram(id); } - void UniqueShader::SetUniform(const std::string& name, const glm::mat4& value) + void Shader::Unbind() + { + glUseProgram(0); + } + + void Shader::SetUniform(const std::string& name, const glm::mat4& value) { GLint location = glGetUniformLocation(id, name.c_str()); if (location == -1) @@ -90,7 +95,7 @@ namespace lol glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(value)); } - void UniqueShader::SetUniform(const std::string& name, const glm::vec4& value) + void Shader::SetUniform(const std::string& name, const glm::vec4& value) { GLint location = glGetUniformLocation(id, name.c_str()); if (location == -1) diff --git a/src/Texture.cpp b/src/Texture.cpp index 045da3e..acc2541 100644 --- a/src/Texture.cpp +++ b/src/Texture.cpp @@ -7,6 +7,14 @@ namespace lol UniqueTexture::UniqueTexture() : textureID(0) { - + glGenTextures(1, &textureID); + + glBindTexture(GL_TEXTURE_2D, textureID); + // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_UNSIGNED_BYTE, data); + } + + UniqueTexture::~UniqueTexture() + { + glDeleteTextures(1, &textureID); } } \ No newline at end of file diff --git a/src/VertexArrayObject.cpp b/src/VertexArrayObject.cpp index d2b8ed9..2bc2a7b 100644 --- a/src/VertexArrayObject.cpp +++ b/src/VertexArrayObject.cpp @@ -6,59 +6,58 @@ namespace lol { - UniqueVertexArrayObject::~UniqueVertexArrayObject() + VertexArray::VertexArray() { - glDeleteBuffers(1, &ebo); - glDeleteBuffers(1, &vbo); - glDeleteVertexArrays(1, &vao); + glGenVertexArrays(1, &id); } - void UniqueVertexArrayObject::Render(GLenum mode) + VertexArray::VertexArray(const std::shared_ptr& vertexBuffer, const std::shared_ptr& elementBuffer) : + id(0) { - assert(vao != 0); + glGenVertexArrays(1, &id); - glBindVertexArray(vao); - // GLenum result = glGetError(); - glDrawElements(mode, indexCount, GL_UNSIGNED_INT, 0); + SetVertexBuffer(vertexBuffer); + SetElementBuffer(elementBuffer); + } + VertexArray::~VertexArray() + { + glDeleteVertexArrays(1, &id); } - UniqueVertexArrayObject::UniqueVertexArrayObject(const VertexArray& vertices, const IndexArray& indices, const Layout& layout, Usage usage) : - vao(0), vbo(0), ebo(0), indexCount(indices.size()) + void VertexArray::SetVertexBuffer(const std::shared_ptr& buffer) { - 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); + glBindVertexArray(id); + buffer->Bind(); // Set up pipeline layout unsigned int index = 0; + const BufferLayout& layout = buffer->GetLayout(); for (const VertexAttribute& attribute : layout) { - glVertexAttribPointer(index, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.pointer); glEnableVertexAttribArray(index); + glVertexAttribPointer(index, attribute.size, NATIVE(attribute.type), attribute.normalized, layout.GetStride(), (void*)(attribute.offset)); index++; } + + vertexBuffer = buffer; + } + + void VertexArray::SetElementBuffer(const std::shared_ptr& buffer) + { + glBindVertexArray(id); + buffer->Bind(); + + elementBuffer = buffer; + } + + void VertexArray::Bind() + { + glBindVertexArray(id); + } + + void Unbind() + { + glBindVertexArray(0); } } \ No newline at end of file diff --git a/src/buffers/ElementBuffer.cpp b/src/buffers/ElementBuffer.cpp new file mode 100644 index 0000000..8fcd81f --- /dev/null +++ b/src/buffers/ElementBuffer.cpp @@ -0,0 +1,10 @@ +#include + +namespace lol +{ + ElementBuffer::ElementBuffer(size_t count, unsigned int* elements, Usage usage) : + Buffer(BufferType::ElementArray), count(count) + { + glBufferData(NATIVE(type), count * sizeof(unsigned int), elements, NATIVE(usage)); + } +} \ No newline at end of file diff --git a/src/buffers/VertexBuffer.cpp b/src/buffers/VertexBuffer.cpp new file mode 100644 index 0000000..dcb8caa --- /dev/null +++ b/src/buffers/VertexBuffer.cpp @@ -0,0 +1,23 @@ +#include +#pragma once + +namespace lol +{ + BufferLayout::BufferLayout(const std::initializer_list& attributes) : + layout(attributes), stride(0) + { + // Calculate stride and offsets of elements + for (VertexAttribute& attribute : layout) + { + attribute.offset += stride; + stride += (attribute.size * SizeOf(attribute.type)); + } + } + + + VertexBuffer::VertexBuffer(size_t size, float* data, Usage usage) : + Buffer(BufferType::Array), layout{} + { + glBufferData(NATIVE(type), size * sizeof(float), (void*)data, NATIVE(usage)); + } +} \ No newline at end of file