Skip to content

Commit

Permalink
2D Batch Renderer works, but only in 2D right now
Browse files Browse the repository at this point in the history
  • Loading branch information
tomheeleynz committed Jul 21, 2023
1 parent bc34845 commit 8c917bf
Show file tree
Hide file tree
Showing 16 changed files with 398 additions and 128 deletions.
5 changes: 1 addition & 4 deletions Arcane/src/Arcane/ECS/Component.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "Arcane/Renderer/Mesh.h"
#include "Arcane/Scripting/Script.h"
#include "Arcane/Renderer/Camera.h"
#include "Arcane/Renderer/Quad.h"

namespace Arcane
{
Expand Down Expand Up @@ -75,9 +74,7 @@ namespace Arcane

struct SpriteRendererComponent
{
Quad* quad;
Material* material;
glm::vec3 color;
glm::vec3 color = {1.0f, 1.0f, 1.0f};
};

struct RigidBodyComponent
Expand Down
4 changes: 4 additions & 0 deletions Arcane/src/Arcane/Platform/OpenGL/OpenGLBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ namespace Arcane
return m_IndexBuffer;
}

void OpenGLVertexBuffer::SetData(void* data, uint32_t size)
{
}

void OpenGLVertexBuffer::Bind()
{
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
Expand Down
1 change: 1 addition & 0 deletions Arcane/src/Arcane/Platform/OpenGL/OpenGLBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Arcane

void AddIndexBuffer(IndexBuffer* _indexBuffer) override;
IndexBuffer* GetIndexBuffer() override;
void SetData(void* data, uint32_t size);

void Bind();
void UnBind();
Expand Down
225 changes: 205 additions & 20 deletions Arcane/src/Arcane/Platform/Vulkan/VulkanBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,44 +30,190 @@ namespace Arcane {
VkDevice logicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetDevice().GetLogicalDevice();
VkPhysicalDevice physicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetPhysicalDevice().GetPhysicalDevice();

VkDeviceSize bufferSize = size;
CreateBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, m_StagingBuffer, m_StagingBufferMemory);

void* data;
vkMapMemory(logicalDevice, m_StagingBufferMemory, 0, bufferSize, 0, &data);
memcpy(data, vertices, (size_t)bufferSize);
vkUnmapMemory(logicalDevice, m_StagingBufferMemory);

CreateBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_VertexBuffer, m_VertexBufferMemory);

CopyBuffer(m_StagingBuffer, m_VertexBuffer, bufferSize);
}

VulkanVertexBuffer::VulkanVertexBuffer(uint32_t size)
{
Application& app = Application::Get();
VkDevice logicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetDevice().GetLogicalDevice();
VkPhysicalDevice physicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetPhysicalDevice().GetPhysicalDevice();

VkDeviceSize bufferSize = size;
CreateBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, m_StagingBuffer, m_StagingBufferMemory);

void* data;
vkMapMemory(logicalDevice, m_StagingBufferMemory, 0, bufferSize, 0, &data);
// memcpy(data, nullptr, (size_t)bufferSize);
vkUnmapMemory(logicalDevice, m_StagingBufferMemory);

CreateBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_VertexBuffer, m_VertexBufferMemory);

CopyBuffer(m_StagingBuffer, m_VertexBuffer, bufferSize);

//VkBufferCreateInfo bufferInfo{};
//bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
//bufferInfo.size = size;
//bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
//bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

//if (vkCreateBuffer(logicalDevice, &bufferInfo, nullptr, &m_VertexBuffer) != VK_SUCCESS) {
// printf("Vertex Buffer Not Created\n");
//}
//else {
// printf("Vertex Buffer Created\n");
//}

//// Get buffer memeory requirements
//VkMemoryRequirements memRequirements;
//vkGetBufferMemoryRequirements(logicalDevice, m_VertexBuffer, &memRequirements);

//VkMemoryAllocateInfo allocInfo{};
//allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
//allocInfo.allocationSize = memRequirements.size;
//allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);

//if (vkAllocateMemory(logicalDevice, &allocInfo, nullptr, &m_VertexBufferMemory) != VK_SUCCESS) {
// printf("Failed to allocated vertex buffer memory\n");
//}
//else {
// printf("Allocated vertex buffer memory\n");
//}

//vkBindBufferMemory(logicalDevice, m_VertexBuffer, m_VertexBufferMemory, 0);

//// Add Data To Vertex Buffer
//void* data;
//vkMapMemory(logicalDevice, m_VertexBufferMemory, 0, bufferInfo.size, 0, &data);
//memcpy(data, nullptr, (size_t)bufferInfo.size);
//vkUnmapMemory(logicalDevice, m_VertexBufferMemory);
}

void VulkanVertexBuffer::SetData(void* data, uint32_t size)
{
Application& app = Application::Get();
VkDevice logicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetDevice().GetLogicalDevice();
VkPhysicalDevice physicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetPhysicalDevice().GetPhysicalDevice();

VkDeviceSize bufferSize = size;

void* vertices;
vkMapMemory(logicalDevice, m_StagingBufferMemory, 0,bufferSize , 0, &vertices);
memcpy(vertices, data, (size_t)bufferSize);
vkUnmapMemory(logicalDevice, m_StagingBufferMemory);

CopyBuffer(m_StagingBuffer, m_VertexBuffer, bufferSize);
}

void VulkanVertexBuffer::CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory)
{
Application& app = Application::Get();
VkDevice logicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetDevice().GetLogicalDevice();
VkPhysicalDevice physicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetPhysicalDevice().GetPhysicalDevice();

VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = size;
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
bufferInfo.usage = usage;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

if (vkCreateBuffer(logicalDevice, &bufferInfo, nullptr, &m_VertexBuffer) != VK_SUCCESS) {
printf("Vertex Buffer Not Created\n");
}
else {
printf("Vertex Buffer Created\n");
if (vkCreateBuffer(logicalDevice, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) {
printf("failed to create buffer!\n");
}

// Get buffer memeory requirements
VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(logicalDevice, m_VertexBuffer, &memRequirements);
vkGetBufferMemoryRequirements(logicalDevice, buffer, &memRequirements);

VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits, properties);

if (vkAllocateMemory(logicalDevice, &allocInfo, nullptr, &m_VertexBufferMemory) != VK_SUCCESS) {
printf("Failed to allocated vertex buffer memory\n");
}
else {
printf("Allocated vertex buffer memory\n");
if (vkAllocateMemory(logicalDevice, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate buffer memory!");
}

vkBindBufferMemory(logicalDevice, m_VertexBuffer, m_VertexBufferMemory, 0);
vkBindBufferMemory(logicalDevice, buffer, bufferMemory, 0);
}

// Add Data To Vertex Buffer
void* data;
vkMapMemory(logicalDevice, m_VertexBufferMemory, 0, bufferInfo.size, 0, &data);
memcpy(data, vertices, (size_t)bufferInfo.size);
vkUnmapMemory(logicalDevice, m_VertexBufferMemory);
void VulkanVertexBuffer::CopyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size)
{
VkCommandBuffer commandBuffer = BeginSingleTimeCommands();

VkBufferCopy copyRegion{};
copyRegion.srcOffset = 0; // Optional
copyRegion.dstOffset = 0; // Optional
copyRegion.size = size;
vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &copyRegion);

EndSingleTimeCommands(commandBuffer);
}

VkCommandBuffer VulkanVertexBuffer::BeginSingleTimeCommands()
{
Application& app = Application::Get();
VkCommandPool commandPool = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetSwapChain().GetCommandPool();
VkDevice logicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetDevice().GetLogicalDevice();

VkCommandBufferAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandPool = commandPool;
allocInfo.commandBufferCount = 1;

VkCommandBuffer commandBuffer;
vkAllocateCommandBuffers(logicalDevice, &allocInfo, &commandBuffer);

VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;

vkBeginCommandBuffer(commandBuffer, &beginInfo);

return commandBuffer;
}

void VulkanVertexBuffer::EndSingleTimeCommands(VkCommandBuffer commandBuffer)
{
Application& app = Application::Get();
VkCommandPool commandPool = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetSwapChain().GetCommandPool();
VulkanDevice logicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetDevice();

vkEndCommandBuffer(commandBuffer);

VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;

VkFenceCreateInfo fenceCreateInfo{};
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceCreateInfo.flags = 0;

VkFence fence;

if (vkCreateFence(logicalDevice.GetLogicalDevice(), &fenceCreateInfo, nullptr, &fence) != VK_SUCCESS) {
printf("Single time fence not created\n");
}

vkQueueSubmit(logicalDevice.GetGraphicsQueue(), 1, &submitInfo, fence);

vkWaitForFences(logicalDevice.GetLogicalDevice(), 1, &fence, VK_TRUE, UINT64_MAX);

vkDestroyFence(logicalDevice.GetLogicalDevice(), fence, nullptr);

vkFreeCommandBuffers(logicalDevice.GetLogicalDevice(), commandPool, 1, &commandBuffer);
}


////////////////////////////////////////////////////////
Expand Down Expand Up @@ -120,4 +266,43 @@ namespace Arcane {
vkUnmapMemory(logicalDevice, m_IndexBufferMemory);
}

VulkanIndexBuffer::VulkanIndexBuffer(uint32_t count)
{
m_Count = count;

Application& app = Application::Get();
VkDevice logicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetDevice().GetLogicalDevice();
VkPhysicalDevice physicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetPhysicalDevice().GetPhysicalDevice();

VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = count * sizeof(uint32_t);
bufferInfo.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;


if (vkCreateBuffer(logicalDevice, &bufferInfo, nullptr, &m_IndexBuffer) != VK_SUCCESS) {
printf("Index Buffer Not Created\n");
}
else {
printf("Index Buffer Created\n");
}

// Get buffer memeory requirements
VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(logicalDevice, m_IndexBuffer, &memRequirements);

VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);

if (vkAllocateMemory(logicalDevice, &allocInfo, nullptr, &m_IndexBufferMemory) != VK_SUCCESS) {
printf("Failed to allocated index buffer memory\n");
}
else {
printf("Allocated index buffer memory\n");
}
}

}
14 changes: 14 additions & 0 deletions Arcane/src/Arcane/Platform/Vulkan/VulkanBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,27 @@ namespace Arcane {
{
public:
VulkanVertexBuffer(void* data, uint32_t size);
VulkanVertexBuffer(uint32_t size);

VkBuffer GetVertexBuffer() { return m_VertexBuffer; }
void AddIndexBuffer(IndexBuffer* _indexBuffer) { m_IndexBuffer = _indexBuffer; }

IndexBuffer* GetIndexBuffer() { return m_IndexBuffer; }

void SetData(void* data, uint32_t size) override;
private:
void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory);
void CopyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size);

VkCommandBuffer BeginSingleTimeCommands();
void EndSingleTimeCommands(VkCommandBuffer commandBuffer);
private:
VkBuffer m_VertexBuffer;
VkBuffer m_StagingBuffer;

VkDeviceMemory m_VertexBufferMemory;
VkDeviceMemory m_StagingBufferMemory;

IndexBuffer* m_IndexBuffer = nullptr;
};

Expand All @@ -30,6 +43,7 @@ namespace Arcane {
{
public:
VulkanIndexBuffer(void* data, uint32_t count);
VulkanIndexBuffer(uint32_t count);

VkBuffer GetIndexBuffer() { return m_IndexBuffer; }

Expand Down
18 changes: 18 additions & 0 deletions Arcane/src/Arcane/Renderer/Buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ namespace Arcane {
}
}

VertexBuffer* VertexBuffer::Create(uint32_t size)
{
switch (RendererAPI::Current())
{
case RendererAPIType::Vulkan: return new VulkanVertexBuffer(size);
default: return nullptr;
}
}

////////////////////////////////////////////////////////
//// Index Buffer
////////////////////////////////////////////////////////
Expand All @@ -35,4 +44,13 @@ namespace Arcane {
default: return nullptr;
}
}

IndexBuffer* IndexBuffer::Create(uint32_t count)
{
switch (RendererAPI::Current())
{
case RendererAPIType::Vulkan: return new VulkanIndexBuffer(count);
default: return nullptr;
}
}
}
7 changes: 7 additions & 0 deletions Arcane/src/Arcane/Renderer/Buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace Arcane {
virtual uint32_t GetCount() = 0;

static IndexBuffer* Create(void* data, uint32_t count);
static IndexBuffer* Create(uint32_t count);
private:


Expand All @@ -27,9 +28,15 @@ namespace Arcane {
{
public:
virtual void AddIndexBuffer(IndexBuffer* _indexBuffer) = 0;
virtual void SetData(void* data, uint32_t size) = 0;
virtual IndexBuffer* GetIndexBuffer() = 0;


static VertexBuffer* Create(void* data, uint32_t size);
static VertexBuffer* Create(uint32_t size);



private:

};
Expand Down

0 comments on commit 8c917bf

Please sign in to comment.