From 593a16c9ccbe92f4c499b3143b00f6ad3fadd110 Mon Sep 17 00:00:00 2001 From: Joey Pollack Date: Wed, 10 Aug 2022 15:49:24 -0400 Subject: [PATCH] Re-write of renderer is more or less stable and hooked back up to the core engine. Quads do not render but gui windows do. --- CMakeLists.txt | 11 +- src/assets/types/image.h | 2 +- src/core/common_defs.h | 3 + src/core/core.cpp | 108 ++------ src/core/core.h | 12 +- src/core/run_mode.h | 3 +- src/internal_data/data_manager.cpp | 38 ++- src/internal_data/data_manager.h | 8 +- src/platform/key_codes.h | 2 +- src/platform/window.cpp | 12 + src/platform/window.h | 6 + src/renderer/frame_buffer.cpp | 7 +- src/renderer/index_buffer.cpp | 91 ++++++ src/renderer/index_buffer.h | 42 +++ src/renderer/orthographic_camera.cpp | 5 + src/renderer/orthographic_camera.h | 1 + src/renderer/render_common.h | 18 ++ src/renderer/render_context.cpp | 30 +- src/renderer/render_context.h | 7 +- src/renderer/renderer2D.cpp | 261 ++++++++++++++++++ src/renderer/renderer2D.h | 80 ++++++ src/renderer/shader.cpp | 211 ++++++++++++++ src/renderer/shader.h | 68 +++++ .../{OLD/opengl => shaders}/defaultShaders.h | 36 ++- src/renderer/texture.cpp | 11 +- src/renderer/texture.h | 4 +- src/renderer/vertex_buffer.cpp | 216 +++++++++++---- src/renderer/vertex_buffer.h | 54 +++- src/run_modes/editor/editor.cpp | 2 +- src/run_modes/editor/editor.h | 2 +- src/run_modes/editor/editor_helpers.cpp | 17 +- src/run_modes/editor/editor_helpers.h | 4 +- src/run_modes/editor/panels/world_tree.cpp | 4 +- src/run_modes/testbed/scenes/base_scene.cpp | 5 - src/run_modes/testbed/scenes/base_scene.h | 1 - .../testbed/scenes/physics_scene.cpp | 50 ++-- src/run_modes/testbed/scenes/physics_scene.h | 2 +- .../testbed/scenes/simple_render_scene.cpp | 111 +++++--- .../testbed/scenes/simple_render_scene.h | 13 +- src/run_modes/testbed/testbed.cpp | 10 +- src/run_modes/testbed/testbed.h | 3 +- src/world/components.h | 2 +- src/world/world.cpp | 3 +- test_data/engine_state.json | 2 +- 44 files changed, 1258 insertions(+), 320 deletions(-) create mode 100644 src/renderer/index_buffer.cpp create mode 100644 src/renderer/index_buffer.h create mode 100644 src/renderer/render_common.h create mode 100644 src/renderer/renderer2D.cpp create mode 100644 src/renderer/shader.cpp create mode 100644 src/renderer/shader.h rename src/renderer/{OLD/opengl => shaders}/defaultShaders.h (62%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ef6e1d..2a23d59 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,10 +73,14 @@ set(LUNARIUM_SRC "src/platform/window.cpp" "src/platform/terminal.cpp" "src/renderer/render_context.cpp" +"src/renderer/renderer2D.cpp" "src/renderer/vertex_buffer.cpp" +"src/renderer/index_buffer.cpp" "src/renderer/orthographic_camera.cpp" "src/renderer/texture.cpp" +"src/renderer/shader.cpp" "src/renderer/frame_buffer.cpp" +"src/renderer/orthographic_camera.cpp" "src/gui/gui.cpp" "src/gui/imgui_ext.cpp" "src/gui/panel.cpp" @@ -163,9 +167,12 @@ add_subdirectory(external/nativefiledialog-extended) add_subdirectory(src/run_modes/testbed) # add run mode editor -add_subdirectory(src/run_modes/editor) +if (NOT NO_EDITOR) + add_subdirectory(src/run_modes/editor) +endif() -# add run mode editor + +# add run mode game add_subdirectory(src/run_modes/game) target_include_directories(${PROJECT_NAME} diff --git a/src/assets/types/image.h b/src/assets/types/image.h index de0f84a..6e02c1c 100644 --- a/src/assets/types/image.h +++ b/src/assets/types/image.h @@ -15,7 +15,7 @@ namespace lunarium { - enum ImageFormat + enum class ImageFormat { RGB, RGBA, diff --git a/src/core/common_defs.h b/src/core/common_defs.h index 7cad8a4..e3ff6ac 100644 --- a/src/core/common_defs.h +++ b/src/core/common_defs.h @@ -54,4 +54,7 @@ typedef u64 LUUID; #endif +// The more complex Lunarium types +#include "types.h" + #endif // LUNARIUM_COMMON_DEFS_H_ \ No newline at end of file diff --git a/src/core/core.cpp b/src/core/core.cpp index 69b1741..af31c74 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -23,18 +23,22 @@ // Sub Systems #include #include -#include +#include +#include +#include #include // #include // #include #include #include +#include + namespace lunarium { Core* Core::mpInstance = nullptr; Core::Core() - : mbIsInit(false), mpArgs(nullptr), mpWindow(nullptr), mpGraphics(nullptr), mpInput(nullptr), + : mbIsInit(false), mpArgs(nullptr), mpWindow(nullptr), mpRenderContext(nullptr), mpRenderer2D(nullptr), mpInput(nullptr), mGUI(GUI::GetInstance()), mbMidRender(false), mbMidTextureRender(false), mpRunMode(nullptr), mbShowGuiDemo(false) { @@ -92,9 +96,9 @@ namespace lunarium delete mpInstance->mpInput; mpInstance->mpInput = nullptr; - mpInstance->mpGraphics->Shutdown(); - delete mpInstance->mpGraphics; - mpInstance->mpGraphics = nullptr; + mpInstance->mpRenderContext->Shutdown(&mpInstance->mpRenderer2D); + delete mpInstance->mpRenderer2D; + mpInstance->mpRenderer2D = nullptr; mpInstance->mpWindow->Shutdown(); delete mpInstance->mpWindow; @@ -173,7 +177,7 @@ namespace lunarium if (RenderSystem::OPENGL == mState.Display.Renderer) { - mpGraphics = new OglGraphics; + mpRenderContext = new RenderContext; } else if (RenderSystem::VULKAN == mState.Display.Renderer) { @@ -190,19 +194,19 @@ namespace lunarium // TODO: This should probably be based on a state setting instead #ifdef _DEBUG - result = mpGraphics->Initialize(mpWindow); + result = mpRenderContext->Initialize(mpWindow, &mpRenderer2D); #else - result = mpGraphics->Initialize(mpWindow, false); + result = mpRenderContext->Initialize(mpWindow, &mpRenderer2D, false); #endif if (Failed(result)) { Logger::Fatal(LogCategory::CORE, - "Could not initialized the graphics system: %s", result.Description); + "Could not initialize the graphics system: %s", result.Description.c_str()); return; } - mpGraphics->SetClearColor(Color(0.5f, 0.5f, 0.75f, 1.0f)); + mpRenderer2D->SetClearColor(Color(0.5f, 0.5f, 0.75f, 1.0f)); // INPUT mpInput = new InputManager; @@ -292,7 +296,8 @@ namespace lunarium // Display FPS in window title for now std::string title = "Lunarium - FPS: "; title += std::to_string(mFrameCounter.GetFrameData().CurrentFPS); - glfwSetWindowTitle(mpWindow->GetWindow(), title.c_str()); + //glfwSetWindowTitle(mpWindow->GetWindow(), title.c_str()); + mpWindow->SetWindowTitle(title); // Get pointers to gui panels CoreConsole* con = (CoreConsole*)mPanels[mPanelIDs.CoreConsole]; @@ -316,7 +321,7 @@ namespace lunarium } else { - // Check if there is a new LUA command + // Check if there is a new script command std::string command; if (con && con->GetNewCommand(command)) { @@ -331,75 +336,12 @@ namespace lunarium // UPDATE game state - mpRunMode->OnTick(mFrameCounter.GetFrameData().LastFrameTime); - - // DEBUG PANELS - if (Core::Input().IsKeyPressed(KeyCode::F2, true) && con) - { - con->SetOpen(!con->IsOpen()); - } - - if (Core::Input().IsKeyPressed(KeyCode::F3, true)) - { - mbShowGuiDemo = !mbShowGuiDemo; - } - - - // RENDER - if (mbMidTextureRender) - { - Logger::Warn(LogCategory::CORE, "Render to texture was not ended!"); - EndRenderToTexture(); - } - - mGUI.NewFrame(); - mpGraphics->BeginDraw(); - mbMidRender = true; - - // Gui windows - if (con) - { - con->DoFrame(); - } - - if (mbShowGuiDemo) - { - mGUI.ShowDemoWindow(mbShowGuiDemo); - } + mpRunMode->OnUpdate(mFrameCounter.GetFrameData().LastFrameTime); - // Run mode - mpRunMode->OnRender(mpGraphics); - - // END RENDER - mGUI.EndFrame(); - mpGraphics->EndDraw(); - mbMidRender = false; + } } - OpRes Core::BeginRenderToTexture(int id) - { - if (mbMidRender) - { - return OpRes::Fail("Can not switch render targets in the middle of rendering"); - } - - mbMidTextureRender = true; - mpGraphics->BeginDraw(id); - return OpRes::OK(); - } - - Image* Core::EndRenderToTexture() - { - if (!mbMidTextureRender) - { - return nullptr; - } - - mbMidTextureRender = false; - return mpGraphics->EndDraw(); - } - //////////////////////////////////////////////////////////// // STATIC INTERFACE //////////////////////////////////////////////////////////// @@ -409,9 +351,15 @@ namespace lunarium return *mpInstance->mpWindow; } - IGraphics& Core::Graphics() + Renderer2D& Core::Graphics() + { + return *mpInstance->mpRenderer2D; + } + + + GUI& Core::GUI() { - return *mpInstance->mpGraphics; + return mpInstance->mGUI; } InputManager& Core::Input() @@ -436,7 +384,7 @@ namespace lunarium mPanels[id] = nullptr; } - CoreLogListener::CoreLogListener(uint32_t acceptedLogLevels, uint32_t acceptedLogCategories, const char* myName) + CoreLogListener::CoreLogListener(uint32_t acceptedLogLevels, uint32_t acceptedLogCategories, const char* myName) : LogListener(acceptedLogLevels, acceptedLogCategories, myName) { } diff --git a/src/core/core.h b/src/core/core.h index 8be0268..e081a64 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -24,7 +24,8 @@ namespace lunarium class Image; class TestBed; class GUI; - class IGraphics; + class Renderer2D; + class RenderContext; class Window; class InputManager; @@ -44,9 +45,6 @@ namespace lunarium void RunGameLoop(); - OpRes BeginRenderToTexture(int id); - Image* EndRenderToTexture(); - private: // DATA static Core* mpInstance; @@ -74,14 +72,16 @@ namespace lunarium private: // SUBSYSTEMS Window* mpWindow; - IGraphics* mpGraphics; + RenderContext* mpRenderContext; + Renderer2D* mpRenderer2D; InputManager* mpInput; GUI& mGUI; public: // SUBSYSTEM GETTERS static Window& MainWindow(); - static IGraphics& Graphics(); + static Renderer2D& Graphics(); + static GUI& GUI(); static InputManager& Input(); private: // HELPERS diff --git a/src/core/run_mode.h b/src/core/run_mode.h index 9902b72..55fbf26 100644 --- a/src/core/run_mode.h +++ b/src/core/run_mode.h @@ -21,8 +21,7 @@ namespace lunarium public: virtual OpRes Initialize() = 0; virtual void Shutdown() = 0; - virtual void OnTick(double delta) = 0; - virtual void OnRender(IGraphics* g) = 0; + virtual void OnUpdate(double delta) = 0; public: // Optional Events virtual void OnKeyPress(InputManager::KeyPress kp); diff --git a/src/internal_data/data_manager.cpp b/src/internal_data/data_manager.cpp index a8f1167..9303b28 100644 --- a/src/internal_data/data_manager.cpp +++ b/src/internal_data/data_manager.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include // ASSETS @@ -26,61 +26,55 @@ namespace lunarium { // Init asset pointers - Image* DataManager::mFolderIcon = nullptr; - Image* DataManager::mNewFolderIcon = nullptr; - Image* DataManager::mUpArrowIcon = nullptr; + Texture* DataManager::mFolderIcon = nullptr; + Texture* DataManager::mNewFolderIcon = nullptr; + Texture* DataManager::mUpArrowIcon = nullptr; void DataManager::Initialize() { ///////////////////////////////////////// // Folder16 - ImageFormat format = ImageFormat::RGB; + TextureFormat format = TextureFormat::RGB; if (lunarium_data_folder16::folder16DataNumChannels == 4) { - format = ImageFormat::RGBA; + format = TextureFormat::RGBA; } unsigned char* pData = new unsigned char[lunarium_data_folder16::folder16DataSize]; memcpy(pData, lunarium_data_folder16::folder16Data, lunarium_data_folder16::folder16DataSize); - mFolderIcon = new Image(pData, lunarium_data_folder16::folder16DataWidth, lunarium_data_folder16::folder16DataHeight, format); - Core::Graphics().RegisterImage(*mFolderIcon); - mFolderIcon->FreeRawData(); + mFolderIcon = Texture::Create(pData, lunarium_data_folder16::folder16DataWidth, lunarium_data_folder16::folder16DataHeight, format); ////////////////////////////////////////// ///////////////////////////////////////// // new_dir_icon - format = ImageFormat::RGB; + format = TextureFormat::RGB; if (lunarium_data_newdir::new_folderDataNumChannels == 4) { - format = ImageFormat::RGBA; + format = TextureFormat::RGBA; } pData = new unsigned char[lunarium_data_newdir::new_folderDataSize]; memcpy(pData, lunarium_data_newdir::new_folderData, lunarium_data_newdir::new_folderDataSize); - mNewFolderIcon = new Image(pData, lunarium_data_newdir::new_folderDataWidth, lunarium_data_newdir::new_folderDataHeight, format); - Core::Graphics().RegisterImage(*mNewFolderIcon); - mNewFolderIcon->FreeRawData(); + mNewFolderIcon = Texture::Create(pData, lunarium_data_newdir::new_folderDataWidth, lunarium_data_newdir::new_folderDataHeight, format); ////////////////////////////////////////// ///////////////////////////////////////// // up_arrow_icon - format = ImageFormat::RGB; + format = TextureFormat::RGB; if (lunarium_data_uparrow::up_arrow_iconDataNumChannels == 4) { - format = ImageFormat::RGBA; + format = TextureFormat::RGBA; } pData = new unsigned char[lunarium_data_uparrow::up_arrow_iconDataSize]; memcpy(pData, lunarium_data_uparrow::up_arrow_iconData, lunarium_data_uparrow::up_arrow_iconDataSize); - mUpArrowIcon = new Image(pData, lunarium_data_uparrow::up_arrow_iconDataWidth, lunarium_data_uparrow::up_arrow_iconDataHeight, format); - Core::Graphics().RegisterImage(*mUpArrowIcon); - mUpArrowIcon->FreeRawData(); + mUpArrowIcon = Texture::Create(pData, lunarium_data_uparrow::up_arrow_iconDataWidth, lunarium_data_uparrow::up_arrow_iconDataHeight, format); ////////////////////////////////////////// } void DataManager::Shutdown() { - delete mUpArrowIcon; - delete mNewFolderIcon; - delete mFolderIcon; + Texture::Destroy(&mUpArrowIcon); + Texture::Destroy(&mNewFolderIcon); + Texture::Destroy(&mFolderIcon); } bool DataManager::GenerateFontFileAt(Font font, const char * filename) diff --git a/src/internal_data/data_manager.h b/src/internal_data/data_manager.h index 07c1407..65d198f 100644 --- a/src/internal_data/data_manager.h +++ b/src/internal_data/data_manager.h @@ -19,7 +19,7 @@ namespace lunarium F_ROBOTO, }; - class Image; + class Texture; class DataManager { public: @@ -31,9 +31,9 @@ namespace lunarium static bool GenerateFontFileAt(Font font, const char* filename); // DATA wrapped in asset types - static Image* mFolderIcon; - static Image* mNewFolderIcon; - static Image* mUpArrowIcon; + static Texture* mFolderIcon; + static Texture* mNewFolderIcon; + static Texture* mUpArrowIcon; }; } diff --git a/src/platform/key_codes.h b/src/platform/key_codes.h index 0e4b3dc..01d0a2d 100644 --- a/src/platform/key_codes.h +++ b/src/platform/key_codes.h @@ -134,7 +134,7 @@ namespace lunarium KEY_UNKNOWN = 0xFFFF }; - static std::vector KeyCodeList = { + static std::vector KeyCodeList = { KeyCode::A, KeyCode::B, KeyCode::C, diff --git a/src/platform/window.cpp b/src/platform/window.cpp index 454e715..d45890e 100644 --- a/src/platform/window.cpp +++ b/src/platform/window.cpp @@ -117,6 +117,18 @@ namespace lunarium } + std::string Window::GetWindowTitle() + { + return mTitle; + } + + void Window::SetWindowTitle(std::string title) + { + mTitle = title; + glfwSetWindowTitle(mpWindow, mTitle.c_str()); + } + + void Window::Hide() { glfwHideWindow(mpWindow); diff --git a/src/platform/window.h b/src/platform/window.h index 5b3cc86..6b07818 100644 --- a/src/platform/window.h +++ b/src/platform/window.h @@ -17,6 +17,8 @@ #include #include +#include + namespace lunarium { class Window @@ -32,6 +34,9 @@ namespace lunarium glm::vec2 GetCursorPos() const; void SetCursorPos(glm::vec2 pos); + std::string GetWindowTitle(); + void SetWindowTitle(std::string title); + void Resize(int width, int height); // TODO: See https://www.glfw.org/docs/latest/window_guide.html#window_full_screen @@ -56,6 +61,7 @@ namespace lunarium // There can only be 1 window for now static bool mbIsInit; GLFWwindow* mpWindow; + std::string mTitle; }; } diff --git a/src/renderer/frame_buffer.cpp b/src/renderer/frame_buffer.cpp index 2260e5e..4ccae33 100644 --- a/src/renderer/frame_buffer.cpp +++ b/src/renderer/frame_buffer.cpp @@ -41,9 +41,6 @@ namespace lunarium glDeleteFramebuffers(1, &mGLID); } - glGenFramebuffers(1, &mGLID); - Bind(); - if (mTexture) { Texture::Destroy(&mTexture); @@ -51,6 +48,9 @@ namespace lunarium mTexture = Texture::Create(nullptr, width, height); + glGenFramebuffers(1, &mGLID); + Bind(); + // Attach texture glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture->GetGLID(), 0); @@ -79,6 +79,7 @@ namespace lunarium void FrameBuffer::Bind() { glBindFramebuffer(GL_FRAMEBUFFER, mGLID); + glViewport(0, 0, mTexture->GetWidth(), mTexture->GetHeight()); } void FrameBuffer::Unbind() diff --git a/src/renderer/index_buffer.cpp b/src/renderer/index_buffer.cpp new file mode 100644 index 0000000..41f4b91 --- /dev/null +++ b/src/renderer/index_buffer.cpp @@ -0,0 +1,91 @@ +/****************************************************************************** +* File - index_buffer.h +* Author - Joey Pollack +* Date - 2022/08/05 (y/m/d) +* Mod Date - 2022/08/05 (y/m/d) +* Description - OpenGL index buffer object +******************************************************************************/ + +#include "index_buffer.h" +#include + +#include + +namespace lunarium +{ + IndexBuffer::IndexBuffer(u32 size, u32* indices) + : mIsStatic(true), mGLID(0), mIndex(0), mSize(size) + { + mIsStatic = indices != nullptr; + glGenBuffers(1, &mGLID); + Bind(); + + if (indices) + { + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW); + } + else + { + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, nullptr, GL_DYNAMIC_DRAW); + } + } + + // IndexBuffer::IndexBuffer(u32 size) + // : mIsStatic(false), mGLID(0), mIndex(0), mSize(size + // { + // glGenBuffers(1, &mGLID); + // Bind(); + // glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, nullptr, GL_DYNAMIC_DRAW); + + // } + + + bool IndexBuffer::IsStatic() const + { + return mIsStatic; + } + + void IndexBuffer::Clear() + { + if (mIsStatic) + { + Logger::Warn(LogCategory::GRAPHICS, "Attemping to clear a static VertexBuffer"); + } + + mIndex = 0; + } + + void IndexBuffer::Bind() + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLID); + } + + + bool IndexBuffer::PushIndices(const u32* indices, u32 size) + { + if (mIsStatic) + { + Logger::Warn(LogCategory::GRAPHICS, "Cannot push indices into a static buffer!"); + return false; + } + + // NOTE: BE CAREFUL! mSize is the size in bytes, not number of vertices. + if (mIndex + size >= mSize) + { + // Vertices do not fit into the buffer + Logger::Warn(LogCategory::GRAPHICS, "Cannot push indices into buffer - not enough space left! Space left: %n, data size: %n", mSize - mIndex, size); + return false; + } + + Bind(); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, mIndex, size, indices); + + mIndex += size; + return true; + } + + u32 IndexBuffer::GetGLID() const + { + return mGLID; + } +} \ No newline at end of file diff --git a/src/renderer/index_buffer.h b/src/renderer/index_buffer.h new file mode 100644 index 0000000..45437d4 --- /dev/null +++ b/src/renderer/index_buffer.h @@ -0,0 +1,42 @@ +/****************************************************************************** +* File - index_buffer.h +* Author - Joey Pollack +* Date - 2022/08/05 (y/m/d) +* Mod Date - 2022/08/05 (y/m/d) +* Description - OpenGL index buffer object +******************************************************************************/ + +#ifndef LUNARIUM_INDEX_BUFFER_H_ +#define LUNARIUM_INDEX_BUFFER_H_ + +#include +#include + +namespace lunarium +{ + class IndexBuffer + { + public: + + IndexBuffer(u32 size, u32* indices = nullptr); + //IndexBuffer(u32 size); + + bool IsStatic() const; + void Clear(); + void Bind(); + + /// Returns false if the data does not fit in the buffer + /// size is the size in bytes + bool PushIndices(const u32* indices, u32 size); + u32 GetGLID() const; + + private: + u32 mGLID; + bool mIsStatic; + u32 mSize; + u32 mIndex; + + }; +} + +#endif // LUNARIUM_INDEX_BUFFER_H_ \ No newline at end of file diff --git a/src/renderer/orthographic_camera.cpp b/src/renderer/orthographic_camera.cpp index b340971..b9220af 100644 --- a/src/renderer/orthographic_camera.cpp +++ b/src/renderer/orthographic_camera.cpp @@ -52,6 +52,11 @@ namespace lunarium return mViewProj; } + Sizef OrthographicCamera::GetViewport() const + { + return mViewportSize; + } + void OrthographicCamera::SetViewportSize(Sizef size) { mViewportSize = size; diff --git a/src/renderer/orthographic_camera.h b/src/renderer/orthographic_camera.h index a96f41c..0b4c531 100644 --- a/src/renderer/orthographic_camera.h +++ b/src/renderer/orthographic_camera.h @@ -28,6 +28,7 @@ namespace lunarium void SetViewportSize(Sizef size); glm::mat4 GetViewProjection(); + Sizef GetViewport() const; private: void RecalculateView(); diff --git a/src/renderer/render_common.h b/src/renderer/render_common.h new file mode 100644 index 0000000..818923c --- /dev/null +++ b/src/renderer/render_common.h @@ -0,0 +1,18 @@ +/****************************************************************************** +* File - render_common.h +* Author - Joey Pollack +* Date - 2022/08/08 (y/m/d) +* Mod Date - 2022/08/08 (y/m/d) +* Description - Common include files for the render system +******************************************************************************/ + +#ifndef LUNARIUM_RENDER_COMMON_H_ +#define LUNARIUM_RENDER_COMMON_H_ + +#include "frame_buffer.h" +#include "index_buffer.h" +#include "shader.h" +#include "texture.h" +#include "vertex_buffer.h" + +#endif // LUNARIUM_RENDER_COMMON_H_ \ No newline at end of file diff --git a/src/renderer/render_context.cpp b/src/renderer/render_context.cpp index 1023e3b..4f6876c 100644 --- a/src/renderer/render_context.cpp +++ b/src/renderer/render_context.cpp @@ -8,6 +8,7 @@ #include "render_context.h" #include +#include "renderer2D.h" #include namespace lunarium @@ -18,18 +19,24 @@ namespace lunarium } - OpRes RenderContext::Initialize(Window* pWindow, bool enableDebugMessages = true) - { - if (!pWindow->IsInit()) + OpRes RenderContext::Initialize(Window* pWindow, Renderer2D** ppR2D, bool enableDebugMessages) + { + if (mIsInit) + { + return OpRes::Fail("Can not initialize Render Context. It is already initialized."); + } + + if (!pWindow->IsInit()) { return OpRes::Fail("Can not initialize Render Context. The Window must be initialized first!"); } - if (mIsInit) + if ((*ppR2D)) { - return OpRes::Fail("Can not initialize Render Context. It is already initialized."); + return OpRes::Fail("Can not initialize Render Context. The Renderer2D pointer should be null."); } + mpWindow = pWindow; glEnable(GL_BLEND); @@ -40,7 +47,13 @@ namespace lunarium InitDebugMsgSystem(); } - // TODO: Init render subsystems + // Init render subsystems + (*ppR2D) = new Renderer2D; + OpRes result = (*ppR2D)->Initialize(); + if (Failed(result)) + { + return OpRes::Fail("Failed to initialize the renderer2D subsystem: %s", result.Description.c_str()); + } // TODO: Init text rendering // OpRes res = mText.Initialize(); @@ -65,9 +78,10 @@ namespace lunarium return OpRes::OK(); } - void RenderContext::Shutdown() + void RenderContext::Shutdown(Renderer2D** ppR2D) { - + (*ppR2D)->Shutdown(); + (*ppR2D) = nullptr; } void RenderContext::SwapBuffers() diff --git a/src/renderer/render_context.h b/src/renderer/render_context.h index c107962..e8c7105 100644 --- a/src/renderer/render_context.h +++ b/src/renderer/render_context.h @@ -18,6 +18,7 @@ namespace lunarium { class Window; + class Renderer2D; // NOTE: // This class will probably not be exposed outside of the Core @@ -26,8 +27,10 @@ namespace lunarium { public: RenderContext(); - OpRes Initialize(Window* pWindow, bool enableDebugMessages = true); - void Shutdown(); + /// pWindow - the initialized platform window + /// ppR2D a pointer to an unitialized Renderer2D pointer + OpRes Initialize(Window* pWindow, Renderer2D** ppR2D, bool enableDebugMessages = true); + void Shutdown(Renderer2D** ppR2D); void SwapBuffers(); diff --git a/src/renderer/renderer2D.cpp b/src/renderer/renderer2D.cpp new file mode 100644 index 0000000..40570dc --- /dev/null +++ b/src/renderer/renderer2D.cpp @@ -0,0 +1,261 @@ +/****************************************************************************** +* File - renderer2D.h +* Author - Joey Pollack +* Date - 2022/07/13 (y/m/d) +* Mod Date - 2022/07/13 (y/m/d) +* Description - The main 2D render class +******************************************************************************/ + +#include "renderer2D.h" +#include "orthographic_camera.h" +#include "shaders/defaultShaders.h" + +#include +#include +#include +#include + +namespace lunarium +{ + OpRes Renderer2D::Initialize() + { + mpCamera = nullptr; + + // INIT QUAD DATA + mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 3 }); // Position + mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 2 }); // Tex_coords + mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::FLOAT32, 4 }); // Color + mQuadData.mBufferLayout.PushVertexAttribute(VertexAttribute { VertexAttributeType::INT32, 1 }); // Texture Sampler Index + mQuadData.mVertexBuffer = VertexBuffer::Create(mQuadData.mBufferLayout, mQuadData.MaxVertices); + + mQuadData.mIndexBuffer = new IndexBuffer(mQuadData.MaxIndices * sizeof(u32)); + + + mQuadData.mQuadShader = new Shader(OGLDefaultShaders.DefaultShapeVertex, nullptr, OGLDefaultShaders.DefaultShapeFragment); + if (!mQuadData.mQuadShader->IsValid()) + { + return OpRes::Fail("Failed to create the quad shader"); + } + + // TODO: INIT SPRITE DATA + + + // TODO: INIT DEBUG TEXTURE + u8 data[4] = {255, 128, 0, 0}; + mpDebugTexture = Texture::Create(data, 1, 1); + + return OpRes::OK(); + } + + void Renderer2D::Shutdown() + { + VertexBuffer::Destroy(&mQuadData.mVertexBuffer); + delete[] mQuadData.mIndexBuffer; + } + + void Renderer2D::SetClearColor(Color color) + { + mClearColor = color; + glClearColor(color.R, color.G, color.B, color.A); + } + + Color Renderer2D::GetClearColor() + { + return mClearColor; + } + + void Renderer2D::ResetFrameStats() + { + mFrameStats.DrawCalls = 0; + } + + Renderer2D::FrameStats Renderer2D::GetFrameStats() const + { + return mFrameStats; + } + + void Renderer2D::BeginDraw(OrthographicCamera* pCamera) + { + mpCamera = pCamera; + glViewport(0, 0, pCamera->GetViewport().Width, pCamera->GetViewport().Height); + glClear(GL_COLOR_BUFFER_BIT); + } + + void Renderer2D::EndDraw() + { + Flush(); + } + + ///////////////////////////////////////////////////////////////////// + // DRAW METHODS + ///////////////////////////////////////////////////////////////////// + void Renderer2D::DrawQuad(Rectangle quad, Color color, Texture* texture, float angle) + { + int texture_slot = -1; + if (texture) + { + for (int i = 0; i < mLoadedTextures.size(); i++) + { + if (texture == mLoadedTextures[i]) + { + texture_slot = i; + break; + } + } + + if (-1 == texture_slot) + { + mLoadedTextures.push_back(texture); + texture_slot = mLoadedTextures.size() - 1; + } + } + + float vertices[40]; + unsigned char* vertices_wl = (unsigned char*)vertices; // vertices write location pointer + + glm::mat4 model(1.0f); + model = glm::translate(model, glm::vec3(quad.CenterPoint().x, quad.CenterPoint().y, 0.0f)); + model = glm::rotate(model, angle, glm::vec3(0.0f, 0.0f, 1.0f)); + + // FIRST + QuadData::Vertex v1; + int vert_size = sizeof(QuadData::Vertex); + v1.pos = mQuadData.vert_pos[0] * model; + v1.tex_coord = mQuadData.vert_tex[0]; + v1.color = color; + v1.tex_slot = texture_slot; + memcpy(vertices_wl, &v1, vert_size); + vertices_wl += vert_size; + + // SECOND + QuadData::Vertex v2; + v2.pos = mQuadData.vert_pos[1] * model; + v2.tex_coord = mQuadData.vert_tex[1]; + v2.color = color; + v2.tex_slot = texture_slot; + memcpy(vertices_wl, &v2, vert_size); + vertices_wl += vert_size; + + // THIRD + QuadData::Vertex v3; + v3.pos = mQuadData.vert_pos[2] * model; + v3.tex_coord = mQuadData.vert_tex[2]; + v3.color = color; + v3.tex_slot = texture_slot; + memcpy(vertices_wl, &v3, vert_size); + vertices_wl += vert_size; + + // FOURTH + QuadData::Vertex v4; + v4.pos = mQuadData.vert_pos[3] * model; + v4.tex_coord = mQuadData.vert_tex[3]; + v4.color = color; + v4.tex_slot = texture_slot; + memcpy(vertices_wl, &v4, vert_size); + + if (!mQuadData.mVertexBuffer->PushVertices(vertices, 4)) + { + Logger::Info(LogCategory::GRAPHICS, "Quad VertexBuffer is full, flushing and retrying"); + Flush(); + DrawQuad(quad, color, texture); + } + + // INDICES + if (!mQuadData.mIndexBuffer->PushIndices(mQuadData.indices, 6 * sizeof(u32))) + { + Logger::Error(LogCategory::GRAPHICS, "Quad IndexBuffer is full - This shouldn't happen because the VertexBuffer should fill up first!"); + return; + } + + mQuadData.mNumQuads++; + } + + void Renderer2D::DrawSprite(Texture& image, glm::vec2 position, Color color, float angle) + { + Logger::Warn(LogCategory::GRAPHICS, "Renderer2D::DrawSprite is not yet implemented"); + // float half_width = image.GetWidth() / 2; + // float half_height = image.GetHeight() / 2; + // DrawImage(image, Rectangle::MakeFromTopLeft(0, 0, image.GetWidth(), image.GetHeight()), + // Rectangle(position.x + half_width, position.y + half_height, half_width, half_height), color, angle); + } + + void Renderer2D::DrawSprite(Texture& image, Rectangle source, Rectangle destination, Color color, float angle) + { + Logger::Warn(LogCategory::GRAPHICS, "Renderer2D::DrawSprite is not yet implemented"); + // glm::mat4 id = glm::mat4(1.0f); + // glm::vec3 pos = glm::vec3(destination.X, destination.Y, 0.0f); + // glm::mat4 trans = glm::translate(id, pos); + // trans = glm::rotate(trans, angle, glm::vec3(0.0f, 0.0f, 1.0f)); + // trans = glm::scale(trans, glm::vec3(destination.HalfWidth * 2, destination.HalfHeight * 2, 1.0f)); + + + // mImageShader.MakeActive(); + + // float xScale = (source.HalfWidth * 2) / image.GetWidth(); + // float xOffset = source.left() / image.GetWidth(); + // float yScale = (source.HalfHeight * 2) / image.GetHeight(); + // float yOffset = source.top() / image.GetHeight(); + + + // // * -1.0f on yScale will flip the image vertically + // mImageShader.SetUniformf("uvManip", { xScale, xOffset, yScale * -1.0f, yOffset}); + // mImageShader.SetUniformMatrix("model", 1, glm::value_ptr(trans)); + // mImageShader.SetUniformMatrix("projection", 1, glm::value_ptr(mProjection)); + // mImageShader.SetUniformf("spriteColor", { color.R, color.G, color.B, color.A }); + + + // glActiveTexture(GL_TEXTURE0); + // glBindTexture(GL_TEXTURE_2D, image.GetGLTextureID()); + + // glBindVertexArray(mImageVAO); + // glDrawArrays(GL_TRIANGLES, 0, 6); + // glBindVertexArray(0); + } + + void Renderer2D::DrawString(const char* string, Rectangle boundingArea, Color color, float scale, int font) + { + Logger::Warn(LogCategory::GRAPHICS, "Renderer2D::DrawString is not yet implemented"); + // mText.DrawString(font, string, glm::vec2(boundingArea.left(), boundingArea.top()), + // glm::vec2(boundingArea.right(), boundingArea.bottom()), color, scale, mProjection); + } + + + ///////////////////////////////////////////////////////////////////// + // HELPERS + ///////////////////////////////////////////////////////////////////// + void Renderer2D::Flush() + { + // TODO: Draw calls + mQuadData.mQuadShader->Use(); + mQuadData.mVertexBuffer->Bind(); + mQuadData.mIndexBuffer->Bind(); + for (int i = 0; i < mLoadedTextures.size(); i++) + { + mLoadedTextures[i]->Bind(i); + } + + Uniform umodel; + umodel.Type = UniformType::FMAT4; + umodel.Location = 0; + umodel.Name = "Model"; + + Uniform uprojview; + uprojview.Type = UniformType::FMAT4; + uprojview.Location = 0; + uprojview.Name = "ProjView"; + + mQuadData.mQuadShader->SetUniform(umodel, (void*)glm::value_ptr(glm::mat4(1.0f))); + mQuadData.mQuadShader->SetUniform(uprojview, (void*)glm::value_ptr(mpCamera->GetViewProjection())); + + glDrawElements(GL_TRIANGLES, mQuadData.mNumQuads * 6, GL_UNSIGNED_INT, nullptr); + mFrameStats.DrawCalls++; + + // Reset drawing data + mLoadedTextures.clear(); + mQuadData.mVertexBuffer->Clear(); + mQuadData.mIndexBuffer->Clear(); + + // TODO: Add the debug texture back to the map + mLoadedTextures.push_back(mpDebugTexture); + } +} \ No newline at end of file diff --git a/src/renderer/renderer2D.h b/src/renderer/renderer2D.h index ffde329..189d4f6 100644 --- a/src/renderer/renderer2D.h +++ b/src/renderer/renderer2D.h @@ -9,11 +9,91 @@ #ifndef LUNARIUM_RENDERER_2D_H_ #define LUNARIUM_RENDERER_2D_H_ +#include +#include "render_common.h" +#include + +#include +#include + namespace lunarium { + class OrthographicCamera; + + class Renderer2D { + public: + struct FrameStats + { + int DrawCalls = 0; + } mFrameStats; + + Texture* GetDebugTexture(); + void SetClearColor(Color color); + Color GetClearColor(); + + void ResetFrameStats(); + FrameStats GetFrameStats() const; + void BeginDraw(OrthographicCamera* pCamera); + void EndDraw(); + + // Draw methods + void DrawQuad(Rectangle quad, Color color, Texture* texture = nullptr, float angle = 0.0f); + void DrawSprite(Texture& image, glm::vec2 position, Color color = {1.0f, 1.0f, 1.0f, 1.0f}, float angle = 0); + void DrawSprite(Texture& image, Rectangle source, Rectangle destination, Color color = {1.0f, 1.0f, 1.0f, 1.0f}, float angle = 0); + void DrawString(const char* string, Rectangle boundingArea, Color color = {1.0f, 1.0f, 1.0f, 1.0f}, float scale = 1.0f, int font = 0); + + private: + friend class RenderContext; + OpRes Initialize(); + void Shutdown(); + void Flush(); + + private: // data + + struct QuadData + { + int mNumQuads = 0; + const int MaxQuads = 10000; + const int MaxVertices = MaxQuads * 4; + const int MaxIndices = MaxQuads * 6; + const int TextureSlots = 32; + + const glm::vec4 vert_pos[4] = { + { -0.5f, 0.5f, 0.0f, 1.0f }, // TOP LEFT + { 0.5f, 0.5f, 0.0f, 1.0f }, // TOP RIGHT + { 0.5f, -0.5f, 0.0f, 1.0f }, // BOTTOM RIGHT + { -0.5f, -0.5f, 0.0f, 1.0f } // BOTTOM LEFT + }; + + const glm::vec2 vert_tex[4] = { + { 0.0f, 1.0f }, + { 1.0f, 1.0f }, + { 1.0f, 0.0f }, + { 0.0f, 0.0f }, + }; + + struct Vertex + { + glm::vec3 pos; + glm::vec2 tex_coord; + glm::vec4 color; + int tex_slot; + }; + + const u32 indices[6] = { 0, 1, 2, 0, 2, 3 }; + + BufferLayout mBufferLayout; + VertexBuffer* mVertexBuffer; + IndexBuffer* mIndexBuffer; + Shader* mQuadShader; + } mQuadData; + OrthographicCamera* mpCamera; + std::vector mLoadedTextures; + Texture* mpDebugTexture; + Color mClearColor; }; } diff --git a/src/renderer/shader.cpp b/src/renderer/shader.cpp new file mode 100644 index 0000000..2cf09a9 --- /dev/null +++ b/src/renderer/shader.cpp @@ -0,0 +1,211 @@ +/****************************************************************************** +* File - shader.cpp +* Author - Joey Pollack +* Date - 2022/08/04 (y/m/d) +* Mod Date - 2022/08/04 (y/m/d) +* Description - opengl shader system +******************************************************************************/ + +#include "shader.h" +#include + +#include +#include + +namespace lunarium +{ + Shader::Shader(const char* vert_source, const char* geo_source, const char* frag_source) + : mGLID(0) + { + // Validate parameters + if (!vert_source) + { + Logger::Error(LogCategory::GRAPHICS, "Failed to create Shader - vert_source can not be nullptr!"); + return; + } + + if (!frag_source) + { + Logger::Error(LogCategory::GRAPHICS, "Failed to create Shader - vert_source can not be nullptr!"); + return; + } + + // Compile source code + u32 vert_id = CompileSource(vert_source, GL_VERTEX_SHADER); + u32 geo_id = (geo_source ? CompileSource(geo_source, GL_GEOMETRY_SHADER) : 0 ); + u32 frag_id = CompileSource(frag_source, GL_FRAGMENT_SHADER); + + // Validate compilation + if (vert_id < 1 || frag_id < 1) + { + // Free any succesfully compiled shader sources + if (vert_id > 0) glDeleteShader(vert_id); + if (geo_id > 0) glDeleteShader(geo_id); + if (frag_id > 0) glDeleteShader(frag_id); + + Logger::Error(LogCategory::GRAPHICS, "Failed to create shader program"); + return; + } + + // Link shader program + mGLID = glCreateProgram(); + glAttachShader(mGLID, vert_id); + if (geo_id > 0) glAttachShader(mGLID, geo_id); + glAttachShader(mGLID, frag_id); + glLinkProgram(mGLID); + + // check for linking errors + int success; + const int buffer_size = 512; + char info_log[buffer_size]; + glGetProgramiv(mGLID, GL_LINK_STATUS, &success); + if (!success) + { + glGetProgramInfoLog(mGLID, 512, NULL, info_log); + Logger::Error(LogCategory::GRAPHICS, "Failed to link shader program: %s", info_log); + glDeleteProgram(mGLID); + mGLID = 0; + } + + // Clean up + if (vert_id > 0) glDeleteShader(vert_id); + if (geo_id > 0) glDeleteShader(geo_id); + if (frag_id > 0) glDeleteShader(frag_id); + } + + Shader::~Shader() + { + if (IsValid()) + { + glDeleteProgram(mGLID); + mGLID = 0; + } + } + + bool Shader::IsValid() const + { + return mGLID > 0; + } + + + void Shader::Use() const + { + glUseProgram(mGLID); + } + + OpRes Shader::GetAllUniforms(std::vector& uniforms) + { + uniforms.clear(); + + GLint size; // size of the variable + GLenum type; // type of the variable (float, vec3 or mat4, etc) + + const GLsizei buffer_size = 16; // maximum name length + GLchar name[buffer_size]; // variable name in GLSL + GLsizei length; // name length + int count = -1; + + glGetProgramiv(mGLID, GL_ACTIVE_UNIFORMS, &count); + Logger::Debug(LogCategory::GRAPHICS, "Active Uniforms for shader %n: %n", mGLID, count); + + for (int i = 0; i < count; i++) + { + glGetActiveUniform(mGLID, (GLuint)i, buffer_size, &length, &size, &type, name); + u32 location = glGetUniformLocation(mGLID, name); + Logger::Debug(LogCategory::GRAPHICS, "Uniform #%n Type: %u Name: %s Location: %n", i, type, name, location); + Uniform u; + u.Location = location; + u.Type = GLToUniformType(type); + u.Name = std::string(name); + uniforms.push_back(u); + } + + return OpRes::OK(); + } + + + void Shader::GetUniformLocation(Uniform& uniform) + { + uniform.Location = glGetUniformLocation(mGLID, uniform.Name.c_str()); + } + + + OpRes Shader::SetUniform(Uniform& uniform, void* values) + { + if (uniform.Location < 1) + { + GetUniformLocation(uniform); + } + + switch (uniform.Type) + { + case UniformType::F1: glUniform1fv(uniform.Location, 1, (GLfloat*)values); break; + case UniformType::F2: glUniform2fv(uniform.Location, 1, (GLfloat*)values); break; + case UniformType::F3: glUniform3fv(uniform.Location, 1, (GLfloat*)values); break; + case UniformType::F4: glUniform4fv(uniform.Location, 1, (GLfloat*)values); break; + + case UniformType::I1: glUniform1iv(uniform.Location, 1, (GLint*)values); break; + case UniformType::I2: glUniform2iv(uniform.Location, 1, (GLint*)values); break; + case UniformType::I3: glUniform3iv(uniform.Location, 1, (GLint*)values); break; + case UniformType::I4: glUniform4iv(uniform.Location, 1, (GLint*)values); break; + + case UniformType::FMAT3: glUniformMatrix3fv(uniform.Location, 1, GL_FALSE, (GLfloat*)values); break; + case UniformType::FMAT4: glUniformMatrix4fv(uniform.Location, 1, GL_FALSE, (GLfloat*)values); break; + + default: return OpRes::Fail("Can not set uniform value - Unknown type"); + } + + return OpRes::OK(); + } + + + u32 Shader::CompileSource(const char* source, u32 source_type) + { + u32 id = glCreateShader(source_type); + glShaderSource(id, 1, &source, NULL); + glCompileShader(id); + + int success; + const int buffer_size = 512; + char info_log[buffer_size]; + glGetShaderiv(id, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(id, buffer_size, NULL, info_log); + std::string type = ""; + switch (source_type) + { + case GL_VERTEX_SHADER: type = "Vertex"; break; + case GL_GEOMETRY_SHADER: type = "Geometry"; break; + case GL_FRAGMENT_SHADER: type = "Fragment"; break; + } + Logger::Error(LogCategory::GRAPHICS, "Failed to compile %s shader source: %s", type.c_str(), info_log); + return 0; + } + + return id; + } + + + UniformType Shader::GLToUniformType(u32 type) + { + switch (type) + { + case GL_FLOAT: return UniformType::F1; + case GL_FLOAT_VEC2: return UniformType::F2; + case GL_FLOAT_VEC3: return UniformType::F3; + case GL_FLOAT_VEC4: return UniformType::F4; + + case GL_INT: return UniformType::I1; + case GL_INT_VEC2: return UniformType::I2; + case GL_INT_VEC3: return UniformType::I3; + case GL_INT_VEC4: return UniformType::I4; + + case GL_FLOAT_MAT3: return UniformType::FMAT3; + case GL_FLOAT_MAT4: return UniformType::FMAT4; + } + + Logger::Warn(LogCategory::GRAPHICS, "Can not convert GL uniform type - Unknown type: %u", type); + return UniformType::UNKNOWN; + } +} \ No newline at end of file diff --git a/src/renderer/shader.h b/src/renderer/shader.h new file mode 100644 index 0000000..0848539 --- /dev/null +++ b/src/renderer/shader.h @@ -0,0 +1,68 @@ +/****************************************************************************** +* File - shader.h +* Author - Joey Pollack +* Date - 2022/08/04 (y/m/d) +* Mod Date - 2022/08/04 (y/m/d) +* Description - opengl shader system +******************************************************************************/ + +#ifndef LUNARIUM_SHADER_H_ +#define LUNARIUM_SHADER_H_ + +#include +#include +#include + +namespace lunarium +{ + enum class UniformType + { + F1, + F2, + F3, + F4, + FMAT3, + FMAT4, + + I1, + I2, + I3, + I4, + + UNKNOWN, + }; + + struct Uniform + { + std::string Name; + UniformType Type; + u32 Location; + }; + + class Shader + { + public: + Shader(const char* vert_source, const char* geo_source, const char* frag_source); + ~Shader(); + bool IsValid() const; + + void Use() const; + + OpRes GetAllUniforms(std::vector& uniforms); + void GetUniformLocation(Uniform& uniform); + OpRes SetUniform(Uniform& uniform, void* values); + + private: + u32 mGLID; + + private: // HELPERS + + /// Compile the given shader source + /// Returns the glid of the compiled source + /// source_type is the GLenum value + u32 CompileSource(const char* source, u32 source_type); + UniformType GLToUniformType(u32 type); + }; +} + +#endif // LUNARIUM_SHADER_H_ \ No newline at end of file diff --git a/src/renderer/OLD/opengl/defaultShaders.h b/src/renderer/shaders/defaultShaders.h similarity index 62% rename from src/renderer/OLD/opengl/defaultShaders.h rename to src/renderer/shaders/defaultShaders.h index b57c652..0f74ced 100644 --- a/src/renderer/OLD/opengl/defaultShaders.h +++ b/src/renderer/shaders/defaultShaders.h @@ -14,29 +14,51 @@ namespace lunarium { struct { - friend class OglGraphics; + friend class Renderer2D; friend class glText; private: const char* DefaultShapeVertex = "#version 450 core\n\ - layout(location = 0) in vec4 vertex;\ + layout(location = 0) in vec3 pos;\ + layout(location = 1) in vec2 tex_coords;\ + layout(location = 2) in vec4 color;\ + layout(location = 3) in int tex_slot;\ \ + struct VertexOutput\ + {\ + vec4 Color;\ + vec2 TexCoord;\ + };\ + out int TexSlot;\ + layout (location = 0) out VertexOutput Output;\ + \ uniform mat4 model;\ - uniform mat4 projection;\ + uniform mat4 projview;\ \ void main()\ {\ - gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0);\ + Output.Color = color;\ + TexSlot = tex_slot;\ + Output.TexCoord = tex_coords;\ + gl_Position = projview * model * vec4(pos.xy, 0.0, 1.0);\ }"; const char* DefaultShapeFragment = "#version 450 core\n\ - in vec2 TexCoords;\ + struct VertexOutput\ + {\ + vec4 Color;\ + vec2 TexCoord;\ + };\ +\ + flat in int TexSlot;\ + \ + layout (location = 0) in VertexOutput Input;\ out vec4 color;\ \ - uniform vec4 shapeColor;\ \ + layout (binding = 0) uniform sampler2D u_Textures[32];\ void main()\ {\ - color = shapeColor;\ + color = texture(u_Textures[TexSlot], Input.TexCoord) * Input.Color;\ }"; const char* DefaultSpriteVertex = "#version 450 core\n\ diff --git a/src/renderer/texture.cpp b/src/renderer/texture.cpp index 5150e5a..3fa1f3e 100644 --- a/src/renderer/texture.cpp +++ b/src/renderer/texture.cpp @@ -29,7 +29,7 @@ namespace lunarium glGenTextures(1, &t->mGLID); t->Bind(); - glTexImage2D(GL_TEXTURE_2D, 0, formats[format], width, height, 0, formats[format], GL_UNSIGNED_BYTE, data); + glTexImage2D(GL_TEXTURE_2D, 0, formats[(int)format], width, height, 0, formats[(int)format], GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -49,9 +49,9 @@ namespace lunarium } - void Texture::Bind() const + void Texture::Bind(u32 slot) const { - glBindTexture(GL_TEXTURE_2D, mGLID); + glBindTextureUnit(slot, mGLID); } void Texture::Unbind() const @@ -89,10 +89,11 @@ namespace lunarium u8* Texture::GetPixels() const { u32 format_size[2] = { 3, 4 }; - u8* buffer = new u8[mWidth * mHeight * format_size[mFormat]]; + u32 formats[2] = { GL_RGB, GL_RGBA }; + u8* buffer = new u8[mWidth * mHeight * format_size[(int)mFormat]]; Bind(); - glGetTexImage(GL_TEXTURE_2D, 0, mFormat, GL_UNSIGNED_BYTE, (void*)buffer); + glGetTexImage(GL_TEXTURE_2D, 0, formats[(int)mFormat], GL_UNSIGNED_BYTE, (void*)buffer); Unbind(); return buffer; diff --git a/src/renderer/texture.h b/src/renderer/texture.h index b3b0e38..b061109 100644 --- a/src/renderer/texture.h +++ b/src/renderer/texture.h @@ -13,7 +13,7 @@ namespace lunarium { - enum TextureFormat + enum class TextureFormat { RGB, RGBA, @@ -25,7 +25,7 @@ namespace lunarium static Texture* Create(u8* data = nullptr, u32 width = 1, u32 height = 1, TextureFormat format = TextureFormat::RGBA); static void Destroy(Texture** ppTex); - void Bind() const; + void Bind(u32 slot = 0) const; void Unbind() const; u32 GetGLID() const; diff --git a/src/renderer/vertex_buffer.cpp b/src/renderer/vertex_buffer.cpp index 0776510..727a4e1 100644 --- a/src/renderer/vertex_buffer.cpp +++ b/src/renderer/vertex_buffer.cpp @@ -12,31 +12,118 @@ #include namespace lunarium -{ - VertexBuffer::VertexBuffer(LayoutType ltype, const void* vertices, u32 size) - : mLayoutType(ltype), mSize(size), mIndex(0), mIsStatic(true) +{ + ///////////////////////////////////////////////////////////////////// + // BUFFER LAYOUT + ///////////////////////////////////////////////////////////////////// + void BufferLayout::PushVertexAttribute(VertexAttribute va) { - glGenVertexArrays(1, &mVAO); - glGenBuffers(1, &mVBO); + mLayout.push_back(va); + } - Bind(); + void BufferLayout::ClearLayout() + { + mLayout.clear(); + } + + std::vector& BufferLayout::GetLayout() + { + return mLayout; + } + + + int BufferLayout::GetNumAttributes() const + { + return mLayout.size(); + } - glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); + int BufferLayout::GetLayoutSizeInBytes() const + { + int size = 0; + for (auto va = mLayout.begin(); va != mLayout.end(); va++) + { + size += GetAttributeSizeInBytes(*va); + } + + return size; + } - InitLayout(); + int BufferLayout::GetAttributeSizeInBytes(VertexAttribute va) const + { + int type_sizes[] = { 4, 8, 4, 8 }; + return type_sizes[va.Type] * va.NumValues; } - VertexBuffer::VertexBuffer(LayoutType ltype, u32 size) - : mLayoutType(ltype), mSize(size), mIndex(0), mIsStatic(false) + void BufferLayout::ImplementLayout() { + int type_sizes[] = { 4, 8, 4, 8 }; + GLenum gl_types[] = { GL_INT, GL_INT, GL_FLOAT, GL_FLOAT }; + int stride = 0; + std::vector offsets; + + for (int i = 0; i < mLayout.size(); i++) + { + offsets.push_back(stride); + stride += type_sizes[mLayout[i].Type] * mLayout[i].NumValues; + } + + for (int i = 0; i < mLayout.size(); i++) + { + glEnableVertexAttribArray(i); + glVertexAttribPointer(i, mLayout[i].NumValues, gl_types[mLayout[i].Type], GL_FALSE, stride, (GLvoid*)offsets[i]); + } + } + + + ///////////////////////////////////////////////////////////////////// + // VERTEX BUFFER + ///////////////////////////////////////////////////////////////////// + VertexBuffer* VertexBuffer::Create(BufferLayout& VertexLayout, u32 num_vertices, const void* vertices) + { + return new VertexBuffer(VertexLayout, num_vertices, vertices); + } + + void VertexBuffer::Destroy(VertexBuffer** ppBuf) + { + (*ppBuf)->Free(); + delete *ppBuf; + *ppBuf = nullptr; + } + + VertexBuffer::VertexBuffer(BufferLayout& VertexLayout, u32 num_vertices, const void* vertices) + : mLayout(VertexLayout), mSize(0), mIndex(0), mIsStatic(false) + { + mIsStatic = vertices != nullptr; + + // Calculate buffer size + mSize = VertexLayout.GetLayoutSizeInBytes() * num_vertices; + glGenVertexArrays(1, &mVAO); glGenBuffers(1, &mVBO); Bind(); - glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_DYNAMIC_DRAW); + if (vertices) + { + glBufferData(GL_ARRAY_BUFFER, mSize, vertices, GL_STATIC_DRAW); + } + else + { + glBufferData(GL_ARRAY_BUFFER, mSize, nullptr, GL_DYNAMIC_DRAW); + } - InitLayout(); + mLayout.ImplementLayout(); + } + + + void VertexBuffer::Clear() + { + if (mIsStatic) + { + Logger::Warn(LogCategory::GRAPHICS, "Attemping to clear a static VertexBuffer"); + } + + mIndex = 0; } void VertexBuffer::Bind() @@ -51,7 +138,7 @@ namespace lunarium glBindBuffer(GL_ARRAY_BUFFER, 0); } - bool VertexBuffer::PushVertices(const void* vertices, u32 size) + bool VertexBuffer::PushVertices(const void* vertices, u32 num_verts) { if (mIsStatic) { @@ -59,67 +146,80 @@ namespace lunarium return false; } - if (mIndex + size >= mSize) + int data_size = mLayout.GetLayoutSizeInBytes() * num_verts; + + // TODO: BE CAREFUL! mSize is the size in bytes, not number of vertices. + if (mIndex + data_size >= mSize) { // Vertices do not fit into the buffer + Logger::Warn(LogCategory::GRAPHICS, "Cannot push vertices into buffer - not enough space left! Space left: %n, data size: %n", mSize - mIndex, data_size); return false; } // Add verts to the buffer Bind(); - glBufferSubData(GL_ARRAY_BUFFER, mIndex, size, vertices); + glBufferSubData(GL_ARRAY_BUFFER, mIndex, data_size, vertices); Unbind(); - mIndex += size; + mIndex += data_size; return true; } ///////////////////////////////////////////////////////////////////// // HELPER METHODS ///////////////////////////////////////////////////////////////////// - - void VertexBuffer::InitLayout() - { + // void VertexBuffer::InitLayout() + // { - switch (mLayoutType) - { - case LayoutType::LINE: - { - Logger::Error(LogCategory::GRAPHICS, "Vertex layout type LINE not supported yet!"); - } - break; - - case LayoutType::QUAD: - { - // position - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 10 * sizeof(GLfloat), (GLvoid*)0); - glEnableVertexAttribArray(0); - - // Texture coords - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 10 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(float))); - glEnableVertexAttribArray(1); - - // Color - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 10 * sizeof(GLfloat), (GLvoid*)(5 * sizeof(float))); - glEnableVertexAttribArray(2); - - // Texture sampler index - glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 10 * sizeof(GLfloat), (GLvoid*)(9 * sizeof(float))); - glEnableVertexAttribArray(2); - - } - break; - - case LayoutType::SPRITE: - { - Logger::Error(LogCategory::GRAPHICS, "Vertex layout type SPRITE not supported yet!"); - } - break; - - default: - Logger::Warn(LogCategory::GRAPHICS, "UNKNOWN Vertex Layout Type: %d", mLayoutType); - - } + // switch (mLayoutType) + // { + // case LayoutType::LINE: + // { + // Logger::Error(LogCategory::GRAPHICS, "Vertex layout type LINE not supported yet!"); + // } + // break; + + // case LayoutType::QUAD: + // { + // // position + // glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 10 * sizeof(GLfloat), (GLvoid*)0); + // glEnableVertexAttribArray(0); + + // // Texture coords + // glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 10 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(float))); + // glEnableVertexAttribArray(1); + + // // Color + // glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 10 * sizeof(GLfloat), (GLvoid*)(5 * sizeof(float))); + // glEnableVertexAttribArray(2); + + // // Texture sampler index + // glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 10 * sizeof(GLfloat), (GLvoid*)(9 * sizeof(float))); + // glEnableVertexAttribArray(2); + + // // Texture ID - SHADERS SHOULD IGNORE THIS + // glVertexAttribPointer(4, 1, GL_INT, GL_FALSE, 10 * 8, (GLvoid*)(10 * sizeof(float))); + // glEnableVertexAttribArray(2); + + // } + // break; + + // case LayoutType::SPRITE: + // { + // Logger::Error(LogCategory::GRAPHICS, "Vertex layout type SPRITE not supported yet!"); + // } + // break; + + // default: + // Logger::Warn(LogCategory::GRAPHICS, "UNKNOWN Vertex Layout Type: %d", mLayoutType); + + // } + //} + + void VertexBuffer::Free() + { + glDeleteVertexArrays(1, &mVAO); + glDeleteBuffers(1, &mVBO); } } \ No newline at end of file diff --git a/src/renderer/vertex_buffer.h b/src/renderer/vertex_buffer.h index f43b3c9..c1e18bd 100644 --- a/src/renderer/vertex_buffer.h +++ b/src/renderer/vertex_buffer.h @@ -10,9 +10,44 @@ #define LUNARIUM_VERTEX_BUFFER_H_ #include +#include namespace lunarium { + enum VertexAttributeType + { + INT32, + INT64, + FLOAT32, + FLOAT64, + }; + + struct VertexAttribute + { + VertexAttributeType Type; + int NumValues; + }; + + class VertexBuffer; + class BufferLayout + { + public: + void PushVertexAttribute(VertexAttribute va); + void ClearLayout(); + std::vector& GetLayout(); + + int GetNumAttributes() const; + int GetLayoutSizeInBytes() const; + int GetAttributeSizeInBytes(VertexAttribute va) const; + + private: + std::vector mLayout; + + private: + friend class VertexBuffer; + void ImplementLayout(); + }; + // For now this class will also contain the VAO for the buffer class VertexBuffer { @@ -26,27 +61,32 @@ namespace lunarium public: - VertexBuffer(LayoutType ltype, const void* vertices, u32 size); - VertexBuffer(LayoutType ltype, u32 size); + + static VertexBuffer* Create(BufferLayout& VertexLayout, u32 num_vertices, const void* vertices = nullptr); + static void Destroy(VertexBuffer** ppBuf); + + void Clear(); void Bind(); void Unbind(); - // Returns false if the data does not fit in the buffer - bool PushVertices(const void* vertices, u32 size); + /// Returns false if the data does not fit in the buffer + /// size is the size in bytes + bool PushVertices(const void* vertices, u32 num_verts); private: - LayoutType mLayoutType; + BufferLayout mLayout; bool mIsStatic; u32 mVAO; u32 mVBO; - u32 mSize; + u32 mSize; // Size of the buffer in bytes u32 mIndex; // The next spot to push data into for a dynamic buffer private: // HELPER METHODS - void InitLayout(); + VertexBuffer(BufferLayout& VertexLayout, u32 num_vertices, const void* vertices = nullptr); + void Free(); }; } diff --git a/src/run_modes/editor/editor.cpp b/src/run_modes/editor/editor.cpp index 41721c0..d2d7ecb 100644 --- a/src/run_modes/editor/editor.cpp +++ b/src/run_modes/editor/editor.cpp @@ -85,7 +85,7 @@ namespace editor mPanelManager.Shutdown(); } - void Editor::OnTick(double delta) + void Editor::OnUpdate(double delta) { // Panels mPanelManager.OnTick(delta); diff --git a/src/run_modes/editor/editor.h b/src/run_modes/editor/editor.h index f302045..5e47fe1 100644 --- a/src/run_modes/editor/editor.h +++ b/src/run_modes/editor/editor.h @@ -45,7 +45,7 @@ namespace lunarium { namespace editor Editor(); [[nodiscard]] OpRes Initialize(); void Shutdown(); - void OnTick(double delta); + void OnUpdate(double delta); void OnRender(lunarium::IGraphics* g); diff --git a/src/run_modes/editor/editor_helpers.cpp b/src/run_modes/editor/editor_helpers.cpp index 7a3d709..fc68824 100644 --- a/src/run_modes/editor/editor_helpers.cpp +++ b/src/run_modes/editor/editor_helpers.cpp @@ -9,13 +9,12 @@ #include "editor_helpers.h" #include -#include -#include +#include #include namespace lunarium { namespace editor { - lunarium::Image* FileLoaders::LoadImage(std::filesystem::path file) + lunarium::Texture* FileLoaders::LoadImage(std::filesystem::path file) { int w, h, n; stbi_set_flip_vertically_on_load(1); @@ -26,19 +25,15 @@ namespace lunarium { namespace editor return nullptr; } - Image* i = new Image(); - i->SetData(buffer); - i->SetFormat(ImageFormat::RGBA); + TextureFormat format = TextureFormat::RGBA; if (n == 3) { - i->SetFormat(ImageFormat::RGB); + format = TextureFormat::RGB; } - i->SetWidth(w); - i->SetHeight(h); + Texture* t = Texture::Create(buffer, w, h, format); - Core::Graphics().RegisterImage(*i); - return i; + return t; } }} \ No newline at end of file diff --git a/src/run_modes/editor/editor_helpers.h b/src/run_modes/editor/editor_helpers.h index f14a1f2..62d8d13 100644 --- a/src/run_modes/editor/editor_helpers.h +++ b/src/run_modes/editor/editor_helpers.h @@ -13,7 +13,7 @@ namespace lunarium { - class Image; + class Texture; } namespace lunarium { namespace editor @@ -21,7 +21,7 @@ namespace lunarium { namespace editor class FileLoaders { public: - static lunarium::Image* LoadImage(std::filesystem::path file); + static lunarium::Texture* LoadImage(std::filesystem::path file); }; }} diff --git a/src/run_modes/editor/panels/world_tree.cpp b/src/run_modes/editor/panels/world_tree.cpp index bffe782..0f0bbf2 100644 --- a/src/run_modes/editor/panels/world_tree.cpp +++ b/src/run_modes/editor/panels/world_tree.cpp @@ -53,7 +53,7 @@ namespace lunarium } return true; - }); + }).LogIfFailed(Editor::LogCat); } void WorldTree::SetWorld(lunarium::World *pWorld) @@ -148,7 +148,7 @@ namespace lunarium } else { - OpenPopup(PopUp::NEW_ENTITY); + OpenPopup(PopUp::NEW_ENTITY).LogIfFailed(Editor::LogCat); } } ImGui::EndPopup(); diff --git a/src/run_modes/testbed/scenes/base_scene.cpp b/src/run_modes/testbed/scenes/base_scene.cpp index e8d4748..f0466ed 100644 --- a/src/run_modes/testbed/scenes/base_scene.cpp +++ b/src/run_modes/testbed/scenes/base_scene.cpp @@ -26,11 +26,6 @@ namespace lunarium } - void BaseScene::OnRender(IGraphics* g) - { - - } - void BaseScene::OnKeyPress(InputManager::KeyPress kp) { diff --git a/src/run_modes/testbed/scenes/base_scene.h b/src/run_modes/testbed/scenes/base_scene.h index 85f1ab7..9884c14 100644 --- a/src/run_modes/testbed/scenes/base_scene.h +++ b/src/run_modes/testbed/scenes/base_scene.h @@ -21,7 +21,6 @@ namespace lunarium BaseScene(uint32_t logCat); virtual void OnLoad(); virtual void OnTick(double delta); - virtual void OnRender(IGraphics* g); virtual void OnKeyPress(InputManager::KeyPress kp); virtual void OnKeyRelease(Keyboard::Key k); diff --git a/src/run_modes/testbed/scenes/physics_scene.cpp b/src/run_modes/testbed/scenes/physics_scene.cpp index 6206920..2aa80b1 100644 --- a/src/run_modes/testbed/scenes/physics_scene.cpp +++ b/src/run_modes/testbed/scenes/physics_scene.cpp @@ -8,7 +8,7 @@ #include "physics_scene.h" #include -#include +#include #include namespace lunarium @@ -113,10 +113,14 @@ namespace lunarium int32 positionIterations = 2; mb2World->Step(timeStep, velocityIterations, positionIterations); + + RenderScene(); } - void PhysicsScene::OnRender(IGraphics* g) + void PhysicsScene::RenderScene() { + Renderer2D g = Core::Graphics(); + // This scaling is a little backwards. // Info about scaling factor: // https://box2d.org/documentation/md__d_1__git_hub_box2d_docs__f_a_q.html#autotoc_md139 @@ -129,7 +133,7 @@ namespace lunarium groundRect.Scale(scaleFactor, scaleFactor); groundRect.X *= scaleFactor; groundRect.Y *= scaleFactor; - g->DrawFilledBox(groundRect, Color(0.0f, 1.0f, 0.0f, 1.0f)); + g.DrawQuad(groundRect, Color(0.0f, 1.0f, 0.0f, 1.0f)); b2AABB groundbox2; mpGroundBox2->ComputeAABB(&groundbox2, mpGroundBody2->GetTransform(), 0); @@ -137,7 +141,7 @@ namespace lunarium groundRect2.Scale(scaleFactor, scaleFactor); groundRect2.X *= scaleFactor; groundRect2.Y *= scaleFactor; - g->DrawFilledBox(groundRect2, Color(0.0f, 1.0f, 0.0f, 1.0f)); + g.DrawQuad(groundRect2, Color(0.0f, 1.0f, 0.0f, 1.0f)); b2AABB dynbox; b2Transform transform; @@ -149,12 +153,12 @@ namespace lunarium dynRect.Scale(scaleFactor, scaleFactor); dynRect.X *= scaleFactor; dynRect.Y *= scaleFactor; - g->DrawFilledBox(dynRect, Color(0.0f, 0.0f, 1.0f, 1.0f), angle); + g.DrawQuad(dynRect, Color(0.0f, 0.0f, 1.0f, 1.0f), nullptr, angle); // Debug info - char str[256] = { 0 }; - sprintf(str, "GroundBox: pos: (%f, %f) size: (%f, %f)", groundRect.X, groundRect.Y, groundRect.HalfWidth, groundRect.HalfHeight); - g->DrawString(str, Rectangle::MakeFromTopLeft(10.0f, 10.0f, 800.0f, 30.0f), Color(0.75f, 0.85f, 0.5f, 1.0f), 0.4f); + // char str[256] = { 0 }; + // sprintf(str, "GroundBox: pos: (%f, %f) size: (%f, %f)", groundRect.X, groundRect.Y, groundRect.HalfWidth, groundRect.HalfHeight); + // g.DrawString(str, Rectangle::MakeFromTopLeft(10.0f, 10.0f, 800.0f, 30.0f), Color(0.75f, 0.85f, 0.5f, 1.0f), 0.4f); // sprintf(str, "GroundBox Half Size: (%f, %f)", groundRect.Width, groundRect.Height); // g->DrawString(str, Rectangle(10.0f, 35.0f, 800.0f, 30.0f), Color(0.75f, 0.85f, 0.5f, 1.0f), 0.4f); @@ -164,21 +168,21 @@ namespace lunarium // dynRect.RightBottom().x * scaleFactor, dynRect.RightBottom().y * scaleFactor, angle); // g->DrawString(str, Rectangle(10.0f, 60.0f, 1000.0f, 100.0f), Color(0.75f, 0.85f, 0.5f, 1.0f), 0.4); - int ww, wh; - Core::MainWindow().GetFramebufferSize(&ww, &wh); - for (int i = 0; i < wh; i += 10) - { - sprintf(str, "%d", i); - g->DrawString(str, Rectangle::MakeFromTopLeft(ww - 35.0f, i, 4.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 0.25f); - g->DrawBox(Rectangle::MakeFromTopLeft(ww - 10.0f, i, 10.0f, 2.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 1.0f); - } - - for (int i = 0; i < ww; i += 25) - { - sprintf(str, "%d", i); - g->DrawString(str, Rectangle::MakeFromTopLeft(i, wh - 20.0f, 4.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 0.25f); - g->DrawBox(Rectangle::MakeFromTopLeft(i, wh - 5.0f, 2.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 1.0f); - } + // int ww, wh; + // Core::MainWindow().GetFramebufferSize(&ww, &wh); + // for (int i = 0; i < wh; i += 10) + // { + // sprintf(str, "%d", i); + // g.DrawString(str, Rectangle::MakeFromTopLeft(ww - 35.0f, i, 4.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 0.25f); + // g.DrawBox(Rectangle::MakeFromTopLeft(ww - 10.0f, i, 10.0f, 2.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 1.0f); + // } + + // for (int i = 0; i < ww; i += 25) + // { + // sprintf(str, "%d", i); + // g.DrawString(str, Rectangle::MakeFromTopLeft(i, wh - 20.0f, 4.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 0.25f); + // g.DrawBox(Rectangle::MakeFromTopLeft(i, wh - 5.0f, 2.0f, 5.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), 1.0f); + // } } } \ No newline at end of file diff --git a/src/run_modes/testbed/scenes/physics_scene.h b/src/run_modes/testbed/scenes/physics_scene.h index d06d10c..97c35f8 100644 --- a/src/run_modes/testbed/scenes/physics_scene.h +++ b/src/run_modes/testbed/scenes/physics_scene.h @@ -21,7 +21,7 @@ namespace lunarium ~PhysicsScene(); virtual void OnLoad(); virtual void OnTick(double delta); - virtual void OnRender(IGraphics* g); + void RenderScene(); private: b2World* mb2World; diff --git a/src/run_modes/testbed/scenes/simple_render_scene.cpp b/src/run_modes/testbed/scenes/simple_render_scene.cpp index 5e555a3..f9cec82 100644 --- a/src/run_modes/testbed/scenes/simple_render_scene.cpp +++ b/src/run_modes/testbed/scenes/simple_render_scene.cpp @@ -8,11 +8,14 @@ #include "simple_render_scene.h" #include +#include #include #include -#include +#include +#include +#include +#include #include -#include #include #include @@ -40,31 +43,23 @@ namespace lunarium mImageSize.Height = 720; // Create the render textures - mFrameBufferOne = Core::Graphics().CreateRenderTexture(mImageSize.Width, mImageSize.Height, 4); - mFrameBufferTwo = Core::Graphics().CreateRenderTexture(1024, 1024, 4); + mFrameBufferOne = FrameBuffer::Create(mImageSize.Width, mImageSize.Height); //Core::Graphics().CreateRenderTexture(mImageSize.Width, mImageSize.Height, 4); + mFrameBufferTwo = FrameBuffer::Create(1024, 1024); //Core::Graphics().CreateRenderTexture(1024, 1024, 4); // Load test image int w, h, n; stbi_set_flip_vertically_on_load(1); unsigned char* buffer = stbi_load("LinkToThePast1_sized.png", &w, &h, &n, 0); - mpTestImageLoad = new Image(); - mpTestImageLoad->SetData(buffer); - mpTestImageLoad->SetFormat(ImageFormat::RGBA); - + TextureFormat format = TextureFormat::RGBA; if (n == 3) { - mpTestImageLoad->SetFormat(ImageFormat::RGB); + format = TextureFormat::RGB; } - - mpTestImageLoad->SetWidth(w); - mpTestImageLoad->SetHeight(h); - + mpTestImageLoad = Texture::Create(buffer, w, h, format); mSrcWidth = w; mSrcHeight = h; - Core::Graphics().RegisterImage(*mpTestImageLoad); - angle = 0.0f; box_angle = 0.0f; } @@ -127,68 +122,96 @@ namespace lunarium if (Core::Input().IsKeyPressed(KeyCode::Q)) { // Test writing out a rendered image with transparency - IGraphics& g = Core::Graphics(); + Renderer2D& g = Core::Graphics(); Color prev = g.GetClearColor(); g.SetClearColor(Color(0.0f, 0.0f, 0.0f, 0.0f)); - OpRes result = Core::GetInstance().BeginRenderToTexture(mFrameBufferTwo); - if (Failed(result)) - { - Logger::Warn(mLogCat, "Unable to render to texture: %s", result.Description.c_str()); - return; - } + mFrameBufferTwo->Bind(); + OrthographicCamera cam(Vec2f{0.0f, 0.0f}, Sizef{(float)mFrameBufferTwo->GetTexture()->GetWidth(), (float)mFrameBufferTwo->GetTexture()->GetHeight()}); + g.BeginDraw(&cam); + // if (Failed(result)) + // { + // Logger::Warn(mLogCat, "Unable to render to texture: %s", result.Description.c_str()); + // return; + // } Logger::Info(mLogCat, "Running transparent image test"); - g.DrawFilledBox(Rectangle(500, 400, 300, 300), Color(0.5f, 0.0f, 0.75f, 1.0f)); + g.DrawQuad(Rectangle(500, 400, 300, 300), Color(0.5f, 0.0f, 0.75f, 1.0f)); g.DrawString("This is a test of rendering an image with transparency", Rectangle::MakeFromTopLeft(50, 50, 600, 200), Color(0.0f, 1.0f, 0.2f, 1.0f), 0.5f); - mpRenderedImage = Core::GetInstance().EndRenderToTexture(); + g.EndDraw(); + mpRenderedImage = mFrameBufferTwo->GetTexture(); + //mpRenderedImage = Core::GetInstance().EndRenderToTexture(); g.SetClearColor(prev); stbi_flip_vertically_on_write(1); stbi_write_png("lunarium_test_image.png", mpRenderedImage->GetWidth(), mpRenderedImage->GetHeight(), 4, - mpRenderedImage->GetData(), mpRenderedImage->GetWidth() * 4); + mpRenderedImage->GetPixels(), mpRenderedImage->GetWidth() * 4); } mImageSize.Width = Math::ClampI(mImageSize.Width, 320, 1280); mImageSize.Height = Math::ClampI(mImageSize.Height, 180, 720); // Render to texture testing - OpRes result = Core::GetInstance().BeginRenderToTexture(mFrameBufferOne); - if (Failed(result)) - { - Logger::Error(mLogCat, "Unable to render to texture: %s", result.Description.c_str()); - return; - } + // mFrameBufferOne->Bind(); + // OrthographicCamera cam(Vec2f{0.0f, 0.0f}, Sizef{(float)mFrameBufferOne->GetTexture()->GetWidth(), (float)mFrameBufferOne->GetTexture()->GetHeight()}); + // Renderer2D& g = Core::Graphics(); + // g.BeginDraw(&cam); + // // OpRes result = Core::GetInstance().BeginRenderToTexture(mFrameBufferOne); + // // if (Failed(result)) + // // { + // // Logger::Error(mLogCat, "Unable to render to texture: %s", result.Description.c_str()); + // // return; + // // } + + + // g.DrawQuad(Rectangle(300, 300, 150, 150), Color::Red()); + // //g.DrawFilledEllipse(glm::vec2(600, 300), glm::vec2(100, 150), Color(1.0f, 0.0f, 1.0f, 1.0f), 100); + // // g.DrawString("This is a test of the text renderer!", Rectangle::MakeFromTopLeft(100, 200, mTextBoxWidth, 300), + // // Color(0.0f, 1.0f, 1.0f, 1.0f), 0.5f, g.DefaultFont()); + + // //mpRenderedImage = Core::GetInstance().EndRenderToTexture(); + // g.EndDraw(); + mpRenderedImage = mFrameBufferOne->GetTexture(); + + box_angle += 0.01f; + int draws = Core::Graphics().GetFrameStats().DrawCalls; + Core::Graphics().ResetFrameStats(); - IGraphics& g = Core::Graphics(); + int w, h; + Core::MainWindow().GetFramebufferSize(&w, &h); + OrthographicCamera main_cam(Vec2f { 0.0f, 0.0f }, Sizef { (float)w, (float)h }); + Core::Graphics().BeginDraw(&main_cam); + RenderScene(); - g.DrawFilledEllipse(glm::vec2(600, 300), glm::vec2(100, 150), Color(1.0f, 0.0f, 1.0f, 1.0f), 100); - g.DrawString("This is a test of the text renderer!", Rectangle::MakeFromTopLeft(100, 200, mTextBoxWidth, 300), - Color(0.0f, 1.0f, 1.0f, 1.0f), 0.5f, g.DefaultFont()); + Core::GUI().NewFrame(); - mpRenderedImage = Core::GetInstance().EndRenderToTexture(); + ImGui::Begin("TEST INFO"); + ImGui::Text("Draw calls: %d", draws); + ImGui::End(); - box_angle += 0.01f; + Core::GUI().EndFrame(); + Core::Graphics().EndDraw(); + Core::MainWindow().SwapBuffers(); } - void SimpleRenderScene::OnRender(IGraphics* g) + void SimpleRenderScene::RenderScene() { - g->DrawImage(*mpRenderedImage, Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpRenderedImage->GetWidth(), (float)mpRenderedImage->GetHeight()), - Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(1.0f, 1.0f, 1.0f, 1.0f), angle); + Renderer2D g = Core::Graphics(); + // g.DrawImage(*mpRenderedImage, Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpRenderedImage->GetWidth(), (float)mpRenderedImage->GetHeight()), + // Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(1.0f, 1.0f, 1.0f, 1.0f), angle); - g->DrawBox(Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(0.0f, 0.0f, 0.0f, 1.0f), 1.0f, angle); + g.DrawQuad(Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(0.0f, 0.0f, 0.0f, 1.0f), nullptr, angle); - g->DrawBox(Rectangle(400, 400, 128.0f, 128.0f), Color(0.0f, 1.0f, 0.0f, 1.0f), 2.0f, box_angle); + g.DrawQuad(Rectangle(400, 400, 128.0f, 128.0f), Color(0.0f, 1.0f, 0.0f, 1.0f), nullptr, box_angle); //g->DrawImage(*mpTestImageLoad, glm::vec2(0.0f, 0.0f), Color::White()); //Rectangle src = Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpTestImageLoad->GetWidth(), (float)mpTestImageLoad->GetHeight()); //Rectangle src = Rectangle::MakeFromTopLeft(0.0f, 0.0f, mSrcWidth, mSrcHeight); Rectangle src = Rectangle::MakeFromTopLeft(0.0f, 0.0f, 16, 16); Rectangle dest = Rectangle::MakeFromTopLeft(100.0f, 100.0f, 512.0f, 512.0f); - g->DrawImage(*mpTestImageLoad, src, - dest, Color(1.0f, 1.0f, 1.0f, 0.9f)); + //g.DrawImage(*mpTestImageLoad, src, dest, Color(1.0f, 1.0f, 1.0f, 0.9f)); // g->DrawImage(*mpTestImageLoad, src, // dest, Color(1.0f, 1.0f, 1.0f, 0.8f)); diff --git a/src/run_modes/testbed/scenes/simple_render_scene.h b/src/run_modes/testbed/scenes/simple_render_scene.h index 558ab64..9849606 100644 --- a/src/run_modes/testbed/scenes/simple_render_scene.h +++ b/src/run_modes/testbed/scenes/simple_render_scene.h @@ -15,7 +15,8 @@ namespace lunarium { - class Image; + class Texture; + class FrameBuffer; class SimpleRenderScene : public BaseScene { public: @@ -23,16 +24,16 @@ namespace lunarium ~SimpleRenderScene(); virtual void OnLoad(); virtual void OnTick(double delta); - virtual void OnRender(IGraphics* g); + void RenderScene(); private: int mTextBoxWidth; Sizei mImageSize; - Image* mpRenderedImage; - Image* mpTestImageLoad; - int mFrameBufferOne; - int mFrameBufferTwo; + Texture* mpRenderedImage; + Texture* mpTestImageLoad; + FrameBuffer* mFrameBufferOne; + FrameBuffer* mFrameBufferTwo; float angle; float box_angle; diff --git a/src/run_modes/testbed/testbed.cpp b/src/run_modes/testbed/testbed.cpp index 0a11fdd..913f8de 100644 --- a/src/run_modes/testbed/testbed.cpp +++ b/src/run_modes/testbed/testbed.cpp @@ -12,7 +12,8 @@ #include #include -#include +#include +#include #include namespace lunarium @@ -50,7 +51,7 @@ namespace lunarium } - void TestBed::OnTick(double delta) + void TestBed::OnUpdate(double delta) { if (Core::Input().IsKeyDown(KeyCode::NUM_1)) { @@ -80,11 +81,6 @@ namespace lunarium mpScene->OnTick(delta); } - void TestBed::OnRender(IGraphics* g) - { - mpScene->OnRender(g); - } - void TestBed::OnKeyPress(InputManager::KeyPress kp) { diff --git a/src/run_modes/testbed/testbed.h b/src/run_modes/testbed/testbed.h index 048bad3..c220afc 100644 --- a/src/run_modes/testbed/testbed.h +++ b/src/run_modes/testbed/testbed.h @@ -23,8 +23,7 @@ namespace lunarium TestBed(); OpRes Initialize(); void Shutdown(); - void OnTick(double delta); - void OnRender(IGraphics* g); + void OnUpdate(double delta); void OnKeyPress(InputManager::KeyPress kp); void SwitchScene(int id); diff --git a/src/world/components.h b/src/world/components.h index 0cfba38..54e9068 100644 --- a/src/world/components.h +++ b/src/world/components.h @@ -16,7 +16,7 @@ #define GLM_ENABLE_EXPERIMENTAL #include -#include +#include #include diff --git a/src/world/world.cpp b/src/world/world.cpp index 49df084..2c85624 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -13,8 +13,7 @@ #include #include #include -#include -#include +#include #include "entity.h" namespace lunarium diff --git a/test_data/engine_state.json b/test_data/engine_state.json index 5004d9f..a338efe 100644 --- a/test_data/engine_state.json +++ b/test_data/engine_state.json @@ -2,7 +2,7 @@ "State": { "DataDirectory": "data/", - "Mode": "editor", + "Mode": "test", "Display": {