Major Maintenance

- Major tidying
- Moved 'RendererProgram' classes out of the 'Renderer' class
- Moved 'RenderCommand' member variable out of 'GraphicsContext' and into
       the 'Renderer' class as a unique_ptr. results in 'Renderer' taking a
       windowHandle for construction
- Defined new macros for max quads in 'Renderer.h'
- Added the 'Stringifier' to 'Base.h'
- Added the 'ResourceManager' to the 'LightEngine.h'
- Application now logs the current file directory
- Fixed the forward declaration in GraphicsContext
- Fixed the debug break in Base.h
- Fixed 'dxShader' not logging compile errors
- 'glVertexLayout' now takes in a shared_ptr for 'VertexBuffer'
- 'glShader' now logs the shader compilation errors properly
- 'dxVertexLayout' now takes in a shared_ptr for 'Shader"
- Modified 'dxSharedContext' members to be private and made getters for them
- 'dxRenderCommand::SwapBuffers' now throws dxException for
       DXGI_ERROR_DEVICE_REMOD error
This commit is contained in:
Light 2021-07-01 19:25:46 +04:30
parent 7872e42c76
commit 2ab97d3863
70 changed files with 709 additions and 587 deletions

View file

@ -6,14 +6,16 @@ R"(
layout(location = 0) in vec3 a_Position; layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec4 a_Color; layout(location = 1) in vec4 a_Color;
out vec4 fragColor; out vec4 vso_FragmentColor;
void main() void main()
{ {
gl_Position = vec4(a_Position, 1.0); gl_Position = vec4(a_Position, 1.0);
fragColor = a_Color; vso_FragmentColor = a_Color;
} }
-GLSL -GLSL
+HLSL +HLSL
struct VertexOut struct VertexOut
{ {
@ -26,6 +28,7 @@ VertexOut main(float3 InPosition : POSITION, float4 InColor : COLOR)
VertexOut vso; VertexOut vso;
vso.Position = float4(InPosition.x, InPosition.y, InPosition.z, 1.0); vso.Position = float4(InPosition.x, InPosition.y, InPosition.z, 1.0);
vso.Color = InColor; vso.Color = InColor;
return vso; return vso;
} }
-HLSL)" -HLSL)"
@ -35,15 +38,17 @@ R"(
+GLSL +GLSL
#version 440 core #version 440 core
in vec4 fragColor; in vec4 vso_FragmentColor;
out vec4 FragmentColor; out vec4 fso_FragmentColor;
void main() void main()
{ {
FragmentColor = fragColor; fso_FragmentColor = vso_FragmentColor;
} }
-GLSL -GLSL
+HLSL +HLSL
float4 main(float4 Color : COLOR) : SV_Target float4 main(float4 Color : COLOR) : SV_Target
{ {

View file

@ -4,28 +4,30 @@ R"(
#version 440 core #version 440 core
layout(location = 0) in vec3 a_Position; layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec2 a_TexCoords; layout(location = 1) in vec2 a_TexCoord;
out vec2 texCoords; out vec2 vso_TexCoord;
void main() void main()
{ {
gl_Position = vec4(a_Position, 1.0); gl_Position = vec4(a_Position, 1.0);
texCoords = a_TexCoords; vso_TexCoord = a_TexCoord;
} }
-GLSL -GLSL
+HLSL +HLSL
struct VertexOut struct VertexOut
{ {
float2 uv : UV; float2 TexChoord : TEXCHOORD;
float4 position : SV_Position; float4 Position : SV_Position;
}; };
VertexOut main(float3 InPosition : POSITION, float2 InUV : UV) VertexOut main(float3 InPosition : POSITION, float2 InTexChoord : TEXCHOORD)
{ {
VertexOut vso; VertexOut vso;
vso.position = float4(InPosition, 1.0); vso.Position = float4(InPosition, 1.0);
vso.uv = InUV; vso.TexChoord = InTexChoord;
return vso; return vso;
} }
@ -37,24 +39,26 @@ R"(
+GLSL +GLSL
#version 440 core #version 440 core
in vec2 texCoords; in vec2 vso_TexCoord;
uniform sampler2D u_Texture; uniform sampler2D u_Texture;
out vec4 FragmentColor; out vec4 fso_FragmentColor;
void main() void main()
{ {
FragmentColor = texture(u_Texture, texCoords); fso_FragmentColor = texture(u_Texture, vso_TexCoord);
} }
-GLSL -GLSL
+HLSL +HLSL
sampler samplerState : register(s0); sampler samplerState : register(s0);
Texture2D<float4> myTexture : register(t0); Texture2D<float4> myTexture : register(t0);
float4 main(float2 InUV : UV) : SV_Target float4 main(float2 InTexChoord : TEXCHOORD) : SV_Target
{ {
return myTexture.Sample(samplerState, InUV); return myTexture.Sample(samplerState, InTexChoord);
} }
-HLSL -HLSL

View file

@ -5,12 +5,16 @@
#endif #endif
#include "Debug/Exceptions.h" #include "Debug/Exceptions.h"
#include "Utility/Stringifier.h"
#include <memory> #include <memory>
#define LT_WIN(x) // Windows #define LT_WIN(x) // windows
#define LT_LIN(x) // Linux #define LT_LIN(x) // linux
#define LT_MAC(x) // Mac #define LT_MAC(x) // mac
// #todo: figure out a proper way to give version numbers
#define LT_VERSION "0.5.1"
#if defined(LIGHT_PLATFORM_WINDOWS) #if defined(LIGHT_PLATFORM_WINDOWS)
#define LT_BUILD_PLATFORM "Windows" #define LT_BUILD_PLATFORM "Windows"
@ -29,5 +33,10 @@
#define BIT(x) 1 << x #define BIT(x) 1 << x
// #todo: log to file in distribution builds // #todo: log to file in distribution builds
#define LT_ENGINE_ASSERT(x, ...) { if(!(x)) { LT_ENGINE_CRITICAL(__VA_ARGS__); /* __builtin_trap() */; throw ::Light::FailedAssertion(__FILE__, __LINE__); } } #if defined(LIGHT_PLATFORM_WINDOWS)
#define LT_CLIENT_ASSERT(x, ...) { if(!(x)) { LT_CLIENT_CRITICAL(__VA_ARGS__); __builtin_trap(); } } #define LT_ENGINE_ASSERT(x, ...) { if(!(x)) { LT_ENGINE_CRITICAL(__VA_ARGS__); __debugbreak(); throw ::Light::FailedAssertion(__FILE__, __LINE__); } }
#define LT_CLIENT_ASSERT(x, ...) { if(!(x)) { LT_CLIENT_CRITICAL(__VA_ARGS__); __debugbreak(); } }
#elif defined(LIGHT_PLATFORM_LINUX)
#define LT_ENGINE_ASSERT(x, ...) { if(!(x)) { LT_ENGINE_CRITICAL(__VA_ARGS__); /* #todo: implement break */ throw ::Light::FailedAssertion(__FILE__, __LINE__); } }
#define LT_CLIENT_ASSERT(x, ...) { if(!(x)) { LT_CLIENT_CRITICAL(__VA_ARGS__); /* #todo: implement break */ } }
#endif

View file

@ -11,6 +11,8 @@
#include "UserInterface/UserInterface.h" #include "UserInterface/UserInterface.h"
#include <filesystem>
namespace Light { namespace Light {
Application::Application() Application::Application()
@ -38,10 +40,10 @@ namespace Light {
// reveal window // reveal window
m_Window->SetVisibility(true); m_Window->SetVisibility(true);
//* [ GAMELOOP ] *// //** GAMELOOP **//
while (!m_Window->IsClosed()) while (!m_Window->IsClosed())
{ {
// update layyers // update layers
m_LayerStack.OnUpdate(1000.0f / 60.0f); // #todo: implement time m_LayerStack.OnUpdate(1000.0f / 60.0f); // #todo: implement time
// render layers // render layers
@ -53,10 +55,6 @@ namespace Light {
m_Window->GetGfxContext()->GetUserInterface()->Begin(); m_Window->GetGfxContext()->GetUserInterface()->Begin();
m_Window->GetGfxContext()->GetUserInterface()->End(); m_Window->GetGfxContext()->GetUserInterface()->End();
// swap buffers
m_Window->GetGfxContext()->GetRenderCommand()->SwapBuffers();
m_Window->GetGfxContext()->GetRenderCommand()->ClearBackBuffer();
// poll events // poll events
m_Window->PollEvents(); m_Window->PollEvents();
} }
@ -85,6 +83,7 @@ namespace Light {
LT_ENGINE_INFO("________________________________________"); LT_ENGINE_INFO("________________________________________");
LT_ENGINE_INFO("Platform::"); LT_ENGINE_INFO("Platform::");
LT_ENGINE_INFO(" OS: {}", LT_BUILD_PLATFORM); LT_ENGINE_INFO(" OS: {}", LT_BUILD_PLATFORM);
LT_ENGINE_INFO(" DIR: {}", std::filesystem::current_path().generic_string());
LT_ENGINE_INFO("________________________________________"); LT_ENGINE_INFO("________________________________________");
} }

View file

@ -34,18 +34,18 @@ namespace Light {
virtual void PollEvents() = 0; virtual void PollEvents() = 0;
virtual void OnEvent(const Event& event) = 0; virtual void OnEvent(const Event& event) = 0;
// Setters // //* SETTERS *//
virtual void SetProperties(const WindowProperties& properties) = 0; virtual void SetProperties(const WindowProperties& properties, bool affectVisibility = false) = 0;
virtual void SetTitle(const std::string& title) = 0; virtual void SetTitle(const std::string& title) = 0;
virtual void SetSize(const glm::uvec2& size, bool add = false) = 0; // pass 0 for width or height for single dimension resizing virtual void SetSize(const glm::uvec2& size, bool additive = false) = 0; // pass 0 for width or height for single dimension resizing
inline void Close() { b_Closed = true; } inline void Close() { b_Closed = true; }
virtual void SetVSync(bool vsync, bool toggle = false) = 0; virtual void SetVSync(bool vsync, bool toggle = false) = 0;
virtual void SetVisibility(bool visible, bool toggle = false) = 0; virtual void SetVisibility(bool visible, bool toggle = false) = 0;
// Getters // //* GETTERS *//
inline GraphicsContext* GetGfxContext() const { return m_GraphicsContext.get(); } inline GraphicsContext* GetGfxContext() const { return m_GraphicsContext.get(); }
inline const WindowProperties& GetProperties() const { return m_Properties; } inline const WindowProperties& GetProperties() const { return m_Properties; }

View file

@ -4,8 +4,6 @@
#include <spdlog/sinks/stdout_color_sinks.h> #include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h> #include <spdlog/sinks/basic_file_sink.h>
#include "Utility/Stringifier.h"
namespace Light { namespace Light {
std::shared_ptr<spdlog::logger> Logger::s_EngineLogger = nullptr; std::shared_ptr<spdlog::logger> Logger::s_EngineLogger = nullptr;

View file

@ -43,7 +43,7 @@
namespace Light { namespace Light {
// #todo: add a FileLogger // #todo: extend
class Logger class Logger
{ {
private: private:

View file

@ -4,7 +4,7 @@
#include <LightEngine.h> #include <LightEngine.h>
// To be defined in client project // to be defined in client project
extern Light::Application* Light::CreateApplication(); extern Light::Application* Light::CreateApplication();
// #todo: use windows specific stuff // #todo: use windows specific stuff
@ -22,17 +22,17 @@ int main(int argc, char** argv)
} }
catch (Light::FailedAssertion) catch (Light::FailedAssertion)
{ {
LT_ENGINE_CRITICAL("main: exitting due to unhandled FailedAssertion"); LT_ENGINE_CRITICAL("main: exitting due to unhandled 'FailedAssertion'");
exitCode = -1; exitCode = -1;
} }
catch(Light::glException) catch(Light::glException)
{ {
LT_ENGINE_CRITICAL("main: exitting due to unhandled glException"); LT_ENGINE_CRITICAL("main: exitting due to unhandled 'glException'");
exitCode = -2; exitCode = -2;
} }
catch (Light::dxException) catch (Light::dxException)
{ {
LT_ENGINE_CRITICAL("main: exitting due to unhandled dxException"); LT_ENGINE_CRITICAL("main: exitting due to unhandled 'dxException'");
exitCode = -3; exitCode = -3;
} }
@ -44,7 +44,7 @@ int main(int argc, char** argv)
#include <LightEngine.h> #include <LightEngine.h>
// To be defined in client project // to be defined in client project
extern Light::Application* Light::CreateApplication(); extern Light::Application* Light::CreateApplication();
// #todo: use linux specific stuff // #todo: use linux specific stuff
@ -62,12 +62,12 @@ int main(int argc, char* argv[])
} }
catch (Light::FailedAssertion) catch (Light::FailedAssertion)
{ {
LT_ENGINE_CRITICAL("main: exitting due to unhandled FailedAssertion"); LT_ENGINE_CRITICAL("main: exitting due to unhandled 'FailedAssertion'");
exitCode = -1; exitCode = -1;
} }
catch(Light::glException) catch(Light::glException)
{ {
LT_ENGINE_CRITICAL("main: exitting due to unhandled glException"); LT_ENGINE_CRITICAL("main: exitting due to unhandled 'glException'");
exitCode = -2; exitCode = -2;
} }

View file

@ -13,7 +13,7 @@ namespace Light {
const int m_Key; const int m_Key;
public: public:
KeyPressedEvent(int key): m_Key(key) {} KeyPressedEvent(int key): m_Key(key) { }
inline int GetKey() const { return m_Key; } inline int GetKey() const { return m_Key; }
@ -33,7 +33,7 @@ namespace Light {
const int m_Key; const int m_Key;
public: public:
KeyReleasedEvent(int key): m_Key(key) {} KeyReleasedEvent(int key): m_Key(key) { }
inline int GetKey() const { return m_Key; } inline int GetKey() const { return m_Key; }

View file

@ -15,7 +15,7 @@ namespace Light {
const glm::vec2 m_Position; const glm::vec2 m_Position;
public: public:
MouseMovedEvent(float x, float y) : m_Position(x, y) {} MouseMovedEvent(float x, float y) : m_Position(x, y) { }
inline const glm::vec2& GetPosition() const { return m_Position; } inline const glm::vec2& GetPosition() const { return m_Position; }
@ -38,7 +38,7 @@ namespace Light {
const float m_Offset; const float m_Offset;
public: public:
WheelScrolledEvent(float offset) : m_Offset(offset) {} WheelScrolledEvent(float offset) : m_Offset(offset) { }
inline float GetOffset() const { return m_Offset; } inline float GetOffset() const { return m_Offset; }
@ -58,7 +58,7 @@ namespace Light {
const int m_Button; const int m_Button;
public: public:
ButtonPressedEvent(int button): m_Button(button) {} ButtonPressedEvent(int button): m_Button(button) { }
inline int GetButton() const { return m_Button; } inline int GetButton() const { return m_Button; }
@ -78,7 +78,7 @@ namespace Light {
const int m_Button; const int m_Button;
public: public:
ButtonReleasedEvent(int button) : m_Button(button) {} ButtonReleasedEvent(int button) : m_Button(button) { }
inline int GetButton() const { return m_Button; } inline int GetButton() const { return m_Button; }

View file

@ -26,7 +26,7 @@ namespace Light {
const glm::ivec2 m_Position; const glm::ivec2 m_Position;
public: public:
WindowMovedEvent(int x, int y): m_Position(x, y) {} WindowMovedEvent(int x, int y): m_Position(x, y) { }
const glm::ivec2& GetPosition() const{ return m_Position; } const glm::ivec2& GetPosition() const{ return m_Position; }
@ -46,7 +46,7 @@ namespace Light {
const glm::uvec2 m_Size; const glm::uvec2 m_Size;
public: public:
WindowResizedEvent(unsigned int width, unsigned int height): m_Size(width, height) {} WindowResizedEvent(unsigned int width, unsigned int height): m_Size(width, height) { }
const glm::uvec2& GetSize() const { return m_Size; } const glm::uvec2& GetSize() const { return m_Size; }

View file

@ -11,10 +11,9 @@
#include "GraphicsContext.h" #include "GraphicsContext.h"
namespace Light { namespace Light {
//* VERTEX BUFFER *// //* VERTEX_BUFFER *//
VertexBuffer* VertexBuffer::Create(float* vertices, unsigned int stride, unsigned int count, std::shared_ptr<SharedContext> sharedContext) VertexBuffer* VertexBuffer::Create(float* vertices, unsigned int stride, unsigned int count, std::shared_ptr<SharedContext> sharedContext)
{ {
switch (GraphicsContext::GetGraphicsAPI()) switch (GraphicsContext::GetGraphicsAPI())
@ -26,12 +25,12 @@ namespace Light {
return new dxVertexBuffer(vertices, stride, count, std::static_pointer_cast<dxSharedContext>(sharedContext));) return new dxVertexBuffer(vertices, stride, count, std::static_pointer_cast<dxSharedContext>(sharedContext));)
default: default:
LT_ENGINE_ASSERT(false, "VertexBuffer::Create: invalid/unsupported GraphicsAPI {}", GraphicsContext::GetGraphicsAPI()); LT_ENGINE_ASSERT(false, "VertexBuffer::Create: invalid/unsupported 'GraphicsAPI' {}", GraphicsContext::GetGraphicsAPI());
return nullptr; return nullptr;
} }
} }
//* INDEX BUFFER *// //* INDEX_BUFFER *//
IndexBuffer* IndexBuffer::Create(unsigned int* indices, unsigned int count, std::shared_ptr<SharedContext> sharedContext) IndexBuffer* IndexBuffer::Create(unsigned int* indices, unsigned int count, std::shared_ptr<SharedContext> sharedContext)
{ {
switch (GraphicsContext::GetGraphicsAPI()) switch (GraphicsContext::GetGraphicsAPI())
@ -43,7 +42,7 @@ namespace Light {
return new dxIndexBuffer(indices, count, std::dynamic_pointer_cast<dxSharedContext>(sharedContext));) return new dxIndexBuffer(indices, count, std::dynamic_pointer_cast<dxSharedContext>(sharedContext));)
default: default:
LT_ENGINE_ASSERT(false, "IndexBuffer::Create: invalid/unsupported GraphicsAPI {}", GraphicsContext::GetGraphicsAPI()); LT_ENGINE_ASSERT(false, "IndexBuffer::Create: invalid/unsupported 'GraphicsAPI' {}", GraphicsContext::GetGraphicsAPI());
return nullptr; return nullptr;
} }
} }

View file

@ -6,7 +6,7 @@ namespace Light {
class SharedContext; class SharedContext;
//* VERTEX BUFFER *// //* VERTEX_BUFFER *//
class VertexBuffer class VertexBuffer
{ {
public: public:
@ -22,7 +22,7 @@ namespace Light {
VertexBuffer() = default; VertexBuffer() = default;
}; };
//* INDEX BUFFER *// //* INDEX_BUFFER *//
class IndexBuffer class IndexBuffer
{ {
public: public:

View file

@ -4,16 +4,14 @@
#ifdef LIGHT_PLATFORM_WINDOWS #ifdef LIGHT_PLATFORM_WINDOWS
#include "DirectX/dxGraphicsContext.h" #include "DirectX/dxGraphicsContext.h"
#include "DirectX/dxSharedContext.h"
#endif #endif
#include "Buffers.h" // forward declaration
#include "Graphics/Renderer.h"
#include "Renderer.h" #include "Graphics/RenderCommand.h"
#include "RenderCommand.h"
#include "UserInterface/UserInterface.h" #include "UserInterface/UserInterface.h"
#include "Utility/ResourceManager.h" #include "Utility/ResourceManager.h"
#include "Utility/Stringifier.h"
namespace Light { namespace Light {
@ -23,11 +21,10 @@ namespace Light {
GraphicsContext* GraphicsContext::Create(GraphicsAPI api, GLFWwindow* windowHandle) GraphicsContext* GraphicsContext::Create(GraphicsAPI api, GLFWwindow* windowHandle)
{ {
// terminate gfx context dependent classes // terminate 'GraphicsContext' dependent classes
if (s_Context) if (s_Context)
{ {
s_Context->m_Renderer.reset(); s_Context->m_Renderer.reset();
s_Context->m_RenderCommand.reset();
s_Context->m_UserInterface.reset(); s_Context->m_UserInterface.reset();
delete s_Context; delete s_Context;
@ -39,7 +36,7 @@ namespace Light {
#if defined(LIGHT_PLATFORM_WINDOWS) #if defined(LIGHT_PLATFORM_WINDOWS)
api = GraphicsAPI::DirectX; api = GraphicsAPI::DirectX;
#elif defined(LIGHT_PLATFORM_LINUX) #elif defined(LIGHT_PLATFORM_LINUX)
// #todo: api = GraphicsContext::OpenGL;
#elif defined(LIGHT_PLATFORM_MAC) #elif defined(LIGHT_PLATFORM_MAC)
// #todo: // #todo:
#endif #endif
@ -57,20 +54,17 @@ namespace Light {
break;) break;)
default: default:
LT_ENGINE_ASSERT(false, "GraphicsContext::Create: invalid/unsupported GraphicsAPI {}", Stringifier::GraphicsAPIToString(api)); LT_ENGINE_ASSERT(false, "GraphicsContext::Create: invalid/unsupported 'GraphicsAPI' {}", Stringifier::GraphicsAPIToString(api));
return nullptr; return nullptr;
} }
// create gfx context dependent classes // create 'GraphicsContext' dependent classes
s_Context->m_ResourceManager = std::unique_ptr<ResourceManager>(ResourceManager::Create(s_Context->m_SharedContext)); s_Context->m_ResourceManager = std::unique_ptr<ResourceManager>(ResourceManager::Create(s_Context->m_SharedContext));
s_Context->m_RenderCommand = std::unique_ptr<RenderCommand>(RenderCommand::Create(windowHandle, s_Context->m_SharedContext));
s_Context->m_UserInterface = std::unique_ptr<UserInterface>(UserInterface::Create(windowHandle, s_Context->m_SharedContext)); s_Context->m_UserInterface = std::unique_ptr<UserInterface>(UserInterface::Create(windowHandle, s_Context->m_SharedContext));
s_Context->m_Renderer = std::unique_ptr<Renderer>(Renderer::Create(s_Context->m_RenderCommand, s_Context->m_SharedContext)); s_Context->m_Renderer = std::unique_ptr<Renderer>(Renderer::Create(windowHandle, s_Context->m_SharedContext));
// check // check
LT_ENGINE_ASSERT(s_Context->m_ResourceManager, "GraphicsContext::Create: failed to create ResourceManager"); LT_ENGINE_ASSERT(s_Context->m_ResourceManager, "GraphicsContext::Create: failed to create ResourceManager");
LT_ENGINE_ASSERT(s_Context->m_RenderCommand, "GraphicsContext::Create: failed to create RenderCommand");
LT_ENGINE_ASSERT(s_Context->m_UserInterface, "GraphicsContext::Create: failed to create UserInterface"); LT_ENGINE_ASSERT(s_Context->m_UserInterface, "GraphicsContext::Create: failed to create UserInterface");
LT_ENGINE_ASSERT(s_Context->m_Renderer, "GraphicsContext::Create: failed to create Renderer"); LT_ENGINE_ASSERT(s_Context->m_Renderer, "GraphicsContext::Create: failed to create Renderer");

View file

@ -2,19 +2,15 @@
#include "Base.h" #include "Base.h"
#include "SharedContext.h"
struct GLFWwindow; struct GLFWwindow;
#include "Utility/ResourceManager.h"
namespace Light { namespace Light {
class ResourceManager; class ResourceManager;
class Renderer;
class RenderCommand;
class UserInterface; class UserInterface;
class Renderer;
class SharedContext;
class WindowResizedEvent; class WindowResizedEvent;
@ -23,8 +19,8 @@ namespace Light {
Default = 0, Default = 0,
OpenGL, OpenGL,
DirectX, DirectX,
Vulkan, Vulkan, // :#todo
Metal Metal // :#todo
}; };
class GraphicsContext class GraphicsContext
@ -33,10 +29,8 @@ namespace Light {
static GraphicsContext* s_Context; static GraphicsContext* s_Context;
std::unique_ptr<ResourceManager> m_ResourceManager; std::unique_ptr<ResourceManager> m_ResourceManager;
std::unique_ptr<Renderer> m_Renderer;
std::shared_ptr<RenderCommand> m_RenderCommand;
std::unique_ptr<UserInterface> m_UserInterface; std::unique_ptr<UserInterface> m_UserInterface;
std::unique_ptr<Renderer> m_Renderer;
protected: protected:
GraphicsAPI m_GraphicsAPI; GraphicsAPI m_GraphicsAPI;
@ -57,7 +51,6 @@ namespace Light {
static inline GraphicsAPI GetGraphicsAPI() { return s_Context->m_GraphicsAPI; } static inline GraphicsAPI GetGraphicsAPI() { return s_Context->m_GraphicsAPI; }
inline Renderer* GetRenderer() { return m_Renderer.get(); } inline Renderer* GetRenderer() { return m_Renderer.get(); }
inline RenderCommand* GetRenderCommand() { return m_RenderCommand.get(); }
inline UserInterface* GetUserInterface() { return m_UserInterface.get(); } inline UserInterface* GetUserInterface() { return m_UserInterface.get(); }
protected: protected:

View file

@ -2,11 +2,9 @@
#include "RenderCommand.h" #include "RenderCommand.h"
#include "OpenGL/glRenderCommand.h" #include "OpenGL/glRenderCommand.h"
#include "SharedContext.h"
#ifdef LIGHT_PLATFORM_WINDOWS #ifdef LIGHT_PLATFORM_WINDOWS
#include "DirectX/dxRenderCommand.h" #include "DirectX/dxRenderCommand.h"
#include "Directx/dxSharedContext.h" #include "DirectX/dxSharedContext.h"
#endif #endif
#include "GraphicsContext.h" #include "GraphicsContext.h"
@ -24,7 +22,7 @@ namespace Light {
return new dxRenderCommand((std::static_pointer_cast<dxSharedContext>)(sharedContext));) return new dxRenderCommand((std::static_pointer_cast<dxSharedContext>)(sharedContext));)
default: default:
LT_ENGINE_ASSERT(false, "RenderCommand::Create: invalid/unsupported GraphicsAPI {}", GraphicsContext::GetGraphicsAPI()); LT_ENGINE_ASSERT(false, "RenderCommand::Create: invalid/unsupported 'GraphicsAPI' {}", GraphicsContext::GetGraphicsAPI());
return nullptr; return nullptr;
} }
} }

View file

@ -11,6 +11,8 @@ namespace Light {
class RenderCommand class RenderCommand
{ {
public: public:
static RenderCommand* Create(GLFWwindow* windowHandle, std::shared_ptr<SharedContext> sharedContext);
RenderCommand(const RenderCommand&) = delete; RenderCommand(const RenderCommand&) = delete;
RenderCommand& operator=(const RenderCommand&) = delete; RenderCommand& operator=(const RenderCommand&) = delete;
@ -22,8 +24,6 @@ namespace Light {
virtual void Draw(unsigned int count) = 0; virtual void Draw(unsigned int count) = 0;
virtual void DrawIndexed(unsigned int count) = 0; virtual void DrawIndexed(unsigned int count) = 0;
static RenderCommand* Create(GLFWwindow* windowHandle, std::shared_ptr<SharedContext> sharedContext);
protected: protected:
RenderCommand() = default; RenderCommand() = default;
}; };

View file

@ -1,47 +1,26 @@
#include "ltpch.h" #include "ltpch.h"
#include "Renderer.h" #include "Renderer.h"
#include "GraphicsContext.h"
#include "Utility/ResourceManager.h"
#include "../res/Shaders/QuadShader.h"
#include "../res/Shaders/TextureShader.h"
#include "RenderCommand.h" #include "RenderCommand.h"
#include "Texture.h" #include "Texture.h"
namespace Light { namespace Light {
Renderer* Renderer::s_Context; Renderer* Renderer::s_Context = nullptr;
Renderer::Renderer(std::shared_ptr<RenderCommand> renderCommand, std::shared_ptr<SharedContext> sharedContext) Renderer::Renderer(GLFWwindow* windowHandle, std::shared_ptr<SharedContext> sharedContext)
: m_RenderCommand(renderCommand), m_SharedContext(sharedContext) : m_QuadRenderer(LT_MAX_QUAD_RENDERER_VERTICES, sharedContext),
m_TextureRenderer(LT_MAX_TEXTURE_RENDERER_VERTICES, sharedContext)
{ {
LT_ENGINE_ASSERT(!s_Context, "Renderer::Renderer: an instance of 'Renderer' already exists, do not construct this class!");
s_Context = this; s_Context = this;
ResourceManager::CreateShader("QuadShader", LT_ENGINE_RESOURCES_QUAD_SHADER_VS, LT_ENGINE_RESOURCES_QUAD_SHADER_PS); m_RenderCommand = std::unique_ptr<RenderCommand>(RenderCommand::Create(windowHandle, sharedContext));
ResourceManager::CreateShader("TextureShader", LT_ENGINE_RESOURCES_TEXTURE_SHADER_VS, LT_ENGINE_RESOURCES_TEXTURE_SHADER_PS);
//** quad renderer **//
m_QuadRenderer.shader = ResourceManager::GetShader("QuadShader");
m_QuadRenderer.vertexBuffer = std::unique_ptr<VertexBuffer>(VertexBuffer::Create(nullptr, sizeof(QuadRendererProgram::QuadVertexData), LT_MAX_QUAD * 4, m_SharedContext));
m_QuadRenderer.indexBuffer = std::unique_ptr<IndexBuffer>(IndexBuffer::Create(nullptr, LT_MAX_QUAD * 6, m_SharedContext));
m_QuadRenderer.vertexLayout = std::unique_ptr<VertexLayout>(VertexLayout::Create(m_QuadRenderer.vertexBuffer.get(), m_QuadRenderer.shader.get(), { { "POSITION", VertexElementType::Float3 },{ "COLOR", VertexElementType::Float4 } }, m_SharedContext));
//** quad renderer **//
//** texture rendererc **//
m_TextureRenderer.shader = ResourceManager::GetShader("TextureShader");
m_TextureRenderer.vertexBuffer = std::unique_ptr<VertexBuffer>(VertexBuffer::Create(nullptr, sizeof(TextureRendererProgram::TextureVertexData), LT_MAX_QUAD * 4, m_SharedContext));
m_TextureRenderer.indexBuffer = std::unique_ptr<IndexBuffer>(IndexBuffer::Create(nullptr, LT_MAX_QUAD * 6, m_SharedContext));
m_TextureRenderer.vertexLayout = std::unique_ptr<VertexLayout>(VertexLayout::Create(m_TextureRenderer.vertexBuffer.get(), m_TextureRenderer.shader.get(), { { "POSITION", VertexElementType::Float3 },{ "UV", VertexElementType::Float2 } }, m_SharedContext));
//** texture rendererc **//
} }
Renderer* Renderer::Create(std::shared_ptr<RenderCommand> renderCommand, std::shared_ptr<SharedContext> sharedContext) Renderer* Renderer::Create(GLFWwindow* windowHandle, std::shared_ptr<SharedContext> sharedContext)
{ {
return new Renderer(renderCommand, sharedContext); return new Renderer(windowHandle, sharedContext);
} }
void Renderer::DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& tint) void Renderer::DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& tint)
@ -56,81 +35,73 @@ namespace Light {
void Renderer::DrawQuadImpl(const glm::vec3& position, const glm::vec2& size, const glm::vec4& tint) void Renderer::DrawQuadImpl(const glm::vec3& position, const glm::vec2& size, const glm::vec4& tint)
{ {
// check
if (m_QuadRenderer.mapCurrent + 4 >= m_QuadRenderer.mapEnd)
{
LT_ENGINE_WARN("Render::DrawQuad: max calls per frame exceeded the limit: {}", LT_MAX_QUAD);
EndScene();
m_QuadRenderer.Map();
}
// locals // locals
QuadRendererProgram::QuadVertexData* bufferMap = m_QuadRenderer.GetMapCurrent();
const float xMin = position.x; const float xMin = position.x;
const float yMin = position.y; const float yMin = position.y;
const float xMax = position.x + size.x; const float xMax = position.x + size.x;
const float yMax = position.y + size.y; const float yMax = position.y + size.y;
// TOP_LEFT //** TOP_LEFT **//
m_QuadRenderer.mapCurrent[0].position = { xMin, yMin, position.z }; bufferMap[0].position = { xMin, yMin, position.z };
m_QuadRenderer.mapCurrent[0].tint = tint; bufferMap[0].tint = tint;
// TOP_RIGHT //** TOP_RIGHT **//
m_QuadRenderer.mapCurrent[1].position = { xMax, yMin, position.z }; bufferMap[1].position = { xMax, yMin, position.z };
m_QuadRenderer.mapCurrent[1].tint = tint; bufferMap[1].tint = tint;
// BOTTOM_RIGHT //** BOTTOM_RIGHT **//
m_QuadRenderer.mapCurrent[2].position = { xMax, yMax, position.z }; bufferMap[2].position = { xMax, yMax, position.z };
m_QuadRenderer.mapCurrent[2].tint = tint; bufferMap[2].tint = tint;
// BOTTOM_LEFT //** BOTTOM_LEFT **//
m_QuadRenderer.mapCurrent[3].position = { xMin, yMax, position.z }; bufferMap[3].position = { xMin, yMax, position.z };
m_QuadRenderer.mapCurrent[3].tint = tint; bufferMap[3].tint = tint;
// advance // advance
m_QuadRenderer.mapCurrent += 4; if (!m_QuadRenderer.Advance())
m_QuadRenderer.quadCount++; {
EndScene();
BeginScene();
}
} }
void Renderer::DrawQuadImpl(const glm::vec3& position, const glm::vec2& size, std::shared_ptr<Texture> texture) void Renderer::DrawQuadImpl(const glm::vec3& position, const glm::vec2& size, std::shared_ptr<Texture> texture)
{ {
// check
if (m_TextureRenderer.mapCurrent + 4 >= m_TextureRenderer.mapEnd)
{
LT_ENGINE_WARN("Render::DrawQuad(Texture): max calls per frame exceeded the limit: {}", LT_MAX_QUAD);
EndScene();
m_TextureRenderer.Map();
}
// #todo: implement a proper binding // #todo: implement a proper binding
texture->Bind(); texture->Bind();
// locals // locals
TextureRendererProgram::TextureVertexData* bufferMap = m_TextureRenderer.GetMapCurrent();
const float xMin = position.x; const float xMin = position.x;
const float yMin = position.y; const float yMin = position.y;
const float xMax = position.x + size.x; const float xMax = position.x + size.x;
const float yMax = position.y + size.y; const float yMax = position.y + size.y;
// TOP_LEFT //** TOP_LEFT **//
m_TextureRenderer.mapCurrent[0].position = { xMin, yMin, position.z }; bufferMap[0].position = { xMin, yMin, position.z };
m_TextureRenderer.mapCurrent[0].uv = { 0, 0 }; bufferMap[0].texcoord = { 0.0f, 0.0f };
// TOP_RIGHT //** TOP_RIGHT **//
m_TextureRenderer.mapCurrent[1].position = { xMax, yMin, position.z }; bufferMap[1].position = { xMax, yMin, position.z };
m_TextureRenderer.mapCurrent[1].uv = { 1, 0 }; bufferMap[1].texcoord = { 1.0f, 0.0f };
// BOTTOM_RIGHT //** BOTTOM_RIGHT **//
m_TextureRenderer.mapCurrent[2].position = { xMax, yMax, position.z }; bufferMap[2].position = { xMax, yMax, position.z };
m_TextureRenderer.mapCurrent[2].uv = { 1, 1 }; bufferMap[2].texcoord = { 1.0f, 1.0f };
// BOTTOM_LEFT //** BOTTOM_LEFT **//
m_TextureRenderer.mapCurrent[3].position = { xMin, yMax, position.z }; bufferMap[3].position = { xMin, yMax, position.z };
m_TextureRenderer.mapCurrent[3].uv = { 0, 1 }; bufferMap[3].texcoord = { 0.0f, 1.0f };
// advance // advance
m_TextureRenderer.mapCurrent += 4; if (!m_TextureRenderer.Advance())
m_TextureRenderer.quadCount++; {
EndScene();
BeginScene();
}
} }
void Renderer::BeginScene() void Renderer::BeginScene()
@ -141,21 +112,22 @@ namespace Light {
void Renderer::EndScene() void Renderer::EndScene()
{ {
if (m_QuadRenderer.quadCount) //** QUAD_RENDERER **//
if (m_QuadRenderer.GetQuadCount())
{ {
m_QuadRenderer.Bind(); m_QuadRenderer.Bind();
m_RenderCommand->DrawIndexed(m_QuadRenderer.GetQuadCount() * 6u);
m_RenderCommand->DrawIndexed(m_QuadRenderer.quadCount * 6);
m_QuadRenderer.quadCount = 0;
} }
if (m_TextureRenderer.quadCount) //** TEXT_RENDERER **//
if (m_TextureRenderer.GetQuadCount())
{ {
m_TextureRenderer.Bind(); m_TextureRenderer.Bind();
m_RenderCommand->DrawIndexed(m_TextureRenderer.GetQuadCount() * 6u);
m_RenderCommand->DrawIndexed(m_TextureRenderer.quadCount * 6);
m_TextureRenderer.quadCount = 0;
} }
m_RenderCommand->SwapBuffers();
m_RenderCommand->ClearBackBuffer();
} }
} }

View file

@ -2,116 +2,33 @@
#include "Base.h" #include "Base.h"
#include "Shader.h" #include "RendererPrograms/QuadRendererProgram.h"
#include "Buffers.h" #include "RendererPrograms/TextureRendererProgram.h"
#include "VertexLayout.h"
#include <glm/glm.hpp> #define LT_MAX_QUAD_RENDERER_VERTICES 1028u * 4u
#define LT_MAX_TEXTURE_RENDERER_VERTICES 1028u * 4u
#include <memory> struct GLFWwindow;
#define LT_MAX_QUAD 124
namespace Light { namespace Light {
class RenderCommand; class RenderCommand;
class SharedContext;
class Texture; class Texture;
struct RendererProgram class SharedContext;
{
virtual void Map() = 0;
virtual void Bind() = 0;
};
class Renderer class Renderer
{ {
private: private:
struct QuadRendererProgram : RendererProgram
{
// graphics context
std::shared_ptr<Shader> shader;
std::shared_ptr<VertexBuffer> vertexBuffer;
std::shared_ptr<IndexBuffer> indexBuffer;
std::shared_ptr<VertexLayout> vertexLayout;
// buffer data
struct QuadVertexData
{
glm::vec3 position;
glm::vec4 tint;
};
QuadVertexData* mapCurrent = nullptr;
QuadVertexData* mapEnd = nullptr;
unsigned int quadCount = 0u;
// functions
void Map()
{
mapCurrent = (QuadVertexData*)vertexBuffer->Map();
mapEnd = mapCurrent + LT_MAX_QUAD * 4;
}
void Bind()
{
vertexBuffer->UnMap();
shader->Bind();
vertexLayout->Bind();
vertexBuffer->Bind();
indexBuffer->Bind();
}
};
struct TextureRendererProgram : public RendererProgram
{
// graphics context
std::shared_ptr<Shader> shader;
std::shared_ptr<VertexBuffer> vertexBuffer;
std::shared_ptr<IndexBuffer> indexBuffer;
std::shared_ptr<VertexLayout> vertexLayout;
// buffer data
struct TextureVertexData
{
glm::vec3 position;
glm::vec2 uv;
};
TextureVertexData* mapCurrent = nullptr;
TextureVertexData* mapEnd = nullptr;
unsigned int quadCount = 0u;
// functions
void Map()
{
mapCurrent = (TextureVertexData*)vertexBuffer->Map();
mapEnd = mapCurrent + LT_MAX_QUAD * 4;
}
void Bind()
{
vertexBuffer->UnMap();
shader->Bind();
vertexLayout->Bind();
vertexBuffer->Bind();
indexBuffer->Bind();
}
};
static Renderer* s_Context; static Renderer* s_Context;
QuadRendererProgram m_QuadRenderer; QuadRendererProgram m_QuadRenderer;
TextureRendererProgram m_TextureRenderer; TextureRendererProgram m_TextureRenderer;
std::shared_ptr<RenderCommand> m_RenderCommand; std::unique_ptr<RenderCommand> m_RenderCommand;
std::shared_ptr<SharedContext> m_SharedContext;
std::shared_ptr<Texture> m_TestTexture;
public: public:
static Renderer* Create(std::shared_ptr<RenderCommand> renderCommand, std::shared_ptr<SharedContext> sharedContext); static Renderer* Create(GLFWwindow* windowHandle, std::shared_ptr<SharedContext> sharedContext);
static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& tint); static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& tint);
static void DrawQuad(const glm::vec3& position, const glm::vec2& size, std::shared_ptr<Texture> texture); static void DrawQuad(const glm::vec3& position, const glm::vec2& size, std::shared_ptr<Texture> texture);
@ -120,7 +37,7 @@ namespace Light {
void EndScene(); void EndScene();
private: private:
Renderer(std::shared_ptr<RenderCommand> renderCommand, std::shared_ptr<SharedContext> sharedContext); Renderer(GLFWwindow* windowHandle, std::shared_ptr<SharedContext> sharedContext);
void DrawQuadImpl(const glm::vec3& position, const glm::vec2& size, const glm::vec4& tint); void DrawQuadImpl(const glm::vec3& position, const glm::vec2& size, const glm::vec4& tint);
void DrawQuadImpl(const glm::vec3& position, const glm::vec2& size, std::shared_ptr<Texture> texture); void DrawQuadImpl(const glm::vec3& position, const glm::vec2& size, std::shared_ptr<Texture> texture);

View file

@ -0,0 +1,54 @@
#include "ltpch.h"
#include "QuadRendererProgram.h"
#include "Graphics/Shader.h"
#include "Graphics/Buffers.h"
#include "Graphics/VertexLayout.h"
#include "../res/Shaders/QuadShader.h"
#include "Utility/ResourceManager.h"
namespace Light {
QuadRendererProgram::QuadRendererProgram(unsigned int maxVertices, std::shared_ptr<SharedContext> sharedContext)
: m_MaxVertices(maxVertices)
{
ResourceManager::CreateShader("LT_ENGINE_RESOURCES_QUAD_SHADER", LT_ENGINE_RESOURCES_QUAD_SHADER_VS, LT_ENGINE_RESOURCES_QUAD_SHADER_PS);
m_Shader = ResourceManager::GetShader("LT_ENGINE_RESOURCES_QUAD_SHADER");
m_VertexBuffer = std::shared_ptr<VertexBuffer>(VertexBuffer::Create(nullptr, sizeof(QuadVertexData), maxVertices, sharedContext));
m_IndexBuffer = std::shared_ptr<IndexBuffer>(IndexBuffer::Create(nullptr, (maxVertices / 4) * 6, sharedContext));
m_VertexLayout = std::shared_ptr<VertexLayout>(VertexLayout::Create(m_VertexBuffer, m_Shader, { { "POSITION", VertexElementType::Float3 },
{ "COLOR" , VertexElementType::Float4 }}, sharedContext));
}
bool QuadRendererProgram::Advance()
{
if (m_MapCurrent + 4 >= m_MapEnd)
{
LT_ENGINE_WARN("QuadRendererProgram::Advance: 'VertexBuffer' map went beyond 'MaxVertices': {}", m_MaxVertices);
return false;
}
m_MapCurrent += 4;
m_QuadCount++;
}
void QuadRendererProgram::Map()
{
m_QuadCount = 0u;
m_MapCurrent = (QuadRendererProgram::QuadVertexData*)m_VertexBuffer->Map();
m_MapEnd = m_MapCurrent + m_MaxVertices;
}
void QuadRendererProgram::Bind()
{
m_VertexBuffer->UnMap();
m_Shader->Bind();
m_VertexLayout->Bind();
m_VertexBuffer->Bind();
m_IndexBuffer->Bind();
}
}

View file

@ -0,0 +1,51 @@
#pragma once
#include "Base.h"
#include "RendererProgram.h"
#include <glm/glm.hpp>
namespace Light {
class Shader;
class VertexBuffer;
class IndexBuffer;
class VertexLayout;
class SharedContext;
class QuadRendererProgram : RendererProgram
{
private:
std::shared_ptr<Shader> m_Shader;
std::shared_ptr<VertexBuffer> m_VertexBuffer;
std::shared_ptr<IndexBuffer> m_IndexBuffer;
std::shared_ptr<VertexLayout> m_VertexLayout;
struct QuadVertexData; // <-- forward declaration
QuadVertexData* m_MapCurrent = nullptr;
QuadVertexData* m_MapEnd = nullptr;
unsigned int m_QuadCount = 0u;
unsigned int m_MaxVertices = 0u;
public:
struct QuadVertexData
{
glm::vec3 position;
glm::vec4 tint;
};
QuadRendererProgram(unsigned int maxVertices, std::shared_ptr<SharedContext> sharedContext);
bool Advance();
void Map() override;
void Bind() override;
inline QuadVertexData* GetMapCurrent() { return m_MapCurrent; }
inline unsigned int GetQuadCount() const { return m_QuadCount; }
inline constexpr unsigned int GetVertexSize() const { return sizeof(QuadVertexData); }
};
}

View file

@ -0,0 +1,13 @@
#pragma once
#include "Base.h"
namespace Light {
class RendererProgram
{
virtual void Map() = 0;
virtual void Bind() = 0;
};
}

View file

@ -0,0 +1,54 @@
#include "ltpch.h"
#include "TextureRendererProgram.h"
#include "Graphics/Shader.h"
#include "Graphics/Buffers.h"
#include "Graphics/VertexLayout.h"
#include "../res/Shaders/TextureShader.h"
#include "Utility/ResourceManager.h"
namespace Light {
TextureRendererProgram::TextureRendererProgram(unsigned int maxVertices, std::shared_ptr<SharedContext> sharedContext)
: m_MaxVertices(maxVertices)
{
ResourceManager::CreateShader("LT_ENGINE_RESOURCES_TEXTURE_SHADER", LT_ENGINE_RESOURCES_TEXTURE_SHADER_VS, LT_ENGINE_RESOURCES_TEXTURE_SHADER_PS);
m_Shader = ResourceManager::GetShader("LT_ENGINE_RESOURCES_TEXTURE_SHADER");
m_VertexBuffer = std::shared_ptr<VertexBuffer>(VertexBuffer::Create(nullptr, sizeof(TextureVertexData), maxVertices, sharedContext));
m_IndexBuffer = std::shared_ptr<IndexBuffer>(IndexBuffer::Create(nullptr, (maxVertices / 4) * 6, sharedContext));
m_VertexLayout = std::shared_ptr<VertexLayout>(VertexLayout::Create(m_VertexBuffer, m_Shader, { { "POSITION", VertexElementType::Float3 },
{ "TEXCOORD", VertexElementType::Float2 }}, sharedContext));
}
bool TextureRendererProgram::Advance()
{
if (m_MapCurrent + 4 >= m_MapEnd)
{
LT_ENGINE_WARN("TextureRendererProgram::Advance: 'VertexBuffer' map went beyond 'MaxVertices': {}", m_MaxVertices);
return false;
}
m_MapCurrent += 4;
m_QuadCount++;
}
void TextureRendererProgram::Map()
{
m_QuadCount = 0u;
m_MapCurrent = (TextureRendererProgram::TextureVertexData*)m_VertexBuffer->Map();
m_MapEnd = m_MapCurrent + m_MaxVertices;
}
void TextureRendererProgram::Bind()
{
m_VertexBuffer->UnMap();
m_Shader->Bind();
m_VertexLayout->Bind();
m_VertexBuffer->Bind();
m_IndexBuffer->Bind();
}
}

View file

@ -0,0 +1,51 @@
#pragma once
#include "Base.h"
#include "RendererProgram.h"
#include <glm/glm.hpp>
namespace Light {
class Shader;
class VertexBuffer;
class IndexBuffer;
class VertexLayout;
class SharedContext;
class TextureRendererProgram : RendererProgram
{
private:
std::shared_ptr<Shader> m_Shader;
std::shared_ptr<VertexBuffer> m_VertexBuffer;
std::shared_ptr<IndexBuffer> m_IndexBuffer;
std::shared_ptr<VertexLayout> m_VertexLayout;
struct TextureVertexData; // <-- forward declaration
TextureVertexData* m_MapCurrent = nullptr;
TextureVertexData* m_MapEnd = nullptr;
unsigned int m_QuadCount = 0u;
unsigned int m_MaxVertices = 0u;
public:
struct TextureVertexData
{
glm::vec3 position;
glm::vec2 texcoord;
};
TextureRendererProgram(unsigned int maxVertices, std::shared_ptr<SharedContext> sharedContext);
bool Advance();
void Map() override;
void Bind() override;
inline TextureVertexData* GetMapCurrent() { return m_MapCurrent; }
inline unsigned int GetQuadCount() const { return m_QuadCount; }
inline constexpr unsigned int GetVertexSize() const { return sizeof(TextureVertexData); }
};
}

View file

@ -4,7 +4,7 @@
#ifdef LIGHT_PLATFORM_WINDOWS #ifdef LIGHT_PLATFORM_WINDOWS
#include "DirectX/dxShader.h" #include "DirectX/dxShader.h"
#include "DirectX/dxSharedContext.h" #include "DirectX/dxSharedContext.h"
#endif #endif
#include "GraphicsContext.h" #include "GraphicsContext.h"
@ -23,7 +23,7 @@ namespace Light {
return new dxShader(vertexSource, pixelSource, std::static_pointer_cast<dxSharedContext>(sharedContext));) return new dxShader(vertexSource, pixelSource, std::static_pointer_cast<dxSharedContext>(sharedContext));)
default: default:
LT_ENGINE_ASSERT(false, "Shader::Create: invalid/unsupported GraphicsAPI {}", GraphicsContext::GetGraphicsAPI()); LT_ENGINE_ASSERT(false, "Shader::Create: invalid/unsupported 'GraphicsAPI' {}", GraphicsContext::GetGraphicsAPI());
return nullptr; return nullptr;
} }
} }

View file

@ -8,7 +8,6 @@ namespace Light {
{ {
public: public:
virtual ~SharedContext() = default; virtual ~SharedContext() = default;
void DummyFunc(const std::string& value) { LT_ENGINE_TRACE(value); }
}; };
} }

View file

@ -1,14 +1,14 @@
#include "ltpch.h" #include "ltpch.h"
#include "Texture.h" #include "Texture.h"
#include "GraphicsContext.h"
#include "OpenGL/glTexture.h" #include "OpenGL/glTexture.h"
#ifdef LIGHT_PLATFORM_WINDOWS #ifdef LIGHT_PLATFORM_WINDOWS
#include "DirectX/dxTexture.h" #include "DirectX/dxTexture.h"
#include "DirectX/dxSharedContext.h" #include "DirectX/dxSharedContext.h"
#endif #endif
#include "GraphicsContext.h"
namespace Light { namespace Light {
Texture* Texture::Create(unsigned int width, unsigned int height, unsigned int components, unsigned char* pixels, std::shared_ptr<SharedContext> sharedContext) Texture* Texture::Create(unsigned int width, unsigned int height, unsigned int components, unsigned char* pixels, std::shared_ptr<SharedContext> sharedContext)
@ -19,11 +19,10 @@ namespace Light {
return new glTexture(width, height, components, pixels); return new glTexture(width, height, components, pixels);
case GraphicsAPI::DirectX: LT_WIN( case GraphicsAPI::DirectX: LT_WIN(
return new dxTexture(width, height, components, pixels, std::static_pointer_cast<dxSharedContext>(sharedContext)); return new dxTexture(width, height, components, pixels, std::static_pointer_cast<dxSharedContext>(sharedContext));)
)
default: default:
LT_ENGINE_ASSERT(false, "Texture::Create: invalid/unsupported GraphicsAPI {}", GraphicsContext::GetGraphicsAPI()); LT_ENGINE_ASSERT(false, "Texture::Create: invalid/unsupported 'GraphicsAPI' {}", GraphicsContext::GetGraphicsAPI());
return nullptr; return nullptr;
} }
} }

View file

@ -4,25 +4,25 @@
#ifdef LIGHT_PLATFORM_WINDOWS #ifdef LIGHT_PLATFORM_WINDOWS
#include "DirectX/dxVertexLayout.h" #include "DirectX/dxVertexLayout.h"
#include "DirectX/dxSharedContext.h" #include "DirectX/dxSharedContext.h"
#endif #endif
#include "GraphicsContext.h" #include "GraphicsContext.h"
namespace Light { namespace Light {
VertexLayout* VertexLayout::Create(VertexBuffer* buffer, Shader* shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, std::shared_ptr<SharedContext> sharedContext) VertexLayout* VertexLayout::Create(std::shared_ptr<VertexBuffer> vertexBuffer, std::shared_ptr<Shader> shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, std::shared_ptr<SharedContext> sharedContext)
{ {
switch (GraphicsContext::GetGraphicsAPI()) switch (GraphicsContext::GetGraphicsAPI())
{ {
case GraphicsAPI::OpenGL: case GraphicsAPI::OpenGL:
return new glVertexLayout(buffer, elements); return new glVertexLayout(vertexBuffer, elements);
case GraphicsAPI::DirectX: LT_WIN( case GraphicsAPI::DirectX: LT_WIN(
return new dxVertexLayout(shader, elements, std::static_pointer_cast<dxSharedContext>(sharedContext));) return new dxVertexLayout(shader, elements, std::static_pointer_cast<dxSharedContext>(sharedContext));)
default: default:
LT_ENGINE_ASSERT(false, "VertexLayout::Create: invalid/unsupported GraphicsAPI {}", GraphicsContext::GetGraphicsAPI()); LT_ENGINE_ASSERT(false, "VertexLayout::Create: invalid/unsupported 'GraphicsAPI' {}", GraphicsContext::GetGraphicsAPI());
return nullptr; return nullptr;
} }
} }

View file

@ -2,8 +2,6 @@
#include "Base.h" #include "Base.h"
#include <vector>
namespace Light { namespace Light {
class VertexBuffer; class VertexBuffer;
@ -13,16 +11,16 @@ namespace Light {
enum class VertexElementType enum class VertexElementType
{ {
Int1, Int2, Int3, Int4, Int1 , Int2 , Int3 , Int4,
UInt1, UInt2, UInt3, UInt4, UInt1 , UInt2 , UInt3 , UInt4,
Float1, Float2, Float3, Float4, Float1 , Float2 , Float3 , Float4,
Double1, Double2, Double3, Double4 Double1, Double2, Double3, Double4
}; };
class VertexLayout class VertexLayout
{ {
public: public:
static VertexLayout* Create(VertexBuffer* buffer, Shader* shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, std::shared_ptr<SharedContext> sharedContext); static VertexLayout* Create(std::shared_ptr<VertexBuffer> vertexBuffer, std::shared_ptr<Shader> shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, std::shared_ptr<SharedContext> sharedContext);
virtual ~VertexLayout() = default;; virtual ~VertexLayout() = default;;

View file

@ -29,23 +29,23 @@ namespace Light {
inline const std::string& GetName() const { return m_Name; } inline const std::string& GetName() const { return m_Name; }
// Updates //** UPDATES //
virtual void OnUpdate(float deltaTime) {} virtual void OnUpdate(float deltaTime) {}
virtual void OnUserInterfaceUpdate() {} virtual void OnUserInterfaceUpdate() {}
virtual void OnRender() {} virtual void OnRender() {}
// Mouse events //** MOUSE_EVENTS //
virtual bool OnMouseMoved(const MouseMovedEvent& event) { return false; } virtual bool OnMouseMoved(const MouseMovedEvent& event) { return false; }
virtual bool OnButtonPressed(const ButtonPressedEvent& event) { return false; } virtual bool OnButtonPressed(const ButtonPressedEvent& event) { return false; }
virtual bool OnButtonReleased(const ButtonReleasedEvent& event) { return false; } virtual bool OnButtonReleased(const ButtonReleasedEvent& event) { return false; }
virtual bool OnWheelScrolled(const WheelScrolledEvent& event) { return false; } virtual bool OnWheelScrolled(const WheelScrolledEvent& event) { return false; }
// Keyboard events //** KEYBOARD_EVENTS **//
virtual bool OnKeyPressed(const KeyPressedEvent& event) { return false; } virtual bool OnKeyPressed(const KeyPressedEvent& event) { return false; }
virtual bool OnKeyReleased(const KeyReleasedEvent& event) { return false; } virtual bool OnKeyReleased(const KeyReleasedEvent& event) { return false; }
// Window Events //** WINDOW_EVENTS **/
virtual bool OnWindowClosed(const WindowClosedEvent& event) { return false; } virtual bool OnWindowClosed(const WindowClosedEvent& event) { return false; }
virtual bool OnWindowResized(const WindowResizedEvent& event) { return false; } virtual bool OnWindowResized(const WindowResizedEvent& event) { return false; }
virtual bool OnWindowMoved(const WindowMovedEvent& event) { return false; } virtual bool OnWindowMoved(const WindowMovedEvent& event) { return false; }

View file

@ -14,7 +14,7 @@ namespace Light {
LayerStack::LayerStack() LayerStack::LayerStack()
{ {
LT_ENGINE_ASSERT(!s_Context, "LayerStack::LayerStack: context re-initialization") LT_ENGINE_ASSERT(!s_Context, "LayerStack::LayerStack: an instance of 'LayerStack' already exists, do not construct this class!")
s_Context = this; s_Context = this;
} }

View file

@ -28,7 +28,7 @@ namespace Light {
return new dxUserInterface(windowHandle, std::dynamic_pointer_cast<dxSharedContext>(sharedContext));) return new dxUserInterface(windowHandle, std::dynamic_pointer_cast<dxSharedContext>(sharedContext));)
default: default:
LT_ENGINE_ASSERT(false, "UserInterface::Create: invalid/unsupported GraphicsAPI {}", GraphicsContext::GetGraphicsAPI()); LT_ENGINE_ASSERT(false, "UserInterface::Create: invalid/unsupported 'GraphicsAPI' {}", GraphicsContext::GetGraphicsAPI());
return nullptr; return nullptr;
} }
} }
@ -38,7 +38,7 @@ namespace Light {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
switch (inputEvent.GetEventType()) switch (inputEvent.GetEventType())
{ {
// Mouse Events //** MOUSE_EVENTS **//
case EventType::MouseMoved: case EventType::MouseMoved:
{ {
const MouseMovedEvent& event = (const MouseMovedEvent&)inputEvent; const MouseMovedEvent& event = (const MouseMovedEvent&)inputEvent;
@ -63,7 +63,7 @@ namespace Light {
ImGui::GetIO().MouseWheel = event.GetOffset(); ImGui::GetIO().MouseWheel = event.GetOffset();
return; return;
} }
// Keyboard Events //** MOUSE_EVENTS **//
case EventType::KeyPressed: case EventType::KeyPressed:
{ {
const KeyPressedEvent& event = (const KeyPressedEvent&)inputEvent; const KeyPressedEvent& event = (const KeyPressedEvent&)inputEvent;

View file

@ -2,12 +2,11 @@
#include "ResourceManager.h" #include "ResourceManager.h"
#include "Graphics/GraphicsContext.h" #include "Graphics/GraphicsContext.h"
#include "Graphics/Shader.h" #include "Graphics/Shader.h"
#include "Graphics/Texture.h" #include "Graphics/Texture.h"
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>g #include <stb_image.h>
namespace Light { namespace Light {
@ -21,7 +20,7 @@ namespace Light {
ResourceManager::ResourceManager(std::shared_ptr<SharedContext> sharedContext) ResourceManager::ResourceManager(std::shared_ptr<SharedContext> sharedContext)
: m_SharedContext(sharedContext) : m_SharedContext(sharedContext)
{ {
LT_ENGINE_ASSERT(!s_Context, "ResourceManager::ResourceManager: an instance of 'resource manager' already exists, do not construct this class"); LT_ENGINE_ASSERT(!s_Context, "ResourceManager::ResourceManager: an instance of 'ResourceManager' already exists, do not construct this class!");
s_Context = this; s_Context = this;
stbi_set_flip_vertically_on_load(true); stbi_set_flip_vertically_on_load(true);
@ -34,15 +33,15 @@ namespace Light {
GraphicsContext::GetGraphicsAPI() == GraphicsAPI::DirectX ? "HLSL" : NULL; GraphicsContext::GetGraphicsAPI() == GraphicsAPI::DirectX ? "HLSL" : NULL;
// check // check
LT_ENGINE_ASSERT(!vertexSource.empty(), "ResourceManager::CreateShader: vertex source is empty"); LT_ENGINE_ASSERT(!vertexSource.empty(), "ResourceManager::CreateShader: 'vertexSource' is empty");
LT_ENGINE_ASSERT(!vertexSource.empty(), "ResourceManager::CreateShader: pixel source is empty"); LT_ENGINE_ASSERT(!vertexSource.empty(), "ResourceManager::CreateShader: 'pixelSource' is empty");
LT_ENGINE_ASSERT(!delim.empty(), "ResourceManager::LoadShader: invalid/unsupported graphics api: {}", GraphicsContext::GetGraphicsAPI()); LT_ENGINE_ASSERT(!delim.empty(), "ResourceManager::LoadShader: invalid/unsupported 'GraphicsAPI': {}", GraphicsContext::GetGraphicsAPI());
// save to string // save to string
std::string vsSource = vertexSource; std::string vsSource = vertexSource;
std::string psSource = pixelSource; std::string psSource = pixelSource;
// extract source // extract shader source
ResourceManager::ExtractShaderSource(vsSource, delim); ResourceManager::ExtractShaderSource(vsSource, delim);
ResourceManager::ExtractShaderSource(psSource, delim); ResourceManager::ExtractShaderSource(psSource, delim);
@ -53,8 +52,8 @@ namespace Light {
void ResourceManager::LoadShaderImpl(const std::string& name, const std::string& vertexPath, const std::string& pixelPath) void ResourceManager::LoadShaderImpl(const std::string& name, const std::string& vertexPath, const std::string& pixelPath)
{ {
// check // check
LT_ENGINE_ASSERT(!vertexPath.empty(), "ResourceManager::LoadShader: vertex path is empty"); LT_ENGINE_ASSERT(!vertexPath.empty(), "ResourceManager::LoadShader: 'vertexPath' is empty");
LT_ENGINE_ASSERT(!pixelPath.empty(), "ResourceManager::LoadShader: pixel path is empty"); LT_ENGINE_ASSERT(!pixelPath.empty(), "ResourceManager::LoadShader: 'pixelPath' is empty");
// initialize // initialize
std::ifstream vsStream(vertexPath), psStream(pixelPath); std::ifstream vsStream(vertexPath), psStream(pixelPath);
@ -67,9 +66,9 @@ namespace Light {
GraphicsContext::GetGraphicsAPI() == GraphicsAPI::DirectX ? "HLSL" : NULL; GraphicsContext::GetGraphicsAPI() == GraphicsAPI::DirectX ? "HLSL" : NULL;
// check // check
LT_ENGINE_ASSERT(!delim.empty(), "ResourceManager::LoadShader: invalid/unsupported graphics api: {}", GraphicsContext::GetGraphicsAPI()); LT_ENGINE_ASSERT(!delim.empty(), "ResourceManager::LoadShader: invalid/unsupported 'GraphicsAPI': {}", GraphicsContext::GetGraphicsAPI());
LT_ENGINE_ASSERT(vsStream.is_open(), "ResourceManager::LoadShader: invalid vertex path: {}", vertexPath); LT_ENGINE_ASSERT(vsStream.is_open(), "ResourceManager::LoadShader: invalid 'vertexPath': {}", vertexPath);
LT_ENGINE_ASSERT(psStream.is_open(), "ResourceManager::LoadShader: invalid pixel path: {}", pixelPath); LT_ENGINE_ASSERT(psStream.is_open(), "ResourceManager::LoadShader: invalid 'pixelPath': {}", pixelPath);
// read // read
while (std::getline(vsStream, line)) while (std::getline(vsStream, line))
@ -90,18 +89,18 @@ namespace Light {
m_Shaders[name] = std::shared_ptr<Shader>(Shader::Create(vertexSource, pixelSource, m_SharedContext)); m_Shaders[name] = std::shared_ptr<Shader>(Shader::Create(vertexSource, pixelSource, m_SharedContext));
} }
void ResourceManager::LoadTextureImpl(const std::string& name, const std::string& path, int desiredComponents) void ResourceManager::LoadTextureImpl(const std::string& name, const std::string& path, unsigned int desiredComponents /* = 4u */)
{ {
// load image // load image
int width, height, components; int width, height, components;
unsigned char* pixels = stbi_load(path.c_str(), &width, &height, &components, desiredComponents); unsigned char* pixels = stbi_load(path.c_str(), &width, &height, &components, desiredComponents);
// check // check
LT_ENGINE_ASSERT(pixels, "ResourceManager::LoadTexture: failed to load texture <{}>, path: {}", name, path); LT_ENGINE_ASSERT(pixels, "ResourceManager::LoadTexture: failed to load texture <{}>, 'path': {}", name, path);
if (components != desiredComponents) if (components != desiredComponents)
{ {
LT_ENGINE_WARN("ResourceManager::LoadTexture: image file compoenents != desired components ({} - {})", components, desiredComponents); LT_ENGINE_WARN("ResourceManager::LoadTexture: image file compoenents != 'desiredComponents' ({} - {})", components, desiredComponents);
LT_ENGINE_WARN("ResourceManager::LoadTexture: <{}> path: {}", name, path); LT_ENGINE_WARN("ResourceManager::LoadTexture: <{}> 'path': {}", name, path);
} }
// create texture // create texture

View file

@ -2,8 +2,6 @@
#include "Base.h" #include "Base.h"
#include <glm/glm.hpp>
namespace Light { namespace Light {
class Shader; class Shader;
@ -11,16 +9,17 @@ namespace Light {
class SharedContext; class SharedContext;
// #todo: optimize
class ResourceManager class ResourceManager
{ {
private: private:
static ResourceManager* s_Context;
std::unordered_map<std::string, std::shared_ptr<Shader>> m_Shaders; std::unordered_map<std::string, std::shared_ptr<Shader>> m_Shaders;
std::unordered_map<std::string, std::shared_ptr<Texture>> m_Textures; std::unordered_map<std::string, std::shared_ptr<Texture>> m_Textures;
std::shared_ptr<SharedContext> m_SharedContext; std::shared_ptr<SharedContext> m_SharedContext;
static ResourceManager* s_Context;
public: public:
static ResourceManager* Create(std::shared_ptr<SharedContext> sharedContext); static ResourceManager* Create(std::shared_ptr<SharedContext> sharedContext);
@ -28,7 +27,7 @@ namespace Light {
static inline void CreateShader(const std::string& name, const std::string& vertexSource, const std::string& pixelSource) { s_Context->CreateShaderImpl(name, vertexSource, pixelSource); } static inline void CreateShader(const std::string& name, const std::string& vertexSource, const std::string& pixelSource) { s_Context->CreateShaderImpl(name, vertexSource, pixelSource); }
static inline void LoadShader(const std::string& name, const std::string& vertexPath, const std::string& pixelPath) { s_Context->LoadShaderImpl(name, vertexPath, pixelPath); } static inline void LoadShader(const std::string& name, const std::string& vertexPath, const std::string& pixelPath) { s_Context->LoadShaderImpl(name, vertexPath, pixelPath); }
static inline void LoadTexture(const std::string& name, const std::string& path, int desiredComponents = 4) { s_Context->LoadTextureImpl(name, path, desiredComponents); } static inline void LoadTexture(const std::string& name, const std::string& path, unsigned int desiredComponents = 4u) { s_Context->LoadTextureImpl(name, path, desiredComponents); }
static inline std::shared_ptr<Shader> GetShader(const std::string& name) { return s_Context->m_Shaders[name]; } static inline std::shared_ptr<Shader> GetShader(const std::string& name) { return s_Context->m_Shaders[name]; }
static inline std::shared_ptr<Texture> GetTexture(const std::string& name) { return s_Context->m_Textures[name]; } static inline std::shared_ptr<Texture> GetTexture(const std::string& name) { return s_Context->m_Textures[name]; }
@ -39,7 +38,7 @@ namespace Light {
void CreateShaderImpl(const std::string& name, const std::string& vertexSource, const std::string& pixelSource); void CreateShaderImpl(const std::string& name, const std::string& vertexSource, const std::string& pixelSource);
void LoadShaderImpl(const std::string& name, const std::string& vertexPath, const std::string& pixelPath); void LoadShaderImpl(const std::string& name, const std::string& vertexPath, const std::string& pixelPath);
void LoadTextureImpl(const std::string& name, const std::string& path, int desiredComponents); void LoadTextureImpl(const std::string& name, const std::string& path, unsigned int desiredComponents = 4u);
private: private:
void ExtractShaderSource(std::string& src, const std::string& delim); void ExtractShaderSource(std::string& src, const std::string& delim);
}; };

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "Base.h" #include "Base.h"
namespace Light { namespace Light {

View file

@ -1,16 +1,17 @@
#pragma once #pragma once
// Engine // ENGINE //
#include "Base.h" #include "Base.h"
// Platform // PLATFORM SPECIFIC //
// windows
#ifdef _WIN32 #ifdef _WIN32
#define NOMINMAX #define NOMINMAX
#include <Windows.h> #include <Windows.h>
#undef NOMINMAX #undef NOMINMAX
#endif #endif
// Containers // CONTAINERS //
#include <array> #include <array>
#include <vector> #include <vector>
#include <list> #include <list>
@ -20,26 +21,26 @@
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
// Miscellaneous // MISCELLANEOUS //
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <tuple> #include <tuple>
#include <utility> #include <utility>
// IO // INPUT_OUTPUT //
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
// Multi-threading // MULTI_THREADING //
#include <thread> #include <thread>
#include <atomic> #include <atomic>
// String // STRING //
#include <string> #include <string>
#include <string_view> #include <string_view>
// C-Libraries // C_LIBRARIES //
#include <time.h> #include <time.h>
#include <math.h> #include <math.h>

View file

@ -30,6 +30,10 @@
#include "UserInterface/UserInterface.h" #include "UserInterface/UserInterface.h"
// ----------------------------- // -----------------------------
// Utility ---------------------
#include "Utility/ResourceManager.h"
// -----------------------------
// Base ----------------------- // Base -----------------------
#include "Base.h" #include "Base.h"

View file

@ -5,10 +5,9 @@
namespace Light { namespace Light {
//* VERTEX BUFFER *// //* VERTEX_BUFFER *//
dxVertexBuffer::dxVertexBuffer(float* vertices, unsigned int stride, unsigned int count, std::shared_ptr<dxSharedContext> sharedContext) dxVertexBuffer::dxVertexBuffer(float* vertices, unsigned int stride, unsigned int count, std::shared_ptr<dxSharedContext> sharedContext)
: m_Stride(stride), m_Context(sharedContext) : m_Stride(stride), m_Context(sharedContext)
{ {
// buffer desc // buffer desc
D3D11_BUFFER_DESC bd = { 0 }; D3D11_BUFFER_DESC bd = { 0 };
@ -22,7 +21,7 @@ namespace Light {
// create buffer // create buffer
HRESULT hr; HRESULT hr;
DXC(m_Context->device->CreateBuffer(&bd, nullptr, &m_Buffer)); DXC(m_Context->GetDevice()->CreateBuffer(&bd, nullptr, &m_Buffer));
} }
dxVertexBuffer::~dxVertexBuffer() dxVertexBuffer::~dxVertexBuffer()
@ -32,19 +31,19 @@ namespace Light {
void* dxVertexBuffer::Map() void* dxVertexBuffer::Map()
{ {
m_Context->deviceContext->Map(m_Buffer.Get(), NULL, D3D11_MAP_WRITE_DISCARD, NULL, &m_Map); m_Context->GetDeviceContext()->Map(m_Buffer.Get(), NULL, D3D11_MAP_WRITE_DISCARD, NULL, &m_Map);
return m_Map.pData; return m_Map.pData;
} }
void dxVertexBuffer::UnMap() void dxVertexBuffer::UnMap()
{ {
m_Context->deviceContext->Unmap(m_Buffer.Get(), NULL); m_Context->GetDeviceContext()->Unmap(m_Buffer.Get(), NULL);
} }
void dxVertexBuffer::Bind() void dxVertexBuffer::Bind()
{ {
static const unsigned int offset = 0u; static const unsigned int offset = 0u;
m_Context->deviceContext->IASetVertexBuffers(0u, 1u, m_Buffer.GetAddressOf(), &m_Stride, &offset); m_Context->GetDeviceContext()->IASetVertexBuffers(0u, 1u, m_Buffer.GetAddressOf(), &m_Stride, &offset);
} }
void dxVertexBuffer::UnBind() void dxVertexBuffer::UnBind()
@ -52,10 +51,10 @@ namespace Light {
static const unsigned int offset = 0u; static const unsigned int offset = 0u;
static ID3D11Buffer* buffer = nullptr; static ID3D11Buffer* buffer = nullptr;
m_Context->deviceContext->IASetVertexBuffers(0u, 1u, &buffer, &m_Stride, &offset); m_Context->GetDeviceContext()->IASetVertexBuffers(0u, 1u, &buffer, &m_Stride, &offset);
} }
//* INDEX BUFFER *// //* INDEX_BUFFER *//
dxIndexBuffer::dxIndexBuffer(unsigned int* indices, unsigned int count, std::shared_ptr<dxSharedContext> sharedContext) dxIndexBuffer::dxIndexBuffer(unsigned int* indices, unsigned int count, std::shared_ptr<dxSharedContext> sharedContext)
: m_Context(sharedContext) : m_Context(sharedContext)
{ {
@ -66,8 +65,8 @@ namespace Light {
// check // check
if (count % 6 != 0) if (count % 6 != 0)
{ {
LT_ENGINE_WARN("dxIndexBuffer::dxIndexBuffer: indices can only be null if count is multiple of 6"); LT_ENGINE_WARN("dxIndexBuffer::dxIndexBuffer: 'indices' can only be null if count is multiple of 6");
LT_ENGINE_WARN("dxIndexBuffer::dxIndexBuffer: adding {} to count -> {}", (6 - (count % 6)), count + (6 - (count % 6))); LT_ENGINE_WARN("dxIndexBuffer::dxIndexBuffer: adding {} to 'count' -> {}", (6 - (count % 6)), count + (6 - (count % 6)));
count = count + (6 - (count % 6)); count = count + (6 - (count % 6));
} }
@ -102,14 +101,11 @@ namespace Light {
// create buffer // create buffer
HRESULT hr; HRESULT hr;
DXC(m_Context->device->CreateBuffer(&bd, &sd, &m_Buffer)); DXC(m_Context->GetDevice()->CreateBuffer(&bd, &sd, &m_Buffer));
// delete indices // delete indices
if (!hasIndices) if (!hasIndices)
{
delete[] indices; delete[] indices;
indices = nullptr;
}
} }
dxIndexBuffer::~dxIndexBuffer() dxIndexBuffer::~dxIndexBuffer()
@ -119,7 +115,7 @@ namespace Light {
void dxIndexBuffer::Bind() void dxIndexBuffer::Bind()
{ {
m_Context->deviceContext->IASetIndexBuffer(m_Buffer.Get(), DXGI_FORMAT_R32_UINT, 0u); m_Context->GetDeviceContext()->IASetIndexBuffer(m_Buffer.Get(), DXGI_FORMAT_R32_UINT, 0u);
} }
void dxIndexBuffer::UnBind() void dxIndexBuffer::UnBind()
@ -127,7 +123,7 @@ namespace Light {
static const unsigned int offset = 0u; static const unsigned int offset = 0u;
static ID3D11Buffer* buffer = nullptr; static ID3D11Buffer* buffer = nullptr;
m_Context->deviceContext->IASetIndexBuffer(buffer, DXGI_FORMAT_R32_UINT, offset); m_Context->GetDeviceContext()->IASetIndexBuffer(buffer, DXGI_FORMAT_R32_UINT, offset);
} }
} }

View file

@ -10,7 +10,7 @@ namespace Light {
class dxSharedContext; class dxSharedContext;
//* VERTEX BUFFER *// //* VERTEX_BUFFER *//
class dxVertexBuffer : public VertexBuffer class dxVertexBuffer : public VertexBuffer
{ {
private: private:
@ -32,7 +32,7 @@ namespace Light {
void UnBind() override; void UnBind() override;
}; };
//* INDEX BUFFER *// //* INDEX_BUFFER *//
class dxIndexBuffer : public IndexBuffer class dxIndexBuffer : public IndexBuffer
{ {
private: private:

View file

@ -1,21 +1,17 @@
#include "ltpch.h" #include "ltpch.h"
#include "dxGraphicsContext.h" #include "dxGraphicsContext.h"
#include "dxSharedContext.h" #include "dxSharedContext.h"
// Required for forward declaration
#include "Graphics/Renderer.h"
#include "Graphics/RenderCommand.h"
#include "Graphics/Shader.h"
#include "Graphics/Buffers.h"
#include "Graphics/VertexLayout.h"
#include "UserInterface/UserInterface.h"
#include "Events/WindowEvents.h" #include "Events/WindowEvents.h"
#include <glfw/glfw3.h> // forward declaration
#include "Graphics/Renderer.h"
#include "Graphics/RenderCommand.h"
#include "UserInterface/UserInterface.h"
#include "Utility/ResourceManager.h"
#define GLFW_EXPOSE_NATIVE_WIN32 #define GLFW_EXPOSE_NATIVE_WIN32
#include <glfw/glfw3.h>
#include <glfw/glfw3native.h> #include <glfw/glfw3native.h>
namespace Light { namespace Light {
@ -23,26 +19,26 @@ namespace Light {
dxGraphicsContext::dxGraphicsContext(GLFWwindow* windowHandle) dxGraphicsContext::dxGraphicsContext(GLFWwindow* windowHandle)
: m_WindowHandle(windowHandle) : m_WindowHandle(windowHandle)
{ {
// DirectX API // set 'GraphicsAPI';
m_GraphicsAPI = GraphicsAPI::DirectX; m_GraphicsAPI = GraphicsAPI::DirectX;
// setup // setup stuff
SetupDeviceAndSwapChain(windowHandle); SetupDeviceAndSwapChain(windowHandle);
SetupRenderTargets(); SetupRenderTargets();
SetupDebugInterface(); SetupDebugInterface();
// create shared context // create 'dxSharedContext'
m_SharedContext = std::make_shared<dxSharedContext>(m_Device, m_DeviceContext, m_SwapChain, m_RenderTargetView); m_SharedContext = std::make_shared<dxSharedContext>(m_Device, m_DeviceContext, m_SwapChain, m_RenderTargetView);
} }
void dxGraphicsContext::OnWindowResize(const WindowResizedEvent& event) void dxGraphicsContext::OnWindowResize(const WindowResizedEvent& event)
{ {
SetResolution(event.GetSize()); SetResolution(event.GetSize().x, event.GetSize().y);
} }
void dxGraphicsContext::SetupDeviceAndSwapChain(GLFWwindow* windowHandle) void dxGraphicsContext::SetupDeviceAndSwapChain(GLFWwindow* windowHandle)
{ {
//* swap chain desc *// // swap chain desc
DXGI_SWAP_CHAIN_DESC sd = { 0 }; DXGI_SWAP_CHAIN_DESC sd = { 0 };
// buffer desc // buffer desc
@ -54,8 +50,7 @@ namespace Light {
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
// sample desc (for multi sampling) // sample desc (for multi sampling) #todo: implement multi-samplingz
// #todo: implement multi-sampling
sd.SampleDesc.Count = 1u; sd.SampleDesc.Count = 1u;
sd.SampleDesc.Quality = 0u; sd.SampleDesc.Quality = 0u;
@ -71,7 +66,7 @@ namespace Light {
sd.Flags = NULL; sd.Flags = NULL;
// determine device flags
UINT flags = NULL; UINT flags = NULL;
#ifdef LIGHT_DEBUG #ifdef LIGHT_DEBUG
flags = D3D11_CREATE_DEVICE_DEBUG; flags = D3D11_CREATE_DEVICE_DEBUG;
@ -123,7 +118,7 @@ namespace Light {
{ {
D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET, D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET,
// #todo: add more message IDs here as needed // #todo: add more message ids here as needed
}; };
D3D11_INFO_QUEUE_FILTER filter = { 0 }; D3D11_INFO_QUEUE_FILTER filter = { 0 };
@ -134,13 +129,13 @@ namespace Light {
#endif #endif
} }
void dxGraphicsContext::SetResolution(const glm::uvec2& resolution) void dxGraphicsContext::SetResolution(unsigned int width, unsigned int height)
{ {
// viewport // viewport
D3D11_VIEWPORT viewport; D3D11_VIEWPORT viewport;
viewport.Width = 800.0f; viewport.Width = width;
viewport.Height = 600.0f; viewport.Height = height;
viewport.MinDepth = 0.0f; viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f; viewport.MaxDepth = 1.0f;

View file

@ -3,8 +3,6 @@
#include "Base.h" #include "Base.h"
#include "Graphics/GraphicsContext.h" #include "Graphics/GraphicsContext.h"
#include <glm/glm.hpp>
#include <d3d11.h> #include <d3d11.h>
#include <wrl.h> #include <wrl.h>
@ -37,7 +35,7 @@ namespace Light {
void SetupDebugInterface(); void SetupDebugInterface();
void SetResolution(const glm::uvec2& resolution); void SetResolution(unsigned int width, unsigned int height);
}; };
} }

View file

@ -1,47 +1,45 @@
#include "ltpch.h" #include "ltpch.h"
#include "dxRenderCommand.h" #include "dxRenderCommand.h"
#include "dxSharedContext.h" #include "dxSharedContext.h"
namespace Light { namespace Light {
dxRenderCommand::dxRenderCommand(std::shared_ptr<dxSharedContext> sharedContext) dxRenderCommand::dxRenderCommand(std::shared_ptr<dxSharedContext> sharedContext)
: m_Context(sharedContext) : m_Context(sharedContext)
{ { }
}
void dxRenderCommand::SwapBuffers() void dxRenderCommand::SwapBuffers()
{ {
#ifdef LIGHT_DEBUG #ifdef LIGHT_DEBUG
HRESULT hr; HRESULT hr;
if (FAILED(hr = m_Context->swapChain->Present(0u, 0u))) if (FAILED(hr = m_Context->GetSwapChain()->Present(0u, 0u)))
{ {
if (hr == DXGI_ERROR_DEVICE_REMOVED) if (hr == DXGI_ERROR_DEVICE_REMOVED)
{ {
LT_ENGINE_CRITICAL("dxRenderCommand::SwapBuffers: DeviceRemoved:"); LT_ENGINE_CRITICAL("dxRenderCommand::SwapBuffers: DeviceRemoved:");
LT_ENGINE_CRITICAL(" {}", m_Context->device->GetDeviceRemovedReason()); LT_ENGINE_CRITICAL(" {}", m_Context->GetDevice()->GetDeviceRemovedReason());
throw dxException(hr, __FILE__, __LINE__);
} }
} }
#else #else
m_Context->swapChain->Present(0u, 0u); m_Context->GetSwapChain()->Present(0u, 0u);
#endif #endif
} }
void dxRenderCommand::ClearBackBuffer() void dxRenderCommand::ClearBackBuffer()
{ {
float colors[] = { 1.2f, 0.4f, 0.9f, 1.0f }; float colors[] = { 1.2f, 0.4f, 0.9f, 1.0f }; // #todo: use a variable for this
m_Context->deviceContext->ClearRenderTargetView(m_Context->renderTargetView.Get(), colors); m_Context->GetDeviceContext()->ClearRenderTargetView(m_Context->GetRenderTargetView().Get(), colors);
} }
void dxRenderCommand::Draw(unsigned int count) void dxRenderCommand::Draw(unsigned int count)
{ {
m_Context->deviceContext->Draw(count, 0u); m_Context->GetDeviceContext()->Draw(count, 0u);
} }
void dxRenderCommand::DrawIndexed(unsigned int count) void dxRenderCommand::DrawIndexed(unsigned int count)
{ {
m_Context->deviceContext->DrawIndexed(count, 0u, 0u); m_Context->GetDeviceContext()->DrawIndexed(count, 0u, 0u);
} }
} }

View file

@ -23,7 +23,6 @@ namespace Light {
virtual void Draw(unsigned int count) override; virtual void Draw(unsigned int count) override;
virtual void DrawIndexed(unsigned int count) override; virtual void DrawIndexed(unsigned int count) override;
}; };
} }

View file

@ -1,13 +1,11 @@
#include "ltpch.h" #include "ltpch.h"
#include "dxShader.h" #include "dxShader.h"
#include "dxSharedContext.h" #include "dxSharedContext.h"
#include <d3dcompiler.h> #include <d3dcompiler.h>
namespace Light { namespace Light {
dxShader::dxShader(const std::string& vertexSource, const std::string& pixelSource, std::shared_ptr<dxSharedContext> sharedContext) dxShader::dxShader(const std::string& vertexSource, const std::string& pixelSource, std::shared_ptr<dxSharedContext> sharedContext)
: m_Context(sharedContext) : m_Context(sharedContext)
{ {
@ -15,16 +13,16 @@ namespace Light {
// compile shaders // compile shaders
HRESULT hr; HRESULT hr;
DXC(D3DCompile(vertexSource.c_str(), vertexSource.length(), NULL, nullptr, nullptr, "main", "vs_4_0", NULL, NULL, &m_VertexBlob, &vsErr)); D3DCompile(vertexSource.c_str(), vertexSource.length(), NULL, nullptr, nullptr, "main", "vs_4_0", NULL, NULL, &m_VertexBlob, &vsErr);
DXC(D3DCompile(pixelSource.c_str(), pixelSource.length(), NULL, nullptr, nullptr, "main", "ps_4_0", NULL, NULL, &ps, &psErr)); D3DCompile(pixelSource.c_str(), pixelSource.length(), NULL, nullptr, nullptr, "main", "ps_4_0", NULL, NULL, &ps, &psErr);
// check // check
LT_ENGINE_ASSERT(!vsErr.Get(), "dxShader::dxShader: vertex shader compile error: {}", (char*)vsErr->GetBufferPointer()); LT_ENGINE_ASSERT(!vsErr.Get(), "dxShader::dxShader: vertex shader compile error: {}", (char*)vsErr->GetBufferPointer());
LT_ENGINE_ASSERT(!psErr.Get(), "dxShader::dxShader: vertex shader compile error: {}", (char*)psErr->GetBufferPointer()); LT_ENGINE_ASSERT(!psErr.Get(), "dxShader::dxShader: pixels shader compile error: {}", (char*)psErr->GetBufferPointer());
// create shaders // create shaders
DXC(m_Context->device->CreateVertexShader(m_VertexBlob->GetBufferPointer(), m_VertexBlob->GetBufferSize(), NULL, &m_VertexShader)); DXC(m_Context->GetDevice()->CreateVertexShader(m_VertexBlob->GetBufferPointer(), m_VertexBlob->GetBufferSize(), NULL, &m_VertexShader));
DXC(m_Context->device->CreatePixelShader(ps->GetBufferPointer(), ps->GetBufferSize(), NULL, &m_PixelShader)); DXC(m_Context->GetDevice()->CreatePixelShader(ps->GetBufferPointer(), ps->GetBufferSize(), NULL, &m_PixelShader));
} }
dxShader::~dxShader() dxShader::~dxShader()
@ -34,14 +32,14 @@ namespace Light {
void dxShader::Bind() void dxShader::Bind()
{ {
m_Context->deviceContext->VSSetShader(m_VertexShader.Get(), nullptr, 0u); m_Context->GetDeviceContext()->VSSetShader(m_VertexShader.Get(), nullptr, 0u);
m_Context->deviceContext->PSSetShader(m_PixelShader.Get(), nullptr, 0u); m_Context->GetDeviceContext()->PSSetShader(m_PixelShader.Get(), nullptr, 0u);
} }
void dxShader::UnBind() void dxShader::UnBind()
{ {
m_Context->deviceContext->VSSetShader(nullptr, nullptr, 0u); m_Context->GetDeviceContext()->VSSetShader(nullptr, nullptr, 0u);
m_Context->deviceContext->PSSetShader(nullptr, nullptr, 0u); m_Context->GetDeviceContext()->PSSetShader(nullptr, nullptr, 0u);
} }
} }

View file

@ -19,6 +19,7 @@ namespace Light {
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_PixelShader; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_PixelShader;
Microsoft::WRL::ComPtr<ID3DBlob> m_VertexBlob; Microsoft::WRL::ComPtr<ID3DBlob> m_VertexBlob;
public: public:
dxShader(const std::string& vertexSource, const std::string& pixelSource, std::shared_ptr<dxSharedContext> sharedContext); dxShader(const std::string& vertexSource, const std::string& pixelSource, std::shared_ptr<dxSharedContext> sharedContext);
~dxShader(); ~dxShader();
@ -29,5 +30,4 @@ namespace Light {
Microsoft::WRL::ComPtr<ID3DBlob> GetVertexBlob() { return m_VertexBlob; } Microsoft::WRL::ComPtr<ID3DBlob> GetVertexBlob() { return m_VertexBlob; }
}; };
} }

View file

@ -11,19 +11,25 @@ namespace Light {
// #todo: // #todo:
class dxSharedContext : public SharedContext class dxSharedContext : public SharedContext
{ {
private:
Microsoft::WRL::ComPtr<ID3D11Device > m_Device;
Microsoft::WRL::ComPtr<ID3D11DeviceContext > m_DeviceContext;
Microsoft::WRL::ComPtr<IDXGISwapChain > m_SwapChain;
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_RenderTargetView;
public: public:
dxSharedContext(Microsoft::WRL::ComPtr<ID3D11Device> _device, dxSharedContext(Microsoft::WRL::ComPtr<ID3D11Device > device,
Microsoft::WRL::ComPtr<ID3D11DeviceContext> _deviceContext, Microsoft::WRL::ComPtr<ID3D11DeviceContext > deviceContext,
Microsoft::WRL::ComPtr<IDXGISwapChain> _swapChain, Microsoft::WRL::ComPtr<IDXGISwapChain > swapChain,
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> _renderTargetView) Microsoft::WRL::ComPtr<ID3D11RenderTargetView> renderTargetView)
: device(_device), deviceContext(_deviceContext), swapChain(_swapChain), renderTargetView(_renderTargetView) : m_Device(device), m_DeviceContext(deviceContext), m_SwapChain(swapChain), m_RenderTargetView(renderTargetView)
{ {
} }
Microsoft::WRL::ComPtr<ID3D11Device> device; inline Microsoft::WRL::ComPtr<ID3D11Device > GetDevice () { return m_Device; }
Microsoft::WRL::ComPtr<ID3D11DeviceContext> deviceContext; inline Microsoft::WRL::ComPtr<ID3D11DeviceContext > GetDeviceContext () { return m_DeviceContext; }
Microsoft::WRL::ComPtr<IDXGISwapChain> swapChain; inline Microsoft::WRL::ComPtr<IDXGISwapChain > GetSwapChain () { return m_SwapChain; }
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> renderTargetView; inline Microsoft::WRL::ComPtr<ID3D11RenderTargetView> GetRenderTargetView() { return m_RenderTargetView; }
}; };
} }

View file

@ -1,6 +1,5 @@
#include "ltpch.h" #include "ltpch.h"
#include "dxTexture.h" #include "dxTexture.h"
#include "dxSharedContext.h" #include "dxSharedContext.h"
namespace Light { namespace Light {
@ -8,37 +7,42 @@ namespace Light {
dxTexture::dxTexture(unsigned int width, unsigned int height, unsigned int components, unsigned char* pixels, std::shared_ptr<dxSharedContext> sharedContext) dxTexture::dxTexture(unsigned int width, unsigned int height, unsigned int components, unsigned char* pixels, std::shared_ptr<dxSharedContext> sharedContext)
: m_Context(sharedContext) : m_Context(sharedContext)
{ {
D3D11_TEXTURE2D_DESC textureDesc = { 0 }; // texture desc
D3D11_TEXTURE2D_DESC textureDesc = { };
textureDesc.Width = width; textureDesc.Width = width;
textureDesc.Height = height; textureDesc.Height = height;
textureDesc.MipLevels = 0; textureDesc.MipLevels = 0u;
textureDesc.ArraySize = 1; textureDesc.ArraySize = 1u;
textureDesc.Format = components == 4 ? DXGI_FORMAT_R8G8B8A8_UNORM : textureDesc.Format = components == 4u ? DXGI_FORMAT_R8G8B8A8_UNORM :
components == 3 ? DXGI_FORMAT_R8G8B8A8_UNORM : components == 3u ? DXGI_FORMAT_R8G8B8A8_UNORM :
components == 2 ? DXGI_FORMAT_R8G8B8A8_UNORM : components == 2u ? DXGI_FORMAT_R8G8B8A8_UNORM :
components == 1 ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGI_FORMAT_UNKNOWN; components == 1u ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGI_FORMAT_UNKNOWN;
textureDesc.SampleDesc.Count = 1; textureDesc.SampleDesc.Count = 1u;
textureDesc.SampleDesc.Quality = 0; textureDesc.SampleDesc.Quality = 0u;
textureDesc.Usage = D3D11_USAGE_DEFAULT; textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
textureDesc.CPUAccessFlags = NULL; textureDesc.CPUAccessFlags = NULL;
textureDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; textureDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
// create texture
HRESULT hr; HRESULT hr;
DXC(m_Context->device->CreateTexture2D(&textureDesc, nullptr, &m_Texture)); DXC(m_Context->GetDevice()->CreateTexture2D(&textureDesc, nullptr, &m_Texture));
m_Context->deviceContext->UpdateSubresource(m_Texture.Get(), 0u, nullptr, pixels, width * 4, 0u); m_Context->GetDeviceContext()->UpdateSubresource(m_Texture.Get(), 0u, nullptr, pixels, width * 4u, 0u);
m_Texture->GetDesc(&textureDesc); m_Texture->GetDesc(&textureDesc);
// shader resource view desc
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc = { }; D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc = { };
shaderResourceViewDesc.Format = textureDesc.Format; shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0u; shaderResourceViewDesc.Texture2D.MostDetailedMip = 0u;
shaderResourceViewDesc.Texture2D.MipLevels = -1; shaderResourceViewDesc.Texture2D.MipLevels = -1;
m_Context->device->CreateShaderResourceView(m_Texture.Get(), &shaderResourceViewDesc, &m_ResourceView); // create shader resource view
m_Context->deviceContext->GenerateMips(m_ResourceView.Get()); m_Context->GetDevice()->CreateShaderResourceView(m_Texture.Get(), &shaderResourceViewDesc, &m_ResourceView);
m_Context->GetDeviceContext()->GenerateMips(m_ResourceView.Get());
// sampler desc
D3D11_SAMPLER_DESC samplerDesc = { }; D3D11_SAMPLER_DESC samplerDesc = { };
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
@ -48,13 +52,14 @@ namespace Light {
samplerDesc.MipLODBias = 0.0f; samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
m_Context->device->CreateSamplerState(&samplerDesc, &m_SamplerState); // create sampler
m_Context->GetDevice()->CreateSamplerState(&samplerDesc, &m_SamplerState);
} }
void dxTexture::Bind(unsigned int slot /* = 0 */) void dxTexture::Bind(unsigned int slot /* = 0u */)
{ {
m_Context->deviceContext->PSSetSamplers(slot, 1u, m_SamplerState.GetAddressOf()); m_Context->GetDeviceContext()->PSSetSamplers(slot, 1u, m_SamplerState.GetAddressOf());
m_Context->deviceContext->PSSetShaderResources(slot, 1u, m_ResourceView.GetAddressOf()); m_Context->GetDeviceContext()->PSSetShaderResources(slot, 1u, m_ResourceView.GetAddressOf());
} }
} }

View file

@ -18,10 +18,11 @@ namespace Light {
Microsoft::WRL::ComPtr<ID3D11Texture2D> m_Texture; Microsoft::WRL::ComPtr<ID3D11Texture2D> m_Texture;
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_ResourceView; Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_ResourceView;
Microsoft::WRL::ComPtr<ID3D11SamplerState> m_SamplerState; Microsoft::WRL::ComPtr<ID3D11SamplerState> m_SamplerState;
public: public:
dxTexture(unsigned int width, unsigned int height, unsigned int components, unsigned char* pixels, std::shared_ptr<dxSharedContext> sharedContext); dxTexture(unsigned int width, unsigned int height, unsigned int components, unsigned char* pixels, std::shared_ptr<dxSharedContext> sharedContext);
void Bind(unsigned int slot /* = 0 */) override; void Bind(unsigned int slot = 0u) override;
}; };
} }

View file

@ -1,6 +1,5 @@
#include "ltpch.h" #include "ltpch.h"
#include "dxUserInterface.h" #include "dxUserInterface.h"
#include "dxSharedContext.h" #include "dxSharedContext.h"
#include <imgui.h> #include <imgui.h>
@ -28,7 +27,7 @@ namespace Light {
// init // init
ImGui_ImplWin32_Init(glfwGetWin32Window(windowHandle)); ImGui_ImplWin32_Init(glfwGetWin32Window(windowHandle));
ImGui_ImplDX11_Init(sharedContext->device.Get(), sharedContext->deviceContext.Get()); ImGui_ImplDX11_Init(sharedContext->GetDevice().Get(), sharedContext->GetDeviceContext().Get());
} }
dxUserInterface::~dxUserInterface() dxUserInterface::~dxUserInterface()
@ -44,7 +43,7 @@ namespace Light {
ImGui_ImplWin32_NewFrame(); ImGui_ImplWin32_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
//* TEMP_ IMGUI DEBUG WINDOW _TEMP *// //** #TEMP_IMGUI_DEMO_TEMP# **//
ImGui::ShowDemoWindow(); ImGui::ShowDemoWindow();
} }
@ -61,7 +60,7 @@ namespace Light {
LT_ENGINE_INFO("UserInterface::"); LT_ENGINE_INFO("UserInterface::");
LT_ENGINE_INFO(" API : ImGui"); LT_ENGINE_INFO(" API : ImGui");
LT_ENGINE_INFO(" Version: {}", ImGui::GetVersion()); LT_ENGINE_INFO(" Version: {}", ImGui::GetVersion());
LT_ENGINE_INFO(" GfxAPI : DirectX"); LT_ENGINE_INFO(" GraphicsAPI : DirectX");
LT_ENGINE_INFO("________________________________________"); LT_ENGINE_INFO("________________________________________");
} }

View file

@ -3,11 +3,11 @@
#include "Base.h" #include "Base.h"
#include "UserInterface/UserInterface.h" #include "UserInterface/UserInterface.h"
struct GLFWwindow;
#include <d3d11.h> #include <d3d11.h>
#include <wrl.h> #include <wrl.h>
struct GLFWwindow;
namespace Light { namespace Light {
class dxSharedContext; class dxSharedContext;

View file

@ -1,15 +1,15 @@
#include "ltpch.h" #include "ltpch.h"
#include "dxVertexLayout.h" #include "dxVertexLayout.h"
#include "dxSharedContext.h"
#include "dxShader.h" #include "dxShader.h"
#include "dxSharedContext.h"
namespace Light { namespace Light {
dxVertexLayout::dxVertexLayout(Shader* shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, std::shared_ptr<dxSharedContext> sharedContext) dxVertexLayout::dxVertexLayout(std::shared_ptr<Shader> shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, std::shared_ptr<dxSharedContext> sharedContext)
: m_Context(sharedContext) : m_Context(sharedContext)
{ {
// local // occupy space for input elements
std::vector<D3D11_INPUT_ELEMENT_DESC> inputElementsDesc; std::vector<D3D11_INPUT_ELEMENT_DESC> inputElementsDesc;
inputElementsDesc.reserve(elements.size()); inputElementsDesc.reserve(elements.size());
@ -26,13 +26,12 @@ namespace Light {
0u }); 0u });
} }
// #todo: take in shared_ptr std::shared_ptr<dxShader> dxpShader = std::dynamic_pointer_cast<dxShader>(shader);
dxShader* dxpShader = static_cast<dxShader*>(shader); LT_ENGINE_ASSERT(dxpShader, "dxVertexLayout::dxVertexLayout: failed to cast 'Shader' to 'dxShader'");
LT_ENGINE_ASSERT(dxpShader, "dxVertexLayout::dxVertexLayout: failed to cast Shader to dxShader");
// create input layout (vertex layout) // create input layout (vertex layout)
HRESULT hr; HRESULT hr;
DXC(m_Context->device->CreateInputLayout(&inputElementsDesc[0], inputElementsDesc.size(), dxpShader->GetVertexBlob().Get()->GetBufferPointer(), dxpShader->GetVertexBlob().Get()->GetBufferSize(), &m_InputLayout)); DXC(m_Context->GetDevice()->CreateInputLayout(&inputElementsDesc[0], inputElementsDesc.size(), dxpShader->GetVertexBlob().Get()->GetBufferPointer(), dxpShader->GetVertexBlob().Get()->GetBufferSize(), &m_InputLayout));
} }
dxVertexLayout::~dxVertexLayout() dxVertexLayout::~dxVertexLayout()
@ -42,18 +41,19 @@ namespace Light {
void dxVertexLayout::Bind() void dxVertexLayout::Bind()
{ {
m_Context->deviceContext->IASetInputLayout(m_InputLayout.Get()); m_Context->GetDeviceContext()->IASetInputLayout(m_InputLayout.Get());
} }
void dxVertexLayout::UnBind() void dxVertexLayout::UnBind()
{ {
m_Context->deviceContext->IASetInputLayout(nullptr); m_Context->GetDeviceContext()->IASetInputLayout(nullptr);
} }
DXGI_FORMAT dxVertexLayout::GetDxgiFormat(VertexElementType type) DXGI_FORMAT dxVertexLayout::GetDxgiFormat(VertexElementType type)
{ {
switch (type) switch (type)
{ {
// #todo: add char
// int // int
case Light::VertexElementType::Int1: return DXGI_FORMAT_R32_SINT; case Light::VertexElementType::Int1: return DXGI_FORMAT_R32_SINT;
case Light::VertexElementType::Int2: return DXGI_FORMAT_R32G32_SINT; case Light::VertexElementType::Int2: return DXGI_FORMAT_R32G32_SINT;
@ -78,7 +78,7 @@ namespace Light {
case Light::VertexElementType::Double3: case Light::VertexElementType::Double3:
case Light::VertexElementType::Double4: case Light::VertexElementType::Double4:
default: LT_ENGINE_ASSERT(false, "dxVertexLayout::GetDxgiFormat: invalid type"); default: LT_ENGINE_ASSERT(false, "dxVertexLayout::GetDxgiFormat: invalid 'VertexElementType'");
} }
} }

View file

@ -19,7 +19,7 @@ namespace Light {
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_InputLayout; Microsoft::WRL::ComPtr<ID3D11InputLayout> m_InputLayout;
public: public:
dxVertexLayout(Shader* shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, std::shared_ptr<dxSharedContext> sharedContext); dxVertexLayout(std::shared_ptr<Shader> shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, std::shared_ptr<dxSharedContext> sharedContext);
~dxVertexLayout(); ~dxVertexLayout();
void Bind() override; void Bind() override;

View file

@ -5,6 +5,7 @@
namespace Light { namespace Light {
//** VERTEX_BUFFER **//
glVertexBuffer::glVertexBuffer(float* vertices, unsigned int count) glVertexBuffer::glVertexBuffer(float* vertices, unsigned int count)
{ {
glCreateBuffers(1, &m_BufferID); glCreateBuffers(1, &m_BufferID);
@ -36,6 +37,7 @@ namespace Light {
glBindBuffer(GL_ARRAY_BUFFER, NULL); glBindBuffer(GL_ARRAY_BUFFER, NULL);
} }
//** INDEX_BUFFER **//
glIndexBuffer::glIndexBuffer(unsigned int* indices, unsigned int count) glIndexBuffer::glIndexBuffer(unsigned int* indices, unsigned int count)
{ {
// generate indices if not provided // generate indices if not provided
@ -45,8 +47,8 @@ namespace Light {
// check // check
if (count % 6 != 0) if (count % 6 != 0)
{ {
LT_ENGINE_WARN("glIndexBuffer::glIndexBuffer: count should be divisible by 6 when no indices is provided"); LT_ENGINE_WARN("glIndexBuffer::dxIndexBuffer: 'indices' can only be null if count is multiple of 6");
LT_ENGINE_WARN("glIndexBuffer::glIndexBuffer: adding {} to count -> {}", (6 - (count % 6)), count + (6 - (count % 6))); LT_ENGINE_WARN("glIndexBuffer::glIndexBuffer: adding {} to 'count' -> {}", (6 - (count % 6)), count + (6 - (count % 6)));
count = count + (6 - (count % 6)); count = count + (6 - (count % 6));
} }

View file

@ -5,6 +5,7 @@
namespace Light { namespace Light {
//** VERTEX_BUFFER **//
class glVertexBuffer : public VertexBuffer class glVertexBuffer : public VertexBuffer
{ {
private: private:
@ -21,6 +22,7 @@ namespace Light {
void UnBind() override; void UnBind() override;
}; };
//** INDEX_BUFFER **//
class glIndexBuffer : public IndexBuffer class glIndexBuffer : public IndexBuffer
{ {
private: private:

View file

@ -1,17 +1,13 @@
#include "ltpch.h" #include "ltpch.h"
#include "glGraphicsContext.h" #include "glGraphicsContext.h"
// Required for forward declaration
#include "Graphics/Renderer.h"
#include "Graphics/RenderCommand.h"
#include "Graphics/Shader.h"
#include "Graphics/Buffers.h"
#include "Graphics/VertexLayout.h"
#include "UserInterface/UserInterface.h"
#include "Events/WindowEvents.h" #include "Events/WindowEvents.h"
#include "Utility/Stringifier.h" // forward declaration
#include "Graphics/Renderer.h"
#include "Graphics/RenderCommand.h"
#include "UserInterface/UserInterface.h"
#include "Utility/ResourceManager.h"
#include <glad/glad.h> #include <glad/glad.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@ -21,10 +17,13 @@ namespace Light {
glGraphicsContext::glGraphicsContext(GLFWwindow* windowHandle) glGraphicsContext::glGraphicsContext(GLFWwindow* windowHandle)
: m_WindowHandle(windowHandle) : m_WindowHandle(windowHandle)
{ {
// set 'GraphicsAPI'
m_GraphicsAPI = GraphicsAPI::OpenGL; m_GraphicsAPI = GraphicsAPI::OpenGL;
// make context current
glfwMakeContextCurrent(windowHandle); glfwMakeContextCurrent(windowHandle);
// load opengl (glad)
LT_ENGINE_ASSERT(gladLoadGLLoader((GLADloadproc)glfwGetProcAddress), "glGraphicsContext::glGraphicsContext: failed to initialize opengl (glad)"); LT_ENGINE_ASSERT(gladLoadGLLoader((GLADloadproc)glfwGetProcAddress), "glGraphicsContext::glGraphicsContext: failed to initialize opengl (glad)");
// #todo: add blender // #todo: add blender
@ -36,7 +35,7 @@ namespace Light {
{ {
if (event.GetSize().x < 0 || event.GetSize().y < 0) if (event.GetSize().x < 0 || event.GetSize().y < 0)
{ {
LT_ENGINE_ERROR("glGraphicsContext::OnWindowResize: width/height cannot be negative: [{}x{}]", event.GetSize().x, event.GetSize().y); LT_ENGINE_ERROR("glGraphicsContext::OnWindowResize: 'width'/'height' cannot be negative: [{}x{}]", event.GetSize().x, event.GetSize().y);
return; return;
} }
@ -56,6 +55,7 @@ namespace Light {
void glGraphicsContext::SetDebugMessageCallback() void glGraphicsContext::SetDebugMessageCallback()
{ {
// determine log level
#if defined(LIGHT_DEBUG) #if defined(LIGHT_DEBUG)
glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
@ -67,6 +67,7 @@ namespace Light {
return; return;
#endif #endif
// setup message callback
glDebugMessageCallback([](unsigned int source, unsigned int type, glDebugMessageCallback([](unsigned int source, unsigned int type,
unsigned int id, unsigned int severity, unsigned int id, unsigned int severity,
int length, const char* message, int length, const char* message,

View file

@ -8,8 +8,7 @@ namespace Light {
glRenderCommand::glRenderCommand(GLFWwindow* windowHandle) glRenderCommand::glRenderCommand(GLFWwindow* windowHandle)
: m_WindowHandle(windowHandle) : m_WindowHandle(windowHandle)
{ { }
}
void glRenderCommand::SwapBuffers() void glRenderCommand::SwapBuffers()
{ {
@ -19,7 +18,7 @@ namespace Light {
void glRenderCommand::ClearBackBuffer() void glRenderCommand::ClearBackBuffer()
{ {
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.25f, 0.45f, 0.91f, 1.0f); glClearColor(0.25f, 0.45f, 0.91f, 1.0f); // #todo: use a variable for this
} }
void glRenderCommand::Draw(unsigned int count) void glRenderCommand::Draw(unsigned int count)

View file

@ -11,58 +11,67 @@ namespace Light {
// create shaders // create shaders
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
unsigned int pixelShader = glCreateShader(GL_FRAGMENT_SHADER); unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
// & (address of) needs an lvalue // &(address of) needs an lvalue
const char* lVertexSource = vertexSource.c_str(); const char* lVertexSource = vertexSource.c_str();
const char* lFragmentSource = fragmentSource.c_str(); const char* lFragmentSource = fragmentSource.c_str();
// set shaders' sorce code // set shaders' source code
glShaderSource(vertexShader, 1, &lVertexSource, NULL); glShaderSource(vertexShader, 1, &lVertexSource, NULL);
glShaderSource(pixelShader, 1, &lFragmentSource, NULL); glShaderSource(fragmentShader, 1, &lFragmentSource, NULL);
// compile shaders // compile shaders
glCompileShader(vertexShader); glCompileShader(vertexShader);
glCompileShader(pixelShader); glCompileShader(fragmentShader);
//* TEMP__ HANDLE SHADER COMPILE FAILURE __TEMP **// //** #TEMP_HANDLE_SHADER_COMPILE_FAILURE# **//
int isCompiled = 0; int isCompiled = 0;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled); glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE) if (isCompiled == GL_FALSE)
{ {
GLint maxLength = 0; int logLength = 0;
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength); glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength);
std::vector<char> errorLog(maxLength); char* errorLog = (char*)alloca(logLength);
glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &errorLog[0]); glGetShaderInfoLog(vertexShader, logLength, &logLength, &errorLog[0]);
for(int i = 0; i < errorLog.size() -1; i++)
std::cout << errorLog[i];
glDeleteShader(vertexShader); glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
LT_ENGINE_ASSERT(false, "glShader::glShader: failed to compile vertex shader:\n {}", errorLog);
return;
} }
glGetShaderiv(pixelShader, GL_COMPILE_STATUS, &isCompiled); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE) if (isCompiled == GL_FALSE)
{ {
GLint maxLength = 0; int logLength = 0;
glGetShaderiv(pixelShader, GL_INFO_LOG_LENGTH, &maxLength); glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &logLength);
std::vector<char> errorLog(maxLength); char* errorLog = (char*)alloca(logLength);
glGetShaderInfoLog(pixelShader, maxLength, &maxLength, &errorLog[0]); glGetShaderInfoLog(fragmentShader, logLength, &logLength, &errorLog[0]);
glDeleteShader(pixelShader); glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
LT_ENGINE_ASSERT(false, "glShader::glShader: failed to compile fragment shader:\n {}", errorLog);
return;
} }
//* TEMP__ HANDLE SHADER COMPILE FAILURE __TEMP **// //** #TEMP_HANDLE_SHADER_COMPILE_FAILURE# **//
// attach and link shaders to the shader program // attach shaders
glAttachShader(m_ShaderID, vertexShader); glAttachShader(m_ShaderID, vertexShader);
glAttachShader(m_ShaderID, pixelShader); glAttachShader(m_ShaderID, fragmentShader);
// link shader program
glLinkProgram(m_ShaderID); glLinkProgram(m_ShaderID);
// delete shaders (free memory) // delete shaders (free memory)
glDeleteShader(vertexShader); glDeleteShader(vertexShader);
glDeleteShader(pixelShader); glDeleteShader(fragmentShader);
// #todo: validate program // #todo: validate program
} }

View file

@ -4,9 +4,6 @@
namespace Light { namespace Light {
struct glSharedContext struct glSharedContext { };
{
};
} }

View file

@ -10,13 +10,13 @@ namespace Light {
// create texture // create texture
glCreateTextures(GL_TEXTURE_2D, 1, &m_TextureID); glCreateTextures(GL_TEXTURE_2D, 1, &m_TextureID);
// texture parameters // set texture parameters
glTextureParameteri(m_TextureID, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTextureParameteri(m_TextureID, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTextureParameteri(m_TextureID, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTextureParameteri(m_TextureID, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTextureParameteri(m_TextureID, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTextureParameteri(m_TextureID, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteri(m_TextureID, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTextureParameteri(m_TextureID, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// vocab = 0 // determine formats
unsigned int format = components == 4u ? GL_RGBA : unsigned int format = components == 4u ? GL_RGBA :
components == 3u ? GL_RGB : components == 3u ? GL_RGB :
components == 2u ? GL_RG : components == 2u ? GL_RG :
@ -30,6 +30,10 @@ namespace Light {
// check // check
LT_ENGINE_ASSERT(format, "glTexture::glTexture: invalid number of components: {}", components); LT_ENGINE_ASSERT(format, "glTexture::glTexture: invalid number of components: {}", components);
// #todo: isn't there something like glTextureImage2D ???
// create texture and mipsmaps
Bind(); Bind();
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, pixels); glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, pixels);
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
@ -40,7 +44,7 @@ namespace Light {
glDeleteTextures(1, &m_TextureID); glDeleteTextures(1, &m_TextureID);
} }
void glTexture::Bind(unsigned int slot/*= 0*/) void glTexture::Bind(unsigned int slot /* = 0u */)
{ {
glActiveTexture(GL_TEXTURE0 + slot); glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(GL_TEXTURE_2D, m_TextureID); glBindTexture(GL_TEXTURE_2D, m_TextureID);

View file

@ -9,13 +9,12 @@ namespace Light {
{ {
private: private:
unsigned int m_TextureID; unsigned int m_TextureID;
unsigned int m_ActiveTexture;
public: public:
glTexture(unsigned int width, unsigned int height, unsigned int components, unsigned char* pixels); glTexture(unsigned int width, unsigned int height, unsigned int components, unsigned char* pixels);
~glTexture(); ~glTexture();
void Bind(unsigned int slot = 0) override; void Bind(unsigned int slot = 0u) override;
}; };
} }

View file

@ -38,7 +38,7 @@ namespace Light {
ImGui_ImplGlfw_NewFrame(); ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
//* TEMP_ IMGUI DEBUG WINDOW _TEMP *// //** #TEMP_IMGUI_DEMO_TEMP# **//
ImGui::ShowDemoWindow(); ImGui::ShowDemoWindow();
} }
@ -55,7 +55,7 @@ namespace Light {
LT_ENGINE_INFO("UserInterface::"); LT_ENGINE_INFO("UserInterface::");
LT_ENGINE_INFO(" API : ImGui"); LT_ENGINE_INFO(" API : ImGui");
LT_ENGINE_INFO(" Version: {}", ImGui::GetVersion()); LT_ENGINE_INFO(" Version: {}", ImGui::GetVersion());
LT_ENGINE_INFO(" GfxAPI : OpenGL"); LT_ENGINE_INFO(" GraphicsAPI : OpenGL");
LT_ENGINE_INFO("________________________________________"); LT_ENGINE_INFO("________________________________________");
} }

View file

@ -7,11 +7,11 @@
namespace Light { namespace Light {
glVertexLayout::glVertexLayout(VertexBuffer* buffer, const std::vector<std::pair<std::string, VertexElementType>>& elements) glVertexLayout::glVertexLayout(std::shared_ptr<VertexBuffer> buffer, const std::vector<std::pair<std::string, VertexElementType>>& elements)
{ {
// check // check
LT_ENGINE_ASSERT(dynamic_cast<glVertexBuffer*>(buffer), "glVertexLayout::glVertexLayout: failed to cast VertexBuffer to glVertexBuffer"); LT_ENGINE_ASSERT(std::dynamic_pointer_cast<glVertexBuffer>(buffer), "glVertexLayout::glVertexLayout: failed to cast 'VertexBuffer' to 'glVertexBuffer'");
LT_ENGINE_ASSERT(!elements.empty(), "glVertexLayout::glVertexLayout: elements is empty"); LT_ENGINE_ASSERT(!elements.empty(), "glVertexLayout::glVertexLayout: 'elements' is empty");
// local // local
std::vector<glVertexElementDesc> elementsDesc; std::vector<glVertexElementDesc> elementsDesc;
@ -60,23 +60,24 @@ namespace Light {
{ {
switch (type) switch (type)
{ {
// #todo: add char
// int // int
case VertexElementType::Int1: return { GL_INT, 1, sizeof(int), offset }; case VertexElementType::Int1: return { GL_INT, 1u, sizeof(int), offset };
case VertexElementType::Int2: return { GL_INT, 2, sizeof(int), offset }; case VertexElementType::Int2: return { GL_INT, 2u, sizeof(int), offset };
case VertexElementType::Int3: return { GL_INT, 3, sizeof(int), offset }; case VertexElementType::Int3: return { GL_INT, 3u, sizeof(int), offset };
case VertexElementType::Int4: return { GL_INT, 4, sizeof(int), offset }; case VertexElementType::Int4: return { GL_INT, 4u, sizeof(int), offset };
// uint // uint
case VertexElementType::UInt1: return { GL_UNSIGNED_INT, 1, sizeof(unsigned int), offset }; case VertexElementType::UInt1: return { GL_UNSIGNED_INT, 1u, sizeof(unsigned int), offset };
case VertexElementType::UInt2: return { GL_UNSIGNED_INT, 2, sizeof(unsigned int), offset }; case VertexElementType::UInt2: return { GL_UNSIGNED_INT, 2u, sizeof(unsigned int), offset };
case VertexElementType::UInt3: return { GL_UNSIGNED_INT, 3, sizeof(unsigned int), offset }; case VertexElementType::UInt3: return { GL_UNSIGNED_INT, 3u, sizeof(unsigned int), offset };
case VertexElementType::UInt4: return { GL_UNSIGNED_INT, 4, sizeof(unsigned int), offset }; case VertexElementType::UInt4: return { GL_UNSIGNED_INT, 4u, sizeof(unsigned int), offset };
// float // float
case VertexElementType::Float1: return { GL_FLOAT, 1, sizeof(float), offset }; case VertexElementType::Float1: return { GL_FLOAT, 1u, sizeof(float), offset };
case VertexElementType::Float2: return { GL_FLOAT, 2, sizeof(float), offset }; case VertexElementType::Float2: return { GL_FLOAT, 2u, sizeof(float), offset };
case VertexElementType::Float3: return { GL_FLOAT, 3, sizeof(float), offset }; case VertexElementType::Float3: return { GL_FLOAT, 3u, sizeof(float), offset };
case VertexElementType::Float4: return { GL_FLOAT, 4, sizeof(float), offset }; case VertexElementType::Float4: return { GL_FLOAT, 4u, sizeof(float), offset };
// double // double
case VertexElementType::Double1: return { GL_DOUBLE, 1, sizeof(float), offset }; case VertexElementType::Double1: return { GL_DOUBLE, 1, sizeof(float), offset };
@ -85,7 +86,7 @@ namespace Light {
case VertexElementType::Double4: return { GL_DOUBLE, 4, sizeof(float), offset }; case VertexElementType::Double4: return { GL_DOUBLE, 4, sizeof(float), offset };
default: default:
LT_ENGINE_ASSERT(false, "glVertexLayout::GetElementDesc: invalid vertex element type"); LT_ENGINE_ASSERT(false, "glVertexLayout::GetElementDesc: invalid 'VertexElementType'");
return {}; return {};
} }
} }

View file

@ -19,7 +19,7 @@ namespace Light {
unsigned int m_ArrayID; unsigned int m_ArrayID;
public: public:
glVertexLayout(VertexBuffer* buffer, const std::vector<std::pair<std::string, VertexElementType>>& elements); glVertexLayout(std::shared_ptr<VertexBuffer> buffer, const std::vector<std::pair<std::string, VertexElementType>>& elements);
~glVertexLayout(); ~glVertexLayout();
void Bind() override; void Bind() override;

View file

@ -21,7 +21,7 @@ namespace Light {
: m_EventCallback(callback) : m_EventCallback(callback)
{ {
// init glfw // init glfw
LT_ENGINE_ASSERT(glfwInit(), "lWindow::lWindow: failed to initialize glfw"); LT_ENGINE_ASSERT(glfwInit(), "lWindow::lWindow: failed to initialize 'glfw'");
// create window // create window
glfwWindowHint(GLFW_VERSION_MAJOR, 4); glfwWindowHint(GLFW_VERSION_MAJOR, 4);
@ -30,7 +30,7 @@ namespace Light {
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
m_Handle = glfwCreateWindow(1u, 1u, "", nullptr, nullptr); m_Handle = glfwCreateWindow(1u, 1u, "", nullptr, nullptr);
LT_ENGINE_ASSERT(m_Handle, "lWindow::lWindow: failed to create glfw window"); LT_ENGINE_ASSERT(m_Handle, "lWindow::lWindow: failed to create 'GLFWwindow'");
// manage events // manage events
glfwSetWindowUserPointer(m_Handle, &m_EventCallback); glfwSetWindowUserPointer(m_Handle, &m_EventCallback);
@ -38,7 +38,7 @@ namespace Light {
// create graphics context // create graphics context
m_GraphicsContext = std::unique_ptr<GraphicsContext>(GraphicsContext::Create(GraphicsAPI::OpenGL, m_Handle)); m_GraphicsContext = std::unique_ptr<GraphicsContext>(GraphicsContext::Create(GraphicsAPI::OpenGL, m_Handle));
LT_ENGINE_ASSERT(m_GraphicsContext, "lWindow::lWindow: failed to create graphics context"); LT_ENGINE_ASSERT(m_GraphicsContext, "lWindow::lWindow: failed to create 'GraphicsContext'");
} }
lWindow::~lWindow() lWindow::~lWindow()
@ -46,13 +46,18 @@ namespace Light {
glfwDestroyWindow(m_Handle); glfwDestroyWindow(m_Handle);
} }
void lWindow::SetProperties(const WindowProperties& properties) void lWindow::SetProperties(const WindowProperties& properties, bool affectsVisiblity /* = false */)
{ {
// save the visibility status and re-assign if 'affectVisibility' is false
bool visible = affectsVisiblity ? properties.visible : m_Properties.visible;
m_Properties = properties; m_Properties = properties;
m_Properties.visible = visible;
glfwSetWindowSize(m_Handle, properties.size.x, properties.size.y); // set properties
glfwSetWindowTitle(m_Handle, properties.title.c_str()); SetTitle(properties.title);
glfwSwapInterval(static_cast<int>(properties.vsync)); SetSize(properties.size);
SetVSync(properties.vsync);
SetVisibility(visible);
} }
void lWindow::SetTitle(const std::string& title) void lWindow::SetTitle(const std::string& title)
@ -62,16 +67,16 @@ namespace Light {
glfwSetWindowTitle(m_Handle, title.c_str()); glfwSetWindowTitle(m_Handle, title.c_str());
} }
void lWindow::SetSize(const glm::uvec2& size, bool add/*= false*/) void lWindow::SetSize(const glm::uvec2& size, bool additive /* = false */)
{ {
m_Properties.size.x = size.x == 0u ? m_Properties.size.x : add ? m_Properties.size.x + size.x : size.x; m_Properties.size.x = size.x == 0u ? m_Properties.size.x : additive ? m_Properties.size.x + size.x : size.x;
m_Properties.size.y = size.y == 0u ? m_Properties.size.y : add ? m_Properties.size.y + size.y : size.y; m_Properties.size.y = size.y == 0u ? m_Properties.size.y : additive ? m_Properties.size.y + size.y : size.y;
glfwSetWindowSize(m_Handle, size.x, size.y); glfwSetWindowSize(m_Handle, size.x, size.y);
} }
void lWindow::SetVSync(bool vsync, bool toggle/*= false*/) void lWindow::SetVSync(bool vsync, bool toggle /* = false */)
{ {
m_Properties.vsync = toggle ? !m_Properties.vsync : vsync; m_Properties.vsync = toggle ? !m_Properties.vsync : vsync;
@ -90,7 +95,8 @@ namespace Light {
void lWindow::BindGlfwEvents() void lWindow::BindGlfwEvents()
{ {
//** mouse events **// //** MOUSE_EVENTS **//
// cursor position
glfwSetCursorPosCallback(m_Handle, [](GLFWwindow* window, double xpos, double ypos) glfwSetCursorPosCallback(m_Handle, [](GLFWwindow* window, double xpos, double ypos)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
@ -99,6 +105,7 @@ namespace Light {
callback(event); callback(event);
}); });
// button
glfwSetMouseButtonCallback(m_Handle, [](GLFWwindow* window, int button, int action, int mods) glfwSetMouseButtonCallback(m_Handle, [](GLFWwindow* window, int button, int action, int mods)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
@ -115,6 +122,7 @@ namespace Light {
} }
}); });
// scroll
glfwSetScrollCallback(m_Handle, [](GLFWwindow* window, double xoffset, double yoffset) glfwSetScrollCallback(m_Handle, [](GLFWwindow* window, double xoffset, double yoffset)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
@ -123,7 +131,8 @@ namespace Light {
callback(event); callback(event);
}); });
//** keyboard events **// //** KEYBOARD_EVENTS **//
// key
glfwSetKeyCallback(m_Handle, [](GLFWwindow* window, int key, int scancode, int action, int mods) glfwSetKeyCallback(m_Handle, [](GLFWwindow* window, int key, int scancode, int action, int mods)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
@ -140,7 +149,8 @@ namespace Light {
} }
}); });
//** window events **// //** WINDOW_EVENTS **//
// position
glfwSetWindowPosCallback(m_Handle, [](GLFWwindow* window, int xpos, int ypos) glfwSetWindowPosCallback(m_Handle, [](GLFWwindow* window, int xpos, int ypos)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
@ -149,6 +159,7 @@ namespace Light {
callback(event); callback(event);
}); });
// size
glfwSetWindowSizeCallback(m_Handle, [](GLFWwindow* window, int width, int height) glfwSetWindowSizeCallback(m_Handle, [](GLFWwindow* window, int width, int height)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
@ -157,6 +168,7 @@ namespace Light {
callback(event); callback(event);
}); });
// close
glfwSetWindowCloseCallback(m_Handle, [](GLFWwindow* window) glfwSetWindowCloseCallback(m_Handle, [](GLFWwindow* window)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
@ -165,6 +177,7 @@ namespace Light {
callback(event); callback(event);
}); });
// focus
glfwSetWindowFocusCallback(m_Handle, [](GLFWwindow* window, int focus) glfwSetWindowFocusCallback(m_Handle, [](GLFWwindow* window, int focus)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);

View file

@ -15,6 +15,7 @@ namespace Light {
GLFWwindow* m_Handle = nullptr; GLFWwindow* m_Handle = nullptr;
std::function<void(Event&)> m_EventCallback; std::function<void(Event&)> m_EventCallback;
public: public:
lWindow(std::function<void(Event&)> callback); lWindow(std::function<void(Event&)> callback);
@ -23,11 +24,11 @@ namespace Light {
void PollEvents() override; void PollEvents() override;
void OnEvent(const Event& event) override; void OnEvent(const Event& event) override;
void SetProperties(const WindowProperties& properties) override; void SetProperties(const WindowProperties& properties, bool affectsVisiblity = false) override;
void SetTitle(const std::string& title) override; void SetTitle(const std::string& title) override;
void SetSize(const glm::uvec2& size, bool add = false) override; void SetSize(const glm::uvec2& size, bool additive = false) override;
void SetVSync(bool vsync, bool toggle = false) override; void SetVSync(bool vsync, bool toggle = false) override;
void SetVisibility(bool visible, bool toggle = false); void SetVisibility(bool visible, bool toggle = false);

View file

@ -21,7 +21,7 @@ namespace Light {
: m_EventCallback(callback) : m_EventCallback(callback)
{ {
// init glfw // init glfw
LT_ENGINE_ASSERT(glfwInit(), "wWindow::wWindow: failed to initialize glfw"); LT_ENGINE_ASSERT(glfwInit(), "wWindow::wWindow: failed to initialize 'glfw'");
// create window // create window
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
@ -30,15 +30,15 @@ namespace Light {
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
m_Handle = glfwCreateWindow(1u, 1u, "", nullptr, nullptr); m_Handle = glfwCreateWindow(1u, 1u, "", nullptr, nullptr);
LT_ENGINE_ASSERT(m_Handle, "wWindow::wWindow: glfwCreateWindow: failed to create glfw window"); LT_ENGINE_ASSERT(m_Handle, "wWindow::wWindow: glfwCreateWindow: failed to create 'GLFWwindow'");
// manage events // bind event stuff
glfwSetWindowUserPointer(m_Handle, &m_EventCallback); glfwSetWindowUserPointer(m_Handle, &m_EventCallback);
BindGlfwEvents(); BindGlfwEvents();
// create graphics context // create graphics context
m_GraphicsContext = std::unique_ptr<GraphicsContext>(GraphicsContext::Create(GraphicsAPI::DirectX, m_Handle)); m_GraphicsContext = std::unique_ptr<GraphicsContext>(GraphicsContext::Create(GraphicsAPI::OpenGL, m_Handle));
LT_ENGINE_ASSERT(m_GraphicsContext, "wWindow::wWindow: failed to create graphics context"); LT_ENGINE_ASSERT(m_GraphicsContext, "wWindow::wWindow: failed to create 'GraphicsContext'");
} }
wWindow::~wWindow() wWindow::~wWindow()
@ -46,13 +46,18 @@ namespace Light {
glfwDestroyWindow(m_Handle); glfwDestroyWindow(m_Handle);
} }
void wWindow::SetProperties(const WindowProperties& properties) void wWindow::SetProperties(const WindowProperties& properties, bool affectVisibility /* = false */)
{ {
// save the visibility status and re-assign if 'affectVisibility' is false
bool visible = affectVisibility ? properties.visible : m_Properties.visible;
m_Properties = properties; m_Properties = properties;
m_Properties.visible = visible;
glfwSetWindowSize(m_Handle, properties.size.x, properties.size.y); // #todo: check if this triggers an event // set properties
glfwSetWindowTitle(m_Handle, properties.title.c_str()); SetTitle(properties.title);
glfwSwapInterval((int)properties.vsync); SetSize(properties.size);
SetVSync(properties.vsync);
SetVisibility(visible);
} }
void wWindow::SetVisibility(bool visible, bool toggle) void wWindow::SetVisibility(bool visible, bool toggle)
@ -74,10 +79,12 @@ namespace Light {
{ {
switch (event.GetEventType()) switch (event.GetEventType())
{ {
// closed
case EventType::WindowClosed: case EventType::WindowClosed:
b_Closed = true; b_Closed = true;
break; break;
// resized
case EventType::WindowResized: case EventType::WindowResized:
m_GraphicsContext->OnWindowResize((const WindowResizedEvent&)event); m_GraphicsContext->OnWindowResize((const WindowResizedEvent&)event);
break; break;
@ -91,114 +98,92 @@ namespace Light {
glfwSetWindowTitle(m_Handle, m_Properties.title.c_str()); glfwSetWindowTitle(m_Handle, m_Properties.title.c_str());
} }
void wWindow::SetVSync(bool vsync, bool toggle /*= false*/) void wWindow::SetVSync(bool vsync, bool toggle /* = false */)
{ {
m_Properties.vsync = toggle ? !m_Properties.vsync : vsync; m_Properties.vsync = toggle ? !m_Properties.vsync : vsync;
glfwSwapInterval(m_Properties.vsync); glfwSwapInterval(m_Properties.vsync);
} }
void wWindow::SetSize(const glm::uvec2& size, bool add /*= false*/) void wWindow::SetSize(const glm::uvec2& size, bool additive /* = false */)
{ {
m_Properties.size.x = size.x == 0u ? m_Properties.size.x : add ? m_Properties.size.x + size.x : size.x; m_Properties.size.x = size.x == 0u ? m_Properties.size.x : additive ? m_Properties.size.x + size.x : size.x;
m_Properties.size.y = size.y == 0u ? m_Properties.size.y : add ? m_Properties.size.y + size.y : size.y; m_Properties.size.y = size.y == 0u ? m_Properties.size.y : additive ? m_Properties.size.y + size.y : size.y;
glfwSetWindowSize(m_Handle, m_Properties.size.x, m_Properties.size.y); glfwSetWindowSize(m_Handle, m_Properties.size.x, m_Properties.size.y);
} }
void wWindow::BindGlfwEvents() void wWindow::BindGlfwEvents()
{ {
// Mouse Events // //** MOUSE_EVENTS **//
// cursor position
glfwSetCursorPosCallback(m_Handle, [](GLFWwindow* window, double xpos, double ypos) glfwSetCursorPosCallback(m_Handle, [](GLFWwindow* window, double xpos, double ypos)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
MouseMovedEvent event(xpos, ypos); callback(MouseMovedEvent(xpos, ypos));
callback(event);
}); });
// button
glfwSetMouseButtonCallback(m_Handle, [](GLFWwindow* window, int button, int action, int mods) glfwSetMouseButtonCallback(m_Handle, [](GLFWwindow* window, int button, int action, int mods)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
if (action == GLFW_PRESS) if (action == GLFW_PRESS)
{ callback(ButtonPressedEvent(button));
ButtonPressedEvent event(button);
callback(event);
}
else else
{ callback(ButtonReleasedEvent (button));
ButtonReleasedEvent event(button);
callback(event);
}
}); });
// scroll
glfwSetScrollCallback(m_Handle, [](GLFWwindow* window, double xoffset, double yoffset) glfwSetScrollCallback(m_Handle, [](GLFWwindow* window, double xoffset, double yoffset)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
callback(WheelScrolledEvent (yoffset));
WheelScrolledEvent event(yoffset);
callback(event);
}); });
// Keyboard Events // //** KEYBOARD_EVENTS **//
// key
glfwSetKeyCallback(m_Handle, [](GLFWwindow* window, int key, int scancode, int action, int mods) glfwSetKeyCallback(m_Handle, [](GLFWwindow* window, int key, int scancode, int action, int mods)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
if (action == GLFW_PRESS) if (action == GLFW_PRESS)
{ callback(KeyPressedEvent(key));
KeyPressedEvent event(key);
callback(event);
}
else else
{ callback(KeyReleasedEvent(key));
KeyReleasedEvent event(key);
callback(event);
}
}); });
// Window Events // // Window Events //
// position
glfwSetWindowPosCallback(m_Handle, [](GLFWwindow* window, int xpos, int ypos) glfwSetWindowPosCallback(m_Handle, [](GLFWwindow* window, int xpos, int ypos)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
WindowMovedEvent event(xpos, ypos); callback(WindowMovedEvent(xpos, ypos));
callback(event);
}); });
// size
glfwSetWindowSizeCallback(m_Handle, [](GLFWwindow* window, int width, int height) glfwSetWindowSizeCallback(m_Handle, [](GLFWwindow* window, int width, int height)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
WindowResizedEvent event(width, height); callback(WindowResizedEvent(width, height));
callback(event);
}); });
// close
glfwSetWindowCloseCallback(m_Handle, [](GLFWwindow* window) glfwSetWindowCloseCallback(m_Handle, [](GLFWwindow* window)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
WindowClosedEvent event; callback(WindowClosedEvent());
callback(event);
}); });
// focus
glfwSetWindowFocusCallback(m_Handle, [](GLFWwindow* window, int focus) glfwSetWindowFocusCallback(m_Handle, [](GLFWwindow* window, int focus)
{ {
std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window); std::function<void(Event&)> callback = *(std::function<void(Event&)>*)glfwGetWindowUserPointer(window);
if(focus == GLFW_TRUE) if(focus == GLFW_TRUE)
{ callback(WindowGainFocusEvent());
WindowGainFocusEvent event;
callback(event);
}
else else
{ callback(WindowLostFocusEvent());
WindowLostFocusEvent event;
callback(event);
}
}); });
} }
} }

View file

@ -25,12 +25,12 @@ namespace Light {
void PollEvents() override; void PollEvents() override;
void OnEvent(const Event& event) override; void OnEvent(const Event& event) override;
// Setters // //** SETTERS **//
void SetProperties(const WindowProperties& properties) override; void SetProperties(const WindowProperties& properties, bool affectVisibility = false) override;
void SetTitle(const std::string& title) override; void SetTitle(const std::string& title) override;
void SetSize(const glm::uvec2& size, bool add = false) override; void SetSize(const glm::uvec2& size, bool additive = false) override;
void SetVSync(bool vsync, bool toggle = false) override; void SetVSync(bool vsync, bool toggle = false) override;
void SetVisibility(bool visible, bool toggle = false) override; void SetVisibility(bool visible, bool toggle = false) override;

View file

@ -18,7 +18,10 @@ public:
Light::Renderer::DrawQuad(glm::vec3(0.2f, 0.5f, 0.0f), glm::vec2(0.6f, 0.6f), glm::vec4(.2f, 1.f, .2f, 1.0f)); Light::Renderer::DrawQuad(glm::vec3(0.2f, 0.5f, 0.0f), glm::vec2(0.6f, 0.6f), glm::vec4(.2f, 1.f, .2f, 1.0f));
Light::Renderer::DrawQuad(glm::vec3(-0.3f, 0.2f, 0.0f), glm::vec2(.4f, .4f), glm::vec4(.2f, 2.f, 1.f, 1.0f)); Light::Renderer::DrawQuad(glm::vec3(-0.3f, 0.2f, 0.0f), glm::vec2(.4f, .4f), glm::vec4(.2f, 2.f, 1.f, 1.0f));
Light::Renderer::DrawQuad(glm::vec3(-0.5f, -0.5f, 0.0f), glm::vec2(1.0f, 1.0f), m_AwesomefaceTexture); Light::Renderer::DrawQuad(glm::vec3(-0.3f, -0.5f, 0.0f), glm::vec2(0.1f, 0.1f), m_AwesomefaceTexture);
Light::Renderer::DrawQuad(glm::vec3(-0.5f, +0.5f, 0.0f), glm::vec2(0.1f, 0.1f), m_AwesomefaceTexture);
Light::Renderer::DrawQuad(glm::vec3(-0.1f, -0.5f, 0.0f), glm::vec2(0.1f, 0.1f), m_AwesomefaceTexture);
Light::Renderer::DrawQuad(glm::vec3(+0.5f, -0.5f, 0.0f), glm::vec2(0.1f, 0.1f), m_AwesomefaceTexture);
} }
}; };