Major changes

- Major tidying
- Some fixes
-
This commit is contained in:
Light 2021-06-19 15:12:42 +04:30
parent 21e4432c60
commit fcfe73923d
54 changed files with 432 additions and 254 deletions

2
Dependencies/imgui vendored

@ -1 +1 @@
Subproject commit 6fb2e276cbee262fed50d9c9acf98fa314f624f8 Subproject commit e401b8f2c0e89ddd783245a88549f5c5e23a2c21

View file

@ -28,5 +28,5 @@
#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__); __debugbreak(); } } #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(); } } #define LT_CLIENT_ASSERT(x, ...) { if(!(x)) { LT_CLIENT_CRITICAL(__VA_ARGS__); __debugbreak(); } }

View file

@ -27,60 +27,61 @@ namespace Light {
void Application::GameLoop() void Application::GameLoop()
{ {
// check // check
LT_ENGINE_ASSERT(!m_LayerStack.IsEmpty(), "Application::GameLoop: Layerstack is empty"); LT_ENGINE_ASSERT(!m_LayerStack.IsEmpty(), "Application::GameLoop(pre): LayerStack is empty");
// Log window data // log debug data
Logger::LogDebugData();
LogDebugData(); LogDebugData();
Logger::LogDebugData();
m_Window->GetGfxContext()->LogDebugData(); m_Window->GetGfxContext()->LogDebugData();
m_Window->GetGfxContext()->GetUserInterface()->LogDebugData(); m_Window->GetGfxContext()->GetUserInterface()->LogDebugData();
// Show window // reveal window
m_Window->SetVisibility(true); m_Window->SetVisibility(true);
// GAMELOOP // //* [ GAMELOOP ] *//
while (!m_Window->IsClosed()) while (!m_Window->IsClosed())
{ {
// Events // update layyers
m_Window->PollEvents(); m_LayerStack.OnUpdate(1000.0f / 60.0f); // #todo: implement time
// Rendering // render layers
m_Window->GetGfxContext()->GetRenderer()->BeginScene(); m_Window->GetGfxContext()->GetRenderer()->BeginScene();
m_LayerStack.OnRender(); m_LayerStack.OnRender();
m_Window->GetGfxContext()->GetRenderer()->EndScene(); m_Window->GetGfxContext()->GetRenderer()->EndScene();
// Buffer updates // render user interface
m_Window->GetGfxContext()->GetUserInterface()->Begin();
m_Window->GetGfxContext()->GetUserInterface()->End();
// swap buffers
m_Window->GetGfxContext()->GetRenderCommand()->SwapBuffers(); m_Window->GetGfxContext()->GetRenderCommand()->SwapBuffers();
m_Window->GetGfxContext()->GetRenderCommand()->ClearBackBuffer(); m_Window->GetGfxContext()->GetRenderCommand()->ClearBackBuffer();
// Update // poll events
// ... m_Window->PollEvents();
// UserInterface
m_Window->GetGfxContext()->GetUserInterface()->Begin();
m_Window->GetGfxContext()->GetUserInterface()->End();
} }
} }
void Application::OnEvent(const Event& event) void Application::OnEvent(const Event& event)
{ {
// Window // window
if (event.HasCategory(WindowEventCategory)) if (event.HasCategory(WindowEventCategory))
m_Window->OnEvent(event); m_Window->OnEvent(event);
// UserInterface // user interface
if (event.HasCategory(InputEventCategory)) if (event.HasCategory(InputEventCategory))
m_Window->GetGfxContext()->GetUserInterface()->OnInput(event); m_Window->GetGfxContext()->GetUserInterface()->OnInput(event);
// Input // #todo: add input manager
// ... // ...
// Layers // layers
m_LayerStack.OnEvent(event); m_LayerStack.OnEvent(event);
} }
void Application::LogDebugData() void Application::LogDebugData()
{ {
// #todo: log more information
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);

View file

@ -39,13 +39,12 @@ namespace Light {
virtual void SetTitle(const std::string& title) = 0; virtual void SetTitle(const std::string& title) = 0;
virtual void SetSize(const glm::uvec2& size) = 0; // pass 0 for width or height for single dimension resizing virtual void SetSize(const glm::uvec2& size, bool add = 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(); }

View file

@ -11,8 +11,14 @@
namespace Light { namespace Light {
FailedAssertion::FailedAssertion(const char* file, int line)
{
LT_ENGINE_CRITICAL("FailedAssertion::FailedAssertion: assertion failed in: {} (line {})", file, line);
}
glException::glException(unsigned int source, unsigned int type, unsigned int id, const char* msg) glException::glException(unsigned int source, unsigned int type, unsigned int id, const char* msg)
{ {
// #todo: improve
LT_ENGINE_CRITICAL("________________________________________"); LT_ENGINE_CRITICAL("________________________________________");
LT_ENGINE_CRITICAL("glException::glException::"); LT_ENGINE_CRITICAL("glException::glException::");
LT_ENGINE_CRITICAL(" Severity: {}", Stringifier::glDebugMsgSeverity(GL_DEBUG_SEVERITY_HIGH)); LT_ENGINE_CRITICAL(" Severity: {}", Stringifier::glDebugMsgSeverity(GL_DEBUG_SEVERITY_HIGH));
@ -28,7 +34,7 @@ namespace Light {
LT_ENGINE_CRITICAL("________________________________________"); LT_ENGINE_CRITICAL("________________________________________");
} }
LT_WIN( #ifdef LIGHT_PLATFORM_WINDOWS
dxException::dxException(long hr, const char* file, int line) dxException::dxException(long hr, const char* file, int line)
{ {
char* message; char* message;
@ -37,7 +43,7 @@ namespace Light {
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)(&message), NULL, nullptr); (LPSTR)(&message), NULL, nullptr);
// #todo: format better // #todo: improve
LT_ENGINE_CRITICAL("________________________________________"); LT_ENGINE_CRITICAL("________________________________________");
LT_ENGINE_CRITICAL("dxException::dxException::"); LT_ENGINE_CRITICAL("dxException::dxException::");
LT_ENGINE_CRITICAL(" File: {}, Line: {}", file, line); LT_ENGINE_CRITICAL(" File: {}, Line: {}", file, line);
@ -45,6 +51,7 @@ namespace Light {
LT_ENGINE_CRITICAL("________________________________________"); LT_ENGINE_CRITICAL("________________________________________");
LocalFree(message); LocalFree(message);
}) }
#endif
} }

View file

@ -4,6 +4,11 @@
namespace Light { namespace Light {
struct FailedAssertion : std::exception
{
FailedAssertion(const char* file, int line);
};
// OpenGL // OpenGL
struct glException : std::exception struct glException : std::exception
{ {

View file

@ -2,6 +2,7 @@
#include "Logger.h" #include "Logger.h"
#include <spdlog/sinks/stdout_color_sinks.h> #include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
#include "Utility/Stringifier.h" #include "Utility/Stringifier.h"
@ -9,6 +10,9 @@ namespace Light {
std::shared_ptr<spdlog::logger> Logger::s_EngineLogger = nullptr; std::shared_ptr<spdlog::logger> Logger::s_EngineLogger = nullptr;
std::shared_ptr<spdlog::logger> Logger::s_ClientLogger = nullptr; std::shared_ptr<spdlog::logger> Logger::s_ClientLogger = nullptr;
std::shared_ptr<spdlog::logger> Logger::s_FileLogger = nullptr;
std::string Logger::s_LogFilePath = LT_LOG_FILE_LOCATION;
void Light::Logger::Initialize() void Light::Logger::Initialize()
{ {
@ -16,8 +20,12 @@ namespace Light {
spdlog::set_pattern("%^[%M:%S:%e] <%n>: %v%$"); spdlog::set_pattern("%^[%M:%S:%e] <%n>: %v%$");
// create loggers // create loggers
#ifndef LIGHT_DIST
s_EngineLogger = spdlog::stdout_color_mt("Engine"); s_EngineLogger = spdlog::stdout_color_mt("Engine");
s_ClientLogger = spdlog::stdout_color_mt("Client"); s_ClientLogger = spdlog::stdout_color_mt("Client");
#endif
s_FileLogger = spdlog::basic_logger_mt("File", s_LogFilePath);
s_FileLogger->set_pattern("%^[%M:%S:%e] <%l>: %v%$");
// set level // set level
#if defined(LIGHT_DEBUG) #if defined(LIGHT_DEBUG)
@ -26,20 +34,17 @@ namespace Light {
#elif defined (LIGHT_RELEASE) #elif defined (LIGHT_RELEASE)
s_EngineLogger->set_level(spdlog::level::info); s_EngineLogger->set_level(spdlog::level::info);
s_ClientLogger->set_level(spdlog::level::info); s_ClientLogger->set_level(spdlog::level::info);
#else
s_EngineLogger->set_level(spdlog::level::off);
s_ClientLogger->set_level(spdlog::level::off);
#endif #endif
} }
void Logger::LogDebugData() void Logger::LogDebugData()
{ {
// #todo: improve
LT_ENGINE_INFO("________________________________________"); LT_ENGINE_INFO("________________________________________");
LT_ENGINE_INFO("Logger::"); LT_ENGINE_INFO("Logger::");
LT_ENGINE_INFO(" ClientLevel: {}", Stringifier::spdlogLevel(s_ClientLogger->level())); LT_ENGINE_INFO(" ClientLevel : {}", Stringifier::spdlogLevel(s_ClientLogger->level()));
LT_ENGINE_INFO(" EngineLevel: {}", Stringifier::spdlogLevel(s_EngineLogger->level())); LT_ENGINE_INFO(" EngineLevel : {}", Stringifier::spdlogLevel(s_EngineLogger->level()));
LT_ENGINE_INFO(" FileLevel : {}", Stringifier::spdlogLevel(s_FileLogger->level()));
LT_ENGINE_INFO(" DefaultLevel: {}", Stringifier::spdlogLevel(spdlog::get_level())); LT_ENGINE_INFO(" DefaultLevel: {}", Stringifier::spdlogLevel(spdlog::get_level()));
LT_ENGINE_INFO("________________________________________"); LT_ENGINE_INFO("________________________________________");
} }

View file

@ -5,6 +5,15 @@
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
// LOGGER MACROS // // LOGGER MACROS //
#define LT_LOG_FILE_LOCATION "Log.txt";
// File
#define LT_FILE_INFO(...) ::Light::Logger::GetFileLogger()->log(spdlog::level::info , __VA_ARGS__)
#define LT_FILE_WARN(...) ::Light::Logger::GetFileLogger()->log(spdlog::level::warn , __VA_ARGS__)
#define LT_FILE_ERROR(...) ::Light::Logger::GetFileLogger()->log(spdlog::level::err , __VA_ARGS__)
#define LT_FILE_CRITICAL(...) ::Light::Logger::GetFileLogger()->log(spdlog::level::critical, __VA_ARGS__)
#ifndef LIGHT_DIST #ifndef LIGHT_DIST
// Engine // Engine
#define LT_ENGINE_TRACE(...) ::Light::Logger::GetEngineLogger()->log(spdlog::level::trace , __VA_ARGS__) #define LT_ENGINE_TRACE(...) ::Light::Logger::GetEngineLogger()->log(spdlog::level::trace , __VA_ARGS__)
@ -38,7 +47,8 @@ namespace Light {
class Logger class Logger
{ {
private: private:
static std::shared_ptr<spdlog::logger> s_EngineLogger, s_ClientLogger; static std::shared_ptr<spdlog::logger> s_EngineLogger, s_ClientLogger, s_FileLogger;
static std::string s_LogFilePath;
public: public:
Logger() = delete; Logger() = delete;
@ -47,6 +57,7 @@ namespace Light {
static inline std::shared_ptr<spdlog::logger> GetEngineLogger() { return s_EngineLogger; } static inline std::shared_ptr<spdlog::logger> GetEngineLogger() { return s_EngineLogger; }
static inline std::shared_ptr<spdlog::logger> GetClientLogger() { return s_ClientLogger; } static inline std::shared_ptr<spdlog::logger> GetClientLogger() { return s_ClientLogger; }
static inline std::shared_ptr<spdlog::logger> GetFileLogger() { return s_FileLogger; }
static void LogDebugData(); static void LogDebugData();
}; };

View file

@ -19,6 +19,11 @@ int main(int argc, char** argv)
application->GameLoop(); application->GameLoop();
} }
catch (Light::FailedAssertion)
{
LT_ENGINE_CRITICAL("main: exitting due to unhandled FailedAssertion");
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");

View file

@ -43,12 +43,12 @@ namespace Light {
class WindowResizedEvent : public Event class WindowResizedEvent : public Event
{ {
private: private:
const glm::ivec2 m_Size; const glm::uvec2 m_Size;
public: public:
WindowResizedEvent(int width, int height): m_Size(width, height) {} WindowResizedEvent(unsigned int width, unsigned int height): m_Size(width, height) {}
const glm::ivec2& GetSize() const { return m_Size; } const glm::uvec2& GetSize() const { return m_Size; }
virtual std::string GetInfoLog() const override virtual std::string GetInfoLog() const override
{ {

View file

@ -2,24 +2,28 @@
#include "Buffers.h" #include "Buffers.h"
#include "OpenGL/glBuffers.h" #include "OpenGL/glBuffers.h"
#include "SharedContext.h"
#ifdef LIGHT_PLATFORM_WINDOWS #ifdef LIGHT_PLATFORM_WINDOWS
#include "DirectX/dxBuffers.h" #include "DirectX/dxBuffers.h"
#include "DirectX/dxSharedContext.h"
#endif #endif
#include "GraphicsContext.h" #include "GraphicsContext.h"
namespace Light { namespace Light {
//* VERTEX BUFFER *//
VertexBuffer* VertexBuffer::Create(float* vertices, unsigned int stride, unsigned int count, void* sharedContext) VertexBuffer* VertexBuffer::Create(float* vertices, unsigned int stride, unsigned int count, std::shared_ptr<SharedContext> sharedContext)
{ {
switch (GraphicsContext::GetGraphicsAPI()) switch (GraphicsContext::GetGraphicsAPI())
{ {
case GraphicsAPI::OpenGL: case GraphicsAPI::OpenGL:
return new glVertexBuffer(vertices, count); return new glVertexBuffer(vertices, count);
case GraphicsAPI::DirectX: LT_WIN( case GraphicsAPI::DirectX:
return new dxVertexBuffer(vertices, stride, count, 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());
@ -27,7 +31,8 @@ namespace Light {
} }
} }
IndexBuffer* IndexBuffer::Create(unsigned int* indices, unsigned int count, void* sharedContext) //* INDEX BUFFER *//
IndexBuffer* IndexBuffer::Create(unsigned int* indices, unsigned int count, std::shared_ptr<SharedContext> sharedContext)
{ {
switch (GraphicsContext::GetGraphicsAPI()) switch (GraphicsContext::GetGraphicsAPI())
{ {
@ -35,7 +40,7 @@ namespace Light {
return new glIndexBuffer(indices, count); return new glIndexBuffer(indices, count);
case GraphicsAPI::DirectX: LT_WIN( case GraphicsAPI::DirectX: LT_WIN(
return new dxIndexBuffer(indices, count, 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());

View file

@ -4,10 +4,13 @@
namespace Light { namespace Light {
class SharedContext;
//* VERTEX BUFFER *//
class VertexBuffer class VertexBuffer
{ {
public: public:
static VertexBuffer* Create(float* vertices, unsigned int stride, unsigned int count, void* sharedContext); static VertexBuffer* Create(float* vertices, unsigned int stride, unsigned int count, std::shared_ptr<SharedContext> sharedContext);
virtual void* Map() = 0; virtual void* Map() = 0;
virtual void UnMap() = 0; virtual void UnMap() = 0;
@ -19,10 +22,11 @@ namespace Light {
VertexBuffer() = default; VertexBuffer() = default;
}; };
//* INDEX BUFFER *//
class IndexBuffer class IndexBuffer
{ {
public: public:
static IndexBuffer* Create(unsigned int* indices, unsigned int count, void* sharedContext); static IndexBuffer* Create(unsigned int* indices, unsigned int count, std::shared_ptr<SharedContext> sharedContext);
virtual void Bind() = 0; virtual void Bind() = 0;
virtual void UnBind() = 0; virtual void UnBind() = 0;

View file

@ -12,6 +12,8 @@
#include "RenderCommand.h" #include "RenderCommand.h"
#include "UserInterface/UserInterface.h" #include "UserInterface/UserInterface.h"
#include "Utility/Stringifier.h"
namespace Light { namespace Light {
GraphicsContext* GraphicsContext::s_Context = nullptr; GraphicsContext* GraphicsContext::s_Context = nullptr;
@ -31,8 +33,12 @@ namespace Light {
// determine the default api // determine the default api
if (api == GraphicsAPI::Default) if (api == GraphicsAPI::Default)
{ {
#ifdef LIGHT_PLATFORM_WINDOWS #if defined(LIGHT_PLATFORM_WINDOWS)
api = GraphicsAPI::OpenGL; // TODO: Change to DirectX api = GraphicsAPI::DirectX;
#elif defined(LIGHT_PLATFORM_LINUX)
// #todo:
#elif defined(LIGHT_PLATFORM_MAC)
// #todo:
#endif #endif
} }
@ -42,11 +48,13 @@ namespace Light {
case GraphicsAPI::OpenGL: case GraphicsAPI::OpenGL:
s_Context = new glGraphicsContext(windowHandle); s_Context = new glGraphicsContext(windowHandle);
break; break;
case GraphicsAPI::DirectX: LT_WIN( case GraphicsAPI::DirectX: LT_WIN(
s_Context = new dxGraphicsContext(windowHandle); s_Context = new dxGraphicsContext(windowHandle);
break;) break;)
default: default:
LT_ENGINE_ASSERT(false, "GraphicsContext::Create: invalid/unsupported GraphicsAPI {}", api); LT_ENGINE_ASSERT(false, "GraphicsContext::Create: invalid/unsupported GraphicsAPI {}", Stringifier::GraphicsAPIToString(api));
return nullptr; return nullptr;
} }
@ -56,8 +64,9 @@ namespace Light {
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(s_Context->m_RenderCommand, s_Context->m_SharedContext));
// sanity check // sanity check
LT_ENGINE_ASSERT(s_Context->m_RenderCommand, "GraphicsContext::Create: RenderCommand creation failed"); LT_ENGINE_ASSERT(s_Context->m_RenderCommand, "GraphicsContext::Create: failed to create RenderCommand");
LT_ENGINE_ASSERT(s_Context->m_UserInterface, "GraphicsContext::Create: UserInterface creation failed"); 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");
return s_Context; return s_Context;
} }

View file

@ -2,6 +2,8 @@
#include "Base.h" #include "Base.h"
#include "SharedContext.h"
struct GLFWwindow; struct GLFWwindow;
namespace Light { namespace Light {
@ -32,7 +34,7 @@ namespace Light {
protected: protected:
GraphicsAPI m_GraphicsAPI; GraphicsAPI m_GraphicsAPI;
void* m_SharedContext = nullptr; std::shared_ptr<SharedContext> m_SharedContext = nullptr;
public: public:
static GraphicsContext* Create(GraphicsAPI api, GLFWwindow* windowHandle); static GraphicsContext* Create(GraphicsAPI api, GLFWwindow* windowHandle);

View file

@ -2,15 +2,18 @@
#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"
#endif #endif
#include "GraphicsContext.h" #include "GraphicsContext.h"
namespace Light { namespace Light {
RenderCommand* RenderCommand::Create(GLFWwindow* windowHandle, void* sharedContext) RenderCommand* RenderCommand::Create(GLFWwindow* windowHandle, std::shared_ptr<SharedContext> sharedContext)
{ {
switch (GraphicsContext::GetGraphicsAPI()) switch (GraphicsContext::GetGraphicsAPI())
{ {
@ -18,7 +21,7 @@ namespace Light {
return new glRenderCommand(windowHandle); return new glRenderCommand(windowHandle);
case GraphicsAPI::DirectX: LT_WIN( case GraphicsAPI::DirectX: LT_WIN(
return new dxRenderCommand(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());

View file

@ -6,6 +6,8 @@ struct GLFWwindow;
namespace Light { namespace Light {
class SharedContext;
class RenderCommand class RenderCommand
{ {
public: public:
@ -20,7 +22,7 @@ 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, void* sharedContext); static RenderCommand* Create(GLFWwindow* windowHandle, std::shared_ptr<SharedContext> sharedContext);
protected: protected:
RenderCommand() = default; RenderCommand() = default;

View file

@ -9,7 +9,7 @@ namespace Light {
Renderer* Renderer::s_Context; Renderer* Renderer::s_Context;
Renderer::Renderer(std::shared_ptr<RenderCommand> renderCommand, void* sharedContext) Renderer::Renderer(std::shared_ptr<RenderCommand> renderCommand, std::shared_ptr<SharedContext> sharedContext)
: m_RenderCommand(renderCommand), m_SharedContext(sharedContext) : m_RenderCommand(renderCommand), m_SharedContext(sharedContext)
{ {
s_Context = this; s_Context = this;
@ -17,12 +17,12 @@ namespace Light {
// QUADRENDERER // // QUADRENDERER //
m_QuadRenderer.shader = std::unique_ptr<Shader>(Shader::Create("res/vertex.vertex", "res/fragment.fragment", m_SharedContext)); m_QuadRenderer.shader = std::unique_ptr<Shader>(Shader::Create("res/vertex.vertex", "res/fragment.fragment", m_SharedContext));
m_QuadRenderer.vertexBuffer = std::unique_ptr<VertexBuffer>(VertexBuffer::Create(nullptr, sizeof(QuadRendererProgram::QuadVertexData), LT_MAX_QUAD * 4, m_SharedContext)); m_QuadRenderer.vertexBuffer = std::unique_ptr<VertexBuffer>(VertexBuffer::Create(nullptr, sizeof(QuadRendererProgram::QuadVertexData), LT_MAX_QUAD * 4, 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));
m_QuadRenderer.indexBuffer = std::unique_ptr<IndexBuffer>(IndexBuffer::Create(nullptr, LT_MAX_QUAD * 6, 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));
// QUADRENDERER // // QUADRENDERER //
} }
Renderer* Renderer::Create(std::shared_ptr<RenderCommand> renderCommand, void* sharedContext) Renderer* Renderer::Create(std::shared_ptr<RenderCommand> renderCommand, std::shared_ptr<SharedContext> sharedContext)
{ {
return new Renderer(renderCommand, sharedContext); return new Renderer(renderCommand, sharedContext);
} }

View file

@ -15,6 +15,7 @@
namespace Light { namespace Light {
class RenderCommand; class RenderCommand;
class SharedContext;
struct RendererProgram struct RendererProgram
{ {
@ -29,9 +30,9 @@ namespace Light {
{ {
// graphics context // graphics context
std::shared_ptr<Shader> shader; std::shared_ptr<Shader> shader;
std::shared_ptr<VertexLayout> vertexLayout;
std::shared_ptr<VertexBuffer> vertexBuffer; std::shared_ptr<VertexBuffer> vertexBuffer;
std::shared_ptr<IndexBuffer> indexBuffer; std::shared_ptr<IndexBuffer> indexBuffer;
std::shared_ptr<VertexLayout> vertexLayout;
// buffer data // buffer data
struct QuadVertexData struct QuadVertexData
@ -67,9 +68,9 @@ namespace Light {
std::shared_ptr<RenderCommand> m_RenderCommand; std::shared_ptr<RenderCommand> m_RenderCommand;
void* m_SharedContext; std::shared_ptr<SharedContext> m_SharedContext;
public: public:
static Renderer* Create(std::shared_ptr<RenderCommand> renderCommand, void* sharedContext); static Renderer* Create(std::shared_ptr<RenderCommand> renderCommand, 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);
@ -77,7 +78,7 @@ namespace Light {
void EndScene(); void EndScene();
private: private:
Renderer(std::shared_ptr<RenderCommand> renderCommand, void* sharedContext); Renderer(std::shared_ptr<RenderCommand> renderCommand, 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);
}; };

View file

@ -4,6 +4,7 @@
#ifdef LIGHT_PLATFORM_WINDOWS #ifdef LIGHT_PLATFORM_WINDOWS
#include "DirectX/dxShader.h" #include "DirectX/dxShader.h"
#include "DirectX/dxSharedContext.h"
#endif #endif
#include "GraphicsContext.h" #include "GraphicsContext.h"
@ -12,7 +13,7 @@
namespace Light { namespace Light {
Shader* Shader::Create(const std::string& vertexPath, const std::string& pixelPath, void* sharedContext) Shader* Shader::Create(const std::string& vertexPath, const std::string& pixelPath, std::shared_ptr<SharedContext> sharedContext)
{ {
// load shader source // load shader source
std::string vertexSource = FileManager::ReadTXTFile(vertexPath); std::string vertexSource = FileManager::ReadTXTFile(vertexPath);
@ -30,7 +31,7 @@ namespace Light {
ExtractShaderSource(vertexSource, "HLSL"); ExtractShaderSource(vertexSource, "HLSL");
ExtractShaderSource(pixelSource, "HLSL"); ExtractShaderSource(pixelSource, "HLSL");
return new dxShader(vertexSource, pixelSource, 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());
@ -42,18 +43,21 @@ namespace Light {
{ {
size_t begDelimPos, endDelimPos; size_t begDelimPos, endDelimPos;
// find begin and end delimiter (eg. +GLSL ... -GLSL )
begDelimPos = src.find('+' + delim) + 5; begDelimPos = src.find('+' + delim) + 5;
endDelimPos = src.find('-' + delim); endDelimPos = src.find('-' + delim);
// check
LT_ENGINE_ASSERT(begDelimPos != std::string::npos + 5, LT_ENGINE_ASSERT(begDelimPos != std::string::npos + 5,
"Shader::ExtractShaderSource: failed to find the start delimeter in shader source, delim: {}, shader:\n{}", "Shader::ExtractShaderSource: failed to find the start delimeter in shader source, delim: {}, shader:\n{}",
delim, src); delim, src);
LT_ENGINE_ASSERT(endDelimPos != std::string::npos, LT_ENGINE_ASSERT(endDelimPos != std::string::npos,
"Shader::ExtractShaderSource: failed to find the end delimeter in shader source, delim: {}, shader:\n{}", "Shader::ExtractShaderSource: failed to find the end delimeter in shader source, delim: {}, shader:\n{}",
delim, src); delim, src);
// extract the shader
src = src.substr(begDelimPos, endDelimPos - begDelimPos); src = src.substr(begDelimPos, endDelimPos - begDelimPos);
} }

View file

@ -4,10 +4,12 @@
namespace Light { namespace Light {
class SharedContext;
class Shader class Shader
{ {
public: public:
static Shader* Create(const std::string& vertexPath, const std::string& pixelPath, void* sharedContext); static Shader* Create(const std::string& vertexPath, const std::string& pixelPath, std::shared_ptr<SharedContext> sharedContext);
virtual ~Shader() = default; virtual ~Shader() = default;

View file

@ -0,0 +1,14 @@
#pragma once
#include "Base.h"
namespace Light {
class SharedContext
{
public:
virtual ~SharedContext() = default;
void DummyFunc(const std::string& value) { LT_ENGINE_TRACE(value); }
};
}

View file

@ -4,21 +4,22 @@
#ifdef LIGHT_PLATFORM_WINDOWS #ifdef LIGHT_PLATFORM_WINDOWS
#include "DirectX/dxVertexLayout.h" #include "DirectX/dxVertexLayout.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, void* sharedContext) VertexLayout* VertexLayout::Create(VertexBuffer* buffer, 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(buffer, elements);
case GraphicsAPI::DirectX: case GraphicsAPI::DirectX: LT_WIN(
return new dxVertexLayout(shader, elements, 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());

View file

@ -9,6 +9,8 @@ namespace Light {
class VertexBuffer; class VertexBuffer;
class Shader; class Shader;
class SharedContext;
enum class VertexElementType enum class VertexElementType
{ {
Int1, Int2, Int3, Int4, Int1, Int2, Int3, Int4,
@ -20,7 +22,7 @@ namespace Light {
class VertexLayout class VertexLayout
{ {
public: public:
static VertexLayout* Create(VertexBuffer* buffer, Shader* shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, void* sharedContext); static VertexLayout* Create(VertexBuffer* buffer, Shader* shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, std::shared_ptr<SharedContext> sharedContext);
virtual ~VertexLayout() = default;; virtual ~VertexLayout() = default;;

View file

@ -100,6 +100,7 @@ namespace Light {
void LayerStack::AttachLayerImpl(Layer* layer) void LayerStack::AttachLayerImpl(Layer* layer)
{ {
// #todo: handle attaching layer on for loop
m_Layers.push_back(layer); m_Layers.push_back(layer);
m_Begin = m_Layers.begin(); m_Begin = m_Layers.begin();
m_End = m_Layers.end(); m_End = m_Layers.end();
@ -107,13 +108,14 @@ namespace Light {
LT_ENGINE_TRACE("LayerStack::PushLayer: Attached [{}]", layer->GetName()); LT_ENGINE_TRACE("LayerStack::PushLayer: Attached [{}]", layer->GetName());
} }
void LayerStack::DetatchLayerImpl(Layer* layer) void LayerStack::DetachLayerImpl(Layer* layer)
{ {
// #todo: handle detaching layer on for loop
m_Layers.erase(std::find(m_Layers.begin(), m_Layers.end(), layer)); m_Layers.erase(std::find(m_Layers.begin(), m_Layers.end(), layer));
m_Begin = m_Layers.begin(); m_Begin = m_Layers.begin();
m_End = m_Layers.end(); m_End = m_Layers.end();
LT_ENGINE_TRACE("LayerStack::PushLayer: Detatched[{}]", layer->GetName()); LT_ENGINE_TRACE("LayerStack::PushLayer: Detached[{}]", layer->GetName());
} }
} }

View file

@ -22,7 +22,7 @@ namespace Light {
~LayerStack(); ~LayerStack();
static inline void AttachLayer(Layer* layer) { s_Context->AttachLayerImpl(layer); } static inline void AttachLayer(Layer* layer) { s_Context->AttachLayerImpl(layer); }
static inline void DetatchLayer(Layer* layer) { s_Context->DetatchLayerImpl(layer); } static inline void DetachLayer(Layer* layer) { s_Context->DetachLayerImpl(layer); }
void OnUpdate(float deltaTime); void OnUpdate(float deltaTime);
void OnUserInterfaceUpdate(); void OnUserInterfaceUpdate();
@ -38,7 +38,7 @@ namespace Light {
private: private:
void AttachLayerImpl(Layer* layer); void AttachLayerImpl(Layer* layer);
void DetatchLayerImpl(Layer* layer); void DetachLayerImpl(Layer* layer);
}; };
} }

View file

@ -4,6 +4,7 @@
#ifdef LIGHT_PLATFORM_WINDOWS #ifdef LIGHT_PLATFORM_WINDOWS
#include "DirectX/dxUserInterface.h" #include "DirectX/dxUserInterface.h"
#include "DirectX/dxSharedContext.h"
#endif #endif
#include "Graphics/GraphicsContext.h" #include "Graphics/GraphicsContext.h"
@ -16,7 +17,7 @@
namespace Light { namespace Light {
UserInterface* UserInterface::Create(GLFWwindow* windowHandle, void* sharedContext) UserInterface* UserInterface::Create(GLFWwindow* windowHandle, std::shared_ptr<SharedContext> sharedContext)
{ {
switch (GraphicsContext::GetGraphicsAPI()) switch (GraphicsContext::GetGraphicsAPI())
{ {
@ -24,7 +25,7 @@ namespace Light {
return new glUserInterface(windowHandle); return new glUserInterface(windowHandle);
case GraphicsAPI::DirectX: LT_WIN( case GraphicsAPI::DirectX: LT_WIN(
return new dxUserInterface(windowHandle, 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());
@ -37,13 +38,13 @@ namespace Light {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
switch (inputEvent.GetEventType()) switch (inputEvent.GetEventType())
{ {
// Mouse Events
case EventType::MouseMoved: case EventType::MouseMoved:
{ {
const MouseMovedEvent& event = (const MouseMovedEvent&)inputEvent; const MouseMovedEvent& event = (const MouseMovedEvent&)inputEvent;
ImGui::GetIO().MousePos = ImVec2(event.GetX(), event.GetY()); ImGui::GetIO().MousePos = ImVec2(event.GetX(), event.GetY());
return; return;
} }
case EventType::ButtonPressed: case EventType::ButtonPressed:
{ {
const ButtonPressedEvent& event = (const ButtonPressedEvent&)inputEvent; const ButtonPressedEvent& event = (const ButtonPressedEvent&)inputEvent;
@ -56,7 +57,13 @@ namespace Light {
ImGui::GetIO().MouseDown[event.GetButton()] = false; ImGui::GetIO().MouseDown[event.GetButton()] = false;
return; return;
} }
case EventType::WheelScrolled:
{
const WheelScrolledEvent& event = (const WheelScrolledEvent&)inputEvent;
ImGui::GetIO().MouseWheel = event.GetOffset();
return;
}
// Keyboard Events
case EventType::KeyPressed: case EventType::KeyPressed:
{ {
const KeyPressedEvent& event = (const KeyPressedEvent&)inputEvent; const KeyPressedEvent& event = (const KeyPressedEvent&)inputEvent;
@ -69,12 +76,6 @@ namespace Light {
ImGui::GetIO().MouseDown[event.GetKey()] = false; ImGui::GetIO().MouseDown[event.GetKey()] = false;
return; return;
} }
case EventType::WheelScrolled:
{
const WheelScrolledEvent& event = (const WheelScrolledEvent&)inputEvent;
ImGui::GetIO().MouseWheel = event.GetOffset();
return;
}
} }
} }

View file

@ -7,11 +7,12 @@ struct GLFWwindow;
namespace Light { namespace Light {
class Event; class Event;
class SharedContext;
class UserInterface class UserInterface
{ {
public: public:
static UserInterface* Create(GLFWwindow* windowHandle, void* sharedContext); static UserInterface* Create(GLFWwindow* windowHandle, std::shared_ptr<SharedContext> sharedContext);
UserInterface(const UserInterface&) = delete; UserInterface(const UserInterface&) = delete;
UserInterface operator=(const UserInterface&) = delete; UserInterface operator=(const UserInterface&) = delete;

View file

@ -1,6 +1,8 @@
#include "ltpch.h" #include "ltpch.h"
#include "Stringifier.h" #include "Stringifier.h"
#include "Graphics/GraphicsContext.h"
#include <glad/glad.h> #include <glad/glad.h>
#include <spdlog/common.h> #include <spdlog/common.h>
@ -65,4 +67,17 @@ namespace Light {
} }
} }
std::string Stringifier::GraphicsAPIToString(GraphicsAPI api)
{
switch (api)
{
case Light::GraphicsAPI::Default: return "Default";
case Light::GraphicsAPI::OpenGL: return "OpenGL";
case Light::GraphicsAPI::DirectX: return "DirectX";
case Light::GraphicsAPI::Vulkan: return "Vulkan";
case Light::GraphicsAPI::Metal: return "Metal";
default: return "UNKNOWN";
}
}
} }

View file

@ -4,6 +4,8 @@
namespace Light { namespace Light {
enum class GraphicsAPI;
class Stringifier class Stringifier
{ {
public: public:
@ -12,6 +14,8 @@ namespace Light {
static std::string glDebugMsgType(unsigned int type); static std::string glDebugMsgType(unsigned int type);
static std::string spdlogLevel(unsigned int level); static std::string spdlogLevel(unsigned int level);
static std::string GraphicsAPIToString(GraphicsAPI api);
}; };
} }

View file

@ -5,9 +5,9 @@
// Platform // Platform
#ifdef _WIN32 #ifdef _WIN32
#define NOMINMAX #define NOMINMAX
#include <Windows.h> #include <Windows.h>
#undef NOMINMAX #undef NOMINMAX
#endif #endif
// Containers // Containers

View file

@ -1,5 +0,0 @@
#pragma once
#include "Base.h"
// DirectX Call

View file

@ -5,67 +5,65 @@
namespace Light { namespace Light {
dxVertexBuffer::dxVertexBuffer(float* vertices, unsigned int stride, unsigned int count, void* sharedContext) //* VERTEX BUFFER *//
: m_Stride(stride) dxVertexBuffer::dxVertexBuffer(float* vertices, unsigned int stride, unsigned int count, std::shared_ptr<dxSharedContext> sharedContext)
: m_Stride(stride), m_Context(sharedContext)
{ {
// buffer desc
D3D11_BUFFER_DESC bd = { 0 };
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bd.ByteWidth = count * stride;
bd.StructureByteStride = stride;
// create buffer
HRESULT hr; HRESULT hr;
DXC(m_Context->device->CreateBuffer(&bd, nullptr, &m_Buffer));
dxSharedContext* dxContext = static_cast<dxSharedContext*>(sharedContext);
LT_ENGINE_ASSERT(dxContext, "dxShader::dxShader: invalid dxContext");
m_Device = dxContext->device;
m_DeviceContext = dxContext->deviceContext;
D3D11_BUFFER_DESC desc = { 0 };
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.ByteWidth = count * stride;
desc.StructureByteStride = stride;
DXC(m_Device->CreateBuffer(&desc, nullptr, &m_Buffer));
} }
dxVertexBuffer::~dxVertexBuffer() dxVertexBuffer::~dxVertexBuffer()
{ {
UnBind();
} }
void* dxVertexBuffer::Map() void* dxVertexBuffer::Map()
{ {
m_DeviceContext->Map(m_Buffer.Get(), NULL, D3D11_MAP_WRITE_DISCARD, NULL, &m_Map); m_Context->deviceContext->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_DeviceContext->Unmap(m_Buffer.Get(), NULL); m_Context->deviceContext->Unmap(m_Buffer.Get(), NULL);
} }
void dxVertexBuffer::Bind() void dxVertexBuffer::Bind()
{ {
static const unsigned int offset = 0u; static const unsigned int offset = 0u;
m_DeviceContext->IASetVertexBuffers(0u, 1u, m_Buffer.GetAddressOf(), &m_Stride, &offset); m_Context->deviceContext->IASetVertexBuffers(0u, 1u, m_Buffer.GetAddressOf(), &m_Stride, &offset);
} }
void dxVertexBuffer::UnBind() void dxVertexBuffer::UnBind()
{ {
static const unsigned int offset = 0u;
static ID3D11Buffer* buffer = nullptr;
m_Context->deviceContext->IASetVertexBuffers(0u, 1u, &buffer, &m_Stride, &offset);
} }
dxIndexBuffer::dxIndexBuffer(unsigned int* indices, unsigned int count, void* sharedContext) //* INDEX BUFFER *//
dxIndexBuffer::dxIndexBuffer(unsigned int* indices, unsigned int count, std::shared_ptr<dxSharedContext> sharedContext)
: m_Context(sharedContext)
{ {
HRESULT hr; // generate indices if not provided
dxSharedContext* dxContext = static_cast<dxSharedContext*>(sharedContext);
LT_ENGINE_ASSERT(dxContext, "dxShader::dxShader: invalid dxContext");
m_Device = dxContext->device;
m_DeviceContext = dxContext->deviceContext;
bool hasIndices = !!indices; bool hasIndices = !!indices;
if (!hasIndices) if (!hasIndices)
{ {
// 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");
@ -73,6 +71,7 @@ namespace Light {
count = count + (6 - (count % 6)); count = count + (6 - (count % 6));
} }
// create indices
indices = new unsigned int[count]; indices = new unsigned int[count];
unsigned int offset = 0; unsigned int offset = 0;
for (unsigned int i = 0; i < count; i += 6) for (unsigned int i = 0; i < count; i += 6)
@ -89,18 +88,23 @@ namespace Light {
} }
} }
D3D11_BUFFER_DESC bufferDesc = { 0 }; // buffer desc
D3D11_BUFFER_DESC bd = { 0 };
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = count * sizeof(unsigned int);
bd.StructureByteStride = sizeof(unsigned int);
// subresource data
D3D11_SUBRESOURCE_DATA sd = { 0 }; D3D11_SUBRESOURCE_DATA sd = { 0 };
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.ByteWidth = count * sizeof(unsigned int);
bufferDesc.StructureByteStride = sizeof(unsigned int);
sd.pSysMem = indices; sd.pSysMem = indices;
DXC(m_Device->CreateBuffer(&bufferDesc, &sd, &m_Buffer)); // create buffer
HRESULT hr;
DXC(m_Context->device->CreateBuffer(&bd, &sd, &m_Buffer));
// delete indices
if (!hasIndices) if (!hasIndices)
{ {
delete[] indices; delete[] indices;
@ -110,15 +114,20 @@ namespace Light {
dxIndexBuffer::~dxIndexBuffer() dxIndexBuffer::~dxIndexBuffer()
{ {
UnBind();
} }
void dxIndexBuffer::Bind() void dxIndexBuffer::Bind()
{ {
m_DeviceContext->IASetIndexBuffer(m_Buffer.Get(), DXGI_FORMAT_R32_UINT, 0u); m_Context->deviceContext->IASetIndexBuffer(m_Buffer.Get(), DXGI_FORMAT_R32_UINT, 0u);
} }
void dxIndexBuffer::UnBind() void dxIndexBuffer::UnBind()
{ {
static const unsigned int offset = 0u;
static ID3D11Buffer* buffer = nullptr;
m_Context->deviceContext->IASetIndexBuffer(buffer, DXGI_FORMAT_R32_UINT, offset);
} }
} }

View file

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "Base.h" #include "Base.h"
#include "dxBase.h"
#include "Graphics/Buffers.h" #include "Graphics/Buffers.h"
#include <d3d11.h> #include <d3d11.h>
@ -9,19 +8,21 @@
namespace Light { namespace Light {
class dxSharedContext;
//* VERTEX BUFFER *//
class dxVertexBuffer : public VertexBuffer class dxVertexBuffer : public VertexBuffer
{ {
private: private:
std::shared_ptr<dxSharedContext> m_Context;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_Buffer; Microsoft::WRL::ComPtr<ID3D11Buffer> m_Buffer;
Microsoft::WRL::ComPtr<ID3D11Device> m_Device;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_DeviceContext;
D3D11_MAPPED_SUBRESOURCE m_Map; D3D11_MAPPED_SUBRESOURCE m_Map;
unsigned int m_Stride; unsigned int m_Stride;
public: public:
dxVertexBuffer(float* vertices, unsigned int stride, unsigned int count, void* sharedContext); dxVertexBuffer(float* vertices, unsigned int stride, unsigned int count, std::shared_ptr<dxSharedContext> sharedContext);
~dxVertexBuffer(); ~dxVertexBuffer();
void* Map() override; void* Map() override;
@ -31,15 +32,16 @@ namespace Light {
void UnBind() override; void UnBind() override;
}; };
//* INDEX BUFFER *//
class dxIndexBuffer : public IndexBuffer class dxIndexBuffer : public IndexBuffer
{ {
private: private:
std::shared_ptr<dxSharedContext> m_Context;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_Buffer; Microsoft::WRL::ComPtr<ID3D11Buffer> m_Buffer;
Microsoft::WRL::ComPtr<ID3D11Device> m_Device;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_DeviceContext;
public: public:
dxIndexBuffer(unsigned int* indices, unsigned int count, void* sharedContext); dxIndexBuffer(unsigned int* indices, unsigned int count, std::shared_ptr<dxSharedContext> sharedContext);
~dxIndexBuffer(); ~dxIndexBuffer();
void Bind() override; void Bind() override;

View file

@ -9,6 +9,8 @@
#include "Graphics/VertexLayout.h" #include "Graphics/VertexLayout.h"
#include "UserInterface/UserInterface.h" #include "UserInterface/UserInterface.h"
#include "Events/WindowEvents.h"
#include <glfw/glfw3.h> #include <glfw/glfw3.h>
#define GLFW_EXPOSE_NATIVE_WIN32 #define GLFW_EXPOSE_NATIVE_WIN32
@ -23,8 +25,7 @@ namespace Light {
{ {
m_GraphicsAPI = GraphicsAPI::DirectX; m_GraphicsAPI = GraphicsAPI::DirectX;
HRESULT hr; // swap chain desc
DXGI_SWAP_CHAIN_DESC sd = { 0 }; DXGI_SWAP_CHAIN_DESC sd = { 0 };
sd.OutputWindow = static_cast<HWND>(glfwGetWin32Window(windowHandle)); sd.OutputWindow = static_cast<HWND>(glfwGetWin32Window(windowHandle));
@ -53,20 +54,29 @@ namespace Light {
flags = D3D11_CREATE_DEVICE_DEBUG; flags = D3D11_CREATE_DEVICE_DEBUG;
#endif #endif
// create device and swap chain
HRESULT hr;
DXC(D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, DXC(D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE,
NULL, flags, NULL, NULL, D3D11_SDK_VERSION, NULL, flags, NULL, NULL, D3D11_SDK_VERSION,
&sd, &m_SwapChain, &m_Device, NULL, &m_DeviceContext)); &sd, &m_SwapChain, &m_Device, NULL, &m_DeviceContext));
// set primitive topology
m_DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// create render target view
Microsoft::WRL::ComPtr<ID3D11Resource> backBuffer; Microsoft::WRL::ComPtr<ID3D11Resource> backBuffer;
DXC(m_SwapChain->GetBuffer(0u, __uuidof(ID3D11Resource), &backBuffer)); DXC(m_SwapChain->GetBuffer(0u, __uuidof(ID3D11Resource), &backBuffer));
DXC(m_Device->CreateRenderTargetView(backBuffer.Get(), nullptr, &m_RenderTargetView)); DXC(m_Device->CreateRenderTargetView(backBuffer.Get(), nullptr, &m_RenderTargetView));
// set render target view
m_DeviceContext->OMSetRenderTargets(1u, m_RenderTargetView.GetAddressOf(), nullptr); m_DeviceContext->OMSetRenderTargets(1u, m_RenderTargetView.GetAddressOf(), nullptr);
#ifdef LIGHT_DEBUG
// configure the debug interface
Microsoft::WRL::ComPtr<ID3D11InfoQueue> infoQueue; Microsoft::WRL::ComPtr<ID3D11InfoQueue> infoQueue;
DXC(m_Device.As(&debugInterface)); DXC(m_Device.As(&m_DebugInterface));
DXC(debugInterface.As(&infoQueue)); DXC(m_DebugInterface.As(&infoQueue));
D3D11_MESSAGE_ID hide[] = D3D11_MESSAGE_ID hide[] =
{ {
@ -80,8 +90,20 @@ namespace Light {
filter.DenyList.NumIDs = _countof(hide); filter.DenyList.NumIDs = _countof(hide);
filter.DenyList.pIDList = hide; filter.DenyList.pIDList = hide;
infoQueue->AddStorageFilterEntries(&filter); infoQueue->AddStorageFilterEntries(&filter);
#endif
// create shared context
m_SharedContext = std::make_shared<dxSharedContext>(m_Device, m_DeviceContext, m_SwapChain, m_RenderTargetView);
}
void dxGraphicsContext::OnWindowResize(const WindowResizedEvent& event)
{
SetResolution(event.GetSize());
}
void dxGraphicsContext::SetResolution(const glm::uvec2& resolution)
{
// viewport
D3D11_VIEWPORT viewport; D3D11_VIEWPORT viewport;
viewport.Width = 800.0f; viewport.Width = 800.0f;
@ -92,17 +114,8 @@ namespace Light {
viewport.TopLeftX = 0.0f; viewport.TopLeftX = 0.0f;
viewport.TopLeftY = 0.0f; viewport.TopLeftY = 0.0f;
// set viewport
m_DeviceContext->RSSetViewports(1u, &viewport); m_DeviceContext->RSSetViewports(1u, &viewport);
dxSharedContext* sharedContext = new dxSharedContext({m_DeviceContext, m_SwapChain, m_RenderTargetView, m_Device});
m_SharedContext = sharedContext;
}
void dxGraphicsContext::OnWindowResize(const WindowResizedEvent& event)
{
} }
void dxGraphicsContext::LogDebugData() void dxGraphicsContext::LogDebugData()
@ -126,7 +139,7 @@ namespace Light {
DXGIDevice->Release(); DXGIDevice->Release();
DXGIAdapter->Release(); DXGIAdapter->Release();
// log info // #todo: log more information // #todo: log more information
LT_ENGINE_INFO("________________________________________"); LT_ENGINE_INFO("________________________________________");
LT_ENGINE_INFO("dxGraphicsContext:"); LT_ENGINE_INFO("dxGraphicsContext:");
LT_ENGINE_INFO(" Renderer: {}", adapterDesc); LT_ENGINE_INFO(" Renderer: {}", adapterDesc);

View file

@ -1,9 +1,10 @@
#pragma once #pragma once
#include "Base.h" #include "Base.h"
#include "dxBase.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>
@ -21,7 +22,7 @@ namespace Light {
Microsoft::WRL::ComPtr<IDXGISwapChain> m_SwapChain; Microsoft::WRL::ComPtr<IDXGISwapChain> m_SwapChain;
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_RenderTargetView; Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_RenderTargetView;
Microsoft::WRL::ComPtr<ID3D11Debug> debugInterface; Microsoft::WRL::ComPtr<ID3D11Debug> m_DebugInterface;
public: public:
dxGraphicsContext(GLFWwindow* windowHandle); dxGraphicsContext(GLFWwindow* windowHandle);
@ -29,6 +30,9 @@ namespace Light {
virtual void OnWindowResize(const WindowResizedEvent& event) override; virtual void OnWindowResize(const WindowResizedEvent& event) override;
virtual void LogDebugData() override; virtual void LogDebugData() override;
private:
void SetResolution(const glm::uvec2& resolution);
}; };
} }

View file

@ -5,13 +5,9 @@
namespace Light { namespace Light {
dxRenderCommand::dxRenderCommand(void* sharedContext) dxRenderCommand::dxRenderCommand(std::shared_ptr<dxSharedContext> sharedContext)
: m_Context(sharedContext)
{ {
dxSharedContext* dxContext = (dxSharedContext*)sharedContext;
m_DeviceContext = dxContext->deviceContext;
m_SwapChain = dxContext->swapChain;
m_RenderTargetView = dxContext->renderTargetView;
} }
dxRenderCommand::~dxRenderCommand() dxRenderCommand::~dxRenderCommand()
@ -20,23 +16,23 @@ namespace Light {
void dxRenderCommand::SwapBuffers() void dxRenderCommand::SwapBuffers()
{ {
m_SwapChain->Present(0, 0); m_Context->swapChain->Present(0, 0);
} }
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 };
m_DeviceContext->ClearRenderTargetView(m_RenderTargetView.Get(), colors); m_Context->deviceContext->ClearRenderTargetView(m_Context->renderTargetView.Get(), colors);
} }
void dxRenderCommand::Draw(unsigned int count) void dxRenderCommand::Draw(unsigned int count)
{ {
m_DeviceContext->Draw(count, 0u); m_Context->deviceContext->Draw(count, 0u);
} }
void dxRenderCommand::DrawIndexed(unsigned int count) void dxRenderCommand::DrawIndexed(unsigned int count)
{ {
m_DeviceContext->DrawIndexed(count, 0u, 0u); m_Context->deviceContext->DrawIndexed(count, 0u, 0u);
} }
} }

View file

@ -8,15 +8,15 @@
namespace Light { namespace Light {
class dxSharedContext;
class dxRenderCommand : public RenderCommand class dxRenderCommand : public RenderCommand
{ {
private: private:
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_DeviceContext; std::shared_ptr<dxSharedContext> m_Context;
Microsoft::WRL::ComPtr<IDXGISwapChain> m_SwapChain;
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_RenderTargetView;
public: public:
dxRenderCommand(void* sharedContext); dxRenderCommand(std::shared_ptr<dxSharedContext> sharedContext);
~dxRenderCommand(); ~dxRenderCommand();
virtual void SwapBuffers() override; virtual void SwapBuffers() override;

View file

@ -8,40 +8,40 @@
namespace Light { namespace Light {
dxShader::dxShader(const std::string& vertexSource, const std::string& pixelSource, void* sharedContext) dxShader::dxShader(const std::string& vertexSource, const std::string& pixelSource, std::shared_ptr<dxSharedContext> sharedContext)
: m_Context(sharedContext)
{ {
HRESULT hr;
dxSharedContext* dxContext = static_cast<dxSharedContext*>(sharedContext);
LT_ENGINE_ASSERT(dxContext, "dxShader::dxShader: invalid dxContext");
m_Device = dxContext->device;
m_DeviceContext = dxContext->deviceContext;
Microsoft::WRL::ComPtr<ID3DBlob> ps = nullptr, vsErr = nullptr, psErr = nullptr; Microsoft::WRL::ComPtr<ID3DBlob> ps = nullptr, vsErr = nullptr, psErr = nullptr;
// compile shaders
HRESULT hr;
DXC(D3DCompile(vertexSource.c_str(), vertexSource.length(), NULL, nullptr, nullptr, "main", "vs_4_0", NULL, NULL, &m_VertexBlob, &vsErr)); DXC(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)); DXC(D3DCompile(pixelSource.c_str(), pixelSource.length(), NULL, nullptr, nullptr, "main", "ps_4_0", NULL, NULL, &ps, &psErr));
// 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: vertex shader compile error: {}", (char*)psErr->GetBufferPointer());
DXC(m_Device->CreateVertexShader(m_VertexBlob->GetBufferPointer(), m_VertexBlob->GetBufferSize(), NULL, &m_VertexShader)); // create shaders
DXC(m_Device->CreatePixelShader(ps->GetBufferPointer(), ps->GetBufferSize(), NULL, &m_PixelShader)); DXC(m_Context->device->CreateVertexShader(m_VertexBlob->GetBufferPointer(), m_VertexBlob->GetBufferSize(), NULL, &m_VertexShader));
DXC(m_Context->device->CreatePixelShader(ps->GetBufferPointer(), ps->GetBufferSize(), NULL, &m_PixelShader));
} }
dxShader::~dxShader() dxShader::~dxShader()
{ {
UnBind();
} }
void dxShader::Bind() void dxShader::Bind()
{ {
m_DeviceContext->VSSetShader(m_VertexShader.Get(), nullptr, 0u); m_Context->deviceContext->VSSetShader(m_VertexShader.Get(), nullptr, 0u);
m_DeviceContext->PSSetShader(m_PixelShader.Get(), nullptr, 0u); m_Context->deviceContext->PSSetShader(m_PixelShader.Get(), nullptr, 0u);
} }
void dxShader::UnBind() void dxShader::UnBind()
{ {
m_Context->deviceContext->VSSetShader(nullptr, nullptr, 0u);
m_Context->deviceContext->PSSetShader(nullptr, nullptr, 0u);
} }
} }

View file

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "Base.h" #include "Base.h"
#include "dxBase.h"
#include "Graphics/Shader.h" #include "Graphics/Shader.h"
#include <d3d11.h> #include <d3d11.h>
@ -9,18 +8,19 @@
namespace Light { namespace Light {
class dxSharedContext;
class dxShader : public Shader class dxShader : public Shader
{ {
private: private:
std::shared_ptr<dxSharedContext> m_Context;
Microsoft::WRL::ComPtr<ID3D11VertexShader> m_VertexShader; Microsoft::WRL::ComPtr<ID3D11VertexShader> m_VertexShader;
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_PixelShader; Microsoft::WRL::ComPtr<ID3D11PixelShader> m_PixelShader;
Microsoft::WRL::ComPtr<ID3D11Device> m_Device;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_DeviceContext;
Microsoft::WRL::ComPtr<ID3DBlob> m_VertexBlob; Microsoft::WRL::ComPtr<ID3DBlob> m_VertexBlob;
public: public:
dxShader(const std::string& vertexSource, const std::string& pixelSource, void* sharedContext); dxShader(const std::string& vertexSource, const std::string& pixelSource, std::shared_ptr<dxSharedContext> sharedContext);
~dxShader(); ~dxShader();
void Bind() override; void Bind() override;

View file

@ -1,19 +1,29 @@
#pragma once #pragma once
#include "Base.h" #include "Base.h"
#include "dxBase.h" #include "Graphics/SharedContext.h"
#include <d3d11.h> #include <d3d11.h>
#include <wrl.h> #include <wrl.h>
namespace Light { namespace Light {
struct dxSharedContext // #todo:
class dxSharedContext : public SharedContext
{ {
public:
dxSharedContext(Microsoft::WRL::ComPtr<ID3D11Device> _device,
Microsoft::WRL::ComPtr<ID3D11DeviceContext> _deviceContext,
Microsoft::WRL::ComPtr<IDXGISwapChain> _swapChain,
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> _renderTargetView)
: device(_device), deviceContext(_deviceContext), swapChain(_swapChain), renderTargetView(_renderTargetView)
{
}
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;
Microsoft::WRL::ComPtr<ID3D11Device> device;
}; };
} }

View file

@ -13,24 +13,22 @@
namespace Light { namespace Light {
dxUserInterface::dxUserInterface(GLFWwindow* windowHandle, void* sharedContext) dxUserInterface::dxUserInterface(GLFWwindow* windowHandle, std::shared_ptr<dxSharedContext> sharedContext)
{ {
// set dxContext // create context
dxSharedContext* dxContext = static_cast<dxSharedContext*>(sharedContext);
LT_ENGINE_ASSERT(dxContext, "dxUserInterface::dxUserInterface: invalid sharedContext");
m_DeviceContext = dxContext->deviceContext;
m_Device = dxContext->device;
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
// configure io
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
// style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
// init
ImGui_ImplWin32_Init(glfwGetWin32Window(windowHandle)); ImGui_ImplWin32_Init(glfwGetWin32Window(windowHandle));
ImGui_ImplDX11_Init(m_Device.Get(), m_DeviceContext.Get()); ImGui_ImplDX11_Init(sharedContext->device.Get(), sharedContext->deviceContext.Get());
} }
dxUserInterface::~dxUserInterface() dxUserInterface::~dxUserInterface()
@ -46,7 +44,7 @@ namespace Light {
ImGui_ImplWin32_NewFrame(); ImGui_ImplWin32_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
// TEMP //* TEMP_ IMGUI DEBUG WINDOW _TEMP *//
ImGui::ShowDemoWindow(); ImGui::ShowDemoWindow();
} }
@ -58,6 +56,7 @@ namespace Light {
void dxUserInterface::LogDebugData() void dxUserInterface::LogDebugData()
{ {
// #todo: improve
LT_ENGINE_INFO("________________________________________"); LT_ENGINE_INFO("________________________________________");
LT_ENGINE_INFO("UserInterface::"); LT_ENGINE_INFO("UserInterface::");
LT_ENGINE_INFO(" API : ImGui"); LT_ENGINE_INFO(" API : ImGui");

View file

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "Base.h" #include "Base.h"
#include "dxBase.h"
#include "UserInterface/UserInterface.h" #include "UserInterface/UserInterface.h"
struct GLFWwindow; struct GLFWwindow;
@ -11,14 +10,12 @@ struct GLFWwindow;
namespace Light { namespace Light {
class dxSharedContext;
class dxUserInterface : public UserInterface class dxUserInterface : public UserInterface
{ {
private:
Microsoft::WRL::ComPtr<ID3D11Device> m_Device;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_DeviceContext;
public: public:
dxUserInterface(GLFWwindow* windowHandle, void* sharedContext); dxUserInterface(GLFWwindow* windowHandle, std::shared_ptr<dxSharedContext> sharedContext);
~dxUserInterface(); ~dxUserInterface();
void Begin() override; void Begin() override;

View file

@ -6,68 +6,75 @@
namespace Light { namespace Light {
dxVertexLayout::dxVertexLayout(Shader* shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, void* sharedContext) dxVertexLayout::dxVertexLayout(Shader* shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, std::shared_ptr<dxSharedContext> sharedContext)
: m_Context(sharedContext)
{ {
HRESULT hr;
dxSharedContext* dxContext = static_cast<dxSharedContext*>(sharedContext);
LT_ENGINE_ASSERT(dxContext, "dxShader::dxShader: invalid dxContext");
m_Device = dxContext->device;
m_DeviceContext = dxContext->deviceContext;
// local
std::vector<D3D11_INPUT_ELEMENT_DESC> inputElementsDesc; std::vector<D3D11_INPUT_ELEMENT_DESC> inputElementsDesc;
inputElementsDesc.reserve(elements.size()); inputElementsDesc.reserve(elements.size());
// extract elements desc
for (const auto& element : elements) for (const auto& element : elements)
{ {
inputElementsDesc.emplace_back(D3D11_INPUT_ELEMENT_DESC{ inputElementsDesc.emplace_back(D3D11_INPUT_ELEMENT_DESC{
element.first.c_str(), element.first.c_str(),
0u, 0u,
GetDxgiFormat(element.second), GetDxgiFormat(element.second),
0u, 0u,
D3D11_APPEND_ALIGNED_ELEMENT, D3D11_APPEND_ALIGNED_ELEMENT,
D3D11_INPUT_PER_VERTEX_DATA, D3D11_INPUT_PER_VERTEX_DATA,
0u }); 0u });
} }
// #todo: take in shared_ptr
dxShader* dxpShader = static_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");
DXC(m_Device->CreateInputLayout(&inputElementsDesc[0], inputElementsDesc.size(), dxpShader->GetVertexBlob().Get()->GetBufferPointer(), dxpShader->GetVertexBlob().Get()->GetBufferSize(), &m_InputLayout)); // create input layout ( vertex layout )
HRESULT hr;
DXC(m_Context->device->CreateInputLayout(&inputElementsDesc[0], inputElementsDesc.size(), dxpShader->GetVertexBlob().Get()->GetBufferPointer(), dxpShader->GetVertexBlob().Get()->GetBufferSize(), &m_InputLayout));
} }
dxVertexLayout::~dxVertexLayout() dxVertexLayout::~dxVertexLayout()
{ {
UnBind();
} }
void dxVertexLayout::Bind() void dxVertexLayout::Bind()
{ {
m_DeviceContext->IASetInputLayout(m_InputLayout.Get()); m_Context->deviceContext->IASetInputLayout(m_InputLayout.Get());
} }
void dxVertexLayout::UnBind() void dxVertexLayout::UnBind()
{ {
m_Context->deviceContext->IASetInputLayout(nullptr);
} }
DXGI_FORMAT dxVertexLayout::GetDxgiFormat(VertexElementType type) DXGI_FORMAT dxVertexLayout::GetDxgiFormat(VertexElementType type)
{ {
switch (type) switch (type)
{ {
// 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;
case Light::VertexElementType::Int3: return DXGI_FORMAT_R32G32B32_SINT; case Light::VertexElementType::Int3: return DXGI_FORMAT_R32G32B32_SINT;
case Light::VertexElementType::Int4: return DXGI_FORMAT_R32G32B32A32_SINT; case Light::VertexElementType::Int4: return DXGI_FORMAT_R32G32B32A32_SINT;
// uint
case Light::VertexElementType::UInt1: return DXGI_FORMAT_R32_UINT; case Light::VertexElementType::UInt1: return DXGI_FORMAT_R32_UINT;
case Light::VertexElementType::UInt2: return DXGI_FORMAT_R32G32_UINT; case Light::VertexElementType::UInt2: return DXGI_FORMAT_R32G32_UINT;
case Light::VertexElementType::UInt3: return DXGI_FORMAT_R32G32B32_UINT; case Light::VertexElementType::UInt3: return DXGI_FORMAT_R32G32B32_UINT;
case Light::VertexElementType::UInt4: return DXGI_FORMAT_R32G32B32A32_UINT; case Light::VertexElementType::UInt4: return DXGI_FORMAT_R32G32B32A32_UINT;
// float
case Light::VertexElementType::Float1: return DXGI_FORMAT_R32_FLOAT; case Light::VertexElementType::Float1: return DXGI_FORMAT_R32_FLOAT;
case Light::VertexElementType::Float2: return DXGI_FORMAT_R32G32_FLOAT; case Light::VertexElementType::Float2: return DXGI_FORMAT_R32G32_FLOAT;
case Light::VertexElementType::Float3: return DXGI_FORMAT_R32G32B32_FLOAT; case Light::VertexElementType::Float3: return DXGI_FORMAT_R32G32B32_FLOAT;
case Light::VertexElementType::Float4: return DXGI_FORMAT_R32G32B32A32_FLOAT; case Light::VertexElementType::Float4: return DXGI_FORMAT_R32G32B32A32_FLOAT;
// TODO: // #todo:
case Light::VertexElementType::Double1: case Light::VertexElementType::Double1:
case Light::VertexElementType::Double2: case Light::VertexElementType::Double2:
case Light::VertexElementType::Double3: case Light::VertexElementType::Double3:

View file

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "Base.h" #include "Base.h"
#include "dxBase.h"
#include "Graphics/VertexLayout.h" #include "Graphics/VertexLayout.h"
#include <d3d11.h> #include <d3d11.h>
@ -10,17 +9,17 @@
namespace Light { namespace Light {
class Shader; class Shader;
class dxSharedContext;
class dxVertexLayout : public VertexLayout class dxVertexLayout : public VertexLayout
{ {
private: private:
std::shared_ptr<dxSharedContext> m_Context;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_InputLayout; Microsoft::WRL::ComPtr<ID3D11InputLayout> m_InputLayout;
Microsoft::WRL::ComPtr<ID3D11Device> m_Device;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_DeviceContext;
public: public:
dxVertexLayout(Shader* shader, const std::vector<std::pair<std::string, VertexElementType>>& elements, void* sharedContext); dxVertexLayout(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

@ -38,9 +38,11 @@ namespace Light {
glIndexBuffer::glIndexBuffer(unsigned int* indices, unsigned int count) glIndexBuffer::glIndexBuffer(unsigned int* indices, unsigned int count)
{ {
// generate indices if not provided
bool hasIndices = !!indices; bool hasIndices = !!indices;
if (!hasIndices) if (!hasIndices)
{ {
// 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::glIndexBuffer: count should be divisible by 6 when no indices is provided");
@ -48,6 +50,7 @@ namespace Light {
count = count + (6 - (count % 6)); count = count + (6 - (count % 6));
} }
// create indices
indices = new unsigned int[count]; indices = new unsigned int[count];
unsigned int offset = 0; unsigned int offset = 0;
for (unsigned int i = 0; i < count; i += 6) for (unsigned int i = 0; i < count; i += 6)
@ -64,9 +67,11 @@ namespace Light {
} }
} }
// create buffer
glCreateBuffers(1, &m_BufferID); glCreateBuffers(1, &m_BufferID);
glNamedBufferData(m_BufferID, count * sizeof(unsigned int), indices, GL_STATIC_DRAW); glNamedBufferData(m_BufferID, count * sizeof(unsigned int), indices, GL_STATIC_DRAW);
// delete indices
if (!hasIndices) if (!hasIndices)
delete[] indices; delete[] indices;
} }

View file

@ -84,6 +84,7 @@ namespace Light {
id); id);
LT_ENGINE_WARN(" {}", message); LT_ENGINE_WARN(" {}", message);
return; return;
case GL_DEBUG_SEVERITY_NOTIFICATION: case GL_DEBUG_SEVERITY_NOTIFICATION:
LT_ENGINE_TRACE("glMessageCallback: Severity: {} :: Source: {} :: Type: {} :: ID: {}", LT_ENGINE_TRACE("glMessageCallback: Severity: {} :: Source: {} :: Type: {} :: ID: {}",
Stringifier::glDebugMsgSeverity(severity), Stringifier::glDebugMsgSeverity(severity),

View file

@ -9,6 +9,7 @@ namespace Light {
{ {
m_ShaderID = glCreateProgram(); m_ShaderID = glCreateProgram();
// 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 pixelShader = glCreateShader(GL_FRAGMENT_SHADER);
@ -16,13 +17,15 @@ namespace Light {
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
glShaderSource(vertexShader, 1, &lVertexSource, NULL); glShaderSource(vertexShader, 1, &lVertexSource, NULL);
glShaderSource(pixelShader, 1, &lFragmentSource, NULL); glShaderSource(pixelShader, 1, &lFragmentSource, NULL);
// compile shaders
glCompileShader(vertexShader); glCompileShader(vertexShader);
glCompileShader(pixelShader); glCompileShader(pixelShader);
// TEMP //* TEMP__ HANDLE SHADER COMPILE FAILURE __TEMP **//
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)
@ -47,16 +50,18 @@ namespace Light {
glDeleteShader(pixelShader); glDeleteShader(pixelShader);
} }
// TEMP //* TEMP__ HANDLE SHADER COMPILE FAILURE __TEMP **//
// attach and link shaders to the shader program
glAttachShader(m_ShaderID, vertexShader); glAttachShader(m_ShaderID, vertexShader);
glAttachShader(m_ShaderID, pixelShader); glAttachShader(m_ShaderID, pixelShader);
glLinkProgram(m_ShaderID); glLinkProgram(m_ShaderID);
// delete shaders (free memory)
glDeleteShader(vertexShader); glDeleteShader(vertexShader);
glDeleteShader(pixelShader); glDeleteShader(pixelShader);
// TODO: validate program // #todo: validate program
} }
glShader::~glShader() glShader::~glShader()

View file

@ -0,0 +1,12 @@
#pragma once
#include "Base.h"
namespace Light {
struct glSharedContext
{
};
}

View file

@ -9,13 +9,18 @@ namespace Light {
glUserInterface::glUserInterface(GLFWwindow* windowHandle) glUserInterface::glUserInterface(GLFWwindow* windowHandle)
{ {
// create context
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
// configure io
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
// style color
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
// init
ImGui_ImplGlfw_InitForOpenGL(windowHandle, false); ImGui_ImplGlfw_InitForOpenGL(windowHandle, false);
ImGui_ImplOpenGL3_Init(); ImGui_ImplOpenGL3_Init();
} }
@ -33,7 +38,7 @@ namespace Light {
ImGui_ImplGlfw_NewFrame(); ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
// TEMP //* TEMP_ IMGUI DEBUG WINDOW _TEMP *//
ImGui::ShowDemoWindow(); ImGui::ShowDemoWindow();
} }
@ -45,6 +50,7 @@ namespace Light {
void glUserInterface::LogDebugData() void glUserInterface::LogDebugData()
{ {
// #todo: improve
LT_ENGINE_INFO("________________________________________"); LT_ENGINE_INFO("________________________________________");
LT_ENGINE_INFO("UserInterface::"); LT_ENGINE_INFO("UserInterface::");
LT_ENGINE_INFO(" API : ImGui"); LT_ENGINE_INFO(" API : ImGui");

View file

@ -13,22 +13,26 @@ namespace Light {
LT_ENGINE_ASSERT(dynamic_cast<glVertexBuffer*>(buffer), "glVertexLayout::glVertexLayout: failed to cast VertexBuffer to glVertexBuffer"); LT_ENGINE_ASSERT(dynamic_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");
// elements desc // local
std::vector<glVertexElementDesc> elementsDesc; std::vector<glVertexElementDesc> elementsDesc;
elementsDesc.reserve(elements.size());
unsigned int stride = 0u; unsigned int stride = 0u;
// extract elements desc
for(const auto& element : elements) for(const auto& element : elements)
{ {
elementsDesc.push_back(GetElementDesc(element.second, stride)); elementsDesc.push_back(GetElementDesc(element.second, stride));
stride += elementsDesc.back().typeSize * elementsDesc.back().count; stride += elementsDesc.back().typeSize * elementsDesc.back().count;
} }
// prepare // create vertex array
glCreateVertexArrays(1, &m_ArrayID); glCreateVertexArrays(1, &m_ArrayID);
// bind buffer and array
buffer->Bind(); buffer->Bind();
Bind(); Bind();
// vertex attributes // enable vertex attributes
unsigned int index = 0u; unsigned int index = 0u;
for (const auto& elementDesc : elementsDesc) for (const auto& elementDesc : elementsDesc)
{ {
@ -56,25 +60,30 @@ namespace Light {
{ {
switch (type) switch (type)
{ {
// int
case VertexElementType::Int1: return { GL_INT, 1, sizeof(int), offset }; case VertexElementType::Int1: return { GL_INT, 1, sizeof(int), offset };
case VertexElementType::Int2: return { GL_INT, 2, sizeof(int), offset }; case VertexElementType::Int2: return { GL_INT, 2, sizeof(int), offset };
case VertexElementType::Int3: return { GL_INT, 3, sizeof(int), offset }; case VertexElementType::Int3: return { GL_INT, 3, sizeof(int), offset };
case VertexElementType::Int4: return { GL_INT, 4, sizeof(int), offset }; case VertexElementType::Int4: return { GL_INT, 4, sizeof(int), offset };
// uint
case VertexElementType::UInt1: return { GL_UNSIGNED_INT, 1, sizeof(unsigned int), offset }; case VertexElementType::UInt1: return { GL_UNSIGNED_INT, 1, sizeof(unsigned int), offset };
case VertexElementType::UInt2: return { GL_UNSIGNED_INT, 2, sizeof(unsigned int), offset }; case VertexElementType::UInt2: return { GL_UNSIGNED_INT, 2, sizeof(unsigned int), offset };
case VertexElementType::UInt3: return { GL_UNSIGNED_INT, 3, sizeof(unsigned int), offset }; case VertexElementType::UInt3: return { GL_UNSIGNED_INT, 3, sizeof(unsigned int), offset };
case VertexElementType::UInt4: return { GL_UNSIGNED_INT, 4, sizeof(unsigned int), offset }; case VertexElementType::UInt4: return { GL_UNSIGNED_INT, 4, sizeof(unsigned int), offset };
// float
case VertexElementType::Float1: return { GL_FLOAT, 1, sizeof(float), offset }; case VertexElementType::Float1: return { GL_FLOAT, 1, sizeof(float), offset };
case VertexElementType::Float2: return { GL_FLOAT, 2, sizeof(float), offset }; case VertexElementType::Float2: return { GL_FLOAT, 2, sizeof(float), offset };
case VertexElementType::Float3: return { GL_FLOAT, 3, sizeof(float), offset }; case VertexElementType::Float3: return { GL_FLOAT, 3, sizeof(float), offset };
case VertexElementType::Float4: return { GL_FLOAT, 4, sizeof(float), offset }; case VertexElementType::Float4: return { GL_FLOAT, 4, sizeof(float), offset };
// double
case VertexElementType::Double1: return { GL_DOUBLE, 1, sizeof(float), offset }; case VertexElementType::Double1: return { GL_DOUBLE, 1, sizeof(float), offset };
case VertexElementType::Double2: return { GL_DOUBLE, 2, sizeof(float), offset }; case VertexElementType::Double2: return { GL_DOUBLE, 2, sizeof(float), offset };
case VertexElementType::Double3: return { GL_DOUBLE, 3, sizeof(float), offset }; case VertexElementType::Double3: return { GL_DOUBLE, 3, sizeof(float), offset };
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 vertex element type");
return {}; return {};

View file

@ -20,16 +20,20 @@ namespace Light {
wWindow::wWindow(std::function<void(Event&)> callback) wWindow::wWindow(std::function<void(Event&)> callback)
: m_EventCallback(callback) : m_EventCallback(callback)
{ {
// init glfw
LT_ENGINE_ASSERT(glfwInit(), "wWindow::wWindow: failed to initialize glfw"); LT_ENGINE_ASSERT(glfwInit(), "wWindow::wWindow: failed to initialize glfw");
// create window
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 glfw window");
// manage events
glfwSetWindowUserPointer(m_Handle, &m_EventCallback); glfwSetWindowUserPointer(m_Handle, &m_EventCallback);
BindGlfwEvents(); BindGlfwEvents();
// create graphics context
m_GraphicsContext = std::unique_ptr<GraphicsContext>(GraphicsContext::Create(GraphicsAPI::DirectX, m_Handle)); m_GraphicsContext = std::unique_ptr<GraphicsContext>(GraphicsContext::Create(GraphicsAPI::DirectX, m_Handle));
LT_ENGINE_ASSERT(m_GraphicsContext, "wWindow::wWindow: failed to create graphics context"); LT_ENGINE_ASSERT(m_GraphicsContext, "wWindow::wWindow: failed to create graphics context");
} }
@ -43,7 +47,7 @@ namespace Light {
{ {
m_Properties = properties; m_Properties = properties;
glfwSetWindowSize(m_Handle, properties.size.x, properties.size.y); glfwSetWindowSize(m_Handle, properties.size.x, properties.size.y); // #todo: check if this triggers an event
glfwSetWindowTitle(m_Handle, properties.title.c_str()); glfwSetWindowTitle(m_Handle, properties.title.c_str());
glfwSwapInterval((int)properties.vsync); glfwSwapInterval((int)properties.vsync);
} }
@ -91,10 +95,10 @@ namespace Light {
glfwSwapInterval(m_Properties.vsync); glfwSwapInterval(m_Properties.vsync);
} }
void wWindow::SetSize(const glm::uvec2& size) void wWindow::SetSize(const glm::uvec2& size, bool add /*= false*/)
{ {
m_Properties.size.x = size.x == 0u ? m_Properties.size.x : size.x; m_Properties.size.x = size.x == 0u ? m_Properties.size.x : add ? m_Properties.size.x + size.x : size.x;
m_Properties.size.y = size.y == 0u ? m_Properties.size.y : size.y; m_Properties.size.y = size.y == 0u ? m_Properties.size.y : add ? 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);
} }
@ -136,10 +140,10 @@ namespace Light {
}); });
// Window Events // // Window Events //
glfwSetWindowCloseCallback(m_Handle, [](GLFWwindow* window) 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);
callback(WindowClosedEvent()); callback(WindowMovedEvent(xpos, ypos));
}); });
glfwSetWindowSizeCallback(m_Handle, [](GLFWwindow* window, int width, int height) glfwSetWindowSizeCallback(m_Handle, [](GLFWwindow* window, int width, int height)
@ -148,10 +152,10 @@ namespace Light {
callback(WindowResizedEvent(width, height)); callback(WindowResizedEvent(width, height));
}); });
glfwSetWindowPosCallback(m_Handle, [](GLFWwindow* window, int xpos, int ypos) 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);
callback(WindowMovedEvent(xpos, ypos)); callback(WindowClosedEvent());
}); });
glfwSetWindowFocusCallback(m_Handle, [](GLFWwindow* window, int focus) glfwSetWindowFocusCallback(m_Handle, [](GLFWwindow* window, int focus)

View file

@ -29,7 +29,7 @@ namespace Light {
void SetTitle(const std::string& title) override; void SetTitle(const std::string& title) override;
void SetSize(const glm::uvec2& size) override; void SetSize(const glm::uvec2& size, bool add = 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;

0
Sandbox/Log.txt Normal file
View file

View file

@ -1,10 +1,10 @@
[Window][Debug##Default] [Window][Debug##Default]
Pos=60,60 Pos=60,-18
Size=400,400 Size=400,400
Collapsed=0 Collapsed=0
[Window][Dear ImGui Demo] [Window][Dear ImGui Demo]
Pos=1,-3 Pos=-16,5
Size=405,290 Size=405,290
Collapsed=0 Collapsed=0