diff --git a/Prism/CMakeLists.txt b/Prism/CMakeLists.txt index 6a2c537..4355dad 100644 --- a/Prism/CMakeLists.txt +++ b/Prism/CMakeLists.txt @@ -2,7 +2,7 @@ project(Prism) file(GLOB_RECURSE SRC_SOURCE src/**.cpp) -# configure +# ------------- configure ------------- set(CMAKE_POSITION_INDEPENDENT_CODE ON) add_subdirectory(vendor/spdlog EXCLUDE_FROM_ALL) @@ -10,7 +10,7 @@ add_subdirectory(vendor/glfw EXCLUDE_FROM_ALL) add_subdirectory(vendor/glad EXCLUDE_FROM_ALL) -# imgui +# ------------- imgui ------------- set(IMGUI_DIR vendor/ImGui) include_directories(${IMGUI_DIR} ${IMGUI_DIR}/backends) file(GLOB IMGUI_SOURCE @@ -21,7 +21,7 @@ file(GLOB IMGUI_SOURCE # add imgui source list(APPEND SRC_SOURCE ${IMGUI_SOURCE}) -# link libraries +# ------------- link libraries ------------- set(LINK_LIBRARIES spdlog glfw @@ -37,19 +37,26 @@ elseif(UNIX AND NOT APPLE) endif() +# ------------- Target include Directory ------------- set(TARGET_INCLUDE_DIR $ ${IMGUI_DIR} ) -# static library +# ------------- debug Defines ------------- +set(DEBUG_DEFINITIONS + $<$:PM_ENABLE_ASSERTS> +) + + + # static library set(STATIC_LIBRARY ${PROJECT_NAME}-static) add_library(${STATIC_LIBRARY} STATIC ${SRC_SOURCE}) target_compile_definitions(${STATIC_LIBRARY} PRIVATE PRISM_STATIC - $<$:PM_ENABLE_ASSERTS> + ${DEBUG_DEFINITIONS} ) target_include_directories(${STATIC_LIBRARY} PUBLIC @@ -74,7 +81,7 @@ add_library(${SHARED_LIBRARY} SHARED ${SRC_SOURCE}) target_compile_definitions(${SHARED_LIBRARY} PRIVATE PRISM_SHARED BUILD_PRISM_DLL - $<$:PM_ENABLE_ASSERTS> + ${DEBUG_DEFINITIONS} ) target_include_directories(${SHARED_LIBRARY} PUBLIC diff --git a/Prism/src/Prism.h b/Prism/src/Prism.h index a059886..e5d0482 100644 --- a/Prism/src/Prism.h +++ b/Prism/src/Prism.h @@ -7,12 +7,14 @@ #include "Prism/Core/Application.h" -#include "Prism/Core/EntryPoint.h" #include "Prism/Core/Events/ApplicationEvent.h" #include "Prism/Core/Events/Event.h" #include "Prism/Core/Events/KeyEvent.h" #include "Prism/Core/Events/MouseEvent.h" +#include "Prism/Renderer/IndexBuffer.h" #include "Prism/Renderer/Renderer.h" - +#include "Prism/Renderer/Shader.h" +#include "Prism/Renderer/Texture.h" +#include "Prism/Renderer/VertexBuffer.h" #endif //PRISM_H diff --git a/Prism/src/Prism/Core/Application.cpp b/Prism/src/Prism/Core/Application.cpp index 0bc0115..1143a7e 100644 --- a/Prism/src/Prism/Core/Application.cpp +++ b/Prism/src/Prism/Core/Application.cpp @@ -7,6 +7,7 @@ #include "glad/glad.h" #include "Prism/Renderer/Renderer.h" +#include "Log.h" namespace Prism @@ -29,6 +30,8 @@ namespace Prism m_ImGuiLayer = new ImGuiLayer("ImGui Layer"); PushOverlay(m_ImGuiLayer); + + Renderer::Init(); } Application::~Application() diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.cpp new file mode 100644 index 0000000..f0769ec --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.cpp @@ -0,0 +1,41 @@ +// +// Created by sfd on 25-11-22. +// + +#include "OpenGLIndexBuffer.h" + +#include "glad/glad.h" +#include "Prism/Renderer/Renderer.h" + +namespace Prism +{ + OpenGLIndexBuffer::OpenGLIndexBuffer(unsigned int size) + : m_RendererID(0), m_Size(size) + { + PM_RENDER_S({ + glGenBuffers(1, &self->m_RendererID); + }); + } + + OpenGLIndexBuffer::~OpenGLIndexBuffer() + { + PM_RENDER_S({ + glDeleteBuffers(1, &self->m_RendererID); + }); + } + + void OpenGLIndexBuffer::SetData(void* buffer, unsigned int size, unsigned int offset) + { + PM_RENDER_S3(buffer, size, offset, { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self->m_RendererID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, buffer, GL_STATIC_DRAW); + }); + } + + void OpenGLIndexBuffer::Bind() const + { + PM_RENDER_S({ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self->m_RendererID); + }); + } +} diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.h b/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.h new file mode 100644 index 0000000..a46e98d --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLIndexBuffer.h @@ -0,0 +1,30 @@ +// +// Created by sfd on 25-11-22. +// + +#ifndef OPENGLINDEXBUFFER_H +#define OPENGLINDEXBUFFER_H +#include "Prism/Renderer/IndexBuffer.h" + + +namespace Prism +{ + class OpenGLIndexBuffer : public IndexBuffer + { + public: + OpenGLIndexBuffer(unsigned int size); + virtual ~OpenGLIndexBuffer(); + + virtual void SetData(void* buffer, unsigned int size, unsigned int offset = 0); + virtual void Bind() const; + + virtual unsigned int GetSize() const { return m_Size; } + virtual RendererID GetRendererID() const { return m_RendererID; } + private: + RendererID m_RendererID; + unsigned int m_Size; + }; +} + + +#endif //OPENGLINDEXBUFFER_H diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLRendererAPI.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLRendererAPI.cpp index 82c8573..137bde6 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLRendererAPI.cpp +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLRendererAPI.cpp @@ -9,6 +9,17 @@ namespace Prism { + void RendererAPI::Init() + { + unsigned int vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + } + + void RendererAPI::Shutdown() + { + } + void RendererAPI::Clear(const float r, const float g, const float b, const float a) { glClearColor(r, g, b, a); @@ -20,5 +31,8 @@ namespace Prism glClearColor(r, g, b, a); } - + void RendererAPI::DrawIndexed(const int count) + { + glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr); + } } diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLShader.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLShader.cpp new file mode 100644 index 0000000..a0c833d --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLShader.cpp @@ -0,0 +1,147 @@ +// +// Created by sfd on 25-11-22. +// + +#include "OpenGLShader.h" + +#include "Prism/Core/Log.h" +#include "Prism/Renderer/Renderer.h" + +namespace Prism +{ + OpenGLShader::OpenGLShader(const std::string& filepath) + { + ReadShaderFromFile(filepath); + CompileAndUploadShader(); + } + + void OpenGLShader::Bind() + { + PM_RENDER_S({ + glUseProgram(self->m_RendererID); + }); + } + + void OpenGLShader::ReadShaderFromFile(const std::string& filepath) + { + std::ifstream file(filepath, std::ios::in | std::ios::binary); + + if (file) + { + file.seekg(0, std::ios::end); + m_ShaderSource.resize(file.tellg()); + file.seekg(0, std::ios::beg); + file.read(&m_ShaderSource[0], m_ShaderSource.size()); + file.close(); + } + else + { + PM_CORE_WARN("Could not read shader file {0}", filepath); + } + } + + void OpenGLShader::CompileAndUploadShader() + { + std::istringstream ss(m_ShaderSource); + std::string token; + while (ss >> token) + { + if (token == "#type") + { + std::string type; + ss >> type; + PM_CORE_TRACE("Type={0}", type); + } + + printf("%s \n", token.c_str()); + } + + std::unordered_map shaderSources; + + + const char* typeToken = "#type"; + size_t typeTokenLength = strlen(typeToken); + size_t pos = m_ShaderSource.find(typeToken, 0); + while (pos != std::string::npos) + { + size_t eol = m_ShaderSource.find("\r\n", pos); + PM_CORE_ASSERT(eol != std::string::npos, "Syntax error"); + size_t begin = pos + typeTokenLength + 1; + std::string type = m_ShaderSource.substr(begin, eol - begin); + PM_CORE_ASSERT(type == "vertex" || type == "fragment" || type == "pixel", "Invalid shader type"); + + size_t nextLinePos = m_ShaderSource.find_first_not_of("\r\n", eol); + pos = m_ShaderSource.find(typeToken, nextLinePos); + shaderSources[ShaderTypeFromString(type)] = m_ShaderSource.substr(nextLinePos, pos - (nextLinePos == std::string::npos ? m_ShaderSource.size() - 1 : nextLinePos)); + } + + std::vector shaderRendererIDs; + + GLuint program = glCreateProgram(); + + for (const auto& kv : shaderSources) + { + GLenum type = kv.first; + const std::string& source = kv.second; + GLuint shaderRendererID = glCreateShader(type); + const GLchar* sourcePtr = source.c_str(); + glShaderSource(shaderRendererID, 1, &sourcePtr, NULL); + + glCompileShader(shaderRendererID); + + GLint isCompiled = 0; + glGetShaderiv(shaderRendererID, GL_COMPILE_STATUS, &isCompiled); + if (isCompiled == GL_FALSE) + { + GLint maxLength = 0; + glGetShaderiv(shaderRendererID, GL_INFO_LOG_LENGTH, &maxLength); + + std::vector infoLog(maxLength); + glGetShaderInfoLog(shaderRendererID, maxLength, &maxLength, &infoLog[0]); + PM_CORE_ERROR("Shader compile failed: \n{0}", &infoLog[0]); + + glDeleteShader(shaderRendererID); + + PM_CORE_ASSERT(false, "Shader compilation failed"); + } + shaderRendererIDs.push_back(shaderRendererID); + glAttachShader(program, shaderRendererID); + } + + glLinkProgram(program); + + GLint isLinked = 0; + glGetProgramiv(program, GL_LINK_STATUS, &isLinked); + if (isLinked == GL_FALSE) + { + GLint maxLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + + std::vector infoLog(maxLength); + glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); + PM_CORE_ERROR("Shader compilation failed:\n{0}", &infoLog[0]); + + glDeleteProgram(program); + + for (auto id : shaderRendererIDs) + glDeleteShader(id); + } + + + // Always detach shaders after a successful link. + for (auto id : shaderRendererIDs) + glDetachShader(program, id); + + m_RendererID = program; + } + + GLenum OpenGLShader::ShaderTypeFromString(const std::string& type) + { + if (type == "vertex") + return GL_VERTEX_SHADER; + if (type == "fragment" || type == "pixel") + return GL_FRAGMENT_SHADER; + + return GL_NONE; + } +} diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLShader.h b/Prism/src/Prism/Platform/OpenGL/OpenGLShader.h new file mode 100644 index 0000000..bc7cd02 --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLShader.h @@ -0,0 +1,33 @@ +// +// Created by sfd on 25-11-22. +// + +#ifndef OPENGLSHADER_H +#define OPENGLSHADER_H +#include "glad/glad.h" +#include "Prism/Renderer/RendererAPI.h" +#include "Prism/Renderer/Shader.h" + + +namespace Prism +{ + class OpenGLShader : public Shader + { + public: + OpenGLShader(const std::string& filepath); + + virtual void Bind() override; + private: + void ReadShaderFromFile(const std::string& filepath); + void CompileAndUploadShader(); + + static GLenum ShaderTypeFromString(const std::string& type); + private: + RendererID m_RendererID; + + std::string m_ShaderSource; + }; +} + + +#endif //OPENGLSHADER_H diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.cpp new file mode 100644 index 0000000..9bec955 --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.cpp @@ -0,0 +1,39 @@ +// +// Created by sfd on 25-11-22. +// + +#include "OpenGLTexture.h" + +#include "glad/glad.h" +#include "Prism/Renderer/Renderer.h" + +namespace Prism +{ + static GLenum PrismToOpenGLTextureFormat(TextureFormat format) + { + switch (format) + { + case Prism::TextureFormat::RGB: return GL_RGB; + case Prism::TextureFormat::RGBA: return GL_RGBA; + } + return 0; + } + + + OpenGLTexture2D::OpenGLTexture2D(TextureFormat format, unsigned int width, unsigned int height) + : m_Format(format), m_Width(width), m_Height(height) + { + auto self = this; + PM_RENDER_1(self, { + glGenTextures(1, &self->m_RendererID); + glBindTexture(GL_TEXTURE_2D, self->m_RendererID); + glTexImage2D(GL_TEXTURE_2D, 0, PrismToOpenGLTextureFormat(self->m_Format), self->m_Width, self->m_Height, 0, PrismToOpenGLTextureFormat(self->m_Format), GL_UNSIGNED_BYTE, nullptr); + glBindTexture(GL_TEXTURE_2D, 0); + }); + + } + + OpenGLTexture2D::~OpenGLTexture2D() + { + } +} diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.h b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.h new file mode 100644 index 0000000..3174efe --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.h @@ -0,0 +1,30 @@ +// +// Created by sfd on 25-11-22. +// + +#ifndef OPENGLTEXTURE_H +#define OPENGLTEXTURE_H +#include "Prism/Renderer/RendererAPI.h" +#include "Prism/Renderer/Texture.h" + + +namespace Prism +{ + class OpenGLTexture2D : public Texture2D + { + public: + OpenGLTexture2D(TextureFormat format, unsigned int width, unsigned int height); + ~OpenGLTexture2D(); + + virtual TextureFormat GetFormat() const { return m_Format; } + virtual unsigned int GetWidth() const { return m_Width; } + virtual unsigned int GetHeight() const { return m_Height; } + private: + RendererID m_RendererID; + TextureFormat m_Format; + unsigned int m_Width, m_Height; + }; +} + + +#endif //OPENGLTEXTURE_H diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.cpp new file mode 100644 index 0000000..2f0eb65 --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.cpp @@ -0,0 +1,44 @@ +// +// Created by sfd on 25-11-22. +// + +#include "OpenGLVertexBuffer.h" + +#include "glad/glad.h" +#include "Prism/Renderer/Renderer.h" + +namespace Prism +{ + OpenGLVertexBuffer::OpenGLVertexBuffer(unsigned int size) + : m_RendererID(0), m_Size(size) + { + PM_RENDER_S({ + glGenBuffers(1, &self->m_RendererID); + }); + } + + OpenGLVertexBuffer::~OpenGLVertexBuffer() + { + PM_RENDER_S({ + glDeleteBuffers(1, &self->m_RendererID); + }); + } + + void OpenGLVertexBuffer::SetData(void* buffer, unsigned int size, unsigned int offset) + { + PM_RENDER_S3(buffer, size, offset, { + glBindBuffer(GL_ARRAY_BUFFER, self->m_RendererID); + glBufferData(GL_ARRAY_BUFFER, size, buffer, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, 0); + }); + } + + void OpenGLVertexBuffer::Bind() const + { + PM_RENDER_S({ + glBindBuffer(GL_ARRAY_BUFFER, self->m_RendererID); + }); + } +} diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.h b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.h new file mode 100644 index 0000000..550beff --- /dev/null +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLVertexBuffer.h @@ -0,0 +1,30 @@ +// +// Created by sfd on 25-11-22. +// + +#ifndef OPENGLVERTEXBUFFER_H +#define OPENGLVERTEXBUFFER_H +#include "Prism/Renderer/VertexBuffer.h" + + +namespace Prism +{ + class OpenGLVertexBuffer : public VertexBuffer + { + public: + OpenGLVertexBuffer(unsigned int size); + virtual ~OpenGLVertexBuffer(); + + virtual void SetData(void* buffer, unsigned int size, unsigned int offset = 0); + virtual void Bind() const; + + virtual unsigned int GetSize() const { return m_Size; } + virtual RendererID GetRendererID() const { return m_RendererID; } + private: + RendererID m_RendererID; + unsigned int m_Size; + }; +} + + +#endif //OPENGLVERTEXBUFFER_H diff --git a/Prism/src/Prism/Platform/Windows/WindowsWindow.cpp b/Prism/src/Prism/Platform/Windows/WindowsWindow.cpp index ca8f6cc..0088376 100644 --- a/Prism/src/Prism/Platform/Windows/WindowsWindow.cpp +++ b/Prism/src/Prism/Platform/Windows/WindowsWindow.cpp @@ -71,6 +71,9 @@ namespace Prism int success = glfwInit(); PM_CORE_ASSERT(success, "Could not initialize GLFW!"); glfwSetErrorCallback(GLFWErrorCallback); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); s_GLFWInitialized = true; } diff --git a/Prism/src/Prism/Renderer/IndexBuffer.cpp b/Prism/src/Prism/Renderer/IndexBuffer.cpp new file mode 100644 index 0000000..65ffe85 --- /dev/null +++ b/Prism/src/Prism/Renderer/IndexBuffer.cpp @@ -0,0 +1,20 @@ +// +// Created by sfd on 25-11-22. +// + +#include "IndexBuffer.h" + +#include "Prism/Platform/OpenGL/OpenGLIndexBuffer.h" + +namespace Prism +{ + IndexBuffer* IndexBuffer::Create(const unsigned int size) + { + switch (RendererAPI::Current()) + { + case RendererAPIType::None: return nullptr; + case RendererAPIType::OpenGL: return new OpenGLIndexBuffer(size); + } + return nullptr; + } +} diff --git a/Prism/src/Prism/Renderer/IndexBuffer.h b/Prism/src/Prism/Renderer/IndexBuffer.h new file mode 100644 index 0000000..06fe90e --- /dev/null +++ b/Prism/src/Prism/Renderer/IndexBuffer.h @@ -0,0 +1,28 @@ +// +// Created by sfd on 25-11-22. +// + +#ifndef INDEXBUFFER_H +#define INDEXBUFFER_H +#include "RendererAPI.h" + + +namespace Prism +{ + class PRISM_API IndexBuffer + { + public: + virtual ~IndexBuffer() {} + + virtual void SetData(void* buffer, unsigned int size, unsigned int offset = 0) = 0; + virtual void Bind() const = 0; + + virtual unsigned int GetSize() const = 0; + virtual RendererID GetRendererID() const = 0; + + static IndexBuffer* Create(unsigned int size = 0); + }; +} + + +#endif //INDEXBUFFER_H diff --git a/Prism/src/Prism/Renderer/RenderCommandQueue.h b/Prism/src/Prism/Renderer/RenderCommandQueue.h index a312435..7ee893b 100644 --- a/Prism/src/Prism/Renderer/RenderCommandQueue.h +++ b/Prism/src/Prism/Renderer/RenderCommandQueue.h @@ -17,7 +17,7 @@ namespace Prism ~RenderCommandQueue(); void* Allocate(RenderCommandFn func, unsigned int size); - void Execute(); + void Execute(); private: unsigned char* m_CommandBuffer = nullptr; diff --git a/Prism/src/Prism/Renderer/Renderer.cpp b/Prism/src/Prism/Renderer/Renderer.cpp index 554fbfc..dbb8f35 100644 --- a/Prism/src/Prism/Renderer/Renderer.cpp +++ b/Prism/src/Prism/Renderer/Renderer.cpp @@ -10,6 +10,7 @@ namespace Prism { Renderer* Renderer::s_Instance = new Renderer(); + RendererAPIType RendererAPI::s_CurrentRendererAPI = RendererAPIType::OpenGL; void Renderer::Clear() { @@ -26,6 +27,13 @@ namespace Prism { } + void Renderer::DrawIndexed(const int count) + { + PM_RENDER_1(count, { + RendererAPI::DrawIndexed(count); + }); + } + void Renderer::ClearMagenta() { Clear(1, 0, 1); @@ -33,7 +41,7 @@ namespace Prism void Renderer::Init() { - s_Instance = new Renderer(); + PM_RENDER({ RendererAPI::Init(); }); } void Renderer::WaitAndRender() diff --git a/Prism/src/Prism/Renderer/Renderer.h b/Prism/src/Prism/Renderer/Renderer.h index 68eb908..135a207 100644 --- a/Prism/src/Prism/Renderer/Renderer.h +++ b/Prism/src/Prism/Renderer/Renderer.h @@ -18,11 +18,12 @@ namespace Prism static void Clear(); static void Clear(float r, float g, float b, float a = 1.0f); static void SetClearColor(float r, float g, float b, float a); + static void DrawIndexed(const int count); // test static void ClearMagenta(); - void Init(); + static void Init(); static void* Submit(const RenderCommandFn func, const unsigned int size) { @@ -52,7 +53,7 @@ namespace Prism }\ };\ {\ - auto mem = RenderCommandQueue::Submit(sizeof(PM_RENDER_UNIQUE(PMRenderCommand)), PM_RENDER_UNIQUE(PMRenderCommand)::Execute);\ + auto mem = ::Prism::Renderer::Submit(PM_RENDER_UNIQUE(PMRenderCommand)::Execute, sizeof(PM_RENDER_UNIQUE(PMRenderCommand)));\ new (mem) PM_RENDER_UNIQUE(PMRenderCommand)();\ }\ @@ -63,9 +64,9 @@ namespace Prism PM_RENDER_UNIQUE(PMRenderCommand)(typename ::std::remove_const::type>::type arg0) \ : m_arg0(arg0) {}\ \ - static void Execute(void* self)\ + static void Execute(void* argBuffer)\ {\ - auto& arg0 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)self)->m_arg0;\ + auto& arg0 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)argBuffer)->m_arg0;\ code\ }\ \ @@ -83,10 +84,10 @@ namespace Prism typename ::std::remove_const::type>::type arg1) \ : m_arg0(arg0), m_arg1(arg1) {}\ \ - static void Execute(void* self)\ + static void Execute(void* argBuffer)\ {\ - auto& arg0 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)self)->m_arg0;\ - auto& arg1 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)self)->m_arg1;\ + auto& arg0 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)argBuffer)->m_arg0;\ + auto& arg1 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)argBuffer)->m_arg1;\ code\ }\ \ @@ -106,11 +107,11 @@ namespace Prism typename ::std::remove_const::type>::type arg2) \ : m_arg0(arg0), m_arg1(arg1), m_arg2(arg2) {}\ \ - static void Execute(void* self)\ + static void Execute(void* argBuffer)\ {\ - auto& arg0 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)self)->m_arg0;\ - auto& arg1 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)self)->m_arg1;\ - auto& arg2 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)self)->m_arg2;\ + auto& arg0 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)argBuffer)->m_arg0;\ + auto& arg1 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)argBuffer)->m_arg1;\ + auto& arg2 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)argBuffer)->m_arg2;\ code\ }\ \ @@ -132,12 +133,12 @@ namespace Prism typename ::std::remove_const::type>::type arg3)\ : m_arg0(arg0), m_arg1(arg1), m_arg2(arg2), m_arg3(arg3) {}\ \ - static void Execute(void* self)\ + static void Execute(void* argBuffer)\ {\ - auto& arg0 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)self)->m_arg0;\ - auto& arg1 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)self)->m_arg1;\ - auto& arg2 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)self)->m_arg2;\ - auto& arg3 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)self)->m_arg3;\ + auto& arg0 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)argBuffer)->m_arg0;\ + auto& arg1 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)argBuffer)->m_arg1;\ + auto& arg2 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)argBuffer)->m_arg2;\ + auto& arg3 = ((PM_RENDER_UNIQUE(PMRenderCommand)*)argBuffer)->m_arg3;\ code\ }\ \ @@ -151,5 +152,17 @@ namespace Prism new (mem) PM_RENDER_UNIQUE(PMRenderCommand)(arg0, arg1, arg2, arg3);\ } +#define PM_RENDER_S(code) auto self = this;\ +PM_RENDER_1(self, code) + +#define PM_RENDER_S1(arg0, code) auto self = this;\ +PM_RENDER_2(self, arg0, code) + +#define PM_RENDER_S2(arg0, arg1, code) auto self = this;\ +PM_RENDER_3(self, arg0, arg1, code) + +#define PM_RENDER_S3(arg0, arg1, arg2, code) auto self = this;\ +PM_RENDER_4(self, arg0, arg1, arg2, code) + } #endif //RENDERER_H diff --git a/Prism/src/Prism/Renderer/RendererAPI.h b/Prism/src/Prism/Renderer/RendererAPI.h index 8fc5ca3..9f11e21 100644 --- a/Prism/src/Prism/Renderer/RendererAPI.h +++ b/Prism/src/Prism/Renderer/RendererAPI.h @@ -7,11 +7,29 @@ namespace Prism { + + using RendererID = unsigned int; + + enum class PRISM_API RendererAPIType + { + None, + OpenGL + }; + class PRISM_API RendererAPI { public: + static void Init(); + static void Shutdown(); + static void Clear(float r, float g, float b, float a); static void SetClearColor(float r, float g, float b, float a); + + static void DrawIndexed(int count); + static RendererAPIType Current() { return s_CurrentRendererAPI; } + + private: + static RendererAPIType s_CurrentRendererAPI; }; } diff --git a/Prism/src/Prism/Renderer/Shader.cpp b/Prism/src/Prism/Renderer/Shader.cpp new file mode 100644 index 0000000..cf072a0 --- /dev/null +++ b/Prism/src/Prism/Renderer/Shader.cpp @@ -0,0 +1,21 @@ +// +// Created by sfd on 25-11-22. +// + +#include "Shader.h" + +#include "RendererAPI.h" +#include "Prism/Platform/OpenGL/OpenGLShader.h" + +namespace Prism +{ + Shader* Shader::Create(const std::string& filepath) + { + switch (RendererAPI::Current()) + { + case RendererAPIType::None: return nullptr; + case RendererAPIType::OpenGL: return new OpenGLShader(filepath); + } + return nullptr; + } +} diff --git a/Prism/src/Prism/Renderer/Shader.h b/Prism/src/Prism/Renderer/Shader.h new file mode 100644 index 0000000..9a1579e --- /dev/null +++ b/Prism/src/Prism/Renderer/Shader.h @@ -0,0 +1,21 @@ +// +// Created by sfd on 25-11-22. +// + +#ifndef SHADER_H +#define SHADER_H + + +namespace Prism +{ + class PRISM_API Shader + { + public: + virtual void Bind() = 0; + + static Shader* Create(const std::string& filepath); + }; +} + + +#endif //SHADER_H diff --git a/Prism/src/Prism/Renderer/Texture.cpp b/Prism/src/Prism/Renderer/Texture.cpp new file mode 100644 index 0000000..f5f98d3 --- /dev/null +++ b/Prism/src/Prism/Renderer/Texture.cpp @@ -0,0 +1,22 @@ +// +// Created by sfd on 25-11-22. +// + +#include "Texture.h" + +#include "RendererAPI.h" +#include "Prism/Platform/OpenGL/OpenGLTexture.h" + +namespace Prism +{ + Texture2D* Texture2D::Create(TextureFormat format, unsigned int width, unsigned int height) + { + switch (RendererAPI::Current()) + { + case RendererAPIType::None: return nullptr; + case RendererAPIType::OpenGL: return new OpenGLTexture2D(format, width, height); + } + return nullptr; + } + +} diff --git a/Prism/src/Prism/Renderer/Texture.h b/Prism/src/Prism/Renderer/Texture.h new file mode 100644 index 0000000..a76f0de --- /dev/null +++ b/Prism/src/Prism/Renderer/Texture.h @@ -0,0 +1,37 @@ +// +// Created by sfd on 25-11-22. +// + +#ifndef TEXTURE_H +#define TEXTURE_H + + +namespace Prism +{ + + enum class TextureFormat + { + None = 0, + RGB = 1, + RGBA = 2, + }; + + class PRISM_API Texture + { + public: + virtual ~Texture() {} + }; + + class PRISM_API Texture2D : public Texture + { + public: + static Texture2D* Create(TextureFormat format, unsigned int width, unsigned int height); + + virtual TextureFormat GetFormat() const = 0; + virtual unsigned int GetWidth() const = 0; + virtual unsigned int GetHeight() const = 0; + }; +} + + +#endif //TEXTURE_H diff --git a/Prism/src/Prism/Renderer/VertexBuffer.cpp b/Prism/src/Prism/Renderer/VertexBuffer.cpp new file mode 100644 index 0000000..0a52879 --- /dev/null +++ b/Prism/src/Prism/Renderer/VertexBuffer.cpp @@ -0,0 +1,21 @@ +// +// Created by sfd on 25-11-22. +// + +#include "VertexBuffer.h" + +#include "Prism/Platform/OpenGL/OpenGLVertexBuffer.h" + +namespace Prism +{ + VertexBuffer* VertexBuffer::Create(unsigned int size) + { + switch (RendererAPI::Current()) + { + case RendererAPIType::None: return nullptr; + case RendererAPIType::OpenGL: return new OpenGLVertexBuffer(size); + } + return nullptr; + + } +} diff --git a/Prism/src/Prism/Renderer/VertexBuffer.h b/Prism/src/Prism/Renderer/VertexBuffer.h new file mode 100644 index 0000000..8e02194 --- /dev/null +++ b/Prism/src/Prism/Renderer/VertexBuffer.h @@ -0,0 +1,29 @@ +// +// Created by sfd on 25-11-22. +// + +#ifndef VERTEXBUFFER_H +#define VERTEXBUFFER_H +#include "RendererAPI.h" + + +namespace Prism +{ + class PRISM_API VertexBuffer + { + public: + virtual ~VertexBuffer() {} + + virtual void SetData(void* buffer, unsigned int size, unsigned int offset = 0) = 0; + virtual void Bind() const = 0; + + virtual unsigned int GetSize() const = 0; + virtual RendererID GetRendererID() const = 0; + + static VertexBuffer* Create(unsigned int size = 0); + + }; +} + + +#endif //VERTEXBUFFER_H diff --git a/Prism/src/pmpch.h b/Prism/src/pmpch.h index ce32a6b..4825ceb 100644 --- a/Prism/src/pmpch.h +++ b/Prism/src/pmpch.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "Prism/Core/Core.h" diff --git a/Sandbox/CMakeLists.txt b/Sandbox/CMakeLists.txt index f693f3d..e01a866 100644 --- a/Sandbox/CMakeLists.txt +++ b/Sandbox/CMakeLists.txt @@ -2,7 +2,11 @@ project(Sandbox) file(GLOB_RECURSE SRC_SOURCE ./**.cpp) +file(GLOB ASSETS assets) +file(COPY ${ASSETS} DESTINATION ${CMAKE_BINARY_DIR}/bin) + add_executable(${PROJECT_NAME} ${SRC_SOURCE}) -target_link_libraries(${PROJECT_NAME} PRIVATE Prism) \ No newline at end of file +target_link_libraries(${PROJECT_NAME} PRIVATE Prism) +target_compile_definitions(${PROJECT_NAME} PRIVATE ENABLE_DOCKSPACE) \ No newline at end of file diff --git a/Sandbox/Sandbox/Layer/DemoLayer.cpp b/Sandbox/Sandbox/Layer/DemoLayer.cpp index 787d0de..2e6facb 100644 --- a/Sandbox/Sandbox/Layer/DemoLayer.cpp +++ b/Sandbox/Sandbox/Layer/DemoLayer.cpp @@ -5,6 +5,7 @@ #include "DemoLayer.h" #include "Prism/Renderer/Renderer.h" +#include "Prism/Renderer/Shader.h" static void ImGuiShowHelpMarker(const char* desc) { @@ -29,6 +30,24 @@ DemoLayer::~DemoLayer() void DemoLayer::OnAttach() { + static float vertices[] = { + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.0f, 0.5f, 0.0f + }; + + static unsigned int indices[] = { + 0, 1, 2 + }; + + m_VertexBuffer = std::unique_ptr(Prism::VertexBuffer::Create()); + m_VertexBuffer->SetData(vertices, sizeof(vertices)); + + m_IndexBuffer = std::unique_ptr(Prism::IndexBuffer::Create()); + m_IndexBuffer->SetData(indices, sizeof(indices)); + + + m_Shader.reset(Prism::Shader::Create("assets/shaders/shader.glsl")); } void DemoLayer::OnDetach() @@ -38,6 +57,10 @@ void DemoLayer::OnDetach() void DemoLayer::OnUpdate() { Prism::Renderer::Clear(m_ClearColor[0], m_ClearColor[1], m_ClearColor[2], m_ClearColor[3]); + m_Shader->Bind(); + m_VertexBuffer->Bind(); + m_IndexBuffer->Bind(); + Prism::Renderer::DrawIndexed(3); } void DemoLayer::OnImGuiRender() @@ -49,6 +72,7 @@ void DemoLayer::OnImGuiRender() ImGui::Begin("GameLayer"); ImGui::ColorEdit4("Clear Color", m_ClearColor); ImGui::End(); + #if ENABLE_DOCKSPACE static bool p_open = true; diff --git a/Sandbox/Sandbox/Layer/DemoLayer.h b/Sandbox/Sandbox/Layer/DemoLayer.h index 72b3048..ecf3d54 100644 --- a/Sandbox/Sandbox/Layer/DemoLayer.h +++ b/Sandbox/Sandbox/Layer/DemoLayer.h @@ -4,8 +4,8 @@ #ifndef DEMOLAYER_H #define DEMOLAYER_H -#include "Prism/Core/Layer.h" +#include "Prism.h" class DemoLayer : public Prism::Layer { @@ -21,6 +21,10 @@ public: private: float m_ClearColor[4] = { 0.2f, 0.2f, 0.2f, 1.0f }; + + std::unique_ptr m_VertexBuffer; + std::unique_ptr m_IndexBuffer; + std::unique_ptr m_Shader; }; diff --git a/Sandbox/Sandbox/Sandbox.cpp b/Sandbox/Sandbox/Sandbox.cpp index f636cb4..c27d31d 100644 --- a/Sandbox/Sandbox/Sandbox.cpp +++ b/Sandbox/Sandbox/Sandbox.cpp @@ -3,10 +3,10 @@ // -#include "Layer/DemoLayer.h" -#include "Prism/Core/Application.h" +#include "Prism.h" #include "Prism/Core/EntryPoint.h" -#include "Prism/Core/ImGui/ImGuiLayer.h" + +#include "Layer/DemoLayer.h" class Sandbox : public Prism::Application { diff --git a/Sandbox/assets/shaders/shader.glsl b/Sandbox/assets/shaders/shader.glsl new file mode 100644 index 0000000..a56ca4e --- /dev/null +++ b/Sandbox/assets/shaders/shader.glsl @@ -0,0 +1,19 @@ +#type vertex +#version 430 core + +layout(location = 0) in vec3 a_Position; + +void main() +{ + gl_Position = vec4(a_Position, 1.0); +} + +#type fragment +#version 430 core + +layout(location = 0) out vec4 o_Color; + +void main() +{ + o_Color = vec4(1.0, 0.0, 1.0, 1.0); +}