From 1f7e1a49ae439fcd842b5bd7171380426b11df4c Mon Sep 17 00:00:00 2001 From: Gordon McCann Date: Sat, 22 Jan 2022 15:45:37 -0500 Subject: [PATCH] Updated rendering pipeline so that, eventually, there will be full functionality. Not actively used --- .gitmodules | 3 + Navigator/src/Navigator/Application.h | 3 +- Navigator/src/Navigator/Renderer/Buffer.cpp | 40 +++++ Navigator/src/Navigator/Renderer/Buffer.h | 149 ++++++++++++++++++ .../{ => Renderer}/GraphicsContext.h | 0 .../Navigator/Renderer/OrthographicCamera.cpp | 23 +++ .../Navigator/Renderer/OrthographicCamera.h | 32 ++++ .../src/Navigator/Renderer/RenderCommand.h | 3 +- Navigator/src/Navigator/Renderer/Renderer.cpp | 16 ++ Navigator/src/Navigator/Renderer/Renderer.h | 6 + .../src/Navigator/Renderer/RendererAPI.h | 5 +- Navigator/src/Navigator/Renderer/Shader.cpp | 133 ++++++++++++++++ Navigator/src/Navigator/Renderer/Shader.h | 25 +++ .../src/Navigator/Renderer/VertexArray.cpp | 20 +++ .../src/Navigator/Renderer/VertexArray.h | 27 ++++ .../src/Platform/OpenGL/OpenGLBuffer.cpp | 52 ++++++ Navigator/src/Platform/OpenGL/OpenGLBuffer.h | 40 +++++ Navigator/src/Platform/OpenGL/OpenGLContext.h | 2 +- .../src/Platform/OpenGL/OpenGLRendererAPI.cpp | 6 +- .../src/Platform/OpenGL/OpenGLRendererAPI.h | 3 +- .../src/Platform/OpenGL/OpenGLVertexArray.cpp | 76 +++++++++ .../src/Platform/OpenGL/OpenGLVertexArray.h | 31 ++++ Navigator/src/Platform/OpenGL/OpenGLWindow.h | 2 +- Navigator/vendor/glm | 1 + premake5.lua | 14 +- 25 files changed, 701 insertions(+), 11 deletions(-) create mode 100644 Navigator/src/Navigator/Renderer/Buffer.cpp create mode 100644 Navigator/src/Navigator/Renderer/Buffer.h rename Navigator/src/Navigator/{ => Renderer}/GraphicsContext.h (100%) create mode 100644 Navigator/src/Navigator/Renderer/OrthographicCamera.cpp create mode 100644 Navigator/src/Navigator/Renderer/OrthographicCamera.h create mode 100644 Navigator/src/Navigator/Renderer/Renderer.cpp create mode 100644 Navigator/src/Navigator/Renderer/Shader.cpp create mode 100644 Navigator/src/Navigator/Renderer/Shader.h create mode 100644 Navigator/src/Navigator/Renderer/VertexArray.cpp create mode 100644 Navigator/src/Navigator/Renderer/VertexArray.h create mode 100644 Navigator/src/Platform/OpenGL/OpenGLBuffer.cpp create mode 100644 Navigator/src/Platform/OpenGL/OpenGLBuffer.h create mode 100644 Navigator/src/Platform/OpenGL/OpenGLVertexArray.cpp create mode 100644 Navigator/src/Platform/OpenGL/OpenGLVertexArray.h create mode 160000 Navigator/vendor/glm diff --git a/.gitmodules b/.gitmodules index 3937efd..b9811c3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,3 +11,6 @@ [submodule "Navigator/vendor/glfw"] path = Navigator/vendor/glfw url = https://github.com/gwm17/glfw.git +[submodule "Navigator/vendor/glm"] + path = Navigator/vendor/glm + url = https://github.com/g-truc/glm.git diff --git a/Navigator/src/Navigator/Application.h b/Navigator/src/Navigator/Application.h index d8fe23d..441c295 100644 --- a/Navigator/src/Navigator/Application.h +++ b/Navigator/src/Navigator/Application.h @@ -11,6 +11,7 @@ #include "Navigator/ImGui/ImGuiLayer.h" #include "Navigator/Physics/PhysicsLayer.h" #include "Navigator/HistogramMap.h" +#include "glm/vec4.hpp" namespace Navigator { @@ -40,7 +41,7 @@ namespace Navigator { PhysicsLayer* m_physicsLayer; bool m_runFlag; - float m_bckgnd_color[4] = {0.1, 0.1, 0.1, 1.0}; + glm::vec4 m_bckgnd_color = {0.1f, 0.1f, 0.1f, 1.0f}; static Application* s_instance; }; diff --git a/Navigator/src/Navigator/Renderer/Buffer.cpp b/Navigator/src/Navigator/Renderer/Buffer.cpp new file mode 100644 index 0000000..8e75281 --- /dev/null +++ b/Navigator/src/Navigator/Renderer/Buffer.cpp @@ -0,0 +1,40 @@ +#include "Buffer.h" +#include "Renderer.h" +#include "RendererAPI.h" +#include "Platform/OpenGL/OpenGLBuffer.h" + +namespace Navigator { + + VertexBuffer* VertexBuffer::Create(size_t size, float* arr) + { + switch (Renderer::GetAPI()) + { + case RendererAPI::API::OpenGL: + return new OpenGLVertexBuffer(size, arr); + return nullptr; + case RendererAPI::API::None: + NAV_ERROR("RendererAPI::None is not currently supported for VertexBuffer. Returning nullptr."); + return nullptr; + } + + NAV_ERROR("Invalid RendererAPI at VertexBuffer::Create(). Returning nullptr."); + return nullptr; + } + + IndexBuffer* IndexBuffer::Create(uint32_t count, uint32_t* arr) + { + switch (Renderer::GetAPI()) + { + case RendererAPI::API::OpenGL: + return new OpenGLIndexBuffer(count, arr); + return nullptr; + case RendererAPI::API::None: + NAV_ERROR("RendererAPI::None is not currently supported for IndexBuffer. Returning nullptr."); + return nullptr; + } + + NAV_ERROR("Invalid RendererAPI at IndexBuffer::Create(). Returning nullptr."); + return nullptr; + } + +} \ No newline at end of file diff --git a/Navigator/src/Navigator/Renderer/Buffer.h b/Navigator/src/Navigator/Renderer/Buffer.h new file mode 100644 index 0000000..395a86f --- /dev/null +++ b/Navigator/src/Navigator/Renderer/Buffer.h @@ -0,0 +1,149 @@ +#ifndef BUFFER_H +#define BUFFER_H + +namespace Navigator { + + NAV_API enum class ShaderDataType { + None, + Float, Float2, Float3, Float4, + Int, Int2, Int3, Int4, + Mat3, Mat4, + Bool + }; + + static uint32_t GetShaderDataTypeSize(ShaderDataType type) + { + switch (type) + { + case ShaderDataType::None: + { + NAV_ERROR("ShaderDataType::None is not supported for GetShaderDataTypeSizes"); + return 0; + } + case ShaderDataType::Float: + return 4; + case ShaderDataType::Float2: + return 4 * 2; + case ShaderDataType::Float3: + return 4 * 3; + case ShaderDataType::Float4: + return 4 * 4; + case ShaderDataType::Int: + return 4; + case ShaderDataType::Int2: + return 4 * 2; + case ShaderDataType::Int3: + return 4 * 3; + case ShaderDataType::Int4: + return 4 * 4; + case ShaderDataType::Mat3: + return 4 * 3 * 3; + case ShaderDataType::Mat4: + return 4 * 4 * 4; + case ShaderDataType::Bool: + return 1; + } + + NAV_ERROR("Unrecognized ShaderDataType at GetShaderDataTypeSize!"); + return 0; + } + + struct NAV_API BufferElement + { + std::string name; + ShaderDataType type; + uint32_t size; + uint32_t offset; + bool normalized; + + BufferElement() {} + BufferElement(ShaderDataType itype, const std::string& iname, bool norm = false) : + name(iname), type(itype), size(GetShaderDataTypeSize(itype)), offset(0), normalized(norm) + { + } + + uint32_t GetComponentCount() const + { + switch (type) + { + case ShaderDataType::Float: return 1; + case ShaderDataType::Float2: return 2; + case ShaderDataType::Float3: return 3; + case ShaderDataType::Float4: return 4; + case ShaderDataType::Int: return 1; + case ShaderDataType::Int2: return 2; + case ShaderDataType::Int3: return 3; + case ShaderDataType::Int4: return 4; + case ShaderDataType::Mat3: return 9; + case ShaderDataType::Mat4: return 16; + case ShaderDataType::Bool: return 1; + } + + NAV_ERROR("Unrecognized ShaderDataType at BufferElement::GetComponentCount!"); + return 0; + } + }; + + class NAV_API BufferLayout + { + public: + + BufferLayout() {} + BufferLayout(const std::initializer_list& elements) : + m_elements(elements) + { + CalculateOffsetsAndStride(); + } + + inline const std::vector& GetElements() const { return m_elements; } + inline const uint32_t GetStride() const { return m_stride; } + + std::vector::iterator begin() { return m_elements.begin(); }; + std::vector::iterator end() { return m_elements.end(); }; + std::vector::const_iterator begin() const { return m_elements.begin(); }; + std::vector::const_iterator end() const { return m_elements.end(); }; + + private: + void CalculateOffsetsAndStride() + { + uint32_t offset = 0; + for (auto& element : m_elements) + { + element.offset = offset; + offset += element.size; + } + + m_stride = offset; + } + + std::vector m_elements; + uint32_t m_stride; + }; + + class NAV_API VertexBuffer + { + public: + virtual ~VertexBuffer() {}; + virtual void Bind() const = 0; + virtual void Unbind() const = 0; + + virtual void SetLayout(const BufferLayout& layout) = 0; + virtual const BufferLayout& GetLayout() const = 0; + + static VertexBuffer* Create(size_t size, float* arr); + + }; + + class NAV_API IndexBuffer + { + public: + virtual ~IndexBuffer() {}; + virtual void Bind() const = 0; + virtual void Unbind() const = 0; + virtual uint32_t GetCount() const = 0; + + static IndexBuffer* Create(uint32_t count, uint32_t* arr); + }; +} + +#endif diff --git a/Navigator/src/Navigator/GraphicsContext.h b/Navigator/src/Navigator/Renderer/GraphicsContext.h similarity index 100% rename from Navigator/src/Navigator/GraphicsContext.h rename to Navigator/src/Navigator/Renderer/GraphicsContext.h diff --git a/Navigator/src/Navigator/Renderer/OrthographicCamera.cpp b/Navigator/src/Navigator/Renderer/OrthographicCamera.cpp new file mode 100644 index 0000000..54b5b45 --- /dev/null +++ b/Navigator/src/Navigator/Renderer/OrthographicCamera.cpp @@ -0,0 +1,23 @@ +#include "OrthographicCamera.h" + +#include "glm/gtc/matrix_transform.hpp" + +namespace Navigator { + + OrthographicCamera::OrthographicCamera(float left, float right, float bottom, float top) : + m_projectionMatrix(glm::ortho(left, right, bottom, top, -1.0f, 1.0f)), m_viewMatrix(1.0f), m_viewProjectionMatrix(1.0f), m_position(0.0f, 0.0f, 0.0f), m_polarRot(0.0f) + { + m_viewProjectionMatrix = m_projectionMatrix * m_viewMatrix; //OpenGL orderer is proj*view, dx is view*proj + } + + void OrthographicCamera::RecalculateViewMatrix() + { + glm::mat4 transform_matrix = glm::translate(glm::mat4(1.0f), m_position); //translate + transform_matrix = glm::rotate(transform_matrix, glm::radians(m_polarRot), glm::vec3(0.0f, 0.0f, 1.0f)); //then rotate + + m_viewMatrix = glm::inverse(transform_matrix); //view is the inverse of the transform to the camera + + m_viewProjectionMatrix = m_projectionMatrix * m_viewMatrix; + } + +} \ No newline at end of file diff --git a/Navigator/src/Navigator/Renderer/OrthographicCamera.h b/Navigator/src/Navigator/Renderer/OrthographicCamera.h new file mode 100644 index 0000000..82b256c --- /dev/null +++ b/Navigator/src/Navigator/Renderer/OrthographicCamera.h @@ -0,0 +1,32 @@ +#ifndef ORTHOGRAPHIC_CAMERA_H +#define ORTHOGRAPHIC_CAMERA_H + +#include "glm/glm.hpp" + +namespace Navigator { + + class OrthographicCamera + { + public: + OrthographicCamera(float left, float right, float bottom, float top); + inline void SetPosition(const glm::vec3& coords) { m_position = coords; RecalculateViewMatrix(); } + inline const glm::vec3& GetPosition() const { return m_position; } + inline void SetPolarRotation(float degrees) { m_polarRot = degrees; RecalculateViewMatrix(); } + inline float GetRotation() const { return m_polarRot; } + inline const glm::mat4& GetProjectionMatrix() const { return m_projectionMatrix; } + inline const glm::mat4& GetViewMatrix() const { return m_viewMatrix; } + inline const glm::mat4& GetViewProjectionMatrix() const { return m_viewProjectionMatrix; } + private: + void RecalculateViewMatrix(); + + glm::mat4 m_projectionMatrix; + glm::mat4 m_viewMatrix; + glm::mat4 m_viewProjectionMatrix; + + glm::vec3 m_position; + float m_polarRot; + }; + +} + +#endif \ No newline at end of file diff --git a/Navigator/src/Navigator/Renderer/RenderCommand.h b/Navigator/src/Navigator/Renderer/RenderCommand.h index 3788ee8..e328519 100644 --- a/Navigator/src/Navigator/Renderer/RenderCommand.h +++ b/Navigator/src/Navigator/Renderer/RenderCommand.h @@ -9,8 +9,9 @@ namespace Navigator { class NAV_API RenderCommand { public: - inline static void SetClearColor(const float* color_array) { s_api->SetClearColor(color_array); } + inline static void SetClearColor(const glm::vec4& color_array) { s_api->SetClearColor(color_array); } inline static void Clear() { s_api->Clear(); } + inline static void DrawIndexed(const std::shared_ptr& array) { s_api->DrawIndexed(array); } private: static RendererAPI* s_api; }; diff --git a/Navigator/src/Navigator/Renderer/Renderer.cpp b/Navigator/src/Navigator/Renderer/Renderer.cpp new file mode 100644 index 0000000..8c3cf72 --- /dev/null +++ b/Navigator/src/Navigator/Renderer/Renderer.cpp @@ -0,0 +1,16 @@ +#include "Renderer.h" + +namespace Navigator { + + + void Renderer::BeginScene() {} + + void Renderer::EndScene() {} + + void Renderer::Submit(const std::shared_ptr& shader, const std::shared_ptr& data) + { + shader->Bind(); + data->Bind(); + RenderCommand::DrawIndexed(data); + } +} \ No newline at end of file diff --git a/Navigator/src/Navigator/Renderer/Renderer.h b/Navigator/src/Navigator/Renderer/Renderer.h index 7515e14..db09fb2 100644 --- a/Navigator/src/Navigator/Renderer/Renderer.h +++ b/Navigator/src/Navigator/Renderer/Renderer.h @@ -4,6 +4,8 @@ #include "Navigator/NavCore.h" #include "RendererAPI.h" #include "RenderCommand.h" +#include "Shader.h" +#include "VertexArray.h" namespace Navigator { @@ -11,6 +13,10 @@ namespace Navigator { { public: + static void BeginScene(); + static void EndScene(); + static void Submit(const std::shared_ptr& shader, const std::shared_ptr& data); + static inline RendererAPI::API GetAPI() { return RendererAPI::GetAPI(); } }; diff --git a/Navigator/src/Navigator/Renderer/RendererAPI.h b/Navigator/src/Navigator/Renderer/RendererAPI.h index 2feb9fc..a07614b 100644 --- a/Navigator/src/Navigator/Renderer/RendererAPI.h +++ b/Navigator/src/Navigator/Renderer/RendererAPI.h @@ -2,6 +2,8 @@ #define RENDERER_API_H #include "Navigator/NavCore.h" +#include "VertexArray.h" +#include "glm/vec4.hpp" namespace Navigator { @@ -15,7 +17,8 @@ namespace Navigator { }; virtual void Clear() = 0; - virtual void SetClearColor(const float* color_array) = 0; + virtual void SetClearColor(const glm::vec4& color) = 0; + virtual void DrawIndexed(const std::shared_ptr& array) = 0; inline static API GetAPI() { return s_api; } diff --git a/Navigator/src/Navigator/Renderer/Shader.cpp b/Navigator/src/Navigator/Renderer/Shader.cpp new file mode 100644 index 0000000..3234b58 --- /dev/null +++ b/Navigator/src/Navigator/Renderer/Shader.cpp @@ -0,0 +1,133 @@ +#include "Shader.h" +#include "glad/glad.h" +#include "glm/gtc/type_ptr.hpp" + +namespace Navigator { + + Shader::Shader(const std::string& vertexSource, const std::string& fragmentSource) + { + // Create an empty vertex shader handle + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + + // Send the vertex shader source code to GL + // Note that std::string's .c_str is NULL character terminated. + const GLchar* source = (const GLchar*)vertexSource.c_str(); + glShaderSource(vertexShader, 1, &source, 0); + + // Compile the vertex shader + glCompileShader(vertexShader); + + GLint isCompiled = 0; + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled); + if (isCompiled == GL_FALSE) + { + GLint maxLength = 0; + glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength); + + // The maxLength includes the NULL character + std::vector infoLog(maxLength); + glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]); + + // We don't need the shader anymore. + glDeleteShader(vertexShader); + + // Use the infoLog as you see fit. + NAV_ERROR("Shader InfoLog: {0}", infoLog.data()); + NAV_ERROR("OpenGL Vertex Shader compilation error!"); + return; + } + + // Create an empty fragment shader handle + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + + // Send the fragment shader source code to GL + // Note that std::string's .c_str is NULL character terminated. + source = (const GLchar*)fragmentSource.c_str(); + glShaderSource(fragmentShader, 1, &source, 0); + + // Compile the fragment shader + glCompileShader(fragmentShader); + + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled); + if (isCompiled == GL_FALSE) + { + GLint maxLength = 0; + glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength); + + // The maxLength includes the NULL character + std::vector infoLog(maxLength); + glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]); + + // We don't need the shader anymore. + glDeleteShader(fragmentShader); + // Either of them. Don't leak shaders. + glDeleteShader(vertexShader); + + // Use the infoLog as you see fit. + NAV_ERROR("Shader InfoLog: {0}", infoLog.data()); + NAV_ERROR("OpenGL Fragment Shader compilation error!"); + return; + } + + // Vertex and fragment shaders are successfully compiled. + // Now time to link them together into a program. + // Get a program object. + m_renderID = glCreateProgram(); + + // Attach our shaders to our program + glAttachShader(m_renderID, vertexShader); + glAttachShader(m_renderID, fragmentShader); + + // Link our program + glLinkProgram(m_renderID); + + // Note the different functions here: glGetProgram* instead of glGetShader*. + GLint isLinked = 0; + glGetProgramiv(m_renderID, GL_LINK_STATUS, (int*)&isLinked); + if (isLinked == GL_FALSE) + { + GLint maxLength = 0; + glGetProgramiv(m_renderID, GL_INFO_LOG_LENGTH, &maxLength); + + // The maxLength includes the NULL character + std::vector infoLog(maxLength); + glGetProgramInfoLog(m_renderID, maxLength, &maxLength, &infoLog[0]); + + // We don't need the program anymore. + glDeleteProgram(m_renderID); + // Don't leak shaders either. + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + // Use the infoLog as you see fit. + NAV_ERROR("Program InfoLog: {0}", infoLog.data()); + NAV_ERROR("OpenGL Shader link error!"); + return; + } + + // Always detach shaders after a successful link. + glDetachShader(m_renderID, vertexShader); + glDetachShader(m_renderID, fragmentShader); + } + + Shader::~Shader() + { + glDeleteProgram(m_renderID); + } + + void Shader::Bind() const + { + glUseProgram(m_renderID); + } + + void Shader::Unbind() const + { + glUseProgram(0); + } + void Shader::UploadUniformMat4(const std::string& name, const glm::mat4& matrix) + { + auto loc = glGetUniformLocation(m_renderID, name.c_str()); + glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(matrix)); + } + +} \ No newline at end of file diff --git a/Navigator/src/Navigator/Renderer/Shader.h b/Navigator/src/Navigator/Renderer/Shader.h new file mode 100644 index 0000000..8aa6231 --- /dev/null +++ b/Navigator/src/Navigator/Renderer/Shader.h @@ -0,0 +1,25 @@ +#ifndef SHADER_H +#define SHADER_H + +#include "glm/glm.hpp" + +namespace Navigator { + + class NAV_API Shader + { + public: + Shader(const std::string& vertexSource, const std::string& fragmentSource); + ~Shader(); + + void Bind() const; + void Unbind() const; + + void UploadUniformMat4(const std::string& name, const glm::mat4& matrix); + + private: + uint32_t m_renderID; + }; + +} + +#endif \ No newline at end of file diff --git a/Navigator/src/Navigator/Renderer/VertexArray.cpp b/Navigator/src/Navigator/Renderer/VertexArray.cpp new file mode 100644 index 0000000..e1a7fee --- /dev/null +++ b/Navigator/src/Navigator/Renderer/VertexArray.cpp @@ -0,0 +1,20 @@ +#include "VertexArray.h" +#include "Renderer.h" +#include "Platform/OpenGL/OpenGLVertexArray.h" + +namespace Navigator { + VertexArray* VertexArray::Create() + { + switch (Renderer::GetAPI()) + { + case RendererAPI::API::OpenGL: + return new OpenGLVertexArray(); + case RendererAPI::API::None: + NAV_ERROR("RendererAPI::None is not currently supported for IndexBuffer. Returning nullptr."); + return nullptr; + } + + NAV_ERROR("Invalid RendererAPI at VertexArray::Create!"); + return nullptr; + } +} \ No newline at end of file diff --git a/Navigator/src/Navigator/Renderer/VertexArray.h b/Navigator/src/Navigator/Renderer/VertexArray.h new file mode 100644 index 0000000..a2c95b4 --- /dev/null +++ b/Navigator/src/Navigator/Renderer/VertexArray.h @@ -0,0 +1,27 @@ +#ifndef VERTEX_ARRAY_H +#define VERTEX_ARRAY_H + +#include "Buffer.h" + +namespace Navigator { + + class NAV_API VertexArray + { + public: + virtual ~VertexArray() {}; + + virtual void Bind() const = 0; + virtual void Unbind() const = 0; + + virtual void AddVertexBuffer(const std::shared_ptr& buffer) = 0; + virtual void SetIndexBuffer(const std::shared_ptr& buffer) = 0; + virtual const std::vector>& GetVertexBuffers() const = 0; + virtual const std::shared_ptr& GetIndexBuffer() const = 0; + + static VertexArray* Create(); + + }; + +} + +#endif \ No newline at end of file diff --git a/Navigator/src/Platform/OpenGL/OpenGLBuffer.cpp b/Navigator/src/Platform/OpenGL/OpenGLBuffer.cpp new file mode 100644 index 0000000..8a1358c --- /dev/null +++ b/Navigator/src/Platform/OpenGL/OpenGLBuffer.cpp @@ -0,0 +1,52 @@ +#include "OpenGLBuffer.h" + +#include "glad/glad.h" + +namespace Navigator { + + OpenGLVertexBuffer::OpenGLVertexBuffer(size_t size, float* arr) + { + glCreateBuffers(1, &m_renderID); + glBindBuffer(GL_ARRAY_BUFFER, m_renderID); + glBufferData(GL_ARRAY_BUFFER, size, arr, GL_STATIC_DRAW); + } + + OpenGLVertexBuffer::~OpenGLVertexBuffer() + { + glDeleteBuffers(1, &m_renderID); + } + + void OpenGLVertexBuffer::Bind() const + { + glBindBuffer(GL_ARRAY_BUFFER, m_renderID); + } + + void OpenGLVertexBuffer::Unbind() const + { + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + + OpenGLIndexBuffer::OpenGLIndexBuffer(uint32_t count, uint32_t* arr) : + m_count(count) + { + glCreateBuffers(1, &m_renderID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_renderID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_count * sizeof(uint32_t), arr, GL_STATIC_DRAW); + } + + OpenGLIndexBuffer::~OpenGLIndexBuffer() + { + glDeleteBuffers(1, &m_renderID); + } + + void OpenGLIndexBuffer::Bind() const + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_renderID); + } + + void OpenGLIndexBuffer::Unbind() const + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + +} \ No newline at end of file diff --git a/Navigator/src/Platform/OpenGL/OpenGLBuffer.h b/Navigator/src/Platform/OpenGL/OpenGLBuffer.h new file mode 100644 index 0000000..dbe0463 --- /dev/null +++ b/Navigator/src/Platform/OpenGL/OpenGLBuffer.h @@ -0,0 +1,40 @@ +#ifndef OPENGL_BUFFER_H +#define OPENGL_BUFFER_H + +#include "Navigator/Renderer/Buffer.h" + +namespace Navigator { + + class NAV_API OpenGLVertexBuffer : public VertexBuffer + { + public: + OpenGLVertexBuffer(size_t size, float* arr); + ~OpenGLVertexBuffer(); + virtual void Bind() const override; + virtual void Unbind() const override; + + virtual void SetLayout(const BufferLayout& layout) override { m_layout = layout; } + virtual const BufferLayout& GetLayout() const override { return m_layout; } + + private: + uint32_t m_renderID; + BufferLayout m_layout; + }; + + class NAV_API OpenGLIndexBuffer : public IndexBuffer + { + public: + OpenGLIndexBuffer(uint32_t count, uint32_t* arr); + ~OpenGLIndexBuffer(); + virtual void Bind() const override; + virtual void Unbind() const override; + virtual uint32_t GetCount() const override { return m_count; } + + private: + uint32_t m_renderID; + uint32_t m_count; + }; + +} + +#endif \ No newline at end of file diff --git a/Navigator/src/Platform/OpenGL/OpenGLContext.h b/Navigator/src/Platform/OpenGL/OpenGLContext.h index 687432c..a1d29e2 100644 --- a/Navigator/src/Platform/OpenGL/OpenGLContext.h +++ b/Navigator/src/Platform/OpenGL/OpenGLContext.h @@ -2,7 +2,7 @@ #define OPEGL_CONTEXT_H #include "Navigator/NavCore.h" -#include "Navigator/GraphicsContext.h" +#include "Navigator/Renderer/GraphicsContext.h" struct GLFWwindow; diff --git a/Navigator/src/Platform/OpenGL/OpenGLRendererAPI.cpp b/Navigator/src/Platform/OpenGL/OpenGLRendererAPI.cpp index 9ed9e21..a0a1b75 100644 --- a/Navigator/src/Platform/OpenGL/OpenGLRendererAPI.cpp +++ b/Navigator/src/Platform/OpenGL/OpenGLRendererAPI.cpp @@ -9,9 +9,13 @@ namespace Navigator { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } - void OpenGLRendererAPI::SetClearColor(const float* color_array) + void OpenGLRendererAPI::SetClearColor(const glm::vec4& color_array) { glClearColor(color_array[0], color_array[1], color_array[2], color_array[3]); } + void OpenGLRendererAPI::DrawIndexed(const std::shared_ptr& array) + { + glDrawElements(GL_TRIANGLES, array->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, nullptr); + } } \ No newline at end of file diff --git a/Navigator/src/Platform/OpenGL/OpenGLRendererAPI.h b/Navigator/src/Platform/OpenGL/OpenGLRendererAPI.h index 55c974a..d378aba 100644 --- a/Navigator/src/Platform/OpenGL/OpenGLRendererAPI.h +++ b/Navigator/src/Platform/OpenGL/OpenGLRendererAPI.h @@ -10,7 +10,8 @@ namespace Navigator { { public: virtual void Clear() override; - virtual void SetClearColor(const float* color_array) override; + virtual void SetClearColor(const glm::vec4& color_array) override; + virtual void DrawIndexed(const std::shared_ptr& array) override; }; } diff --git a/Navigator/src/Platform/OpenGL/OpenGLVertexArray.cpp b/Navigator/src/Platform/OpenGL/OpenGLVertexArray.cpp new file mode 100644 index 0000000..6871417 --- /dev/null +++ b/Navigator/src/Platform/OpenGL/OpenGLVertexArray.cpp @@ -0,0 +1,76 @@ +#include "OpenGLVertexArray.h" + +#include "glad/glad.h" + +namespace Navigator { + + static GLenum ConvertShaderDataTypeToGLenum(ShaderDataType type) + { + switch (type) + { + case Navigator::ShaderDataType::Float: return GL_FLOAT; + case Navigator::ShaderDataType::Float2: return GL_FLOAT; + case Navigator::ShaderDataType::Float3: return GL_FLOAT; + case Navigator::ShaderDataType::Float4: return GL_FLOAT; + case Navigator::ShaderDataType::Int: return GL_INT; + case Navigator::ShaderDataType::Int2: return GL_INT; + case Navigator::ShaderDataType::Int3: return GL_INT; + case Navigator::ShaderDataType::Int4: return GL_INT; + case Navigator::ShaderDataType::Mat3: return GL_FLOAT; + case Navigator::ShaderDataType::Mat4: return GL_FLOAT; + case Navigator::ShaderDataType::Bool: return GL_BOOL; + } + + NAV_ERROR("Unrecognized ShaderDataType at ConvertShaderDataTypeToGLenum!"); + return 0; + } + + OpenGLVertexArray::OpenGLVertexArray() + { + glCreateVertexArrays(1, &m_rendererID); + } + + OpenGLVertexArray::~OpenGLVertexArray() + { + glDeleteVertexArrays(1, &m_rendererID); + } + + void OpenGLVertexArray::Bind() const + { + glBindVertexArray(m_rendererID); + } + + void OpenGLVertexArray::Unbind() const + { + glBindVertexArray(0); + } + + void OpenGLVertexArray::AddVertexBuffer(const std::shared_ptr& buffer) + { + if(buffer->GetLayout().GetElements().size() == 0) + NAV_ERROR("VertexBuffer with no layout passed to VertexArray::AddVertexBuffer!"); + glBindVertexArray(m_rendererID); + buffer->Bind(); + + + uint32_t index = 0; + const auto& layout = buffer->GetLayout(); + for (const auto& element : layout) + { + glEnableVertexAttribArray(index); + glVertexAttribPointer(index, element.GetComponentCount(), ConvertShaderDataTypeToGLenum(element.type), element.normalized ? GL_TRUE : GL_FALSE, layout.GetStride(), (const void*)element.offset); + index++; + } + + m_vertexBuffers.push_back(buffer); + } + + void OpenGLVertexArray::SetIndexBuffer(const std::shared_ptr& buffer) + { + glBindVertexArray(m_rendererID); + buffer->Bind(); + + m_indexBuffer = buffer; + } + +} \ No newline at end of file diff --git a/Navigator/src/Platform/OpenGL/OpenGLVertexArray.h b/Navigator/src/Platform/OpenGL/OpenGLVertexArray.h new file mode 100644 index 0000000..6213f36 --- /dev/null +++ b/Navigator/src/Platform/OpenGL/OpenGLVertexArray.h @@ -0,0 +1,31 @@ +#ifndef OPENGL_VERTEX_ARRAY +#define OPENGL_VERTEX_ARRAY + +#include "Navigator/Renderer/VertexArray.h" + +namespace Navigator { + + class NAV_API OpenGLVertexArray : public VertexArray + { + public: + OpenGLVertexArray(); + virtual ~OpenGLVertexArray(); + virtual void Bind() const override; + virtual void Unbind() const override; + + virtual void AddVertexBuffer(const std::shared_ptr& buffer) override; + virtual void SetIndexBuffer(const std::shared_ptr& buffer) override; + + inline virtual const std::vector>& GetVertexBuffers() const override { return m_vertexBuffers; } + inline virtual const std::shared_ptr& GetIndexBuffer() const { return m_indexBuffer; } + + private: + std::vector> m_vertexBuffers; + std::shared_ptr m_indexBuffer; + + uint32_t m_rendererID; + }; + +} + +#endif \ No newline at end of file diff --git a/Navigator/src/Platform/OpenGL/OpenGLWindow.h b/Navigator/src/Platform/OpenGL/OpenGLWindow.h index a1a6853..130a870 100644 --- a/Navigator/src/Platform/OpenGL/OpenGLWindow.h +++ b/Navigator/src/Platform/OpenGL/OpenGLWindow.h @@ -3,7 +3,7 @@ #include "Navigator/NavCore.h" #include "Navigator/Window.h" -#include "Navigator/GraphicsContext.h" +#include "Navigator/Renderer/GraphicsContext.h" #include "GLFW/glfw3.h" namespace Navigator { diff --git a/Navigator/vendor/glm b/Navigator/vendor/glm new file mode 160000 index 0000000..6ad79aa --- /dev/null +++ b/Navigator/vendor/glm @@ -0,0 +1 @@ +Subproject commit 6ad79aae3eb5bf809c30bf1168171e9e55857e45 diff --git a/premake5.lua b/premake5.lua index 5dedd8b..908cdad 100644 --- a/premake5.lua +++ b/premake5.lua @@ -15,6 +15,7 @@ IncludeDirs["glfw"] = "Navigator/vendor/glfw/include" IncludeDirs["ImGui"] = "Navigator/vendor/imgui" IncludeDirs["glad"] = "Navigator/vendor/glad/include" IncludeDirs["ImPlot"] = "Navigator/vendor/implot" +IncludeDirs["glm"] = "Navigator/vendor/glm" include "Navigator/vendor/glfw" include "Navigator/vendor/imgui" @@ -42,7 +43,8 @@ project "Navigator" "%{IncludeDirs.glfw}", "%{IncludeDirs.ImGui}", "%{IncludeDirs.glad}", - "%{IncludeDirs.ImPlot}" + "%{IncludeDirs.ImPlot}", + "%{IncludeDirs.glm}" } filter {} @@ -52,7 +54,8 @@ project "Navigator" "%{IncludeDirs.glfw}", "%{IncludeDirs.ImGui}", "%{IncludeDirs.glad}", - "%{IncludeDirs.ImPlot}" + "%{IncludeDirs.ImPlot}", + "%{IncludeDirs.glm}" } @@ -141,7 +144,9 @@ project "NavProject" "Navigator/src/Navigator", "Navigator/vendor/spdlog/include/", "Navigator/vendor/implot/", - "Navigator/vendor" + "Navigator/vendor", + "%{IncludeDirs.glm}" + } links { @@ -158,7 +163,8 @@ project "NavProject" "%{IncludeDirs.glfw}", "%{IncludeDirs.ImGui}", "%{IncludeDirs.glad}", - "%{IncludeDirs.ImPlot}" + "%{IncludeDirs.ImPlot}", + "%{IncludeDirs.glm}" } filter "system:windows" defines "NAV_WINDOWS"