Skip to content

Commit

Permalink
refactor(gfx/UniformBinding): cleaned up binding typecasts
Browse files Browse the repository at this point in the history
  • Loading branch information
tomezpl committed Oct 18, 2024
1 parent 422c1ee commit 7ed9c8a
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 217 deletions.
4 changes: 2 additions & 2 deletions src/examples/demo/DemoApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,8 @@ class DemoApp : public system::BaseApp
m_UniformState.projMatrix = m_Camera.BuildPerspectiveMatrix();
m_UniformState.viewMatrix = m_Camera.BuildViewMatrix();

((lepus::gfx::GLMatrixUniformBinding*)api->GetUniform<lepus::gfx::GLMatrixUniformBinding>(LEPUS_GFX_UNIFORMS_GLOBAL_PROJECTION_MATRIX))->Value((float*)m_UniformState.projMatrix.data());
((lepus::gfx::GLMatrixUniformBinding*)api->GetUniform<lepus::gfx::GLMatrixUniformBinding>(LEPUS_GFX_UNIFORMS_GLOBAL_VIEW_MATRIX))->Value((float*)m_UniformState.viewMatrix.data());
api->GetUniform<lepus::gfx::GLMatrixUniformBinding>(LEPUS_GFX_UNIFORMS_GLOBAL_PROJECTION_MATRIX)->Value(m_UniformState.projMatrix.data());
api->GetUniform<lepus::gfx::GLMatrixUniformBinding>(LEPUS_GFX_UNIFORMS_GLOBAL_VIEW_MATRIX)->Value(m_UniformState.viewMatrix.data());
}

inline void Tick(float deltaTime, const KeyboardState& keys)
Expand Down
4 changes: 2 additions & 2 deletions src/lepus/gfx/GraphicsEngine/Apis/ApiGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ namespace lepus
void SetupUniforms();

private:
inline void* GetUniformInternal(char* name) override
inline void* GetUniformInternal(const char* name) override
{
size_t targetKeyLength = strlen(name);

Expand Down Expand Up @@ -147,7 +147,7 @@ namespace lepus
void Shutdown() override;
};

template const lepus::gfx::GLUniformBinding<void*>* GraphicsApi::GetUniform<lepus::gfx::GLUniformBinding<void*>*>(char* name);
template lepus::gfx::GLUniformBinding<void*>* const GraphicsApi::GetUniform<lepus::gfx::GLUniformBinding<void*>*>(const char* name);

template GraphicsApiGL& GraphicsEngine::GetApi<GraphicsApiGL>();
} // namespace gfx
Expand Down
44 changes: 23 additions & 21 deletions src/lepus/gfx/GraphicsEngine/Apis/ApiGL/Bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,31 @@ namespace lepus
{
namespace gfx
{
class GLMatrixUniformBinding : public GLUniformBinding<float*>
{
public:
GLMatrixUniformBinding(GLint location) : GLUniformBinding(location)
{
Value(new float[4 * 4]);
memset(Value(), 0, 4 * 4 * sizeof(float));
}
class GLMatrixUniformBinding : public GLUniformBinding<float*>
{
public:
explicit GLMatrixUniformBinding(GLint location)
: GLUniformBinding(location)
{
Value(new float[4 * 4]);
memset(Value(), 0, 4 * 4 * sizeof(float));
}

inline UniformType Type() { return UniformType::MATRIX4; }
};
inline UniformType Type() override { return UniformType::MATRIX4; }
};

class GLFloatUniformBinding : public GLUniformBinding<float>
{
public:
GLFloatUniformBinding(GLint location) : GLUniformBinding(location)
{
Value(0.f);
}
class GLFloatUniformBinding : public GLUniformBinding<float>
{
public:
explicit GLFloatUniformBinding(GLint location)
: GLUniformBinding(location)
{
Value(0.f);
}

inline UniformType Type() { return UniformType::FLOAT; }
};
}
}
inline UniformType Type() override { return UniformType::FLOAT; }
};
} // namespace gfx
} // namespace lepus

#endif
294 changes: 147 additions & 147 deletions src/lepus/gfx/GraphicsEngine/GraphicsApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,154 +9,154 @@

namespace lepus
{
namespace gfx
namespace gfx
{
/// @brief Types of graphics APIs.
/// These are passed in GraphicsApiOptions structs to indicate which API should be initialised by the GraphicsEngine.
enum GraphicsApiType
{
/// @brief Types of graphics APIs.
/// These are passed in GraphicsApiOptions structs to indicate which API should be initialised by the GraphicsEngine.
enum GraphicsApiType
{
/// @brief Do not use outside of unit tests.
GraphicsApiTest = -1,

/// @brief Unspecified graphics API. Results in an exception, or undefined behaviour.
GraphicsApiUnknown = 0,

/// @brief Modern OpenGL implementation.
GraphicsApiOpenGL,

/// @brief Not implemented.
GraphicsApiVulkan
};

class GraphicsApiOptions
{
public:
/// @brief Indicates what API type this options object is used for.
/// @return The GraphicsApiType enum value for this GraphicsApiOptions.
virtual GraphicsApiType GetType() { return GraphicsApiUnknown; }

/// @brief Main viewport used by the application.
lepus::types::Viewport mainViewport = {};

virtual ~GraphicsApiOptions() {}
};

/// @brief API wrapper to be used by GraphicsEngine.
/// The purpose of this class is to obfuscate API-specific calls,
/// so that GraphicsEngine code can focus on implementing drawing techniques,
/// not a variety of D3D/GL/VK methods.
class GraphicsApi
{
private:
bool m_ShutdownCalled;

protected:
GraphicsApiOptions* m_Options;

protected:
/// @brief Performs internal, boilerplate setup for all API wrappers.
/// @tparam TGraphicsApiOptions An options type derived from GraphicsApiOptions for a specific graphics API.
/// @param options Pointer to an options object (using the type matching the requested graphics API).
template <class TGraphicsApiOptions>
void InitInternal(TGraphicsApiOptions* options)
{
// TODO: This might be a bad idea actually. If options contain pointers, they will be reused, and ownership conflicts may emerge.
const size_t optionsSz = sizeof(TGraphicsApiOptions);
m_Options = new TGraphicsApiOptions();
memcpy(m_Options, options, optionsSz);
}

/// @brief Internal API-specific method for retrieving a native handle to a uniform object.
/// @param name The name of the uniform to fetch.
/// @return API-specific handle for a uniform of a given type.
virtual void* GetUniformInternal(char* name) = 0;

public:
/// @brief Default constructor. Does nothing, so Init(GraphicsApiOptions*) needs to be called manually.
GraphicsApi()
{
m_Options = nullptr;
m_ShutdownCalled = false;
}

GraphicsApi(GraphicsApiOptions* options)
{
m_Options = nullptr;
GraphicsApi::Init(options);
}

/// @brief Initialises the API with the provided
/// options.
/// @param options An options object using a
/// GraphicsApiOptions type for the requested API. Make
/// sure you don't pass a pointer to a new object here.
/// Implementations of this class must copy the options,
/// not reference a pointer, so there's a potential risk
/// of a memory leak there.
virtual inline void Init(GraphicsApiOptions* options)
{
assert(options == nullptr);

InitInternal(options);
m_ShutdownCalled = false;
}

/// @brief Obtains the options object this GraphicsApi was initialised with.
///
/// @tparam TGraphicsApiOptions An options type derived from GraphicsApiOptions
/// (typically a GraphicsApiOptions derived class matching the API).
///
/// @return A reference to the internal options object.
/// cast to the requested API-specific TGraphicsApiOptions type.
template <class TGraphicsApiOptions>
TGraphicsApiOptions& GetOptions()
{
// The internal options object NEEDS to have been allocated.
assert(m_Options != nullptr);

return *(TGraphicsApiOptions*)m_Options;
}

virtual void CreatePipeline() = 0;

/// @brief Gets a Lepus UniformBinding wrapper for an API-specific uniform with the given name.
/// @tparam TUniformHandle API-specific handle type used for this type of uniform.
/// @tparam TUniformBinding UniformBinding implementation
/// @param name Name of the uniform to fetch.
/// @return A UniformBinding wrapper for the named uniform object.
template<typename TUniformHandle = void*, class TUniformBinding = lepus::gfx::UniformBinding<TUniformHandle>>
inline const TUniformBinding* GetUniform(char* name)
{
return reinterpret_cast<const TUniformBinding*>(GetUniformInternal(name));
}

/// @brief Applies uniforms in the shader.
/// Implementations can fire & forget by issuing this before every draw, but it might be worth having a mechanism to invalidate uniforms
/// and only update them once they're marked as dirty.
virtual void UpdateUniforms() = 0;

virtual void Draw() = 0;

virtual void ClearFrameBuffer(float r, float g, float b) = 0;

/// @brief Invokes any API-specific code for back/front buffer swap.
/// This is usually a task for the Windowing class; GraphicsApi provides a dummy method
/// that can perform the API-specific swap chain operations before the call to Windowing,
/// but it does not need to be used or implemented.
virtual void SwapBuffers() {}

virtual void Shutdown()
{
m_ShutdownCalled = true;
}

virtual ~GraphicsApi()
{
assert(m_ShutdownCalled == true);
Shutdown();
}
};
} // namespace gfx
/// @brief Do not use outside of unit tests.
GraphicsApiTest = -1,

/// @brief Unspecified graphics API. Results in an exception, or undefined behaviour.
GraphicsApiUnknown = 0,

/// @brief Modern OpenGL implementation.
GraphicsApiOpenGL,

/// @brief Not implemented.
GraphicsApiVulkan
};

class GraphicsApiOptions
{
public:
/// @brief Indicates what API type this options object is used for.
/// @return The GraphicsApiType enum value for this GraphicsApiOptions.
virtual GraphicsApiType GetType() { return GraphicsApiUnknown; }

/// @brief Main viewport used by the application.
lepus::types::Viewport mainViewport = {};

virtual ~GraphicsApiOptions() {}
};

/// @brief API wrapper to be used by GraphicsEngine.
/// The purpose of this class is to obfuscate API-specific calls,
/// so that GraphicsEngine code can focus on implementing drawing techniques,
/// not a variety of D3D/GL/VK methods.
class GraphicsApi
{
private:
bool m_ShutdownCalled;

protected:
GraphicsApiOptions* m_Options;

protected:
/// @brief Performs internal, boilerplate setup for all API wrappers.
/// @tparam TGraphicsApiOptions An options type derived from GraphicsApiOptions for a specific graphics API.
/// @param options Pointer to an options object (using the type matching the requested graphics API).
template <class TGraphicsApiOptions>
void InitInternal(TGraphicsApiOptions* options)
{
// TODO: This might be a bad idea actually. If options contain pointers, they will be reused, and ownership conflicts may emerge.
const size_t optionsSz = sizeof(TGraphicsApiOptions);
m_Options = new TGraphicsApiOptions();
memcpy(m_Options, options, optionsSz);
}

/// @brief Internal API-specific method for retrieving a native handle to a uniform object.
/// @param name The name of the uniform to fetch.
/// @return API-specific handle for a uniform of a given type.
virtual void* GetUniformInternal(const char* name) = 0;

public:
/// @brief Default constructor. Does nothing, so Init(GraphicsApiOptions*) needs to be called manually.
GraphicsApi()
{
m_Options = nullptr;
m_ShutdownCalled = false;
}

GraphicsApi(GraphicsApiOptions* options)
{
m_Options = nullptr;
GraphicsApi::Init(options);
}

/// @brief Initialises the API with the provided
/// options.
/// @param options An options object using a
/// GraphicsApiOptions type for the requested API. Make
/// sure you don't pass a pointer to a new object here.
/// Implementations of this class must copy the options,
/// not reference a pointer, so there's a potential risk
/// of a memory leak there.
virtual inline void Init(GraphicsApiOptions* options)
{
assert(options == nullptr);

InitInternal(options);
m_ShutdownCalled = false;
}

/// @brief Obtains the options object this GraphicsApi was initialised with.
///
/// @tparam TGraphicsApiOptions An options type derived from GraphicsApiOptions
/// (typically a GraphicsApiOptions derived class matching the API).
///
/// @return A reference to the internal options object.
/// cast to the requested API-specific TGraphicsApiOptions type.
template <class TGraphicsApiOptions>
TGraphicsApiOptions& GetOptions()
{
// The internal options object NEEDS to have been allocated.
assert(m_Options != nullptr);

return *(TGraphicsApiOptions*)m_Options;
}

virtual void CreatePipeline() = 0;

/// @brief Gets a Lepus UniformBinding wrapper for an API-specific uniform with the given name.
/// @tparam TUniformHandle API-specific handle type used for this type of uniform.
/// @tparam TUniformBinding UniformBinding implementation
/// @param name Name of the uniform to fetch.
/// @return A UniformBinding wrapper for the named uniform object.
template <typename TUniformHandle = void*, class TUniformBinding = lepus::gfx::UniformBinding<TUniformHandle>>
inline TUniformBinding* const GetUniform(const char* name)
{
return static_cast<TUniformBinding* const>(GetUniformInternal(name));
}

/// @brief Applies uniforms in the shader.
/// Implementations can fire & forget by issuing this before every draw, but it might be worth having a mechanism to invalidate uniforms
/// and only update them once they're marked as dirty.
virtual void UpdateUniforms() = 0;

virtual void Draw() = 0;

virtual void ClearFrameBuffer(float r, float g, float b) = 0;

/// @brief Invokes any API-specific code for back/front buffer swap.
/// This is usually a task for the Windowing class; GraphicsApi provides a dummy method
/// that can perform the API-specific swap chain operations before the call to Windowing,
/// but it does not need to be used or implemented.
virtual void SwapBuffers() {}

virtual void Shutdown()
{
m_ShutdownCalled = true;
}

virtual ~GraphicsApi()
{
assert(m_ShutdownCalled == true);
Shutdown();
}
};
} // namespace gfx
} // namespace lepus

#endif
Loading

0 comments on commit 7ed9c8a

Please sign in to comment.