Assignment 03
September 14, 2026
Objective
This week, I made my Graphics.cpp file platform-independent by introducing a new cRenderer class that provides a platform-independent interface for interacting with buffers. The cMesh class was reworked to use an index buffer and generalized so that multiple meshes and effects can now be initialized.
Gameplay
Download Links
Gameplay Footage
Platform Independence
cRenderer
In order to make Graphics.cpp platform-independent, I created several new interfaces under a new cRenderer class. This class handles the platform specific logic needed for handling buffers: initializing, cleaning, clearing color and depth, and swapping buffers. The declaration of these interfaces can be found in cRenderer.h and the definition of these interfaces can be found in cRenderer.cpp. The declaration of these interfaces can be seen below:
1
2
3
4
5
6
7
8
9
10
class cRenderer
{
public:
cResult Initialize(const sInitializationParameters& i_initializationParameters);
void CleanUp();
void ClearColor(const float x, const float y, const float z, const float a = 1.0f);
void ClearDepth(const float clearToFarDepth = 1.0f);
void SwapFrontAndBackBuffers();
};
This clean, well encapsulated interface allows for Graphics.cpp interact with the buffers in a platform-independent way. Below is an example usage of the platform-independent interfaces.
1
2
s_renderer->ClearColor(1.0f, 0.0f, 0.0f);
s_renderer->ClearDepth();
cEffect
This week, I also took time to improve the the cEffect and cMesh classes. cEffect can now be initialized with provided vertex and fragment shaders, allowing for the creation of multiple of effects that use their own shaders. Below is an example of the animated color fragment shader I made in previous weeks being initialized.
1
2
3
4
5
6
7
8
9
s_animatedColorEffect = new eae6320::Graphics::cEffect();
if (!(result = s_animatedColorEffect->Initialize(
"data/Shaders/Vertex/standard.shader",
"data/Shaders/Fragment/animatedcolor.shader" )))
{
EAE6320_ASSERTF(false, "Can't initialize animated color effect");
return result;
}
The logging message below was used to determine the size of cEffect on both platforms. On the x64 architecture, cEffect is 48 bytes and on the x86 architecture, cEffect is 16 bytes.
1
2
eae6320::Logging::OutputMessage(std::to_string(sizeof(eae6320::Graphics::cEffect)).c_str());
Below is all of the data stored in the cEffect struct, which I do not think can be reduced further. Part of the reason for the significant difference in size between the two platforms is that addresses on x86 architecture are 4 bytes whereas addresses on x64 architecture are 8 bytes. The cRenderState class also has platform specific pointers for the D3D implementation.
1
2
3
4
5
6
7
8
9
10
struct cEffect
{
#if defined( EAE6320_PLATFORM_GL )
GLuint m_programId = 0;
#endif
cShader* m_vertexShader;
cShader* m_fragmentShader;
cRenderState m_renderState;
};
cMesh
The cMesh class had similar improvements this week. cMesh can now be initialized with provided vertex and index data, allowing for the creation of multiple of meshes. Below is an example of the initialization of a square mesh. To initialize a mesh, the user MUST provide the number of vertices, a pointer to vertex data, the number of triangles, and a pointer to the index data.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
s_mesh = new eae6320::Graphics::cMesh();
constexpr auto vertexCount = 4;
constexpr unsigned int triangleCount = 2;
eae6320::Graphics::VertexFormats::sVertex_mesh vertexData[] =
{
0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
uint16_t indexData[] =
{
0, 1, 2,
0, 3, 1
};
if (!(result = s_mesh->Initialize(vertexCount, vertexData, triangleCount, indexData)))
{
EAE6320_ASSERTF(false, "Can't initialize mesh");
return result;
}
The logging message below was used to determine the size of cMesh on both platforms. On the x64 architecture, cMesh is 32 bytes and on the x86 architecture, cMesh is 16 bytes.
1
eae6320::Logging::OutputMessage(std::to_string(sizeof(eae6320::Graphics::cMesh)).c_str());
Below is all of the data stored in the cMesh struct, which I do not think can be reduced further. As stated before, pointers on the x64 platform are 8 bytes. In OpenGL, GLuint is defined as an unsigned int, which is 4 bytes. Since the x64 platform has 4 unsigned int variables, the total size is 16 bytes. The D3D implementation for the x86 platform has 3 pointers and one unsigned int, which comes out to 28 bytes, but includes 4 bytes of padding to keep the addresses aligned to multiples 8.
1
2
3
4
5
6
7
8
9
10
11
12
13
struct cMesh
{
#if defined( EAE6320_PLATFORM_D3D )
cVertexFormat* m_vertexFormat = nullptr;
ID3D11Buffer* m_vertexBuffer = nullptr;
ID3D11Buffer* m_indexBuffer = nullptr;
#elif defined( EAE6320_PLATFORM_GL )
GLuint m_vertexBufferId = 0;
GLuint m_vertexArrayId = 0;
GLuint m_indexBufferId = 0;
#endif
unsigned int m_triangleCount;
};