Add proper wireframe mode, rotation to triangle

This commit is contained in:
Doyle Thai 2016-11-12 00:22:09 +11:00
parent 6d67485d49
commit 981d87a2d7
7 changed files with 232 additions and 165 deletions

View File

@ -193,7 +193,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
ship->scale = 1; ship->scale = 1;
ship->type = entitytype_ship; ship->type = entitytype_ship;
ship->direction = direction_null; ship->direction = direction_null;
ship->tex = asset_getTex(&state->assetManager, "nullTex"); ship->tex = NULL;
ship->collides = FALSE; ship->collides = FALSE;
} }
@ -293,17 +293,22 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
v2_add(halfAccelerationDtSquared, oldVelocityDt), oldPos); v2_add(halfAccelerationDtSquared, oldVelocityDt), oldPos);
} }
renderer_entity(&state->renderer, state->camera, entity, V2(0, 0), 0, RenderFlags flags = renderflag_wireframe;
V4(0.0f, 1.0f, 1.0f, 1.0f)); renderer_entity(&state->renderer, state->camera, entity, V2(0, 0),
0, V4(0.4f, 0.8f, 1.0f, 1.0f), flags);
} }
RenderTex nullRenderTex = renderer_createNullRenderTex(&state->assetManager);
TrianglePoints triangle = {0}; TrianglePoints triangle = {0};
triangle.points[0] = V2(100, 200); triangle.points[0] = V2(100, 200);
triangle.points[2] = V2(100, 100); triangle.points[2] = V2(100, 300);
triangle.points[1] = V2(200, 100); triangle.points[1] = V2(200, 100);
renderer_triangle(&state->renderer, state->camera, triangle, V2(0, 0), 0,
nullRenderTex, V4(1, 1, 1, 1)); LOCAL_PERSIST Radians rotation = 0.0f;
rotation += DEGREES_TO_RADIANS(((60.0f) * dt));
RenderFlags flags = renderflag_wireframe;
renderer_triangle(&state->renderer, state->camera, triangle, V2(0, 0),
rotation, NULL, V4(1, 1, 1, 1), flags);
renderer_renderGroups(&state->renderer); renderer_renderGroups(&state->renderer);
} }

View File

@ -229,9 +229,9 @@ INTERNAL void updateAndRenderDebugStack(Renderer *renderer, MemoryArena_ *arena,
{ {
f32 rotate = 0; f32 rotate = 0;
v4 color = V4(0, 0, 0, 1); v4 color = V4(0, 0, 0, 1);
renderer_staticString(renderer, arena, &GLOBAL_debug.font, renderer_staticString(
GLOBAL_debug.debugStrings[i], renderer, arena, &GLOBAL_debug.font, GLOBAL_debug.debugStrings[i],
GLOBAL_debug.currStringP, V2(0, 0), rotate, color); GLOBAL_debug.currStringP, V2(0, 0), rotate, color, 0);
GLOBAL_debug.currStringP.y -= (0.9f * GLOBAL_debug.stringLineGap); GLOBAL_debug.currStringP.y -= (0.9f * GLOBAL_debug.stringLineGap);
} }
@ -263,7 +263,7 @@ INTERNAL void renderConsole(Renderer *renderer, MemoryArena_ *arena)
v4 color = V4(0, 0, 0, 1); v4 color = V4(0, 0, 0, 1);
renderer_staticString(renderer, arena, &GLOBAL_debug.font, renderer_staticString(renderer, arena, &GLOBAL_debug.font,
GLOBAL_debug.console[i], consoleStrP, GLOBAL_debug.console[i], consoleStrP,
V2(0, 0), rotate, color); V2(0, 0), rotate, color, 0);
consoleStrP.y -= (0.9f * GLOBAL_debug.stringLineGap); consoleStrP.y -= (0.9f * GLOBAL_debug.stringLineGap);
} }
} }

View File

@ -8,8 +8,6 @@
#include "Dengine/Shader.h" #include "Dengine/Shader.h"
#include "Dengine/Texture.h" #include "Dengine/Texture.h"
#define RENDER_BOUNDING_BOX FALSE
typedef struct RenderQuad typedef struct RenderQuad
{ {
Vertex vertex[4]; Vertex vertex[4];
@ -22,7 +20,8 @@ typedef struct RenderTriangle
INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color, INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color,
Vertex *vertexList, i32 numVertexes, Vertex *vertexList, i32 numVertexes,
enum RenderMode targetRenderMode) enum RenderMode targetRenderMode,
RenderFlags flags)
{ {
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
@ -38,26 +37,50 @@ INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color,
{ {
RenderGroup *group = &renderer->groups[i]; RenderGroup *group = &renderer->groups[i];
b32 groupIsValid = FALSE; b32 groupIsValid = FALSE;
if (group->tex) if (group->init)
{ {
/* If the textures match and have the same color modulation, we can /* If the textures match and have the same color modulation, we can
* add these vertices to the current group */ * add these vertices to the current group */
if (group->tex->id == tex->id &&
v4_equals(group->color, color) && group->mode == targetRenderMode) b32 renderModeMatches = FALSE;
if (group->mode == targetRenderMode) renderModeMatches = TRUE;
b32 colorMatches = FALSE;
if (v4_equals(group->color, color)) colorMatches = TRUE;
b32 flagsMatches = FALSE;
if (group->flags == flags) flagsMatches = TRUE;
b32 texMatches = TRUE;
if (!tex && !group->tex)
{ {
groupIsValid = TRUE; texMatches = TRUE;
} }
else if (tex && group->tex)
{
if (group->tex->id == tex->id)
{
texMatches = TRUE;
}
}
if (texMatches && colorMatches && renderModeMatches && flagsMatches)
groupIsValid = TRUE;
} }
else else
{ {
/* New group, unused so initialise it */ /* New group, unused so initialise it */
groupIsValid = TRUE; groupIsValid = TRUE;
// NOTE(doyle): Mark first vertex as degenerate vertex // NOTE(doyle): Mark first vertex as degenerate vertex, but where we
group->vertexIndex++; // request wireframe mode- we can't use degenerate vertexes for line
// mode
if (!(flags & renderflag_wireframe)) group->vertexIndex++;
group->init = TRUE;
group->tex = tex; group->tex = tex;
group->color = color; group->color = color;
group->mode = targetRenderMode; group->mode = targetRenderMode;
group->flags = flags;
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
debug_countIncrement(debugcount_renderGroups); debug_countIncrement(debugcount_renderGroups);
@ -132,8 +155,54 @@ INTERNAL void bufferRenderGroupToGL(Renderer *renderer, RenderGroup *group)
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
INTERNAL void applyRotationToVertexes(v2 pos, v2 pivotPoint, Radians rotate,
Vertex *vertexList, i32 vertexListSize)
{
// NOTE(doyle): Move the world origin to the base position of the object.
// Then move the origin to the pivot point (e.g. center of object) and
// rotate from that point.
v2 pointOfRotation = v2_add(pivotPoint, pos);
mat4 rotateMat = mat4_translate(pointOfRotation.x, pointOfRotation.y, 0.0f);
rotateMat = mat4_mul(rotateMat, mat4_rotate(rotate, 0.0f, 0.0f, 1.0f));
rotateMat = mat4_mul(rotateMat, mat4_translate(-pointOfRotation.x,
-pointOfRotation.y, 0.0f));
for (i32 i = 0; i < vertexListSize; i++)
{
// NOTE(doyle): Manual matrix multiplication since vertex pos is 2D and
// matrix is 4D
v2 oldP = vertexList[i].pos;
v2 newP = {0};
newP.x = (oldP.x * rotateMat.e[0][0]) + (oldP.y * rotateMat.e[1][0]) +
(rotateMat.e[3][0]);
newP.y = (oldP.x * rotateMat.e[0][1]) + (oldP.y * rotateMat.e[1][1]) +
(rotateMat.e[3][1]);
vertexList[i].pos = newP;
}
}
INTERNAL v4 getTexRectNormaliseDeviceCoords(RenderTex renderTex)
{
/* Convert texture coordinates to normalised texture coordinates */
v4 result = renderTex.texRect;
if (renderTex.tex)
{
v2 texNdcFactor =
V2(1.0f / renderTex.tex->width, 1.0f / renderTex.tex->height);
result.e[0] *= texNdcFactor.w;
result.e[1] *= texNdcFactor.h;
result.e[2] *= texNdcFactor.w;
result.e[3] *= texNdcFactor.h;
}
return result;
}
INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size, INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size,
v2 pivotPoint, f32 rotate, v2 pivotPoint, Radians rotate,
RenderTex renderTex) RenderTex renderTex)
{ {
/* /*
@ -152,18 +221,7 @@ INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size,
v4 vertexPair = {0}; v4 vertexPair = {0};
vertexPair.vec2[0] = pos; vertexPair.vec2[0] = pos;
vertexPair.vec2[1] = v2_add(pos, size); vertexPair.vec2[1] = v2_add(pos, size);
v4 texRectNdc = getTexRectNormaliseDeviceCoords(renderTex);
/* Convert texture coordinates to normalised texture coordinates */
v4 texRectNdc = renderTex.texRect;
if (renderTex.tex)
{
v2 texNdcFactor =
V2(1.0f / renderTex.tex->width, 1.0f / renderTex.tex->height);
texRectNdc.e[0] *= texNdcFactor.w;
texRectNdc.e[1] *= texNdcFactor.h;
texRectNdc.e[2] *= texNdcFactor.w;
texRectNdc.e[3] *= texNdcFactor.h;
}
// NOTE(doyle): Create a quad composed of 4 vertexes to be rendered as // NOTE(doyle): Create a quad composed of 4 vertexes to be rendered as
// a triangle strip using vertices v0, v1, v2, then v2, v1, v3 (note the // a triangle strip using vertices v0, v1, v2, then v2, v1, v3 (note the
@ -185,53 +243,20 @@ INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size,
// NOTE(doyle): Precalculate rotation on vertex positions // NOTE(doyle): Precalculate rotation on vertex positions
// NOTE(doyle): No translation/scale matrix as we pre-calculate it from // NOTE(doyle): No translation/scale matrix as we pre-calculate it from
// entity data and work in world space until GLSL uses the projection matrix // entity data and work in world space until GLSL uses the projection matrix
applyRotationToVertexes(pos, pivotPoint, rotate, result.vertex,
// NOTE(doyle): Move the world origin to the base position of the object. ARRAY_COUNT(result.vertex));
// Then move the origin to the pivot point (e.g. center of object) and
// rotate from that point.
v2 pointOfRotation = v2_add(pivotPoint, pos);
mat4 rotateMat = mat4_translate(pointOfRotation.x, pointOfRotation.y, 0.0f);
rotateMat = mat4_mul(rotateMat, mat4_rotate(rotate, 0.0f, 0.0f, 1.0f));
rotateMat = mat4_mul(rotateMat, mat4_translate(-pointOfRotation.x,
-pointOfRotation.y, 0.0f));
for (i32 i = 0; i < ARRAY_COUNT(result.vertex); i++)
{
// NOTE(doyle): Manual matrix multiplication since vertex pos is 2D and
// matrix is 4D
v2 oldP = result.vertex[i].pos;
v2 newP = {0};
newP.x = (oldP.x * rotateMat.e[0][0]) + (oldP.y * rotateMat.e[1][0]) +
(rotateMat.e[3][0]);
newP.y = (oldP.x * rotateMat.e[0][1]) + (oldP.y * rotateMat.e[1][1]) +
(rotateMat.e[3][1]);
result.vertex[i].pos = newP;
}
return result; return result;
} }
INTERNAL RenderTriangle_ createRenderTriangle(Renderer *renderer, INTERNAL RenderTriangle_ createRenderTriangle(Renderer *renderer,
TrianglePoints triangle, TrianglePoints triangle,
v2 pivotPoint, f32 rotate, v2 pivotPoint, Radians rotate,
RenderTex renderTex) RenderTex renderTex)
{ {
/* Convert texture coordinates to normalised texture coordinates */ /* Convert texture coordinates to normalised texture coordinates */
v4 texRectNdc = renderTex.texRect; v4 texRectNdc = getTexRectNormaliseDeviceCoords(renderTex);
if (renderTex.tex)
{
v2 texNdcFactor =
V2(1.0f / renderTex.tex->width, 1.0f / renderTex.tex->height);
texRectNdc.e[0] *= texNdcFactor.w;
texRectNdc.e[1] *= texNdcFactor.h;
texRectNdc.e[2] *= texNdcFactor.w;
texRectNdc.e[3] *= texNdcFactor.h;
}
RenderTriangle_ result = {0};
RenderTriangle_ result = {0};
result.vertex[0].pos = triangle.points[0]; result.vertex[0].pos = triangle.points[0];
result.vertex[0].texCoord = V2(texRectNdc.x, texRectNdc.w); result.vertex[0].texCoord = V2(texRectNdc.x, texRectNdc.w);
@ -242,39 +267,34 @@ INTERNAL RenderTriangle_ createRenderTriangle(Renderer *renderer,
result.vertex[2].texCoord = V2(texRectNdc.z, texRectNdc.w); result.vertex[2].texCoord = V2(texRectNdc.z, texRectNdc.w);
if (rotate == 0) return result; if (rotate == 0) return result;
applyRotationToVertexes(triangle.points[0], pivotPoint, rotate,
result.vertex, ARRAY_COUNT(result.vertex));
return result; return result;
} }
INTERNAL inline RenderQuad_ INTERNAL inline RenderQuad_
createDefaultTexQuad(Renderer *renderer, RenderTex renderTex) createDefaultTexQuad(Renderer *renderer, RenderTex *renderTex)
{ {
RenderQuad_ result = {0}; RenderQuad_ result = {0};
result = createRenderQuad(renderer, V2(0, 0), V2(0, 0), V2(0, 0), result = createRenderQuad(renderer, V2(0, 0), V2(0, 0), V2(0, 0),
0.0f, renderTex); 0.0f, *renderTex);
return result; return result;
} }
INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *renderGroup) INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *group)
{ {
ASSERT(renderGroup->mode < rendermode_invalid); ASSERT(group->mode < rendermode_invalid);
/* Load transformation matrix */ /* Load transformation matrix */
shader_use(renderer->shader); shader_use(renderer->shader);
GL_CHECK_ERROR(); GL_CHECK_ERROR();
/* Set color modulation value */ /* Set color modulation value */
shader_uniformSetVec4f(renderer->shader, "spriteColor", shader_uniformSetVec4f(renderer->shader, "spriteColor",
renderGroup->color); group->color);
GL_CHECK_ERROR(); GL_CHECK_ERROR();
/* Send draw calls */ Texture *tex = group->tex;
#if RENDER_BOUNDING_BOX
glBindVertexArray(renderer->vao[renderGroup->mode]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo);
glBindVertexArray(0);
#endif
Texture *tex = renderGroup->tex;
if (tex) if (tex)
{ {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
@ -282,13 +302,17 @@ INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *renderGroup)
shader_uniformSet1i(renderer->shader, "tex", 0); shader_uniformSet1i(renderer->shader, "tex", 0);
} }
glBindVertexArray(renderer->vao[renderGroup->mode]); glBindVertexArray(renderer->vao[group->mode]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo);
GL_CHECK_ERROR();
#ifdef DENGINE_DEBUG u32 drawMethod = GL_TRIANGLE_STRIP;
if (group->flags & renderflag_wireframe)
{
drawMethod = GL_LINE_LOOP;
}
glDrawArrays(drawMethod, 0, renderer->numVertexesInVbo);
GL_CHECK_ERROR();
debug_countIncrement(debugcount_drawArrays); debug_countIncrement(debugcount_drawArrays);
#endif
/* Unbind */ /* Unbind */
glBindVertexArray(0); glBindVertexArray(0);
@ -304,14 +328,29 @@ RenderTex renderer_createNullRenderTex(AssetManager *const assetManager)
} }
void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size, void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size,
v2 pivotPoint, f32 rotate, RenderTex renderTex, v4 color) v2 pivotPoint, Radians rotate, RenderTex *renderTex, v4 color,
RenderFlags flags)
{ {
// NOTE(doyle): Bottom left and top right position of quad in world space // NOTE(doyle): Bottom left and top right position of quad in world space
v2 posInCameraSpace = v2_sub(pos, camera.pos); v2 posInCameraSpace = v2_sub(pos, camera.pos);
RenderQuad_ quad = createRenderQuad(renderer, posInCameraSpace, size,
pivotPoint, rotate, renderTex);
{ // addRenderQuadToRenderGroup RenderTex emptyRenderTex = {0};
if (!renderTex) renderTex = &emptyRenderTex;
RenderQuad_ quad = createRenderQuad(renderer, posInCameraSpace, size,
pivotPoint, rotate, *renderTex);
// addRenderQuadToRenderGroup
if (flags & renderflag_wireframe)
{
Vertex vertexList[4] = {quad.vertex[0], quad.vertex[1], quad.vertex[3],
quad.vertex[2]};
addVertexToRenderGroup(renderer, renderTex->tex, color, vertexList,
ARRAY_COUNT(vertexList), rendermode_quad,
flags);
}
else
{
/* /*
NOTE(doyle): Entity rendering is always done in two pairs of NOTE(doyle): Entity rendering is always done in two pairs of
triangles, i.e. quad. To batch render quads as a triangle strip, we triangles, i.e. quad. To batch render quads as a triangle strip, we
@ -333,38 +372,39 @@ void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size,
The first has been chosen for simplicity of code, at the cost of The first has been chosen for simplicity of code, at the cost of
1 degenerate vertex at the start of each render group. 1 degenerate vertex at the start of each render group.
*/ */
Vertex vertexList[6] = {quad.vertex[0], quad.vertex[0], quad.vertex[1], Vertex vertexList[6] = {quad.vertex[0], quad.vertex[0], quad.vertex[1],
quad.vertex[2], quad.vertex[3], quad.vertex[3]}; quad.vertex[2], quad.vertex[3], quad.vertex[3]};
addVertexToRenderGroup(renderer, renderTex.tex, color, vertexList, addVertexToRenderGroup(renderer, renderTex->tex, color, vertexList,
ARRAY_COUNT(vertexList), rendermode_quad); ARRAY_COUNT(vertexList), rendermode_quad, flags);
} }
} }
void renderer_triangle(Renderer *const renderer, Rect camera, void renderer_triangle(Renderer *const renderer, Rect camera,
TrianglePoints triangle, v2 pivotPoint, f32 rotate, TrianglePoints triangle, v2 pivotPoint, Radians rotate,
RenderTex renderTex, v4 color) RenderTex *renderTex, v4 color, RenderFlags flags)
{ {
TrianglePoints triangleInCamSpace = {0}; TrianglePoints triangleInCamSpace = {0};
ASSERT(ARRAY_COUNT(triangle.points) == ASSERT(ARRAY_COUNT(triangle.points) ==
ARRAY_COUNT(triangleInCamSpace.points)); ARRAY_COUNT(triangleInCamSpace.points));
for (i32 i = 0; i < ARRAY_COUNT(triangleInCamSpace.points); i++) for (i32 i = 0; i < ARRAY_COUNT(triangleInCamSpace.points); i++)
{
triangleInCamSpace.points[i] = v2_sub(triangle.points[i], camera.pos); triangleInCamSpace.points[i] = v2_sub(triangle.points[i], camera.pos);
}
RenderTex emptyRenderTex = {0};
if (!renderTex) renderTex = &emptyRenderTex;
RenderTriangle_ renderTriangle = createRenderTriangle( RenderTriangle_ renderTriangle = createRenderTriangle(
renderer, triangleInCamSpace, pivotPoint, rotate, renderTex); renderer, triangleInCamSpace, pivotPoint, rotate, *renderTex);
addVertexToRenderGroup( addVertexToRenderGroup(
renderer, renderTex.tex, color, renderTriangle.vertex, renderer, renderTex->tex, color, renderTriangle.vertex,
ARRAY_COUNT(renderTriangle.vertex), rendermode_triangle); ARRAY_COUNT(renderTriangle.vertex), rendermode_triangle, flags);
} }
void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera,
Font *const font, const char *const string, v2 pos, Font *const font, const char *const string, v2 pos,
v2 pivotPoint, f32 rotate, v4 color) v2 pivotPoint, Radians rotate, v4 color, RenderFlags flags)
{ {
i32 strLen = common_strlen(string); i32 strLen = common_strlen(string);
if (strLen <= 0) return; if (strLen <= 0) return;
@ -422,7 +462,7 @@ void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera,
} }
addVertexToRenderGroup(renderer, tex, color, vertexList, addVertexToRenderGroup(renderer, tex, color, vertexList,
numVertexesToAlloc, rendermode_quad); numVertexesToAlloc, rendermode_quad, flags);
// TODO(doyle): Mem free // TODO(doyle): Mem free
// PLATFORM_MEM_FREE(arena, vertexList, // PLATFORM_MEM_FREE(arena, vertexList,
// sizeof(Vertex) * numVertexesToAlloc); // sizeof(Vertex) * numVertexesToAlloc);
@ -430,7 +470,7 @@ void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera,
} }
void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, void renderer_entity(Renderer *renderer, Rect camera, Entity *entity,
v2 pivotPoint, f32 rotate, v4 color) v2 pivotPoint, Radians rotate, v4 color, RenderFlags flags)
{ {
// TODO(doyle): Batch into render groups // TODO(doyle): Batch into render groups
@ -442,33 +482,40 @@ void renderer_entity(Renderer *renderer, Rect camera, Entity *entity,
if (math_pointInRect(camera, leftAlignedP) || if (math_pointInRect(camera, leftAlignedP) ||
math_pointInRect(camera, rightAlignedP)) math_pointInRect(camera, rightAlignedP))
{ {
EntityAnim *entityAnim = &entity->animList[entity->animListIndex];
v4 texRect = {0}; RenderTex renderTex = {0};
if (entityAnim->anim) if (entity->tex)
{ {
Animation *anim = entityAnim->anim; EntityAnim *entityAnim = &entity->animList[entity->animListIndex];
char *frameName = anim->frameList[entityAnim->currFrame]; v4 texRect = {0};
SubTexture subTex = asset_getAtlasSubTex(anim->atlas, frameName); if (entityAnim->anim)
{
Animation *anim = entityAnim->anim;
char *frameName = anim->frameList[entityAnim->currFrame];
SubTexture subTex =
asset_getAtlasSubTex(anim->atlas, frameName);
texRect.vec2[0] = subTex.rect.pos; texRect.vec2[0] = subTex.rect.pos;
texRect.vec2[1] = v2_add(subTex.rect.pos, subTex.rect.size); texRect.vec2[1] = v2_add(subTex.rect.pos, subTex.rect.size);
flipTexCoord(&texRect, entity->flipX, entity->flipY); flipTexCoord(&texRect, entity->flipX, entity->flipY);
} }
else else
{ {
texRect = V4(0.0f, 0.0f, (f32)entity->tex->width, texRect = V4(0.0f, 0.0f, (f32)entity->tex->width,
(f32)entity->tex->height); (f32)entity->tex->height);
}
if (entity->direction == direction_east)
{
flipTexCoord(&texRect, TRUE, FALSE);
}
renderTex.tex = entity->tex;
renderTex.texRect = texRect;
} }
if (entity->direction == direction_east)
{
flipTexCoord(&texRect, TRUE, FALSE);
}
RenderTex renderTex = {entity->tex, texRect};
renderer_rect(renderer, camera, entity->pos, entity->size, pivotPoint, renderer_rect(renderer, camera, entity->pos, entity->size, pivotPoint,
entity->rotation + rotate, renderTex, color); entity->rotation + rotate, &renderTex, color, flags);
} }
} }
@ -477,7 +524,7 @@ void renderer_renderGroups(Renderer *renderer)
for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++) for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++)
{ {
RenderGroup *currGroup = &renderer->groups[i]; RenderGroup *currGroup = &renderer->groups[i];
if (currGroup->tex) if (currGroup->init)
{ {
bufferRenderGroupToGL(renderer, currGroup); bufferRenderGroupToGL(renderer, currGroup);
renderGLBufferedData(renderer, currGroup); renderGLBufferedData(renderer, currGroup);

View File

@ -67,13 +67,14 @@ i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena,
if (uiState->kbdItem == id) if (uiState->kbdItem == id)
{ {
// Draw outline // Draw outline
renderer_staticRect( renderer_staticRect(renderer,
renderer, v2_add(V2(-2, -2), v2_add(buttonOffset, rect.pos)), v2_add(V2(-2, -2), v2_add(buttonOffset, rect.pos)),
v2_add(V2(4, 4), rect.size), V2(0, 0), 0, renderTex, buttonColor); v2_add(V2(4, 4), rect.size), V2(0, 0), 0, &renderTex,
buttonColor, 0);
} }
renderer_staticRect(renderer, v2_add(buttonOffset, rect.pos), rect.size, renderer_staticRect(renderer, v2_add(buttonOffset, rect.pos), rect.size,
V2(0, 0), 0, renderTex, buttonColor); V2(0, 0), 0, &renderTex, buttonColor, 0);
if (label) if (label)
{ {
@ -95,7 +96,7 @@ i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena,
labelPos = v2_add(labelPos, buttonOffset); labelPos = v2_add(labelPos, buttonOffset);
renderer_staticString(renderer, arena, font, label, labelPos, V2(0, 0), renderer_staticString(renderer, arena, font, label, labelPos, V2(0, 0),
0, V4(0, 0, 0, 1)); 0, V4(0, 0, 0, 1), 0);
} }
// After renderering before click check, see if we need to process keys // After renderering before click check, see if we need to process keys
@ -169,12 +170,12 @@ i32 userInterface_scrollbar(UiState *const uiState,
// Draw outline // Draw outline
renderer_staticRect(renderer, v2_add(V2(-2, -2), scrollBarRect.pos), renderer_staticRect(renderer, v2_add(V2(-2, -2), scrollBarRect.pos),
v2_add(V2(4, 4), scrollBarRect.size), V2(0, 0), 0, v2_add(V2(4, 4), scrollBarRect.size), V2(0, 0), 0,
renderTex, V4(1, 0, 0, 1)); &renderTex, V4(1, 0, 0, 1), 0);
} }
// Render scroll bar background // Render scroll bar background
renderer_staticRect(renderer, scrollBarRect.pos, scrollBarRect.size, renderer_staticRect(renderer, scrollBarRect.pos, scrollBarRect.size,
V2(0, 0), 0, renderTex, V4(0.75f, 0.5f, 0.5f, 1)); V2(0, 0), 0, &renderTex, V4(0.75f, 0.5f, 0.5f, 1), 0);
// Render scroll bar slider // Render scroll bar slider
v2 sliderSize = V2(16, 16); v2 sliderSize = V2(16, 16);
@ -190,8 +191,8 @@ i32 userInterface_scrollbar(UiState *const uiState,
else else
sliderColor = V4(0.0f, 1.0f, 0, 1); sliderColor = V4(0.0f, 1.0f, 0, 1);
renderer_staticRect(renderer, sliderPos, sliderSize, V2(0, 0), 0, renderTex, renderer_staticRect(renderer, sliderPos, sliderSize, V2(0, 0), 0, &renderTex,
sliderColor); sliderColor, 0);
if (uiState->kbdItem == id) if (uiState->kbdItem == id)
{ {
@ -283,27 +284,27 @@ i32 userInterface_textField(UiState *const uiState, MemoryArena_ *const arena,
// Draw outline // Draw outline
renderer_staticRect(renderer, v2_add(V2(-2, -2), rect.pos), renderer_staticRect(renderer, v2_add(V2(-2, -2), rect.pos),
v2_add(V2(4, 4), rect.size), V2(0, 0), 0, v2_add(V2(4, 4), rect.size), V2(0, 0), 0,
renderTex, V4(1.0f, 0, 0, 1)); &renderTex, V4(1.0f, 0, 0, 1), 0);
} }
// Render text field // Render text field
renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0, renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0,
renderTex, V4(0.75f, 0.5f, 0.5f, 1)); &renderTex, V4(0.75f, 0.5f, 0.5f, 1), 0);
if (uiState->activeItem == id || uiState->hotItem == id) if (uiState->activeItem == id || uiState->hotItem == id)
{ {
renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0, renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0,
renderTex, V4(0.75f, 0.75f, 0.0f, 1)); &renderTex, V4(0.75f, 0.75f, 0.0f, 1), 0);
} }
else else
{ {
renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0, renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0,
renderTex, V4(0.5f, 0.5f, 0.5f, 1)); &renderTex, V4(0.5f, 0.5f, 0.5f, 1), 0);
} }
v2 strPos = rect.pos; v2 strPos = rect.pos;
renderer_staticString(renderer, arena, font, string, strPos, V2(0, 0), 0, renderer_staticString(renderer, arena, font, string, strPos, V2(0, 0), 0,
V4(0, 0, 0, 1)); V4(0, 0, 0, 1), 0);
if (uiState->kbdItem == id) if (uiState->kbdItem == id)
{ {
@ -365,11 +366,11 @@ i32 userInterface_window(UiState *const uiState, MemoryArena_ *const arena,
Rect rect = window->rect; Rect rect = window->rect;
RenderTex nullRenderTex = renderer_createNullRenderTex(assetManager); RenderTex nullRenderTex = renderer_createNullRenderTex(assetManager);
renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0, renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0,
nullRenderTex, V4(0.25f, 0.25f, 0.5f, 0.5f)); &nullRenderTex, V4(0.25f, 0.25f, 0.5f, 0.5f), 0);
v2 menuTitleP = v2_add(rect.pos, V2(0, rect.size.h - 10)); v2 menuTitleP = v2_add(rect.pos, V2(0, rect.size.h - 10));
renderer_staticString(renderer, arena, font, window->title, menuTitleP, renderer_staticString(renderer, arena, font, window->title, menuTitleP,
V2(0, 0), 0, V4(0, 0, 0, 1)); V2(0, 0), 0, V4(0, 0, 0, 1), 0);
/* Draw window elements */ /* Draw window elements */
i32 firstActiveChildId = -1; i32 firstActiveChildId = -1;

View File

@ -200,7 +200,7 @@ i32 main(void)
glfwPollEvents(); glfwPollEvents();
/* Rendering commands here*/ /* Rendering commands here*/
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
asteroid_gameUpdateAndRender(&gameState, &memory, windowSize, asteroid_gameUpdateAndRender(&gameState, &memory, windowSize,

View File

@ -11,6 +11,8 @@
#define RADIANS_TO_DEGREES(x) (x * (180.0f / MATH_PI)) #define RADIANS_TO_DEGREES(x) (x * (180.0f / MATH_PI))
#define SQRT(x) (sqrtf(x)) #define SQRT(x) (sqrtf(x))
typedef f32 Radians;
INTERNAL inline f32 math_acosf(f32 a) INTERNAL inline f32 math_acosf(f32 a)
{ {
f32 result = acosf(a); f32 result = acosf(a);

View File

@ -28,16 +28,10 @@ typedef struct TrianglePoints {
v2 points[3]; v2 points[3];
} TrianglePoints; } TrianglePoints;
typedef struct RenderGroup typedef u32 RenderFlags;
{ enum RenderFlag {
enum RenderMode mode; renderflag_wireframe = 0x1,
Texture *tex; };
v4 color;
Vertex *vertexList;
i32 vertexIndex;
} RenderGroup;
enum RenderMode enum RenderMode
{ {
@ -47,6 +41,20 @@ enum RenderMode
rendermode_invalid, rendermode_invalid,
}; };
typedef struct RenderGroup
{
b32 init;
RenderFlags flags;
enum RenderMode mode;
Texture *tex;
v4 color;
Vertex *vertexList;
i32 vertexIndex;
} RenderGroup;
typedef struct Renderer typedef struct Renderer
{ {
Shader *shader; Shader *shader;
@ -62,6 +70,7 @@ typedef struct Renderer
i32 groupCapacity; i32 groupCapacity;
} Renderer; } Renderer;
// TODO(doyle): Use z-index occluding for rendering // TODO(doyle): Use z-index occluding for rendering
RenderTex RenderTex
renderer_createNullRenderTex(AssetManager *const assetManager); renderer_createNullRenderTex(AssetManager *const assetManager);
@ -69,37 +78,40 @@ renderer_createNullRenderTex(AssetManager *const assetManager);
// TODO(doyle): Clean up lines // TODO(doyle): Clean up lines
// Renderer::~Renderer() { glDeleteVertexArrays(1, &this->quadVAO); } // Renderer::~Renderer() { glDeleteVertexArrays(1, &this->quadVAO); }
void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size, void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size,
v2 pivotPoint, f32 rotate, RenderTex renderTex, v4 color); v2 pivotPoint, Radians rotate, RenderTex *renderTex, v4 color,
RenderFlags flags);
inline void renderer_staticRect(Renderer *const renderer, v2 pos, v2 size, inline void renderer_staticRect(Renderer *const renderer, v2 pos, v2 size,
v2 pivotPoint, f32 rotate, RenderTex renderTex, v2 pivotPoint, Radians rotate, RenderTex *renderTex,
v4 color) v4 color, RenderFlags flags)
{ {
Rect staticCamera = {V2(0, 0), renderer->size}; Rect staticCamera = {V2(0, 0), renderer->size};
renderer_rect(renderer, staticCamera, pos, size, pivotPoint, rotate, renderer_rect(renderer, staticCamera, pos, size, pivotPoint, rotate,
renderTex, color); renderTex, color, flags);
} }
void renderer_triangle(Renderer *const renderer, Rect camera, void renderer_triangle(Renderer *const renderer, Rect camera,
TrianglePoints triangle, v2 pivotPoint, f32 rotate, TrianglePoints triangle, v2 pivotPoint, Radians rotate,
RenderTex renderTex, v4 color); RenderTex *renderTex, v4 color, RenderFlags flags);
void renderer_string(Renderer *const renderer, MemoryArena_ *arena, void renderer_string(Renderer *const renderer, MemoryArena_ *arena,
Rect camera, Font *const font, Rect camera, Font *const font,
const char *const string, v2 pos, v2 pivotPoint, const char *const string, v2 pos, v2 pivotPoint,
f32 rotate, v4 color); Radians rotate, v4 color, RenderFlags flags);
inline void renderer_staticString(Renderer *const renderer, MemoryArena_ *arena, inline void renderer_staticString(Renderer *const renderer, MemoryArena_ *arena,
Font *const font, const char *const string, Font *const font, const char *const string,
v2 pos, v2 pivotPoint, f32 rotate, v4 color) v2 pos, v2 pivotPoint, Radians rotate, v4 color,
RenderFlags flags)
{ {
Rect staticCamera = {V2(0, 0), renderer->size}; Rect staticCamera = {V2(0, 0), renderer->size};
renderer_string(renderer, arena, staticCamera, font, string, pos, renderer_string(renderer, arena, staticCamera, font, string, pos,
pivotPoint, rotate, color); pivotPoint, rotate, color, flags);
} }
void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, void renderer_entity(Renderer *renderer, Rect camera, Entity *entity,
v2 pivotPoint, f32 rotate, v4 color); v2 pivotPoint, Radians rotate, v4 color,
RenderFlags flags);
void renderer_renderGroups(Renderer *renderer); void renderer_renderGroups(Renderer *renderer);