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

@@ -7,6 +7,7 @@ class ControlLayer : public OpenEngine::Layer
{ {
public: public:
ControlLayer(OpenEngine::Ref<OpenEngine::Layer> layer); ControlLayer(OpenEngine::Ref<OpenEngine::Layer> layer);
ControlLayer();
~ControlLayer() = default; ~ControlLayer() = default;
void OnUpdate() override; void OnUpdate() override;
@@ -17,6 +18,7 @@ class ControlLayer : public OpenEngine::Layer
private: private:
bool SwitchLayer(OpenEngine::KeyPressedEvent& event); bool SwitchLayer(OpenEngine::KeyPressedEvent& event);
bool SwitchExistingLayer(OpenEngine::KeyPressedEvent& event);
bool StopRunning(OpenEngine::KeyPressedEvent& event); bool StopRunning(OpenEngine::KeyPressedEvent& event);
OpenEngine::Ref<OpenEngine::Layer> active_layer; OpenEngine::Ref<OpenEngine::Layer> active_layer;

View File

@@ -8,19 +8,18 @@
""" """
*/ */
#include <glm/ext/matrix_clip_space.hpp>
#include <open_engine.hpp> #include <open_engine.hpp>
#include <glm/ext/matrix_clip_space.hpp>
#include "freetype/fttypes.h" #include "freetype/fttypes.h"
#include "open_engine/events/event.hpp" #include "open_engine/ref_scope.hpp"
#include "open_engine/logging.hpp" #include "shmup.hpp"
#include "open_engine/renderer/shader.hpp"
#include <freetype2/ft2build.h> #include <freetype2/ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
#include <glad/glad.h> #include <glad/glad.h>
#include <map> #include <map>
struct Character { struct Character {
unsigned int texture_id; // ID handle of the glyph texture unsigned int texture_id; // ID handle of the glyph texture
glm::ivec2 size; // Size of glyph glm::ivec2 size; // Size of glyph
@@ -31,7 +30,8 @@ struct Character {
class Overlay : public OpenEngine::Layer class Overlay : public OpenEngine::Layer
{ {
public: public:
Overlay() Overlay(OpenEngine::Ref<Shmup>& shmup)
: game_layer(shmup)
{}; {};
~Overlay() {}; ~Overlay() {};
@@ -205,7 +205,36 @@ class Overlay : public OpenEngine::Layer
float x = height - 40; float x = height - 40;
float y = 0; float y = 0;
//RenderText("Test String", 0.0f, 0.0f, 1.0f, {0.8f, 0.3f, 0.2f});
switch (game_layer->GetGameState()) {
case GameState::GameOver:
{
auto& window = OpenEngine::Application::Get().GetWindow();
int width = window.GetWidth();
int height = window.GetHeight();
float x = width / 2.0f;
float y = height / 2.0f;
RenderTextCentered("Game Over!", x, y, 1.0f, glm::vec3(0.8f, 0.2f, 0.3f));
break;
}
case GameState::Paused:
RenderTextCentered("Paused", x, y, 1.0f, glm::vec3(0.8f, 0.2f, 0.3f));
break;
case GameState::Playing:
break;
}
std::string s_score = "Score: " + std::to_string(game_layer->GetScore());
std::string s_lives = std::to_string(game_layer->GetLives()) + " lives";
RenderText(s_score, 10, OpenEngine::Application::Get().GetWindow().GetHeight() - 50, 1.0f, {0.8f, 0.2f, 0.3f});
RenderText(
s_lives,
OpenEngine::Application::Get().GetWindow().GetWidth() - 220,
OpenEngine::Application::Get().GetWindow().GetHeight() - 50,
1.0f,
{0.8f, 0.2f, 0.3f});
}; };
void OnEvent(OpenEngine::Event& event) override void OnEvent(OpenEngine::Event& event) override
@@ -216,6 +245,7 @@ class Overlay : public OpenEngine::Layer
std::map<char, Character> characters; std::map<char, Character> characters;
OpenEngine::Ref<OpenEngine::Shader> text_shader; OpenEngine::Ref<OpenEngine::Shader> text_shader;
glm::mat4 projection; glm::mat4 projection;
OpenEngine::Ref<Shmup> game_layer;
unsigned int VAO, VBO; unsigned int VAO, VBO;
}; };

View File

@@ -1,13 +1,12 @@
#ifndef SANDBOX_HPP #ifndef SANDBOX_HPP
#define SANDBOX_HPP #define SANDBOX_HPP
#include "open_engine/core/time.hpp"
#include <glm/fwd.hpp>
#include <open_engine.hpp> #include <open_engine.hpp>
#include "open_engine/core/time.hpp"
#include <glm/ext/matrix_transform.hpp> #include <glm/ext/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include <glm/fwd.hpp>
#include <imgui.h> #include <imgui.h>
#include <glad/glad.h> #include <glad/glad.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>

View File

@@ -1,12 +1,8 @@
#ifndef SHMUP_HPP #ifndef SHMUP_HPP
#define SHMUP_HPP #define SHMUP_HPP
#include <iostream>
#include <open_engine.hpp> #include <open_engine.hpp>
#include "imgui.h"
#include "overlay.hpp"
#include <fstream> #include <fstream>
#include <dlfcn.h> #include <dlfcn.h>
#include <glm/ext/matrix_transform.hpp> #include <glm/ext/matrix_transform.hpp>
@@ -16,12 +12,18 @@
#include <unistd.h> #include <unistd.h>
#include <vector> #include <vector>
enum class GameState
{
Playing,
Paused,
GameOver
};
class Shmup : public OpenEngine::Layer class Shmup : public OpenEngine::Layer
{ {
public: public:
Shmup(OpenEngine::Ref<Overlay>& overlay) Shmup()
: OpenEngine::Layer("shmup"), overlay(overlay), : camera((float)OpenEngine::Application::Get().GetWindow().GetWidth() /
camera((float)OpenEngine::Application::Get().GetWindow().GetWidth() /
OpenEngine::Application::Get().GetWindow().GetHeight(), 1.0f) OpenEngine::Application::Get().GetWindow().GetHeight(), 1.0f)
{ {
} }
@@ -37,8 +39,6 @@ class Shmup : public OpenEngine::Layer
bullet_tx = OpenEngine::Texture2D::Create("assets/textures/shmup/bullet.png"); bullet_tx = OpenEngine::Texture2D::Create("assets/textures/shmup/bullet.png");
} }
tr1 = {glm::vec3(0.0f, -0.9f, 1.0f), glm::vec3(0.1f), 0.0f};
LoadMap(); LoadMap();
} }
@@ -69,7 +69,7 @@ class Shmup : public OpenEngine::Layer
return overlapX && overlapY; return overlapX && overlapY;
} }
void MoveShip() void MovePlayerShip()
{ {
double delta = OpenEngine::Time::DeltaTime(); double delta = OpenEngine::Time::DeltaTime();
if (OpenEngine::Input::IsKeyPressed(OpenEngine::KeyCode::Up)) { if (OpenEngine::Input::IsKeyPressed(OpenEngine::KeyCode::Up)) {
@@ -95,30 +95,77 @@ class Shmup : public OpenEngine::Layer
tr1.position.x = 0.8; tr1.position.x = 0.8;
} }
bool MovePlayerShipDiscrete(OpenEngine::KeyPressedEvent& event)
{
if (state == GameState::Playing) {
double delta = OpenEngine::Time::DeltaTime();
if (event.GetKeyCode() == OpenEngine::KeyCode::Right) {
tr1.position.x += 0.1f;
}
if (event.GetKeyCode() == OpenEngine::KeyCode::Left) {
tr1.position.x -= 0.1f;
}
if (tr1.position.y <= -0.9)
tr1.position.y = -0.9;
if (tr1.position.y >= -0.3)
tr1.position.y = -0.3;
if (tr1.position.x <= -0.8)
tr1.position.x = -0.8;
if (tr1.position.x >= 0.8)
tr1.position.x = 0.8;
}
return true;
}
void MoveEntities(double time_step) {
double delta = time_step;
// Updating enemy positions
for (auto& enemy : enemies) {
enemy.position.y -= 0.3 * delta;
if (state == GameState::Playing && (enemy.position.y <= -1.1 || CheckCollision(
GetBounds(enemy.position, enemy.size),
GetBounds(tr1.position, tr1.size))))
lives--;
}
// Updating friendly bullets positions
for (auto& bullet : bullets) {
bullet.position.y += 1.1 * delta;
}
}
void UpdateEntity() void UpdateEntity()
{ {
double delta = OpenEngine::Time::DeltaTime(); double delta = OpenEngine::Time::DeltaTime();
for (auto& enemy : enemies) { MoveEntities(delta);
enemy.position.y -= 0.3 * delta;
if (enemy.position.y <= -1.1 || CheckCollision(
GetBounds(enemy.position, enemy.size),
GetBounds(tr1.position, tr1.size))){
lives--;
}
}
for (auto& bullet : bullets) {
bullet.position.y += 1.1 * delta;
}
// Deletes enemies offscreen
std::erase_if(enemies, [](const auto& enemy) { std::erase_if(enemies, [](const auto& enemy) {
return enemy.position.y <= -1.1f; return enemy.position.y <= -1.1f;
}); });
// Deletes bullets offscreen
std::erase_if(bullets, [](const auto& bullet) { std::erase_if(bullets, [](const auto& bullet) {
return bullet.position.y >= 1.2f; return bullet.position.y >= 1.2f;
}); });
// Lowers lives upon collision between player and enemy
for (auto& enemy : enemies) {
if (state == GameState::Playing) {
if (enemy.position.y <= -1.1)
lives--;
if (CheckCollision(
GetBounds(enemy.position, enemy.size),
GetBounds(tr1.position, tr1.size)))
lives = 0;
}
}
// Deletes enemy and bullet and increases score after collision
for (auto& bullet : bullets) { for (auto& bullet : bullets) {
for (auto& enemy : enemies) { for (auto& enemy : enemies) {
Bounds bullet_bounds = GetBounds(bullet.position, bullet.size); Bounds bullet_bounds = GetBounds(bullet.position, bullet.size);
@@ -135,33 +182,15 @@ class Shmup : public OpenEngine::Layer
} }
} }
} }
} }
void GameOver() void Render()
{ {
paused = true;
auto& window = OpenEngine::Application::Get().GetWindow();
int width = window.GetWidth();
int height = window.GetHeight();
enemies.clear();
bullets.clear();
float x = width / 2.0f;
float y = height / 2.0f;
overlay->RenderTextCentered("Game Over!", x, y, 1.0f, glm::vec3(0.8f, 0.2f, 0.3f));
};
void OnUpdate() override
{
float delta = OpenEngine::Time::DeltaTime();
OE_PROFILE_FUNCTION() OE_PROFILE_FUNCTION()
{ {
OE_PROFILE_SCOPE("Setting up Rendering"); OE_PROFILE_SCOPE("Setting up Rendering");
//OpenEngine::RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f}); OpenEngine::RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f});
OpenEngine::RenderCommand::SetClearColor({1.0f, 1.0f, 1.0f, 1.0f});
OpenEngine::RenderCommand::Clear(); OpenEngine::RenderCommand::Clear();
OpenEngine::Renderer2D::BeginScene(camera.GetCamera()); OpenEngine::Renderer2D::BeginScene(camera.GetCamera());
} }
@@ -177,75 +206,69 @@ class Shmup : public OpenEngine::Layer
OpenEngine::Renderer2D::EndScene(); OpenEngine::Renderer2D::EndScene();
if (!paused) { }
void OnUpdate() override
{
float delta = OpenEngine::Time::DeltaTime();
Render();
UpdateEntity();
if (state == GameState::Playing) {
if (spawn_cooldown >= spawn_min_time) { if (spawn_cooldown >= spawn_min_time) {
SpawnEnemyRandom(); //SpawnEnemyRandom();
//ReadMap(); ReadMap();
spawn_cooldown = 0; spawn_cooldown = 0;
if (spawn_min_time > 0.5) if (spawn_min_time > 0.5)
spawn_min_time -= 0.01; spawn_min_time -= 0.01;
} }
MoveShip(); //MovePlayerShip();
UpdateEntity();
if (shooting) if (shooting)
SpawnBullet(); SpawnBullet();
for (auto& enemy : enemies) {
if (CheckCollision(GetBounds(enemy.position, enemy.size), GetBounds(tr1.position, tr1.size)))
game_over = true;
}
shot_cooldown += delta; shot_cooldown += delta;
spawn_cooldown += delta; spawn_cooldown += delta;
} }
if (lives <= 0) if (lives <= 0)
game_over = true; state = GameState::GameOver;
if (game_over)
GameOver();
std::string s_score = "Score: " + std::to_string(score);
std::string s_lives = std::to_string(lives) + " lives";
overlay->RenderText(s_score, 10, OpenEngine::Application::Get().GetWindow().GetHeight() - 50, 1.0f, {0.8f, 0.2f, 0.3f});
overlay->RenderText(
s_lives,
OpenEngine::Application::Get().GetWindow().GetWidth() - 220,
OpenEngine::Application::Get().GetWindow().GetHeight() - 50,
1.0f,
{0.8f, 0.2f, 0.3f});
} }
void Reset() void Reset()
{ {
tr1 = {glm::vec3(0.0f, -0.9f, 1.0f), glm::vec3(0.1f), 0.0f}; tr1 = {glm::vec3(0.0f, -0.9f, -0.1f), glm::vec3(0.1f), 0.0f};
score = 0; score = 0;
lives = 5; lives = 5;
game_over = false;
paused = false; bullets.clear();
enemies.clear();
state = GameState::Playing;
} }
void SpawnEnemyRandom() void SpawnEnemyRandom()
{ {
static std::uniform_int_distribution<int> dist{-8, 8}; static std::uniform_int_distribution<int> dist{-8, 8};
OpenEngine::Transform enemy_tr({glm::vec3(dist(rd)/10.0f, 1.2f, -0.1f), glm::vec3(0.1f), 180.0f}); SpawnEnemy(dist(rd));
enemies.emplace_back(enemy_tr);
}; };
void SpawnEnemy(int x) void SpawnEnemy(int x)
{ {
OpenEngine::Transform enemy_tr({{x/10.0f, 1.2f, 0.0f}, glm::vec3(0.1f), 180.0f}); OpenEngine::Transform enemy_tr({{x/10.0f, 1.2f, 0.1f}, glm::vec3(0.1f), 180.0f});
enemies.emplace_back(enemy_tr); enemies.emplace_back(enemy_tr);
}; };
void LoadMap() void LoadMap(const char* path = "assets/maps/lvl1.txt")
{ {
std::string buffer; std::string buffer;
std::ifstream map_file("assets/maps/lvl1.txt"); std::ifstream map_file(path);
while (std::getline(map_file, buffer)) { while (std::getline(map_file, buffer)) {
map.emplace_back(buffer); map.emplace_back(buffer);
@@ -289,7 +312,7 @@ class Shmup : public OpenEngine::Layer
if (event.GetKeyCode() == OpenEngine::KeyCode::Space) { if (event.GetKeyCode() == OpenEngine::KeyCode::Space) {
shooting = true; shooting = true;
} }
if (game_over && event.GetKeyCode() == OpenEngine::KeyCode::Enter) { if (state == GameState::GameOver && event.GetKeyCode() == OpenEngine::KeyCode::Enter) {
Reset(); Reset();
} }
@@ -310,6 +333,7 @@ class Shmup : public OpenEngine::Layer
OpenEngine::EventDispatcher dispatcher(event); OpenEngine::EventDispatcher dispatcher(event);
dispatcher.Dispatch<OpenEngine::KeyPressedEvent>(BIND_EVENT_FN(Shmup::ProcessKeyPressedEvents)); dispatcher.Dispatch<OpenEngine::KeyPressedEvent>(BIND_EVENT_FN(Shmup::ProcessKeyPressedEvents));
dispatcher.Dispatch<OpenEngine::KeyPressedEvent>(BIND_EVENT_FN(Shmup::MovePlayerShipDiscrete));
dispatcher.Dispatch<OpenEngine::KeyReleasedEvent>(BIND_EVENT_FN(Shmup::ProcessKeyReleased)); dispatcher.Dispatch<OpenEngine::KeyReleasedEvent>(BIND_EVENT_FN(Shmup::ProcessKeyReleased));
{ {
OE_PROFILE_SCOPE("Camera OnEvent"); OE_PROFILE_SCOPE("Camera OnEvent");
@@ -317,26 +341,23 @@ class Shmup : public OpenEngine::Layer
} }
} }
void OnImGuiRender() override //void OnImGuiRender() override
{ //{
ImGuiIO io = ImGui::GetIO(); // ImGuiIO io = ImGui::GetIO();
static auto m_Font = io.Fonts->AddFontFromFileTTF("/usr/share/fonts/TTF/JetBrainsMono-Regular.ttf", 120.0f); // static auto m_Font = io.Fonts->AddFontFromFileTTF("/usr/share/fonts/TTF/JetBrainsMono-Regular.ttf", 120.0f);
ImGui::GetForegroundDrawList()->AddText(m_Font, 48.0f, {5.0f, 5.0f}, 0xffffffff, "test"); // ImGui::GetForegroundDrawList()->AddText(m_Font, 48.0f, {5.0f, 5.0f}, 0xffffffff, "test");
} //}
GameState GetGameState() { return state; };
int GetScore() { return score; };
int GetLives() { return lives; };
private: private:
//glm::vec3 square_pos = glm::vec3(0.0f);
//glm::vec4 square_color = glm::vec4(1.0f);
bool paused = false;
bool game_over = false;
//float color[4] = {0.5f, 0.3f, 0.4f, 1.0f};
OpenEngine::Ref<OpenEngine::Texture2D> ship; OpenEngine::Ref<OpenEngine::Texture2D> ship;
OpenEngine::Ref<OpenEngine::Texture2D> enemy_ship; OpenEngine::Ref<OpenEngine::Texture2D> enemy_ship;
OpenEngine::Ref<OpenEngine::Texture2D> bullet_tx; OpenEngine::Ref<OpenEngine::Texture2D> bullet_tx;
OpenEngine::Transform tr1; OpenEngine::Transform tr1 = {glm::vec3(0.0f, -0.9f, -0.1f), glm::vec3(0.1f), 0.0f};
std::vector<OpenEngine::Transform> enemies, bullets; std::vector<OpenEngine::Transform> enemies, bullets;
int score = 0; int score = 0;
int lives = 5; int lives = 5;
@@ -349,12 +370,10 @@ class Shmup : public OpenEngine::Layer
std::random_device rd; std::random_device rd;
std::mt19937 e{rd()}; // or std::default_random_engine e{rd()}; std::mt19937 e{rd()}; // or std::default_random_engine e{rd()};
//std::unordered_map<std::string, unsigned int> bindings;
OpenEngine::OrthographicCameraController camera; OpenEngine::OrthographicCameraController camera;
GameState state = GameState::Playing;
OpenEngine::Ref<Overlay> overlay; //OpenEngine::Ref<Overlay> overlay;
//std::vector<OpenEngine::Time::ProfilingResult> profiling_results;
}; };
#endif // SHMUP_HPP #endif // SHMUP_HPP

View File

@@ -60,7 +60,7 @@ bool ControlLayer::StopRunning(OpenEngine::KeyPressedEvent& event)
return true; return true;
} }
return false; return true;
} }

View File

@@ -12,15 +12,18 @@
Sandbox::Sandbox() Sandbox::Sandbox()
{ {
//OpenEngine::Ref<Sandbox2DLayer> initial_layer = std::make_shared<Sandbox2DLayer>(); //OpenEngine::Ref<Sandbox2DLayer> initial_layer = std::make_shared<Sandbox2DLayer>();
OpenEngine::Ref<Overlay> overlay = OpenEngine::CreateRef<Overlay>(); OpenEngine::Ref<OpenEngine::Layer> shmup = OpenEngine::CreateRef<Shmup>();
OpenEngine::Ref<Shmup> shmup = OpenEngine::CreateRef<Shmup>(overlay); //OpenEngine::Ref<Overlay> overlay = OpenEngine::CreateRef<Overlay>(shmup);
OpenEngine::Ref<ControlLayer> control_layer = std::make_shared<ControlLayer>(shmup); //OpenEngine::Ref<Overlay> overlay = OpenEngine::CreateRef<Overlay>(initial_layer);
OpenEngine::Ref<Modding> modding_layer = std::make_shared<Modding>(); OpenEngine::Ref<OpenEngine::Layer> control_layer = std::make_shared<ControlLayer>(shmup);
//OpenEngine::Ref<ControlLayer> control_layer = std::make_shared<ControlLayer>();
OpenEngine::Ref<OpenEngine::Layer> modding_layer = std::make_shared<Modding>();
QueueLayerPush(shmup); QueueLayerPush(shmup);
QueueLayerPush(modding_layer); //QueueLayerPush(initial_layer);
QueueLayerPush(control_layer); QueueLayerPush(control_layer);
QueueOverlayPush(overlay); QueueLayerPush(modding_layer);
//QueueOverlayPush(overlay);
} }
Sandbox::~Sandbox() Sandbox::~Sandbox()

View File

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

View File

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

View File

@@ -2,6 +2,7 @@
#define OPENGL_RENDERER_API_HPP #define OPENGL_RENDERER_API_HPP
#include "open_engine/renderer/renderer_api.hpp" #include "open_engine/renderer/renderer_api.hpp"
#include <cstdint>
namespace OpenEngine { namespace OpenEngine {
class OpenGLRendererAPI : public RendererAPI class OpenGLRendererAPI : public RendererAPI
@@ -14,7 +15,7 @@ namespace OpenEngine {
virtual void SetClearColor(const glm::vec4& color) override; virtual void SetClearColor(const glm::vec4& color) override;
virtual void Clear() 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: public:
virtual ~VertexBuffer() = default; virtual ~VertexBuffer() = default;
virtual void SetData(const void* data, uint32_t size) = 0;
virtual void Bind() const = 0; virtual void Bind() const = 0;
virtual void UnBind() const = 0; virtual void UnBind() const = 0;
virtual const BufferLayout& GetLayout() const = 0; virtual const BufferLayout& GetLayout() const = 0;
virtual void SetLayout(const BufferLayout& layout) = 0; virtual void SetLayout(const BufferLayout& layout) = 0;
static Ref<VertexBuffer> Create(uint32_t size);
static Ref<VertexBuffer> Create(float* vertices, uint32_t size); static Ref<VertexBuffer> Create(float* vertices, uint32_t size);
}; };
@@ -80,7 +83,7 @@ namespace OpenEngine {
virtual uint32_t GetCount() const = 0; 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(); 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(); 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) 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 #ifndef RENDERER2D_HPP
#define RENDERER2D_HPP #define RENDERER2D_HPP
#include "open_engine/logging.hpp"
#include "open_engine/orthographic_camera.hpp" #include "open_engine/orthographic_camera.hpp"
#include "open_engine/renderer/texture.hpp" #include "open_engine/renderer/texture.hpp"
#include "open_engine/ref_scope.hpp" #include "open_engine/ref_scope.hpp"
@@ -23,6 +24,7 @@ namespace OpenEngine {
static void BeginScene(const OrthographicCamera& camera); static void BeginScene(const OrthographicCamera& camera);
static void EndScene(); 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 glm::vec4& color);
static void DrawQuad(const Transform& transform_data, const Ref<Texture2D>& texture, float tiling_factor = 1.0f); 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 "open_engine/renderer/vertex_array.hpp"
#include <cstdint>
#include <glm/glm.hpp> #include <glm/glm.hpp>
namespace OpenEngine { namespace OpenEngine {
@@ -22,7 +23,7 @@ namespace OpenEngine {
virtual void SetClearColor(const glm::vec4& color) = 0; virtual void SetClearColor(const glm::vec4& color) = 0;
virtual void Clear() = 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; }; static inline API GetAPI() { return api; };

View File

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

View File

@@ -11,6 +11,15 @@ namespace OpenEngine {
// Vertex Buffer ==================================================== // 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) OpenGLVertexBuffer::OpenGLVertexBuffer(float* vertices, uint32_t size)
{ {
OE_PROFILE_FUNCTION(); OE_PROFILE_FUNCTION();
@@ -24,6 +33,12 @@ namespace OpenEngine {
glDeleteBuffers(1, &id); 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 void OpenGLVertexBuffer::Bind() const
{ {
glBindBuffer(GL_ARRAY_BUFFER, id); glBindBuffer(GL_ARRAY_BUFFER, id);

View File

@@ -1,7 +1,10 @@
#include <pch.hpp> #include <pch.hpp>
#include <core.hpp>
#include <opengl/opengl_renderer_api.hpp> #include <opengl/opengl_renderer_api.hpp>
#include <instrumentor.hpp>
#include <cstdint>
#include <glad/glad.h> #include <glad/glad.h>
namespace OpenEngine { namespace OpenEngine {
@@ -59,11 +62,12 @@ namespace OpenEngine {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 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(); 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); glBindTexture(GL_TEXTURE_2D, 0);
} }
} }

View File

@@ -1,3 +1,4 @@
#include "logging.hpp"
#include <pch.hpp> #include <pch.hpp>
#include <core.hpp> #include <core.hpp>
@@ -25,7 +26,6 @@ namespace OpenEngine {
glTextureParameteri(id, GL_TEXTURE_WRAP_S, GL_REPEAT); glTextureParameteri(id, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTextureParameteri(id, GL_TEXTURE_WRAP_T, GL_REPEAT); glTextureParameteri(id, GL_TEXTURE_WRAP_T, GL_REPEAT);
} }
OpenGLTexture2D::OpenGLTexture2D(const std::string& path) 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) Ref<VertexBuffer> VertexBuffer::Create(float* vertices, uint32_t size)
{ {
OE_PROFILE_FUNCTION(); OE_PROFILE_FUNCTION();

View File

@@ -1,92 +1,130 @@
#include <filesystem>
#include <glm/trigonometric.hpp>
#include <pch.hpp> #include <pch.hpp>
#include <renderer/buffer.hpp>
#include <renderer/texture.hpp>
#include <renderer/render_command.hpp> #include <renderer/render_command.hpp>
#include <renderer/shader.hpp>
#include <renderer/vertex_array.hpp> #include <renderer/vertex_array.hpp>
#include <renderer/renderer2d.hpp> #include <renderer/renderer2d.hpp>
#include <renderer/texture.hpp>
#include <renderer/buffer.hpp>
#include <renderer/shader.hpp>
#include <cstdint> #include <cstdint>
#include <glm/fwd.hpp> #include <glm/fwd.hpp>
#include <glm/trigonometric.hpp>
#include <glm/ext/matrix_transform.hpp> #include <glm/ext/matrix_transform.hpp>
namespace OpenEngine { namespace OpenEngine {
struct Renderer2DData struct QuadVertex
{ {
Ref<VertexArray> vertex_array; glm::vec3 position;
Ref<Shader> texture_shader; glm::vec4 color;
Ref<Texture2D> white_texture; 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() void Renderer2D::Init()
{ {
OE_PROFILE_FUNCTION(); OE_PROFILE_FUNCTION();
renderer_data = new Renderer2DData(); renderer_data.vertex_array = VertexArray::Create();
renderer_data->vertex_array = VertexArray::Create(); renderer_data.vertex_buffer = VertexBuffer::Create(renderer_data.MaxVertices * sizeof(QuadVertex));
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));
BufferLayout layout = { BufferLayout layout = {
{ ShaderDataType::Float3, "a_Position" }, { ShaderDataType::Float3, "a_Position" },
{ ShaderDataType::Float4, "a_Color" },
{ ShaderDataType::Float2, "a_TextCoord" } { ShaderDataType::Float2, "a_TextCoord" }
}; };
vertex_buffer->SetLayout(layout); renderer_data.vertex_buffer->SetLayout(layout);
renderer_data->vertex_array->AddVertexBuffer(vertex_buffer); renderer_data.vertex_array->AddVertexBuffer(renderer_data.vertex_buffer);
uint32_t indices[6] = { 0, 1, 2, 2, 3, 0 }; renderer_data.quad_vertex_base = new QuadVertex[renderer_data.MaxIndices];
Ref<IndexBuffer> index_buffer = IndexBuffer::Create(indices, sizeof(indices) / sizeof(uint32_t));
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; 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 = Shader::Create("assets/shaders/texture.glsl");
renderer_data.texture_shader->Bind();
renderer_data->texture_shader->Bind(); renderer_data.texture_shader->SetInt("u_Texture", 0);
renderer_data->texture_shader->SetInt("u_Texture", 0);
} }
void Renderer2D::Shutdown() 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) void Renderer2D::BeginScene(const OrthographicCamera& camera)
{ {
OE_PROFILE_FUNCTION(); OE_PROFILE_FUNCTION();
renderer_data->texture_shader->Bind(); renderer_data.texture_shader->Bind();
renderer_data->texture_shader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix()); 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() 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) void Renderer2D::DrawQuad(const Transform& transform_data, const Ref<Texture2D>& texture, float tiling_factor)
{ {
OE_PROFILE_FUNCTION(); OE_PROFILE_FUNCTION();
renderer_data->texture_shader->SetVec4("u_Color", glm::vec4(1.0f)); renderer_data.texture_shader->SetVec4("u_Color", glm::vec4(1.0f));
renderer_data->texture_shader->SetFloat("u_TilingFactor", tiling_factor); renderer_data.texture_shader->SetFloat("u_TilingFactor", tiling_factor);
texture->Bind(); texture->Bind();
glm::mat4 transform = glm::translate(glm::mat4(1.0f), transform_data.position) 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}) glm::rotate(glm::mat4(1.0f), glm::radians(transform_data.rotation), {0.0f, 0.0f, 1.0f})
: 1.0f) : 1.0f)
* glm::scale(glm::mat4(1.0f), transform_data.size); * 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(); renderer_data.vertex_array->Bind();
RenderCommand::DrawIndexed(renderer_data->vertex_array); RenderCommand::DrawIndexed(renderer_data.vertex_array);
} }
void Renderer2D::DrawQuad(const Transform& transform_data, const glm::vec4& color) void Renderer2D::DrawQuad(const Transform& transform_data, const glm::vec4& color)
{ {
OE_PROFILE_FUNCTION(); OE_PROFILE_FUNCTION();
renderer_data->texture_shader->SetVec4("u_Color", color); glm::vec3 position = transform_data.position;
renderer_data->white_texture->Bind(); 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) glm::mat4 transform = glm::translate(glm::mat4(1.0f), transform_data.position)
* ((transform_data.rotation != 0) ? * ((transform_data.rotation != 0) ?
glm::rotate(glm::mat4(1.0f), glm::radians(transform_data.rotation), {0.0f, 0.0f, 1.0f}) glm::rotate(glm::mat4(1.0f), glm::radians(transform_data.rotation), {0.0f, 0.0f, 1.0f})
: 1.0f) : 1.0f)
* glm::scale(glm::mat4(1.0f), transform_data.size); * 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(); renderer_data.vertex_array->Bind();
RenderCommand::DrawIndexed(renderer_data->vertex_array); RenderCommand::DrawIndexed(renderer_data.vertex_array);
*/
} }
} }

View File

@@ -63,14 +63,14 @@ namespace OpenEngine {
glfw_initialized = true; glfw_initialized = true;
} }
#ifdef OE_DEBUG #ifdef OE_DEBUG_TOOLS
if (Renderer::GetAPI() == RendererAPI::API::OpenGL) if (Renderer::GetAPI() == RendererAPI::API::OpenGL)
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
#endif #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 = CreateScope<OpenGLContext>(gl_window);
context->Init(); context->Init();
} }