diff --git a/Engine/src/Engine/Graphics/VertexLayout.cpp b/Engine/src/Engine/Graphics/VertexLayout.cpp new file mode 100644 index 0000000..3ee2898 --- /dev/null +++ b/Engine/src/Engine/Graphics/VertexLayout.cpp @@ -0,0 +1,23 @@ +#include "ltpch.h" +#include "VertexLayout.h" +#include "OpenGL/glVertexLayout.h" + +#include "GraphicsContext.h" +#include "Buffers.h" + +namespace Light { + + VertexLayout* VertexLayout::Create(VertexBuffer* buffer, const std::vector elements) + { + switch (GraphicsContext::GetGraphicsAPI()) + { + case GraphicsAPI::OpenGL: + return new glVertexLayout(buffer, elements); + + default: + LT_ENGINE_ASSERT(false, "VertexLayout::Create: invalid/unsupported GraphicsAPI {}", GraphicsContext::GetGraphicsAPI()); + return nullptr; + } + } + +} \ No newline at end of file diff --git a/Engine/src/Engine/Graphics/VertexLayout.h b/Engine/src/Engine/Graphics/VertexLayout.h new file mode 100644 index 0000000..729bb68 --- /dev/null +++ b/Engine/src/Engine/Graphics/VertexLayout.h @@ -0,0 +1,31 @@ +#pragma once + +#include "Base.h" + +#include + +namespace Light { + + class VertexBuffer; + + enum class VertexElementType + { + Int1, Int2, Int3, Int4, + UInt1, UInt2, UInt3, UInt4, + Float1, Float2, Float3, Float4, + Double1, Double2, Double3, Double4 + }; + + class VertexLayout + { + public: + static VertexLayout* Create(VertexBuffer* buffer, const std::vector elements); + + virtual void Bind() = 0; + virtual void UnBind() = 0; + + protected: + VertexLayout() = default; + }; + +} \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glVertexLayout.cpp b/Engine/src/Platform/GraphicsAPI/OpenGL/glVertexLayout.cpp new file mode 100644 index 0000000..34015f6 --- /dev/null +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glVertexLayout.cpp @@ -0,0 +1,83 @@ +#include "ltpch.h" +#include "glVertexLayout.h" + +#include "glBuffers.h" + +#include + +namespace Light { + + glVertexLayout::glVertexLayout(VertexBuffer* buffer, std::vector elements) + { + // sanity check + LT_ENGINE_ASSERT(dynamic_cast(buffer), "glVertexLayout::glVertexLayout: failed to cast VertexBuffer to glVertexBuffer"); + + // elements desc + std::vector elementsDesc(elements.size()); + + unsigned int stride = 0u; + for(const auto& element : elements) + { + elementsDesc.push_back(GetElementDesc(element, stride)); + stride += elementsDesc.back().typeSize * elementsDesc.back().count; + } + + // bind + glCreateVertexArrays(1, &m_ArrayID); + buffer->Bind(); + Bind(); + + // vertex attributes + unsigned int index = 0u; + for (const auto& elementDesc : elementsDesc) + { + glVertexAttribPointer(index, elementDesc.count, elementDesc.type, GL_FALSE, stride, (const void*)elementDesc.offset); + glEnableVertexAttribArray(index++); + } + } + + glVertexLayout::~glVertexLayout() + { + glDeleteVertexArrays(1, &m_ArrayID); + } + + void glVertexLayout::Bind() + { + glBindVertexArray(m_ArrayID); + } + + void glVertexLayout::UnBind() + { + glBindVertexArray(NULL); + } + + glVertexElementDesc glVertexLayout::GetElementDesc(VertexElementType type, unsigned int offset) + { + switch (type) + { + case VertexElementType::Int1: return { GL_INT, 1, sizeof(int), offset }; + case VertexElementType::Int2: return { GL_INT, 2, sizeof(int), offset }; + case VertexElementType::Int3: return { GL_INT, 3, sizeof(int), offset }; + case VertexElementType::Int4: return { GL_INT, 4, sizeof(int), offset }; + + case VertexElementType::UInt1: return { GL_UNSIGNED_INT, 1, sizeof(unsigned int), offset }; + case VertexElementType::UInt2: return { GL_UNSIGNED_INT, 2, sizeof(unsigned int), offset }; + case VertexElementType::UInt3: return { GL_UNSIGNED_INT, 3, sizeof(unsigned int), offset }; + case VertexElementType::UInt4: return { GL_UNSIGNED_INT, 4, sizeof(unsigned int), offset }; + + case VertexElementType::Float1: return { GL_FLOAT, 1, sizeof(float), offset }; + case VertexElementType::Float2: return { GL_FLOAT, 2, sizeof(float), offset }; + case VertexElementType::Float3: return { GL_FLOAT, 3, sizeof(float), offset }; + case VertexElementType::Float4: return { GL_FLOAT, 4, sizeof(float), offset }; + + case VertexElementType::Double1: return { GL_DOUBLE, 1, sizeof(float), offset }; + case VertexElementType::Double2: return { GL_DOUBLE, 2, sizeof(float), offset }; + case VertexElementType::Double3: return { GL_DOUBLE, 3, sizeof(float), offset }; + case VertexElementType::Double4: return { GL_DOUBLE, 4, sizeof(float), offset }; + default: + LT_ENGINE_ASSERT(false, "glVertexLayout::GetElementDesc: invalid vertex element type"); + return {}; + } + } + +} \ No newline at end of file diff --git a/Engine/src/Platform/GraphicsAPI/OpenGL/glVertexLayout.h b/Engine/src/Platform/GraphicsAPI/OpenGL/glVertexLayout.h new file mode 100644 index 0000000..fe44432 --- /dev/null +++ b/Engine/src/Platform/GraphicsAPI/OpenGL/glVertexLayout.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Base.h" +#include "Graphics/VertexLayout.h" + +namespace Light { + + struct glVertexElementDesc + { + unsigned int type; + unsigned int count; + unsigned int typeSize; + unsigned int offset; + }; + + class glVertexLayout : public VertexLayout + { + private: + unsigned int m_ArrayID; + + public: + glVertexLayout(VertexBuffer* buffer, std::vector elements); + ~glVertexLayout(); + + void Bind() override; + void UnBind() override; + + private: + glVertexElementDesc GetElementDesc(VertexElementType type, unsigned int offset); + }; + +} \ No newline at end of file