added batch rendering

This commit is contained in:
Erris
2026-02-03 14:52:21 +01:00
parent 7b4950dda0
commit 01a8f03451
20 changed files with 331 additions and 175 deletions

View File

@@ -34,13 +34,13 @@ namespace OpenEngine {
bool OnWindowResize(WindowResizeEvent& event);
private:
inline static Application* instance;
bool running = true;
std::unique_ptr<Window> window;
Ref<ImGuiLayer> imgui_layer;
inline static Application* instance;
bool running = true;
LayerStack layer_stack;
Ref<ImGuiLayer> imgui_layer;
friend int ::main(int argc, char **argv);
};

View File

@@ -9,9 +9,12 @@ namespace OpenEngine {
class OpenGLVertexBuffer : public VertexBuffer
{
public:
OpenGLVertexBuffer(uint32_t size);
OpenGLVertexBuffer(float* vertices, uint32_t size);
virtual ~OpenGLVertexBuffer();
virtual void SetData(const void* data, uint32_t size) override;
virtual void Bind() const override;
virtual void UnBind() const override;

View File

@@ -2,6 +2,7 @@
#define OPENGL_RENDERER_API_HPP
#include "open_engine/renderer/renderer_api.hpp"
#include <cstdint>
namespace OpenEngine {
class OpenGLRendererAPI : public RendererAPI
@@ -14,7 +15,7 @@ namespace OpenEngine {
virtual void SetClearColor(const glm::vec4& color) override;
virtual void Clear() override;
virtual void DrawIndexed(const Ref<VertexArray>& vertex_array) override;
virtual void DrawIndexed(const Ref<VertexArray>& vertex_array, uint32_t index_count = 0) override;
};
}

View File

@@ -61,12 +61,15 @@ namespace OpenEngine {
public:
virtual ~VertexBuffer() = default;
virtual void SetData(const void* data, uint32_t size) = 0;
virtual void Bind() const = 0;
virtual void UnBind() const = 0;
virtual const BufferLayout& GetLayout() const = 0;
virtual void SetLayout(const BufferLayout& layout) = 0;
static Ref<VertexBuffer> Create(uint32_t size);
static Ref<VertexBuffer> Create(float* vertices, uint32_t size);
};
@@ -80,7 +83,7 @@ namespace OpenEngine {
virtual uint32_t GetCount() const = 0;
static Ref<IndexBuffer> Create(uint32_t* indices, uint32_t size);
static Ref<IndexBuffer> Create(uint32_t* indices, uint32_t count);
};
}

View File

@@ -29,11 +29,11 @@ namespace OpenEngine {
api->Clear();
};
inline static void DrawIndexed(const Ref<VertexArray>& vertex_array)
inline static void DrawIndexed(const Ref<VertexArray>& vertex_array, uint32_t count = 0)
{
OE_PROFILE_FUNCTION();
api->DrawIndexed(vertex_array);
api->DrawIndexed(vertex_array, count);
};
inline static void SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height)

View File

@@ -1,6 +1,7 @@
#ifndef RENDERER2D_HPP
#define RENDERER2D_HPP
#include "open_engine/logging.hpp"
#include "open_engine/orthographic_camera.hpp"
#include "open_engine/renderer/texture.hpp"
#include "open_engine/ref_scope.hpp"
@@ -23,6 +24,7 @@ namespace OpenEngine {
static void BeginScene(const OrthographicCamera& camera);
static void EndScene();
static void Flush();
static void DrawQuad(const Transform& transform_data, const glm::vec4& color);
static void DrawQuad(const Transform& transform_data, const Ref<Texture2D>& texture, float tiling_factor = 1.0f);

View File

@@ -3,6 +3,7 @@
#include "open_engine/renderer/vertex_array.hpp"
#include <cstdint>
#include <glm/glm.hpp>
namespace OpenEngine {
@@ -22,7 +23,7 @@ namespace OpenEngine {
virtual void SetClearColor(const glm::vec4& color) = 0;
virtual void Clear() = 0;
virtual void DrawIndexed(const Ref<VertexArray>& vertex_array) = 0;
virtual void DrawIndexed(const Ref<VertexArray>& vertex_array, uint32_t count = 0) = 0;
static inline API GetAPI() { return api; };

View File

@@ -2,7 +2,6 @@
#define VERTEX_ARRAY_HPP
#include "open_engine/renderer/buffer.hpp"
#include "open_engine/core.hpp"
#include <vector>

View File

@@ -11,6 +11,15 @@ namespace OpenEngine {
// Vertex Buffer ====================================================
// ==================================================================
OpenGLVertexBuffer::OpenGLVertexBuffer(uint32_t size)
{
OE_PROFILE_FUNCTION();
glCreateBuffers(1, &id);
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_DYNAMIC_DRAW);
}
OpenGLVertexBuffer::OpenGLVertexBuffer(float* vertices, uint32_t size)
{
OE_PROFILE_FUNCTION();
@@ -24,6 +33,12 @@ namespace OpenEngine {
glDeleteBuffers(1, &id);
}
void OpenGLVertexBuffer::SetData(const void* data, uint32_t size)
{
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferSubData(GL_ARRAY_BUFFER, 0, size, data);
}
void OpenGLVertexBuffer::Bind() const
{
glBindBuffer(GL_ARRAY_BUFFER, id);

View File

@@ -1,7 +1,10 @@
#include <pch.hpp>
#include <core.hpp>
#include <opengl/opengl_renderer_api.hpp>
#include <instrumentor.hpp>
#include <cstdint>
#include <glad/glad.h>
namespace OpenEngine {
@@ -59,11 +62,12 @@ namespace OpenEngine {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void OpenGLRendererAPI::DrawIndexed(const Ref<VertexArray>& vertex_array)
void OpenGLRendererAPI::DrawIndexed(const Ref<VertexArray>& vertex_array, uint32_t index_count)
{
OE_PROFILE_FUNCTION();
glDrawElements(GL_TRIANGLES, vertex_array->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, nullptr);
uint32_t count = index_count? vertex_array->GetIndexBuffer()->GetCount() : index_count;
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr);
glBindTexture(GL_TEXTURE_2D, 0);
}
}

View File

@@ -1,3 +1,4 @@
#include "logging.hpp"
#include <pch.hpp>
#include <core.hpp>
@@ -25,7 +26,6 @@ namespace OpenEngine {
glTextureParameteri(id, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTextureParameteri(id, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
OpenGLTexture2D::OpenGLTexture2D(const std::string& path)

View File

@@ -65,6 +65,19 @@ namespace OpenEngine {
}
}
Ref<VertexBuffer> VertexBuffer::Create(uint32_t size)
{
OE_PROFILE_FUNCTION();
switch (Renderer::GetAPI()) {
case RendererAPI::API::None : OE_CORE_ASSERT(false, "No render API selected!"); return nullptr;
case RendererAPI::API::OpenGL : return CreateRef<OpenGLVertexBuffer>(size);
}
OE_CORE_ASSERT(false, "Selected API not supported");
return nullptr;
}
Ref<VertexBuffer> VertexBuffer::Create(float* vertices, uint32_t size)
{
OE_PROFILE_FUNCTION();

View File

@@ -1,92 +1,130 @@
#include <filesystem>
#include <glm/trigonometric.hpp>
#include <pch.hpp>
#include <renderer/buffer.hpp>
#include <renderer/texture.hpp>
#include <renderer/render_command.hpp>
#include <renderer/shader.hpp>
#include <renderer/vertex_array.hpp>
#include <renderer/renderer2d.hpp>
#include <renderer/texture.hpp>
#include <renderer/buffer.hpp>
#include <renderer/shader.hpp>
#include <cstdint>
#include <glm/fwd.hpp>
#include <glm/trigonometric.hpp>
#include <glm/ext/matrix_transform.hpp>
namespace OpenEngine {
struct Renderer2DData
struct QuadVertex
{
Ref<VertexArray> vertex_array;
Ref<Shader> texture_shader;
Ref<Texture2D> white_texture;
glm::vec3 position;
glm::vec4 color;
glm::vec2 tex_coord;
};
static Renderer2DData* renderer_data;
struct Renderer2DData
{
const uint32_t MaxQuads = 10000;
const uint32_t MaxVertices = MaxQuads * 4;
const uint32_t MaxIndices = MaxQuads * 6;
Ref<VertexArray> vertex_array;
Ref<VertexBuffer> vertex_buffer;
Ref<Shader> texture_shader;
Ref<Texture2D> white_texture;
uint32_t quad_index_count = 0;
QuadVertex* quad_vertex_base = nullptr;
QuadVertex* quad_vertex_ptr = nullptr;
};
static Renderer2DData renderer_data;
void Renderer2D::Init()
{
OE_PROFILE_FUNCTION();
renderer_data = new Renderer2DData();
renderer_data->vertex_array = VertexArray::Create();
float square_vertices[5 * 4] = {
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
};
Ref<VertexBuffer> vertex_buffer = VertexBuffer::Create(square_vertices, sizeof(square_vertices));
renderer_data.vertex_array = VertexArray::Create();
renderer_data.vertex_buffer = VertexBuffer::Create(renderer_data.MaxVertices * sizeof(QuadVertex));
BufferLayout layout = {
{ ShaderDataType::Float3, "a_Position" },
{ ShaderDataType::Float4, "a_Color" },
{ ShaderDataType::Float2, "a_TextCoord" }
};
vertex_buffer->SetLayout(layout);
renderer_data->vertex_array->AddVertexBuffer(vertex_buffer);
renderer_data.vertex_buffer->SetLayout(layout);
renderer_data.vertex_array->AddVertexBuffer(renderer_data.vertex_buffer);
uint32_t indices[6] = { 0, 1, 2, 2, 3, 0 };
Ref<IndexBuffer> index_buffer = IndexBuffer::Create(indices, sizeof(indices) / sizeof(uint32_t));
renderer_data.quad_vertex_base = new QuadVertex[renderer_data.MaxIndices];
renderer_data->vertex_array->SetIndexBuffer(index_buffer);
uint32_t* quad_indices = new uint32_t[renderer_data.MaxIndices];
renderer_data->white_texture = Texture2D::Create(1, 1);
uint32_t offset = 0;
for (uint32_t i = 0; i < renderer_data.MaxIndices; i += 6) {
quad_indices[i + 0] = offset + 0;
quad_indices[i + 1] = offset + 1;
quad_indices[i + 2] = offset + 2;
quad_indices[i + 3] = offset + 2;
quad_indices[i + 4] = offset + 3;
quad_indices[i + 5] = offset + 0;
offset += 4;
}
Ref<IndexBuffer> index_buffer = IndexBuffer::Create(quad_indices, renderer_data.MaxIndices);
renderer_data.vertex_array->SetIndexBuffer(index_buffer);
delete[] quad_indices;
renderer_data.white_texture = Texture2D::Create(1, 1);
uint32_t white_texture_data = 0xffffffff;
renderer_data->white_texture->SetData(&white_texture_data, sizeof(uint32_t));
renderer_data.white_texture->SetData(&white_texture_data, sizeof(uint32_t));
renderer_data->texture_shader = Shader::Create("assets/shaders/texture.glsl");
renderer_data->texture_shader->Bind();
renderer_data->texture_shader->SetInt("u_Texture", 0);
renderer_data.texture_shader = Shader::Create("assets/shaders/texture.glsl");
renderer_data.texture_shader->Bind();
renderer_data.texture_shader->SetInt("u_Texture", 0);
}
void Renderer2D::Shutdown()
{
OE_PROFILE_FUNCTION();
renderer_data.white_texture.reset();
renderer_data.vertex_array.reset();
renderer_data.vertex_buffer.reset();
delete renderer_data;
OE_PROFILE_FUNCTION();
}
void Renderer2D::BeginScene(const OrthographicCamera& camera)
{
OE_PROFILE_FUNCTION();
renderer_data->texture_shader->Bind();
renderer_data->texture_shader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
renderer_data.texture_shader->Bind();
renderer_data.texture_shader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
renderer_data.quad_index_count = 0;
renderer_data.quad_vertex_ptr = renderer_data.quad_vertex_base;
}
void Renderer2D::EndScene()
{
OE_PROFILE_FUNCTION();
uint32_t data_size = (uint8_t*)renderer_data.quad_vertex_ptr - (uint8_t*)renderer_data.quad_vertex_base;
renderer_data.vertex_buffer->SetData(renderer_data.quad_vertex_base, data_size);
Flush();
}
void Renderer2D::Flush()
{
RenderCommand::DrawIndexed(renderer_data.vertex_array, renderer_data.quad_index_count);
}
void Renderer2D::DrawQuad(const Transform& transform_data, const Ref<Texture2D>& texture, float tiling_factor)
{
OE_PROFILE_FUNCTION();
renderer_data->texture_shader->SetVec4("u_Color", glm::vec4(1.0f));
renderer_data->texture_shader->SetFloat("u_TilingFactor", tiling_factor);
renderer_data.texture_shader->SetVec4("u_Color", glm::vec4(1.0f));
renderer_data.texture_shader->SetFloat("u_TilingFactor", tiling_factor);
texture->Bind();
glm::mat4 transform = glm::translate(glm::mat4(1.0f), transform_data.position)
@@ -94,27 +132,51 @@ namespace OpenEngine {
glm::rotate(glm::mat4(1.0f), glm::radians(transform_data.rotation), {0.0f, 0.0f, 1.0f})
: 1.0f)
* glm::scale(glm::mat4(1.0f), transform_data.size);
renderer_data->texture_shader->SetMat4("u_Transform", transform);
renderer_data.texture_shader->SetMat4("u_Transform", transform);
renderer_data->vertex_array->Bind();
RenderCommand::DrawIndexed(renderer_data->vertex_array);
renderer_data.vertex_array->Bind();
RenderCommand::DrawIndexed(renderer_data.vertex_array);
}
void Renderer2D::DrawQuad(const Transform& transform_data, const glm::vec4& color)
{
OE_PROFILE_FUNCTION();
renderer_data->texture_shader->SetVec4("u_Color", color);
renderer_data->white_texture->Bind();
glm::vec3 position = transform_data.position;
glm::vec3 size = transform_data.size;
renderer_data.quad_vertex_ptr->position = position;
renderer_data.quad_vertex_ptr->color = color;
renderer_data.quad_vertex_ptr->tex_coord = { 0.0f, 0.0f };
renderer_data.quad_vertex_ptr++;
renderer_data.quad_vertex_ptr->position = { position.x + size.x, position.y, position.z };
renderer_data.quad_vertex_ptr->color = color;
renderer_data.quad_vertex_ptr->tex_coord = {1.0f, 0.0f};
renderer_data.quad_vertex_ptr++;
renderer_data.quad_vertex_ptr->position = { position.x + size.x, position.y + size.y, position.z };
renderer_data.quad_vertex_ptr->color = color;
renderer_data.quad_vertex_ptr->tex_coord = {1.0f, 1.0f};
renderer_data.quad_vertex_ptr++;
renderer_data.quad_vertex_ptr->position = { position.x, position.y + size.y, position.z };
renderer_data.quad_vertex_ptr->color = color;
renderer_data.quad_vertex_ptr->tex_coord = {0.0f, 1.0f};
renderer_data.quad_vertex_ptr++;
renderer_data.quad_index_count += 6;
/*
glm::mat4 transform = glm::translate(glm::mat4(1.0f), transform_data.position)
* ((transform_data.rotation != 0) ?
glm::rotate(glm::mat4(1.0f), glm::radians(transform_data.rotation), {0.0f, 0.0f, 1.0f})
: 1.0f)
* glm::scale(glm::mat4(1.0f), transform_data.size);
renderer_data->texture_shader->SetMat4("u_Transform", transform);
renderer_data.texture_shader->SetMat4("u_Transform", transform);
renderer_data->vertex_array->Bind();
RenderCommand::DrawIndexed(renderer_data->vertex_array);
renderer_data.vertex_array->Bind();
RenderCommand::DrawIndexed(renderer_data.vertex_array);
*/
}
}

View File

@@ -63,14 +63,14 @@ namespace OpenEngine {
glfw_initialized = true;
}
#ifdef OE_DEBUG
#ifdef OE_DEBUG_TOOLS
if (Renderer::GetAPI() == RendererAPI::API::OpenGL)
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
#endif
gl_window = glfwCreateWindow((int)props.width, (int)props.height, props.title.c_str(), nullptr, nullptr);
gl_window = glfwCreateWindow((int)props.width, (int)props.height, props.title.c_str(), nullptr, nullptr);
context = CreateScope<OpenGLContext>(gl_window);
context->Init();
context = CreateScope<OpenGLContext>(gl_window);
context->Init();
}