diff --git a/Editor/assets/scenes/PinkSunrise.hsc b/Editor/assets/scenes/PinkSunrise.hsc index fb59c8f..c720bf3 100644 --- a/Editor/assets/scenes/PinkSunrise.hsc +++ b/Editor/assets/scenes/PinkSunrise.hsc @@ -1,6 +1,6 @@ Scene: Scene Name Environment: - AssetPath: assets\env\birchwood_4k.hdr + AssetPath: assets/env/birchwood_4k.hdr Light: Direction: [-0.5, -0.5, 1] Radiance: [1, 1, 1] @@ -20,7 +20,7 @@ Entities: Type: 1 Data: 5 MeshComponent: - AssetPath: assets\meshes\Sphere1m.fbx + AssetPath: assets/meshes/Sphere1m.fbx - Entity: 5178862374589434728 TagComponent: Tag: Camera @@ -63,4 +63,4 @@ Entities: Type: 6 Data: [0, 0, 0] MeshComponent: - AssetPath: assets\meshes\TestScene.fbx \ No newline at end of file + AssetPath: assets/meshes/TestScene.fbx \ No newline at end of file diff --git a/Prism/src/Prism.h b/Prism/src/Prism.h index 5bd99ad..63c5829 100644 --- a/Prism/src/Prism.h +++ b/Prism/src/Prism.h @@ -21,13 +21,14 @@ // ImGui #include "imgui.h" -#include "Prism/Renderer/Buffer.h" #include "Prism/Renderer/Renderer.h" #include "Prism/Renderer/SceneRenderer.h" #include "Prism/Renderer/RenderPass.h" #include "Prism/Renderer/Shader.h" #include "Prism/Renderer/Texture.h" #include "Prism/Renderer/FrameBuffer.h" +#include "Prism//Renderer/VertexBuffer.h" +#include "Prism//Renderer/IndexBuffer.h" #include "Prism/Renderer/Shader.h" #include "Prism/Renderer/Mesh.h" #include "Prism/Renderer/Camera.h" diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLBuffer.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLBuffer.cpp deleted file mode 100644 index 4fea116..0000000 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLBuffer.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// -// Created by sfd on 25-11-22. -// - -#include "OpenGLBuffer.h" - -#include "Prism/Renderer/Renderer.h" - -namespace Prism -{ - - static GLenum OpenGLUsage(VertexBufferUsage usage) - { - switch (usage) - { - case VertexBufferUsage::Static: return GL_STATIC_DRAW; - case VertexBufferUsage::Dynamic: return GL_DYNAMIC_DRAW; - } - PM_CORE_ASSERT(false, "Unknown vertex buffer usage"); - return 0; - } - - // ****************************************** - // Vertex - // ****************************************** - OpenGLVertexBuffer::OpenGLVertexBuffer(void* data, const uint32_t size, const VertexBufferUsage usage) - : m_Size(size), m_Usage(usage) - { - m_LocalData = Buffer::Copy(data, size); - - Ref instance = this; - Renderer::Submit([instance]() mutable { - glCreateBuffers(1, &instance->m_RendererID); - glNamedBufferData(instance->m_RendererID, instance->m_Size, instance->m_LocalData.Data, OpenGLUsage(instance->m_Usage)); - }); - } - - OpenGLVertexBuffer::OpenGLVertexBuffer(const uint32_t size, const VertexBufferUsage usage) - : m_Size(size), m_Usage(usage) - { - Ref instance = this; - Renderer::Submit([instance]() mutable { - glCreateBuffers(1, &instance->m_RendererID); - glNamedBufferData(instance->m_RendererID, instance->m_Size, nullptr, OpenGLUsage(instance->m_Usage)); - }); - } - - - OpenGLVertexBuffer::~OpenGLVertexBuffer() - { - GLuint rendererID = m_RendererID; - Renderer::Submit([rendererID](){ - glDeleteBuffers(1, &rendererID); - }); - } - - void OpenGLVertexBuffer::SetData(void* buffer, uint32_t size, uint32_t offset) - { - m_LocalData = Buffer::Copy(buffer, size); - m_Size = size; - Ref instance = this; - Renderer::Submit([instance, offset]() { - glNamedBufferSubData(instance->m_RendererID, offset, instance->m_Size, instance->m_LocalData.Data); - }); - } - - void OpenGLVertexBuffer::Bind() const - { - Ref instance = this; - Renderer::Submit([instance]() { - glBindBuffer(GL_ARRAY_BUFFER, instance->m_RendererID); - }); - } - - - OpenGLIndexBuffer::OpenGLIndexBuffer(const uint32_t size) - : m_Size(size) - { - Renderer::Submit([this]() - { - glCreateBuffers(1, &m_RendererID); - glNamedBufferData(m_RendererID, m_Size, nullptr, GL_DYNAMIC_DRAW); - }); - } - - // ****************************************** - // IndexBuffer - // ****************************************** - OpenGLIndexBuffer::OpenGLIndexBuffer(void* data, const uint32_t size) - : m_Size(size) - { - m_LocalData = Buffer::Copy(data, size); - - - Ref instance = this; - Renderer::Submit([instance]() mutable { - glCreateBuffers(1, &instance->m_RendererID); - glNamedBufferData(instance->m_RendererID, instance->m_Size, instance->m_LocalData.Data, GL_STATIC_DRAW); - }); - } - - OpenGLIndexBuffer::~OpenGLIndexBuffer() - { - const GLuint rendererID = m_RendererID; - Renderer::Submit([rendererID](){ - glDeleteBuffers(1, &rendererID); - }); - } - - void OpenGLIndexBuffer::SetData(void* data, uint32_t size, uint32_t offset) - { - m_LocalData = Buffer::Copy(data, size); - m_Size = size; - Renderer::Submit([this, offset](){ - glNamedBufferSubData(m_RendererID, offset, m_Size, m_LocalData.Data); - }); - } - - void OpenGLIndexBuffer::Bind() const - { - - Ref instance = this; - Renderer::Submit([instance]() { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, instance->m_RendererID); - }); - } -} diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLBuffer.h b/Prism/src/Prism/Platform/OpenGL/OpenGLBuffer.h deleted file mode 100644 index 939f6c8..0000000 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLBuffer.h +++ /dev/null @@ -1,69 +0,0 @@ -// -// Created by sfd on 25-11-22. -// - -#ifndef OPENGLBUFFER_H -#define OPENGLBUFFER_H - -#include "glad/glad.h" -#include "Prism/Core/Buffer.h" -#include "Prism/Renderer/Buffer.h" - -namespace Prism -{ - - // ****************************************** - // Vertex - // ****************************************** - class OpenGLVertexBuffer : public VertexBuffer - { - public: - OpenGLVertexBuffer(void* data, uint32_t size, VertexBufferUsage usage = VertexBufferUsage::Static); - OpenGLVertexBuffer(uint32_t size, VertexBufferUsage usage = VertexBufferUsage::Dynamic); - virtual ~OpenGLVertexBuffer(); - - void SetData(void* buffer, uint32_t size, uint32_t offset = 0) override; - void Bind() const override; - - virtual const BufferLayout& GetLayout() const override { return m_Layout; } - virtual void SetLayout(const BufferLayout& layout) override { m_Layout = layout; } - - uint32_t GetSize() const override { return m_Size; } - RendererID GetRendererID() const override { return m_RendererID; } - private: - RendererID m_RendererID = 0; - uint32_t m_Size; - - VertexBufferUsage m_Usage; - BufferLayout m_Layout; - - Buffer m_LocalData; - }; - - // ****************************************** - // IndexBuffer - // ****************************************** - - class OpenGLIndexBuffer : public IndexBuffer - { - public: - OpenGLIndexBuffer(uint32_t size); - OpenGLIndexBuffer(void* data, uint32_t size); - virtual ~OpenGLIndexBuffer(); - - virtual void SetData(void* data, uint32_t size, uint32_t offset = 0); - virtual void Bind() const; - - virtual uint32_t GetCount() const { return m_Size / sizeof(uint32_t); } - - virtual uint32_t GetSize() const { return m_Size; } - virtual RendererID GetRendererID() const { return m_RendererID; } - private: - RendererID m_RendererID = 0; - uint32_t m_Size; - Buffer m_LocalData; - }; - -} - -#endif //OPENGLBUFFER_H diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.cpp new file mode 100644 index 0000000..e0a04bd --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.cpp @@ -0,0 +1,62 @@ +// +// Created by sfd on 2025/12/15. +// + +#include "OpenGLIndexBuffer.h" + +#include "glad/glad.h" +#include "Prism/Renderer/Renderer.h" + +namespace Prism { + + OpenGLIndexBuffer::OpenGLIndexBuffer(void* data, uint32_t size) + : m_RendererID(0), m_Size(size) + { + m_LocalData = Buffer::Copy(data, size); + + Ref instance = this; + Renderer::Submit([instance]() mutable { + glCreateBuffers(1, &instance->m_RendererID); + glNamedBufferData(instance->m_RendererID, instance->m_Size, instance->m_LocalData.Data, GL_STATIC_DRAW); + }); + } + + OpenGLIndexBuffer::OpenGLIndexBuffer(uint32_t size) + : m_Size(size) + { + // m_LocalData = Buffer(size); + + Ref instance = this; + Renderer::Submit([instance]() mutable { + glCreateBuffers(1, &instance->m_RendererID); + glNamedBufferData(instance->m_RendererID, instance->m_Size, nullptr, GL_DYNAMIC_DRAW); + }); + } + + OpenGLIndexBuffer::~OpenGLIndexBuffer() + { + GLuint rendererID = m_RendererID; + Renderer::Submit([rendererID]() { + glDeleteBuffers(1, &rendererID); + }); + } + + void OpenGLIndexBuffer::SetData(void* data, uint32_t size, uint32_t offset) + { + m_LocalData = Buffer::Copy(data, size); + m_Size = size; + Ref instance = this; + Renderer::Submit([instance, offset]() { + glNamedBufferSubData(instance->m_RendererID, offset, instance->m_Size, instance->m_LocalData.Data); + }); + } + + void OpenGLIndexBuffer::Bind() const + { + Ref instance = this; + Renderer::Submit([instance]() { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, instance->m_RendererID); + }); + } + +} diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.h b/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.h new file mode 100644 index 0000000..666fac7 --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.h @@ -0,0 +1,35 @@ +// +// Created by sfd on 2025/12/15. +// + +#ifndef PRISM_OPENGLINDEXBUFFER_H +#define PRISM_OPENGLINDEXBUFFER_H +#include "Prism/Core/Buffer.h" +#include "Prism/Renderer/IndexBuffer.h" + +namespace Prism { + class OpenGLIndexBuffer : public IndexBuffer + { + public: + OpenGLIndexBuffer(uint32_t size); + OpenGLIndexBuffer(void* data, uint32_t size); + virtual ~OpenGLIndexBuffer(); + + void SetData(void* data, uint32_t size, uint32_t offset = 0) override; + + void Bind() const override; + + uint32_t GetCount() const override { return m_Size / sizeof(uint32_t); } + + uint32_t GetSize() const override { return m_Size; } + RendererID GetRendererID() const override { return m_RendererID; } + private: + RendererID m_RendererID = 0; + uint32_t m_Size; + + Buffer m_LocalData; + }; +} + + +#endif //PRISM_OPENGLINDEXBUFFER_H \ No newline at end of file diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLPipeline.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLPipeline.cpp new file mode 100644 index 0000000..e41b6f1 --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLPipeline.cpp @@ -0,0 +1,129 @@ +// +// Created by sfd on 2025/12/15. +// + +#include "OpenGLPipeline.h" + +#include "glad/glad.h" +#include "Prism/Renderer/Pipeline.h" +#include "Prism/Renderer/Renderer.h" +#include "Prism/Renderer/VertexBuffer.h" + +namespace Prism { + static GLenum ShaderDataTypeToOpenGLBaseType(ShaderDataType type) + { + switch (type) + { + case ShaderDataType::Float: return GL_FLOAT; + case ShaderDataType::Float2: return GL_FLOAT; + case ShaderDataType::Float3: return GL_FLOAT; + case ShaderDataType::Float4: return GL_FLOAT; + case ShaderDataType::Mat3: return GL_FLOAT; + case ShaderDataType::Mat4: return GL_FLOAT; + case ShaderDataType::Int: return GL_INT; + case ShaderDataType::Int2: return GL_INT; + case ShaderDataType::Int3: return GL_INT; + case ShaderDataType::Int4: return GL_INT; + case ShaderDataType::Bool: return GL_BOOL; + } + + PM_CORE_ASSERT(false, "Unknown ShaderDataType!"); + return 0; + } + + OpenGLPipeline::OpenGLPipeline(const PipelineSpecification& spec) + : m_Specification(spec) + { + OpenGLPipeline::Invalidate(); + } + + OpenGLPipeline::~OpenGLPipeline() + { + GLuint rendererID = m_VertexArrayRendererID; + Renderer::Submit([rendererID]() + { + glDeleteVertexArrays(1, &rendererID); + }); + } + + void OpenGLPipeline::Invalidate() + { + PM_CORE_ASSERT(m_Specification.Layout.GetElements().size(), "Layout is empty!"); + + Ref instance = this; + Renderer::Submit([instance]() mutable + { + auto& vertexArrayRendererID = instance->m_VertexArrayRendererID; + + if (vertexArrayRendererID) + glDeleteVertexArrays(1, &vertexArrayRendererID); + + glGenVertexArrays(1, &vertexArrayRendererID); + glBindVertexArray(vertexArrayRendererID); + +#if 0 + const auto& layout = instance->m_Specification.Layout; + uint32_t attribIndex = 0; + for (const auto& element : layout) + { + auto glBaseType = ShaderDataTypeToOpenGLBaseType(element.Type); + glEnableVertexAttribArray(attribIndex); + if (glBaseType == GL_INT) + { + glVertexAttribIPointer(attribIndex, + element.GetComponentCount(), + glBaseType, + layout.GetStride(), + (const void*)(intptr_t)element.Offset); + } + else + { + glVertexAttribPointer(attribIndex, + element.GetComponentCount(), + glBaseType, + element.Normalized ? GL_TRUE : GL_FALSE, + layout.GetStride(), + (const void*)(intptr_t)element.Offset); + } + attribIndex++; + } +#endif + glBindVertexArray(0); + }); + } + + void OpenGLPipeline::Bind() + { + Ref instance = this; + Renderer::Submit([instance]() + { + glBindVertexArray(instance->m_VertexArrayRendererID); + + const auto& layout = instance->m_Specification.Layout; + uint32_t attribIndex = 0; + for (const auto& element : layout) + { + auto glBaseType = ShaderDataTypeToOpenGLBaseType(element.Type); + glEnableVertexAttribArray(attribIndex); + if (glBaseType == GL_INT) + { + glVertexAttribIPointer(attribIndex, + element.GetComponentCount(), + glBaseType, + layout.GetStride(), + (const void*)(intptr_t)element.Offset); + } + else + { + glVertexAttribPointer(attribIndex, + element.GetComponentCount(), + glBaseType, + element.Normalized ? GL_TRUE : GL_FALSE, + layout.GetStride(), + (const void*)(intptr_t)element.Offset); + } + attribIndex++; + } + }); + } +} diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLPipeline.h b/Prism/src/Prism/Platform/OpenGL/OpenGLPipeline.h new file mode 100644 index 0000000..dacfd75 --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLPipeline.h @@ -0,0 +1,31 @@ +// +// Created by sfd on 2025/12/15. +// + +#ifndef PRISM_OPENGLPIPELINE_H +#define PRISM_OPENGLPIPELINE_H +#include "Prism/Renderer/Pipeline.h" + +namespace Prism { + + class OpenGLPipeline : public Pipeline + { + public: + OpenGLPipeline(const PipelineSpecification& spec); + virtual ~OpenGLPipeline(); + + virtual PipelineSpecification& GetSpecification() { return m_Specification; } + virtual const PipelineSpecification& GetSpecification() const { return m_Specification; } + + virtual void Invalidate() override; + + virtual void Bind() override; + private: + PipelineSpecification m_Specification; + uint32_t m_VertexArrayRendererID = 0; + }; + +} + + +#endif //PRISM_OPENGLPIPELINE_H \ No newline at end of file diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLVertexArray.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexArray.cpp index 10770f7..264b670 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLVertexArray.cpp +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexArray.cpp @@ -4,7 +4,6 @@ #include "OpenGLVertexArray.h" -#include "OpenGLBuffer.h" #include "glad/glad.h" #include "Prism/Renderer/Renderer.h" diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.cpp new file mode 100644 index 0000000..4721f8d --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.cpp @@ -0,0 +1,71 @@ +// +// Created by sfd on 2025/12/15. +// + +#include "OpenGLVertexBuffer.h" + +#include "glad/glad.h" +#include "Prism/Renderer/Renderer.h" + +namespace Prism { + + static GLenum OpenGLUsage(VertexBufferUsage usage) + { + switch (usage) + { + case VertexBufferUsage::Static: return GL_STATIC_DRAW; + case VertexBufferUsage::Dynamic: return GL_DYNAMIC_DRAW; + } + PM_CORE_ASSERT(false, "Unknown vertex buffer usage"); + return 0; + } + + OpenGLVertexBuffer::OpenGLVertexBuffer(void* data, const uint32_t size, const VertexBufferUsage usage) + : m_Size(size), m_Usage(usage) + { + m_LocalData = Buffer::Copy(data, size); + + Ref instance = this; + Renderer::Submit([instance]() mutable { + glCreateBuffers(1, &instance->m_RendererID); + glNamedBufferData(instance->m_RendererID, instance->m_Size, instance->m_LocalData.Data, OpenGLUsage(instance->m_Usage)); + }); + } + + OpenGLVertexBuffer::OpenGLVertexBuffer(const uint32_t size, const VertexBufferUsage usage) + : m_Size(size), m_Usage(usage) + { + Ref instance = this; + Renderer::Submit([instance]() mutable { + glCreateBuffers(1, &instance->m_RendererID); + glNamedBufferData(instance->m_RendererID, instance->m_Size, nullptr, OpenGLUsage(instance->m_Usage)); + }); + } + + + OpenGLVertexBuffer::~OpenGLVertexBuffer() + { + GLuint rendererID = m_RendererID; + Renderer::Submit([rendererID](){ + glDeleteBuffers(1, &rendererID); + }); + } + + void OpenGLVertexBuffer::SetData(void* buffer, uint32_t size, uint32_t offset) + { + m_LocalData = Buffer::Copy(buffer, size); + m_Size = size; + Ref instance = this; + Renderer::Submit([instance, offset]() { + glNamedBufferSubData(instance->m_RendererID, offset, instance->m_Size, instance->m_LocalData.Data); + }); + } + + void OpenGLVertexBuffer::Bind() const + { + Ref instance = this; + Renderer::Submit([instance]() { + glBindBuffer(GL_ARRAY_BUFFER, instance->m_RendererID); + }); + } +} diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.h b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.h new file mode 100644 index 0000000..0063ab7 --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.h @@ -0,0 +1,41 @@ +// +// Created by sfd on 2025/12/15. +// + +#ifndef PRISM_OPENGLVERTEXBUFFER_H +#define PRISM_OPENGLVERTEXBUFFER_H +#include "Prism/Core/Buffer.h" +#include "Prism/Renderer/VertexBuffer.h" + +namespace Prism { + + class OpenGLVertexBuffer : public VertexBuffer + { + public: + OpenGLVertexBuffer(void* data, uint32_t size, VertexBufferUsage usage = VertexBufferUsage::Static); + OpenGLVertexBuffer(uint32_t size, VertexBufferUsage usage = VertexBufferUsage::Dynamic); + + ~OpenGLVertexBuffer() override; + + void SetData(void* data, uint32_t size, uint32_t offset = 0) override; + + void Bind() const override; + + virtual const VertexBufferLayout& GetLayout() const override { return m_Layout; } + virtual void SetLayout(const VertexBufferLayout& layout) override { m_Layout = layout; } + + uint32_t GetSize() const override { return m_Size; } + RendererID GetRendererID() const override { return m_RendererID; } + private: + RendererID m_RendererID = 0; + uint32_t m_Size; + VertexBufferUsage m_Usage; + VertexBufferLayout m_Layout; + + Buffer m_LocalData; + }; +} + + + +#endif //PRISM_OPENGLVERTEXBUFFER_H \ No newline at end of file diff --git a/Prism/src/Prism/Renderer/Buffer.cpp b/Prism/src/Prism/Renderer/Buffer.cpp deleted file mode 100644 index d1bc7e0..0000000 --- a/Prism/src/Prism/Renderer/Buffer.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// -// Created by sfd on 25-11-22. -// - -#include "Buffer.h" - -#include "Prism/Platform/OpenGL/OpenGLBuffer.h" - -namespace Prism -{ - Ref VertexBuffer::Create(void* data, uint32_t size, VertexBufferUsage usage) - { - switch (RendererAPI::Current()) - { - case RendererAPIType::None: return nullptr; - case RendererAPIType::OpenGL: return Ref::Create(data, size, usage); - } - PM_CORE_ASSERT(false, "Unknown RendererAPI"); - return nullptr; - } - - Ref VertexBuffer::Create(uint32_t size, VertexBufferUsage usage) - { - switch (RendererAPI::Current()) - { - case RendererAPIType::None: return nullptr; - case RendererAPIType::OpenGL: return Ref::Create(size, usage); - } - PM_CORE_ASSERT(false, "Unknown RendererAPI"); - return nullptr; - } - - - Ref IndexBuffer::Create(uint32_t size) - { - switch (RendererAPI::Current()) - { - case RendererAPIType::None: return nullptr; - case RendererAPIType::OpenGL: return Ref::Create(size); - } - PM_CORE_ASSERT(false, "Unknown RendererAPI"); - return nullptr; - } - - Ref IndexBuffer::Create(void* data, uint32_t size) - { - switch (RendererAPI::Current()) - { - case RendererAPIType::None: return nullptr; - case RendererAPIType::OpenGL: return Ref::Create(data, size); - } - PM_CORE_ASSERT(false, "Unknown RendererAPI"); - return nullptr; - } - -} diff --git a/Prism/src/Prism/Renderer/Buffer.h b/Prism/src/Prism/Renderer/Buffer.h deleted file mode 100644 index 0591c8a..0000000 --- a/Prism/src/Prism/Renderer/Buffer.h +++ /dev/null @@ -1,160 +0,0 @@ -// -// Created by sfd on 25-11-22. -// - -#ifndef RENDERER_BUFFER_H -#define RENDERER_BUFFER_H -#include "RendererAPI.h" -#include "Prism/Core/Ref.h" - - -namespace Prism -{ - enum class ShaderDataType - { - None = 0, Float, Float2, Float3, Float4, Mat3, Mat4, Int, Int2, Int3, Int4, Bool - }; - - static uint32_t ShaderDataTypeSize(ShaderDataType type) - { - switch (type) - { - case ShaderDataType::Float: return 4; - case ShaderDataType::Float2: return 4 * 2; - case ShaderDataType::Float3: return 4 * 3; - case ShaderDataType::Float4: return 4 * 4; - case ShaderDataType::Mat3: return 4 * 3 * 3; - case ShaderDataType::Mat4: return 4 * 4 * 4; - case ShaderDataType::Int: return 4; - case ShaderDataType::Int2: return 4 * 2; - case ShaderDataType::Int3: return 4 * 3; - case ShaderDataType::Int4: return 4 * 4; - case ShaderDataType::Bool: return 1; - } - - PM_CORE_ASSERT(false, "Unknown ShaderDataType!"); - return 0; - } - - - struct BufferElement - { - std::string Name; - ShaderDataType Type; - uint32_t Size; - uint32_t Offset; - bool Normalized; - - BufferElement() = default; - - BufferElement(ShaderDataType type, const std::string& name, bool normalized = false) - : Name(name), Type(type), Size(ShaderDataTypeSize(type)), Offset(0), Normalized(normalized) - { - } - - uint32_t GetComponentCount() const - { - switch (Type) - { - case ShaderDataType::Float: return 1; - case ShaderDataType::Float2: return 2; - case ShaderDataType::Float3: return 3; - case ShaderDataType::Float4: return 4; - case ShaderDataType::Mat3: return 3 * 3; - case ShaderDataType::Mat4: return 4 * 4; - case ShaderDataType::Int: return 1; - case ShaderDataType::Int2: return 2; - case ShaderDataType::Int3: return 3; - case ShaderDataType::Int4: return 4; - case ShaderDataType::Bool: return 1; - } - - PM_CORE_ASSERT(false, "Unknown ShaderDataType!"); - return 0; - } - }; - - - class BufferLayout - { - public: - BufferLayout() {} - - BufferLayout(const std::initializer_list& elements) - : m_Elements(elements) - { - CalculateOffsetsAndStride(); - } - - inline uint32_t GetStride() const { return m_Stride; } - inline const std::vector& GetElements() const { return m_Elements; } - - std::vector::iterator begin() { return m_Elements.begin(); } - std::vector::iterator end() { return m_Elements.end(); } - std::vector::const_iterator begin() const { return m_Elements.begin(); } - std::vector::const_iterator end() const { return m_Elements.end(); } - private: - void CalculateOffsetsAndStride() - { - uint32_t offset = 0; - m_Stride = 0; - for (auto& element : m_Elements) - { - element.Offset = offset; - offset += element.Size; - m_Stride += element.Size; - } - } - private: - std::vector m_Elements; - uint32_t m_Stride = 0; - }; - - - enum class VertexBufferUsage - { - None = 0, Static = 1, Dynamic = 2 - }; - - - class PRISM_API VertexBuffer : public RefCounted - { - public: - virtual ~VertexBuffer() {} - - static Ref Create(void* data, uint32_t size, VertexBufferUsage usage = VertexBufferUsage::Static); - static Ref Create(uint32_t size, VertexBufferUsage usage = VertexBufferUsage::Dynamic); - - virtual void SetData(void* buffer, uint32_t size, uint32_t offset = 0) = 0; - virtual void Bind() const = 0; - - virtual const BufferLayout& GetLayout() const = 0; - virtual void SetLayout(const BufferLayout& layout) = 0; - - virtual unsigned int GetSize() const = 0; - virtual RendererID GetRendererID() const = 0; - - }; - - - class PRISM_API IndexBuffer : public RefCounted - { - public: - virtual ~IndexBuffer() {} - - static Ref Create(uint32_t size); - static Ref Create(void* data, uint32_t size = 0); - - virtual void SetData(void* buffer, uint32_t size, uint32_t offset = 0) = 0; - virtual void Bind() const = 0; - - virtual uint32_t GetCount() const = 0; - virtual unsigned int GetSize() const = 0; - virtual RendererID GetRendererID() const = 0; - - }; -} - - - -#endif //RENDERER_BUFFER_H diff --git a/Prism/src/Prism/Renderer/IndexBuffer.cpp b/Prism/src/Prism/Renderer/IndexBuffer.cpp new file mode 100644 index 0000000..4915b80 --- /dev/null +++ b/Prism/src/Prism/Renderer/IndexBuffer.cpp @@ -0,0 +1,33 @@ +// +// Created by sfd on 2025/12/15. +// + +#include "IndexBuffer.h" + +#include "Prism/Platform/OpenGL/OpenGLIndexBuffer.h" + +namespace Prism { + + Ref IndexBuffer::Create(uint32_t size) + { + switch (RendererAPI::Current()) + { + case RendererAPIType::None: return nullptr; + case RendererAPIType::OpenGL: return Ref::Create(size); + } + PM_CORE_ASSERT(false, "Unknown RendererAPI"); + return nullptr; + } + + Ref IndexBuffer::Create(void* data, uint32_t size) + { + switch (RendererAPI::Current()) + { + case RendererAPIType::None: return nullptr; + case RendererAPIType::OpenGL: return Ref::Create(data, size); + } + PM_CORE_ASSERT(false, "Unknown RendererAPI"); + return nullptr; + } + +} diff --git a/Prism/src/Prism/Renderer/IndexBuffer.h b/Prism/src/Prism/Renderer/IndexBuffer.h new file mode 100644 index 0000000..15dc03d --- /dev/null +++ b/Prism/src/Prism/Renderer/IndexBuffer.h @@ -0,0 +1,32 @@ +// +// Created by sfd on 2025/12/15. +// + +#ifndef PRISM_INDEXBUFFER_H +#define PRISM_INDEXBUFFER_H +#include "RendererAPI.h" +#include "Prism/Core/Ref.h" + +namespace Prism { + class IndexBuffer : public RefCounted { + public: + virtual ~IndexBuffer() { + } + + virtual void SetData(void *buffer, uint32_t size, uint32_t offset = 0) = 0; + + virtual void Bind() const = 0; + + virtual uint32_t GetCount() const = 0; + + virtual uint32_t GetSize() const = 0; + + virtual RendererID GetRendererID() const = 0; + + static Ref Create(uint32_t size); + + static Ref Create(void *data, uint32_t size = 0); + }; +} + +#endif //PRISM_INDEXBUFFER_H diff --git a/Prism/src/Prism/Renderer/Mesh.cpp b/Prism/src/Prism/Renderer/Mesh.cpp index f966356..9b6512b 100644 --- a/Prism/src/Prism/Renderer/Mesh.cpp +++ b/Prism/src/Prism/Renderer/Mesh.cpp @@ -475,11 +475,11 @@ namespace Prism PM_MESH_LOG("------------------------"); } - m_VertexArray = VertexArray::Create(); + VertexBufferLayout vertexBufferLayout; if (m_IsAnimated) { - auto vb = VertexBuffer::Create(m_AnimatedVertices.data(), (uint32_t)m_AnimatedVertices.size() * sizeof(AnimatedVertex)); - vb->SetLayout({ + m_VertexBuffer = VertexBuffer::Create(m_AnimatedVertices.data(), (uint32_t)m_AnimatedVertices.size() * sizeof(AnimatedVertex)); + vertexBufferLayout = { { ShaderDataType::Float3, "a_Position" }, { ShaderDataType::Float3, "a_Normal" }, { ShaderDataType::Float3, "a_Tangent" }, @@ -487,24 +487,24 @@ namespace Prism { ShaderDataType::Float2, "a_TexCoord" }, { ShaderDataType::Int4, "a_BoneIDs" }, { ShaderDataType::Float4, "a_BoneWeights" }, - }); - m_VertexArray->AddVertexBuffer(vb); + }; }else { - auto vb = VertexBuffer::Create(m_StaticVertices.data(), (uint32_t)m_StaticVertices.size() * sizeof(Vertex)); - vb->SetLayout({ + m_VertexBuffer = VertexBuffer::Create(m_StaticVertices.data(), (uint32_t)m_StaticVertices.size() * sizeof(Vertex)); + vertexBufferLayout = { { ShaderDataType::Float3, "a_Position" }, { ShaderDataType::Float3, "a_Normal" }, { ShaderDataType::Float3, "a_Tangent" }, { ShaderDataType::Float3, "a_Binormal" }, { ShaderDataType::Float2, "a_TexCoord" }, - }); - m_VertexArray->AddVertexBuffer(vb); - + }; } - auto ib = IndexBuffer::Create(m_Indices.data(), (uint32_t)m_Indices.size() * sizeof(Index)); - m_VertexArray->SetIndexBuffer(ib); + m_IndexBuffer = IndexBuffer::Create(m_Indices.data(), (uint32_t)m_Indices.size() * sizeof(Index)); + + PipelineSpecification pipelineSpecification; + pipelineSpecification.Layout = vertexBufferLayout; + m_Pipeline = Pipeline::Create(pipelineSpecification); } Mesh::~Mesh() = default; diff --git a/Prism/src/Prism/Renderer/Mesh.h b/Prism/src/Prism/Renderer/Mesh.h index 4fc3efc..aee4a26 100644 --- a/Prism/src/Prism/Renderer/Mesh.h +++ b/Prism/src/Prism/Renderer/Mesh.h @@ -8,6 +8,7 @@ #include #include "Material.h" +#include "Pipeline.h" #include "Shader.h" #include "VertexArray.h" #include "Prism/Core/TimeStep.h" @@ -145,7 +146,10 @@ namespace Prism uint32_t m_BoneCount = 0; std::vector m_BoneInfo; - Ref m_VertexArray; + // Ref m_VertexArray; + Ref m_Pipeline; + Ref m_VertexBuffer; + Ref m_IndexBuffer; std::vector m_StaticVertices; diff --git a/Prism/src/Prism/Renderer/Pipeline.cpp b/Prism/src/Prism/Renderer/Pipeline.cpp new file mode 100644 index 0000000..96cff55 --- /dev/null +++ b/Prism/src/Prism/Renderer/Pipeline.cpp @@ -0,0 +1,21 @@ +// +// Created by sfd on 2025/12/15. +// + +#include "Pipeline.h" +#include "Prism/Platform/OpenGL/OpenGLPipeline.h" + +namespace Prism { + + Ref Pipeline::Create(const PipelineSpecification& spec) + { + switch (RendererAPI::Current()) + { + case RendererAPIType::None: return nullptr; + case RendererAPIType::OpenGL: return Ref::Create(spec); + } + PM_CORE_ASSERT(false, "Unknown RendererAPI"); + return nullptr; + } + +} \ No newline at end of file diff --git a/Prism/src/Prism/Renderer/Pipeline.h b/Prism/src/Prism/Renderer/Pipeline.h new file mode 100644 index 0000000..d9b3fdb --- /dev/null +++ b/Prism/src/Prism/Renderer/Pipeline.h @@ -0,0 +1,36 @@ +// +// Created by sfd on 2025/12/15. +// + +#ifndef PRISM_PIPELINE_H +#define PRISM_PIPELINE_H +#include "Shader.h" +#include "VertexBuffer.h" +#include "Prism/Core/Ref.h" + +namespace Prism { + struct PipelineSpecification + { + Ref Shader; + VertexBufferLayout Layout; + }; + + class Pipeline : public RefCounted + { + public: + virtual ~Pipeline() = default; + + virtual PipelineSpecification& GetSpecification() = 0; + virtual const PipelineSpecification& GetSpecification() const = 0; + + virtual void Invalidate() = 0; + + // TEMP: remove this when render command buffers are a thing + virtual void Bind() = 0; + + static Ref Create(const PipelineSpecification& spec); + }; + +} + +#endif //PRISM_PIPELINE_H \ No newline at end of file diff --git a/Prism/src/Prism/Renderer/RenderPass.h b/Prism/src/Prism/Renderer/RenderPass.h index 28d7c1d..dae3773 100644 --- a/Prism/src/Prism/Renderer/RenderPass.h +++ b/Prism/src/Prism/Renderer/RenderPass.h @@ -17,7 +17,7 @@ namespace Prism class PRISM_API RenderPass : public RefCounted { public: - virtual ~RenderPass() {} + virtual ~RenderPass() = default; virtual RenderPassSpecification& GetSpecification() = 0; diff --git a/Prism/src/Prism/Renderer/Renderer.cpp b/Prism/src/Prism/Renderer/Renderer.cpp index 681891b..4bb0708 100644 --- a/Prism/src/Prism/Renderer/Renderer.cpp +++ b/Prism/src/Prism/Renderer/Renderer.cpp @@ -19,7 +19,10 @@ namespace Prism Ref m_ActiveRenderPass; RenderCommandQueue m_CommandQueue; Ref m_ShaderLibrary; - Ref m_FullscreenQuadVertexArray; + + Ref m_FullscreenQuadVertexBuffer; + Ref m_FullscreenQuadIndexBuffer; + Ref m_FullscreenQuadPipeline; }; static RendererData s_Data; @@ -45,16 +48,16 @@ namespace Prism 0, 1, 2, 2, 3, 0 }; - s_Data.m_FullscreenQuadVertexArray = VertexArray::Create(); - auto quadVB = VertexBuffer::Create(fullScreenQuadVertex, sizeof(float) * sizeof(fullScreenQuadVertex)); - quadVB->SetLayout({ + + PipelineSpecification pipelineSpecification; + pipelineSpecification.Layout = { { ShaderDataType::Float3, "a_Position" }, { ShaderDataType::Float2, "a_TexCoord" } - }); + }; + s_Data.m_FullscreenQuadPipeline = Pipeline::Create(pipelineSpecification); - auto quadIB = IndexBuffer::Create(fullScreenQuadIndices, sizeof(fullScreenQuadIndices) * sizeof(uint32_t)); - s_Data.m_FullscreenQuadVertexArray->AddVertexBuffer(quadVB); - s_Data.m_FullscreenQuadVertexArray->SetIndexBuffer(quadIB); + s_Data.m_FullscreenQuadVertexBuffer = VertexBuffer::Create(fullScreenQuadVertex, sizeof(fullScreenQuadVertex[0]) * sizeof(fullScreenQuadVertex)); + s_Data.m_FullscreenQuadIndexBuffer = IndexBuffer::Create(fullScreenQuadIndices, sizeof(fullScreenQuadIndices[0]) * sizeof(fullScreenQuadIndices)); Renderer2D::Init(); } @@ -141,7 +144,10 @@ namespace Prism shader->SetMat4("u_Transform", transform); } - s_Data.m_FullscreenQuadVertexArray->Bind(); + s_Data.m_FullscreenQuadVertexBuffer->Bind(); + s_Data.m_FullscreenQuadPipeline->Bind(); + s_Data.m_FullscreenQuadIndexBuffer->Bind(); + Renderer::DrawIndexed(6, PrimitiveType::Triangles, depthTest); } @@ -154,7 +160,10 @@ namespace Prism depthTest = material->GetFlag(MaterialFlag::DepthTest); } - s_Data.m_FullscreenQuadVertexArray->Bind(); + s_Data.m_FullscreenQuadVertexBuffer->Bind(); + s_Data.m_FullscreenQuadPipeline->Bind(); + s_Data.m_FullscreenQuadIndexBuffer->Bind(); + Renderer::DrawIndexed(6, PrimitiveType::Triangles, depthTest); } @@ -164,7 +173,9 @@ namespace Prism // auto shader = material->GetShader(); // TODO: Sort this out - mesh->m_VertexArray->Bind(); + mesh->m_VertexBuffer->Bind(); + mesh->m_Pipeline->Bind(); + mesh->m_IndexBuffer->Bind(); const auto& materials = mesh->GetMaterials(); for (Submesh& submesh : mesh->m_Submeshes) diff --git a/Prism/src/Prism/Renderer/Renderer2D.cpp b/Prism/src/Prism/Renderer/Renderer2D.cpp index 2d84634..90ad4e2 100644 --- a/Prism/src/Prism/Renderer/Renderer2D.cpp +++ b/Prism/src/Prism/Renderer/Renderer2D.cpp @@ -38,8 +38,10 @@ namespace Prism static constexpr uint32_t MaxLineIndices = MaxLines * 6; // Quad - Ref QuadVertexArray; + Ref QuadPipeline; Ref QuadVertexBuffer; + Ref QuadIndexBuffer; + Ref TextureShader; Ref WhiteTexture; @@ -54,8 +56,9 @@ namespace Prism // Lines - Ref LineVertexArray; + Ref LinePipeline; Ref LineVertexBuffer; + Ref LineIndexBuffer; Ref LineShader; uint32_t LineIndexCount = 0; @@ -74,39 +77,39 @@ namespace Prism void Renderer2D::Init() { - s_Data.QuadVertexArray = VertexArray::Create(); + { + PipelineSpecification pipelineSpecification; + pipelineSpecification.Layout = { + { ShaderDataType::Float3, "a_Position" }, + { ShaderDataType::Float4, "a_Color" }, + { ShaderDataType::Float2, "a_TexCoord" }, + { ShaderDataType::Float, "a_TexIndex" }, + { ShaderDataType::Float, "a_TilingFactor" } + }; + s_Data.QuadPipeline = Pipeline::Create(pipelineSpecification); - s_Data.QuadVertexBuffer = VertexBuffer::Create(s_Data.MaxVertices * sizeof(QuadVertex)); - s_Data.QuadVertexBuffer->SetLayout({ - { ShaderDataType::Float3, "a_Position" }, - { ShaderDataType::Float4, "a_Color" }, - { ShaderDataType::Float2, "a_TexCoord" }, - { ShaderDataType::Float, "a_TexIndex" }, - { ShaderDataType::Float, "a_TilingFactor" } - }); - s_Data.QuadVertexArray->AddVertexBuffer(s_Data.QuadVertexBuffer); + s_Data.QuadVertexBuffer = VertexBuffer::Create(s_Data.MaxVertices * sizeof(QuadVertex)); + s_Data.QuadVertexBufferBase = new QuadVertex[s_Data.MaxVertices]; - s_Data.QuadVertexBufferBase = new QuadVertex[s_Data.MaxVertices]; + uint32_t* quadIndices = new uint32_t[s_Data.MaxIndices]; - uint32_t* quadIndices = new uint32_t[s_Data.MaxIndices]; + uint32_t offset = 0; + for (uint32_t i = 0; i < s_Data.MaxIndices; i += 6) + { + quadIndices[i + 0] = offset + 0; + quadIndices[i + 1] = offset + 1; + quadIndices[i + 2] = offset + 2; - uint32_t offset = 0; - for (uint32_t i = 0; i < s_Data.MaxIndices; i += 6) - { - quadIndices[i + 0] = offset + 0; - quadIndices[i + 1] = offset + 1; - quadIndices[i + 2] = offset + 2; + quadIndices[i + 3] = offset + 2; + quadIndices[i + 4] = offset + 3; + quadIndices[i + 5] = offset + 0; - quadIndices[i + 3] = offset + 2; - quadIndices[i + 4] = offset + 3; - quadIndices[i + 5] = offset + 0; + offset += 4; + } - offset += 4; - } - - Ref quadIB = IndexBuffer::Create(quadIndices, s_Data.MaxIndices); - s_Data.QuadVertexArray->SetIndexBuffer(quadIB); - delete[] quadIndices; + s_Data.QuadIndexBuffer = IndexBuffer::Create(quadIndices, s_Data.MaxIndices); + delete[] quadIndices; + } s_Data.WhiteTexture = Texture2D::Create(TextureFormat::RGBA, 1, 1); uint32_t whiteTextureData = 0xffffffff; @@ -125,25 +128,26 @@ namespace Prism s_Data.QuadVertexPositions[3] = { -0.5f, 0.5f, 0.0f, 1.0f }; // Lines - s_Data.LineShader = Shader::Create("assets/shaders/Renderer2D_Line.glsl"); - s_Data.LineVertexArray = VertexArray::Create(); + { + s_Data.LineShader = Shader::Create("assets/shaders/Renderer2D_Line.glsl"); - s_Data.LineVertexBuffer = VertexBuffer::Create(s_Data.MaxLineVertices * sizeof(LineVertex)); - s_Data.LineVertexBuffer->SetLayout({ - { ShaderDataType::Float3, "a_Position" }, - { ShaderDataType::Float4, "a_Color" } - }); - s_Data.LineVertexArray->AddVertexBuffer(s_Data.LineVertexBuffer); + PipelineSpecification pipelineSpecification; + pipelineSpecification.Layout = { + { ShaderDataType::Float3, "a_Position" }, + { ShaderDataType::Float4, "a_Color" } + }; + s_Data.LinePipeline = Pipeline::Create(pipelineSpecification); - s_Data.LineVertexBufferBase = new LineVertex[s_Data.MaxLineVertices]; + s_Data.LineVertexBuffer = VertexBuffer::Create(s_Data.MaxLineVertices * sizeof(LineVertex)); + s_Data.LineVertexBufferBase = new LineVertex[s_Data.MaxLineVertices]; - uint32_t* lineIndices = new uint32_t[s_Data.MaxLineIndices]; - for (uint32_t i = 0; i < s_Data.MaxLineIndices; i++) - lineIndices[i] = i; + uint32_t* lineIndices = new uint32_t[s_Data.MaxLineIndices]; + for (uint32_t i = 0; i < s_Data.MaxLineIndices; i++) + lineIndices[i] = i; - Ref lineIB = IndexBuffer::Create(lineIndices, s_Data.MaxLineIndices); - s_Data.LineVertexArray->SetIndexBuffer(lineIB); - delete[] lineIndices; + s_Data.LineIndexBuffer = IndexBuffer::Create(lineIndices, s_Data.MaxLineIndices); + delete[] lineIndices; + } } void Renderer2D::Shutdown() @@ -180,7 +184,9 @@ namespace Prism for (uint32_t i = 0; i < s_Data.TextureSlotIndex; i++) s_Data.TextureSlots[i]->Bind(i); - s_Data.QuadVertexArray->Bind(); + s_Data.QuadVertexBuffer->Bind(); + s_Data.QuadPipeline->Bind(); + s_Data.QuadIndexBuffer->Bind(); Renderer::DrawIndexed(s_Data.QuadIndexCount, PrimitiveType::Triangles, s_Data.DepthTest); s_Data.Stats.DrawCalls++; } @@ -193,7 +199,9 @@ namespace Prism s_Data.LineShader->Bind(); s_Data.LineShader->SetMat4("u_ViewProjection", s_Data.CameraViewProj); - s_Data.LineVertexArray->Bind(); + s_Data.LineVertexBuffer->Bind(); + s_Data.LinePipeline->Bind(); + s_Data.LineIndexBuffer->Bind(); Renderer::SetLineThickness(1.0f); Renderer::DrawIndexed(s_Data.LineIndexCount, PrimitiveType::Lines, s_Data.DepthTest); s_Data.Stats.DrawCalls++; diff --git a/Prism/src/Prism/Renderer/VertexArray.h b/Prism/src/Prism/Renderer/VertexArray.h index ba64925..5420bfd 100644 --- a/Prism/src/Prism/Renderer/VertexArray.h +++ b/Prism/src/Prism/Renderer/VertexArray.h @@ -4,7 +4,9 @@ #ifndef VERTEXARRAY_H #define VERTEXARRAY_H -#include "Buffer.h" +#include "IndexBuffer.h" +#include "VertexBuffer.h" +#include "Prism/Core/Ref.h" namespace Prism diff --git a/Prism/src/Prism/Renderer/VertexBuffer.cpp b/Prism/src/Prism/Renderer/VertexBuffer.cpp new file mode 100644 index 0000000..eed819e --- /dev/null +++ b/Prism/src/Prism/Renderer/VertexBuffer.cpp @@ -0,0 +1,33 @@ +// +// Created by sfd on 2025/12/15. +// + +#include "VertexBuffer.h" + +#include "Prism/Platform/OpenGL/OpenGLVertexBuffer.h" + +namespace Prism { + + Ref VertexBuffer::Create(void* data, uint32_t size, VertexBufferUsage usage) + { + switch (RendererAPI::Current()) + { + case RendererAPIType::None: return nullptr; + case RendererAPIType::OpenGL: return Ref::Create(data, size, usage); + } + PM_CORE_ASSERT(false, "Unknown RendererAPI"); + return nullptr; + } + + Ref VertexBuffer::Create(uint32_t size, VertexBufferUsage usage) + { + switch (RendererAPI::Current()) + { + case RendererAPIType::None: return nullptr; + case RendererAPIType::OpenGL: return Ref::Create(size, usage); + } + PM_CORE_ASSERT(false, "Unknown RendererAPI"); + return nullptr; + } + +} diff --git a/Prism/src/Prism/Renderer/VertexBuffer.h b/Prism/src/Prism/Renderer/VertexBuffer.h new file mode 100644 index 0000000..7a37c30 --- /dev/null +++ b/Prism/src/Prism/Renderer/VertexBuffer.h @@ -0,0 +1,129 @@ +// +// Created by sfd on 2025/12/15. +// + +#ifndef PRISM_VERTEXBUFFER_H +#define PRISM_VERTEXBUFFER_H +#include "RendererAPI.h" +#include "Prism/Core/Ref.h" + + +namespace Prism { + enum class ShaderDataType { + None = 0, Float, Float2, Float3, Float4, Mat3, Mat4, Int, Int2, Int3, Int4, Bool + }; + + static uint32_t ShaderDataTypeSize(const ShaderDataType type) { + switch (type) { + case ShaderDataType::Float: return 4; + case ShaderDataType::Float2: return 4 * 2; + case ShaderDataType::Float3: return 4 * 3; + case ShaderDataType::Float4: return 4 * 4; + case ShaderDataType::Mat3: return 4 * 3 * 3; + case ShaderDataType::Mat4: return 4 * 4 * 4; + case ShaderDataType::Int: return 4; + case ShaderDataType::Int2: return 4 * 2; + case ShaderDataType::Int3: return 4 * 3; + case ShaderDataType::Int4: return 4 * 4; + case ShaderDataType::Bool: return 1; + } + + PM_CORE_ASSERT(false, "Unknown ShaderDataType!"); + return 0; + } + + struct VertexBufferElement { + std::string Name; + ShaderDataType Type; + uint32_t Size; + uint32_t Offset; + bool Normalized; + + VertexBufferElement() = default; + + VertexBufferElement(const ShaderDataType type, const std::string &name, const bool normalized = false) + : Name(name), Type(type), Size(ShaderDataTypeSize(type)), Offset(0), Normalized(normalized) { + } + + uint32_t GetComponentCount() const { + switch (Type) { + case ShaderDataType::Float: return 1; + case ShaderDataType::Float2: return 2; + case ShaderDataType::Float3: return 3; + case ShaderDataType::Float4: return 4; + case ShaderDataType::Mat3: return 3 * 3; + case ShaderDataType::Mat4: return 4 * 4; + case ShaderDataType::Int: return 1; + case ShaderDataType::Int2: return 2; + case ShaderDataType::Int3: return 3; + case ShaderDataType::Int4: return 4; + case ShaderDataType::Bool: return 1; + } + + PM_CORE_ASSERT(false, "Unknown ShaderDataType!"); + return 0; + } + }; + + class VertexBufferLayout { + public: + VertexBufferLayout() { + } + + VertexBufferLayout(const std::initializer_list &elements) + : m_Elements(elements) { + CalculateOffsetsAndStride(); + } + + inline uint32_t GetStride() const { return m_Stride; } + inline const std::vector &GetElements() const { return m_Elements; } + + std::vector::iterator begin() { return m_Elements.begin(); } + std::vector::iterator end() { return m_Elements.end(); } + std::vector::const_iterator begin() const { return m_Elements.begin(); } + std::vector::const_iterator end() const { return m_Elements.end(); } + + private: + void CalculateOffsetsAndStride() { + uint32_t offset = 0; + m_Stride = 0; + for (auto &element: m_Elements) { + element.Offset = offset; + offset += element.Size; + m_Stride += element.Size; + } + } + + private: + std::vector m_Elements; + uint32_t m_Stride = 0; + }; + + enum class VertexBufferUsage { + None = 0, Static = 1, Dynamic = 2 + }; + + class VertexBuffer : public RefCounted { + public: + virtual ~VertexBuffer() { + } + + virtual void SetData(void *buffer, uint32_t size, uint32_t offset = 0) = 0; + + virtual void Bind() const = 0; + + virtual const VertexBufferLayout &GetLayout() const = 0; + + virtual void SetLayout(const VertexBufferLayout &layout) = 0; + + virtual unsigned int GetSize() const = 0; + + virtual RendererID GetRendererID() const = 0; + + static Ref Create(void *data, uint32_t size, VertexBufferUsage usage = VertexBufferUsage::Static); + + static Ref Create(uint32_t size, VertexBufferUsage usage = VertexBufferUsage::Dynamic); + }; +} + +#endif //PRISM_VERTEXBUFFER_H