Lumenarium/foldhaus_renderer.cpp

175 lines
6.3 KiB
C++

internal render_command_buffer
AllocateRenderCommandBuffer (u8* Memory, s32 Size)
{
render_command_buffer Result = {};
Result.CommandMemory = Memory;
Result.CommandMemoryUsed = 0;
Result.CommandMemorySize = Size;
return Result;
}
internal void
Render3DQuadBatch (u8* CommandData, s32 TriCount)
{
DEBUG_TRACK_FUNCTION;
v4* Vertecies = (v4*)(CommandData + BATCH_3D_VERTECIES_OFFSET(TriCount));
v2* UVs = (v2*)(CommandData + BATCH_3D_UVS_OFFSET(TriCount));
v4* Colors = (v4*)(CommandData + BATCH_3D_COLORS_OFFSET(TriCount));
#if IMMEDIATE_MODE_RENDERING
glBegin(GL_TRIANGLES);
for (s32 Tri = 0; Tri < TriCount; Tri++)
{
v4 P0 = Vertecies[BATCH_3D_VERTEX_INDEX(Tri, 0)];
v4 P1 = Vertecies[BATCH_3D_VERTEX_INDEX(Tri, 1)];
v4 P2 = Vertecies[BATCH_3D_VERTEX_INDEX(Tri, 2)];
v2 UV0 = UVs[BATCH_3D_UV_INDEX(Tri, 0)];
v2 UV1 = UVs[BATCH_3D_UV_INDEX(Tri, 1)];
v2 UV2 = UVs[BATCH_3D_UV_INDEX(Tri, 2)];
v4 C0 = Colors[BATCH_3D_COLOR_INDEX(Tri, 0)];
v4 C1 = Colors[BATCH_3D_COLOR_INDEX(Tri, 1)];
v4 C2 = Colors[BATCH_3D_COLOR_INDEX(Tri, 2)];
OpenGLDraw3DTri(P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
}
glEnd();
#else
OpenGLRenderTriBuffer((u8*)Vertecies, 4, UVs, 2, Colors, 4, TriCount * 3);
#endif
}
internal void
Render2DQuadBatch (u8* CommandData, s32 QuadCount)
{
DEBUG_TRACK_FUNCTION;
v2* Vertecies = (v2*)(CommandData + BATCH_2D_VERTECIES_OFFSET(QuadCount));
v2* UVs = (v2*)(CommandData + BATCH_2D_UVS_OFFSET(QuadCount));
v4* Colors = (v4*)(CommandData + BATCH_2D_COLORS_OFFSET(QuadCount));
#if IMMEDIATE_MODE_RENDERING
for (s32 Quad = 0; Quad < QuadCount; Quad++)
{
for (s32 Tri = 0; Tri < 2; Tri++)
{
v2 P0 = Vertecies[BATCH_2D_VERTEX_INDEX(Quad, Tri, 0)];
v2 P1 = Vertecies[BATCH_2D_VERTEX_INDEX(Quad, Tri, 1)];
v2 P2 = Vertecies[BATCH_2D_VERTEX_INDEX(Quad, Tri, 2)];
v2 UV0 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 0)];
v2 UV1 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 1)];
v2 UV2 = UVs[BATCH_2D_UV_INDEX(Quad, Tri, 2)];
v4 C0 = Colors[BATCH_2D_COLOR_INDEX(Quad, Tri, 0)];
v4 C1 = Colors[BATCH_2D_COLOR_INDEX(Quad, Tri, 1)];
v4 C2 = Colors[BATCH_2D_COLOR_INDEX(Quad, Tri, 2)];
OpenGLDraw2DTri(P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
}
}
#else
OpenGLRenderTriBuffer((u8*)Vertecies, 2, UVs, 2, Colors, 4, QuadCount * 2 * 3);
#endif
}
internal void
RenderCommandBuffer (render_command_buffer CommandBuffer)
{
DEBUG_TRACK_FUNCTION;
glViewport(0, 0, CommandBuffer.ViewWidth, CommandBuffer.ViewHeight);
glMatrixMode(GL_TEXTURE_2D);
glLoadIdentity();
glClearColor(0.1f, 0.1f, 0.1f, 1);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_2D);
b32 GLTextureEnabled = false;
u8* CurrentPosition = CommandBuffer.CommandMemory;
while(CurrentPosition < CommandBuffer.CommandMemory + CommandBuffer.CommandMemoryUsed)
{
render_command_header* CommandHeader = (render_command_header*)CurrentPosition;
CurrentPosition += sizeof(render_command_header);
switch (CommandHeader->Type)
{
case RenderCommand_render_command_set_render_mode:
{
render_command_set_render_mode* Command = (render_command_set_render_mode*)(CommandHeader + 1);
LoadModelView(Command->ModelView.E);
LoadProjection(Command->Projection.E);
if (Command->UseDepthBuffer)
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
}
else
{
glDisable(GL_DEPTH_TEST);
}
CurrentPosition += sizeof(render_command_set_render_mode);
}break;
case RenderCommand_render_command_clear_screen:
{
render_command_clear_screen* Command = (render_command_clear_screen*)(CommandHeader + 1);
ClearRenderBuffer();
CurrentPosition += sizeof(render_command_clear_screen);
}break;
case RenderCommand_render_batch_command_quad_2d:
{
render_batch_command_quad_2d* Command = (render_batch_command_quad_2d*)(CommandHeader + 1);
if (GLTextureEnabled) { glDisable(GL_TEXTURE_2D); GLTextureEnabled = false; }
u8* CommandData = (u8*)(Command + 1);
Render2DQuadBatch(CommandData, Command->QuadCount);
CurrentPosition += sizeof(render_batch_command_quad_2d) + Command->DataSize;
}break;
case RenderCommand_render_batch_command_quad_3d:
{
render_batch_command_quad_3d* Command = (render_batch_command_quad_3d*)(CommandHeader + 1);
if (GLTextureEnabled) { glDisable(GL_TEXTURE_2D); GLTextureEnabled = false; }
u8* CommandData = (u8*)(Command + 1);
Render3DQuadBatch(CommandData, Command->QuadCount * 2);
CurrentPosition += sizeof(render_batch_command_quad_3d) + Command->DataSize;
}break;
case RenderCommand_render_batch_command_texture_2d:
{
render_batch_command_texture_2d* Command = (render_batch_command_texture_2d*)(CommandHeader + 1);
if (!GLTextureEnabled) { glEnable(GL_TEXTURE_2D); GLTextureEnabled = true; }
Assert(Command->Texture.Handle > 0);
glBindTexture(GL_TEXTURE_2D, Command->Texture.Handle);
u8* CommandData = (u8*)(Command + 1);
Render2DQuadBatch(CommandData, Command->QuadCount);
CurrentPosition += sizeof(render_batch_command_texture_2d) + Command->DataSize;
}break;
default:
{
InvalidCodePath;
}break;
}
}
}
internal void
ClearRenderBuffer (render_command_buffer* Buffer)
{
Buffer->CommandMemoryUsed = 0;
}