Fix triangle rendering and wireframe
This commit is contained in:
parent
339ae38b38
commit
21bf650298
161
src/Asteroid.c
161
src/Asteroid.c
@ -42,10 +42,7 @@ void initAssetManager(GameState *state)
|
|||||||
|
|
||||||
i32 result =
|
i32 result =
|
||||||
asset_loadTTFont(assetManager, arena, "C:/Windows/Fonts/Arialbd.ttf");
|
asset_loadTTFont(assetManager, arena, "C:/Windows/Fonts/Arialbd.ttf");
|
||||||
|
if (result) ASSERT(TRUE);
|
||||||
if (result) {
|
|
||||||
ASSERT(TRUE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initRenderer(GameState *state, v2 windowSize) {
|
void initRenderer(GameState *state, v2 windowSize) {
|
||||||
@ -76,11 +73,12 @@ void initRenderer(GameState *state, v2 windowSize) {
|
|||||||
glGenBuffers(ARRAY_COUNT(renderer->vbo), renderer->vbo);
|
glGenBuffers(ARRAY_COUNT(renderer->vbo), renderer->vbo);
|
||||||
GL_CHECK_ERROR();
|
GL_CHECK_ERROR();
|
||||||
|
|
||||||
|
// Bind buffers and configure vao, vao automatically intercepts
|
||||||
|
// glBindCalls and associates the state with that buffer for us
|
||||||
|
for (enum RenderMode mode = 0; mode < rendermode_count; mode++)
|
||||||
{
|
{
|
||||||
// Bind buffers and configure vao, vao automatically intercepts
|
glBindVertexArray(renderer->vao[mode]);
|
||||||
// glBindCalls and associates the state with that buffer for us
|
glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[mode]);
|
||||||
glBindVertexArray(renderer->vao[rendermode_quad]);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[rendermode_quad]);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
u32 numVertexElements = 4;
|
u32 numVertexElements = 4;
|
||||||
@ -92,20 +90,6 @@ void initRenderer(GameState *state, v2 windowSize) {
|
|||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
glBindVertexArray(renderer->vao[rendermode_triangle]);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[rendermode_triangle]);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
u32 numVertexElements = 3;
|
|
||||||
u32 stride = sizeof(Vertex);
|
|
||||||
|
|
||||||
glVertexAttribPointer(0, numVertexElements, GL_FLOAT,
|
|
||||||
GL_FALSE, stride, (GLvoid *)0);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unbind */
|
/* Unbind */
|
||||||
GL_CHECK_ERROR();
|
GL_CHECK_ERROR();
|
||||||
|
|
||||||
@ -183,37 +167,44 @@ INTERNAL b32 getKeyStatus(KeyState *key, enum ReadKeyType readType,
|
|||||||
void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||||
v2 windowSize, f32 dt)
|
v2 windowSize, f32 dt)
|
||||||
{
|
{
|
||||||
if (!state->init) {
|
if (!state->init)
|
||||||
|
{
|
||||||
|
|
||||||
memory_arenaInit(&state->persistentArena, memory->persistent,
|
memory_arenaInit(&state->persistentArena, memory->persistent,
|
||||||
memory->persistentSize);
|
memory->persistentSize);
|
||||||
memory_arenaInit(&state->transientArena, memory->transient,
|
|
||||||
memory->transientSize);
|
|
||||||
|
|
||||||
initAssetManager(state);
|
initAssetManager(state);
|
||||||
initRenderer(state, windowSize);
|
initRenderer(state, windowSize);
|
||||||
|
|
||||||
state->pixelsPerMeter = 70.0f;
|
state->pixelsPerMeter = 70.0f;
|
||||||
|
|
||||||
{ // Init ship entity
|
{ // Init ship entity
|
||||||
Entity *ship = &state->entityList[state->entityIndex++];
|
Entity *ship = &state->entityList[state->entityIndex++];
|
||||||
ship->id = 0;
|
ship->id = 0;
|
||||||
ship->pos = V2(100.0f, 100.0f);
|
ship->pos = V2(100, 100);
|
||||||
ship->hitbox = V2(100.0f, 100.0f);
|
ship->size = V2(25.0f, 50.0f);
|
||||||
ship->size = V2(100.0f, 100.0f);
|
ship->hitbox = ship->size;
|
||||||
ship->scale = 1;
|
ship->offset = v2_scale(ship->size, 0.5f);
|
||||||
ship->type = entitytype_ship;
|
ship->scale = 1;
|
||||||
ship->direction = direction_null;
|
ship->type = entitytype_ship;
|
||||||
ship->tex = NULL;
|
ship->direction = direction_null;
|
||||||
ship->collides = FALSE;
|
ship->renderMode = rendermode_triangle;
|
||||||
|
ship->tex = NULL;
|
||||||
|
ship->collides = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->camera.pos = V2(0, 0);
|
state->camera.pos = V2(0, 0);
|
||||||
state->camera.size = state->renderer.size;
|
state->camera.size = state->renderer.size;
|
||||||
|
state->init = TRUE;
|
||||||
|
|
||||||
|
state->worldSize = windowSize;
|
||||||
|
|
||||||
state->init = TRUE;
|
debug_init(&state->persistentArena, windowSize,
|
||||||
|
state->assetManager.font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memory_arenaInit(&state->transientArena, memory->transient,
|
||||||
|
memory->transientSize);
|
||||||
|
|
||||||
{
|
{
|
||||||
KeyState *keys = state->input.keys;
|
KeyState *keys = state->input.keys;
|
||||||
for (enum KeyCode code = 0; code < keycode_count; code++)
|
for (enum KeyCode code = 0; code < keycode_count; code++)
|
||||||
@ -244,40 +235,40 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
Entity *entity = &state->entityList[i];
|
Entity *entity = &state->entityList[i];
|
||||||
ASSERT(entity->type != entitytype_invalid);
|
ASSERT(entity->type != entitytype_invalid);
|
||||||
|
|
||||||
|
v2 pivotPoint = {0};
|
||||||
if (entity->type == entitytype_ship) {
|
if (entity->type == entitytype_ship) {
|
||||||
|
|
||||||
|
v2 ddP = {0};
|
||||||
v2 acceleration = {0};
|
|
||||||
if (getKeyStatus(&state->input.keys[keycode_up], readkeytype_repeat,
|
if (getKeyStatus(&state->input.keys[keycode_up], readkeytype_repeat,
|
||||||
0.0f, dt))
|
0.0f, dt))
|
||||||
{
|
{
|
||||||
acceleration.y = 1.0f;
|
// TODO(doyle): Renderer creates upfacing triangles by default,
|
||||||
}
|
// but we need to offset rotation so that our base "0 degrees"
|
||||||
|
// is right facing for trig to work
|
||||||
|
Radians rotation = DEGREES_TO_RADIANS((entity->rotation + 90.0f));
|
||||||
|
v2 direction = V2(math_cosf(rotation), math_sinf(rotation));
|
||||||
|
|
||||||
if (getKeyStatus(&state->input.keys[keycode_down],
|
ddP = v2_normalise(direction);
|
||||||
readkeytype_repeat, 0.0f, dt))
|
|
||||||
{
|
|
||||||
acceleration.y = -1.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyStatus(&state->input.keys[keycode_left],
|
if (getKeyStatus(&state->input.keys[keycode_left],
|
||||||
readkeytype_repeat, 0.0f, dt))
|
readkeytype_repeat, 0.0f, dt))
|
||||||
{
|
{
|
||||||
acceleration.x = -1.0f;
|
entity->rotation += (120.0f) * dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getKeyStatus(&state->input.keys[keycode_right],
|
if (getKeyStatus(&state->input.keys[keycode_right],
|
||||||
readkeytype_repeat, 0.0f, dt))
|
readkeytype_repeat, 0.0f, dt))
|
||||||
{
|
{
|
||||||
acceleration.x = 1.0f;
|
entity->rotation -= (120.0f) * dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acceleration.x != 0.0f && acceleration.y != 0.0f)
|
if (ddP.x != 0.0f && ddP.y != 0.0f)
|
||||||
{
|
{
|
||||||
// NOTE(doyle): Cheese it and pre-compute the vector for
|
// NOTE(doyle): Cheese it and pre-compute the vector for
|
||||||
// diagonal using pythagoras theorem on a unit triangle 1^2
|
// diagonal using pythagoras theorem on a unit triangle 1^2
|
||||||
// + 1^2 = c^2
|
// + 1^2 = c^2
|
||||||
acceleration = v2_scale(acceleration, 0.70710678118f);
|
ddP = v2_scale(ddP, 0.70710678118f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -285,41 +276,77 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
|
|
||||||
newVelocity = a*t + oldVelocity
|
newVelocity = a*t + oldVelocity
|
||||||
newPos = (a*t^2)/2 + oldVelocity*t + oldPos
|
newPos = (a*t^2)/2 + oldVelocity*t + oldPos
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
acceleration = v2_scale(acceleration, state->pixelsPerMeter * 25);
|
ddP = v2_scale(ddP, state->pixelsPerMeter * 25);
|
||||||
|
|
||||||
v2 oldVelocity = entity->velocity;
|
v2 oldDp = entity->dP;
|
||||||
v2 resistance = v2_scale(oldVelocity, 4.0f);
|
v2 resistance = v2_scale(oldDp, 2.0f);
|
||||||
acceleration = v2_sub(acceleration, resistance);
|
ddP = v2_sub(ddP, resistance);
|
||||||
|
|
||||||
entity->velocity = v2_add(v2_scale(acceleration, dt), oldVelocity);
|
entity->dP = v2_add(v2_scale(ddP, dt), oldDp);
|
||||||
|
|
||||||
v2 halfAcceleration = v2_scale(acceleration, 0.5f);
|
v2 ddPHalf = v2_scale(ddP, 0.5f);
|
||||||
v2 halfAccelerationDtSquared =
|
v2 ddPHalfDtSquared = v2_scale(ddPHalf, (SQUARED(dt)));
|
||||||
v2_scale(halfAcceleration, (SQUARED(dt)));
|
v2 oldDpDt = v2_scale(oldDp, dt);
|
||||||
v2 oldVelocityDt = v2_scale(oldVelocity, dt);
|
v2 oldPos = entity->pos;
|
||||||
v2 oldPos = entity->pos;
|
entity->pos = v2_add(v2_add(ddPHalfDtSquared, oldDpDt), oldPos);
|
||||||
entity->pos = v2_add(
|
|
||||||
v2_add(halfAccelerationDtSquared, oldVelocityDt), oldPos);
|
pivotPoint = v2_scale(entity->size, 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderFlags flags = renderflag_wireframe;
|
if (entity->pos.y >= state->worldSize.h)
|
||||||
renderer_entity(&state->renderer, state->camera, entity, V2(0, 0),
|
{
|
||||||
0, V4(0.4f, 0.8f, 1.0f, 1.0f), flags);
|
entity->pos.y = 0;
|
||||||
|
}
|
||||||
|
else if (entity->pos.y < 0)
|
||||||
|
{
|
||||||
|
entity->pos.y = state->worldSize.h;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity->pos.x >= state->worldSize.w)
|
||||||
|
{
|
||||||
|
entity->pos.x = 0;
|
||||||
|
}
|
||||||
|
else if (entity->pos.x < 0)
|
||||||
|
{
|
||||||
|
entity->pos.x = state->worldSize.w;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_PUSH_VAR("Pos: %5.2f, %5.2f", entity->pos, "v2");
|
||||||
|
DEBUG_PUSH_VAR("Velocity: %5.2f, %5.2f", entity->dP, "v2");
|
||||||
|
DEBUG_PUSH_VAR("Rotation: %5.2f", entity->rotation, "f32");
|
||||||
|
|
||||||
|
RenderFlags flags = renderflag_wireframe | renderflag_no_texture;
|
||||||
|
renderer_entity(&state->renderer, state->camera, entity, pivotPoint, 0,
|
||||||
|
V4(0.4f, 0.8f, 1.0f, 1.0f), flags);
|
||||||
|
|
||||||
|
v2 rightAlignedP = v2_add(entity->pos, entity->hitbox);
|
||||||
|
renderer_rect(&state->renderer, state->camera, rightAlignedP, V2(10, 10),
|
||||||
|
V2(0, 0), DEGREES_TO_RADIANS(entity->rotation), NULL,
|
||||||
|
V4(0.4f, 0.8f, 1.0f, 1.0f), flags);
|
||||||
|
|
||||||
|
v2 leftAlignedP = entity->pos;
|
||||||
|
renderer_rect(&state->renderer, state->camera, leftAlignedP, V2(10, 10),
|
||||||
|
V2(0, 0), DEGREES_TO_RADIANS(entity->rotation), NULL,
|
||||||
|
V4(0.4f, 0.8f, 1.0f, 1.0f), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
TrianglePoints triangle = {0};
|
TrianglePoints triangle = {0};
|
||||||
triangle.points[0] = V2(100, 200);
|
triangle.points[0] = V2(100, 200);
|
||||||
triangle.points[2] = V2(100, 300);
|
|
||||||
triangle.points[1] = V2(200, 100);
|
triangle.points[1] = V2(200, 100);
|
||||||
|
triangle.points[2] = V2(100, 300);
|
||||||
|
|
||||||
LOCAL_PERSIST Radians rotation = 0.0f;
|
LOCAL_PERSIST Radians rotation = 0.0f;
|
||||||
rotation += DEGREES_TO_RADIANS(((60.0f) * dt));
|
rotation += DEGREES_TO_RADIANS(((60.0f) * dt));
|
||||||
|
|
||||||
RenderFlags flags = renderflag_wireframe;
|
RenderFlags flags = renderflag_wireframe | renderflag_no_texture;
|
||||||
renderer_triangle(&state->renderer, state->camera, triangle, V2(0, 0),
|
renderer_triangle(&state->renderer, state->camera, triangle, V2(0, 0),
|
||||||
rotation, NULL, V4(1, 1, 1, 1), flags);
|
rotation, NULL, V4(1, 1, 1, 1), flags);
|
||||||
|
|
||||||
|
debug_drawUi(state, dt);
|
||||||
|
debug_clearCounter();
|
||||||
|
|
||||||
renderer_renderGroups(&state->renderer);
|
renderer_renderGroups(&state->renderer);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ GLOBAL_VAR DebugState GLOBAL_debug;
|
|||||||
|
|
||||||
void debug_init(MemoryArena_ *arena, v2 windowSize, Font font)
|
void debug_init(MemoryArena_ *arena, v2 windowSize, Font font)
|
||||||
{
|
{
|
||||||
GLOBAL_debug.font = font;
|
GLOBAL_debug.font = font;
|
||||||
GLOBAL_debug.callCount =
|
GLOBAL_debug.callCount =
|
||||||
memory_pushBytes(arena, debugcount_num * sizeof(i32));
|
memory_pushBytes(arena, debugcount_num * sizeof(i32));
|
||||||
GLOBAL_debug.stringLineGap = CAST(f32) font.verticalSpacing;
|
GLOBAL_debug.stringLineGap = CAST(f32) font.verticalSpacing;
|
||||||
@ -228,7 +228,7 @@ INTERNAL void updateAndRenderDebugStack(Renderer *renderer, MemoryArena_ *arena,
|
|||||||
for (i32 i = 0; i < GLOBAL_debug.numDebugStrings; i++)
|
for (i32 i = 0; i < GLOBAL_debug.numDebugStrings; i++)
|
||||||
{
|
{
|
||||||
f32 rotate = 0;
|
f32 rotate = 0;
|
||||||
v4 color = V4(0, 0, 0, 1);
|
v4 color = V4(1, 1, 1, 1);
|
||||||
renderer_staticString(
|
renderer_staticString(
|
||||||
renderer, arena, &GLOBAL_debug.font, GLOBAL_debug.debugStrings[i],
|
renderer, arena, &GLOBAL_debug.font, GLOBAL_debug.debugStrings[i],
|
||||||
GLOBAL_debug.currStringP, V2(0, 0), rotate, color, 0);
|
GLOBAL_debug.currStringP, V2(0, 0), rotate, color, 0);
|
||||||
@ -270,5 +270,7 @@ INTERNAL void renderConsole(Renderer *renderer, MemoryArena_ *arena)
|
|||||||
|
|
||||||
void debug_drawUi(GameState *state, f32 dt)
|
void debug_drawUi(GameState *state, f32 dt)
|
||||||
{
|
{
|
||||||
|
updateAndRenderDebugStack(&state->renderer, &state->transientArena, dt);
|
||||||
|
renderConsole(&state->renderer, &state->transientArena);
|
||||||
debug_clearCounter();
|
debug_clearCounter();
|
||||||
}
|
}
|
||||||
|
130
src/Renderer.c
130
src/Renderer.c
@ -75,7 +75,7 @@ INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color,
|
|||||||
// NOTE(doyle): Mark first vertex as degenerate vertex, but where we
|
// NOTE(doyle): Mark first vertex as degenerate vertex, but where we
|
||||||
// request wireframe mode- we can't use degenerate vertexes for line
|
// request wireframe mode- we can't use degenerate vertexes for line
|
||||||
// mode
|
// mode
|
||||||
if (!(flags & renderflag_wireframe)) group->vertexIndex++;
|
group->vertexIndex++;
|
||||||
group->init = TRUE;
|
group->init = TRUE;
|
||||||
group->tex = tex;
|
group->tex = tex;
|
||||||
group->color = color;
|
group->color = color;
|
||||||
@ -158,6 +158,7 @@ INTERNAL void bufferRenderGroupToGL(Renderer *renderer, RenderGroup *group)
|
|||||||
INTERNAL void applyRotationToVertexes(v2 pos, v2 pivotPoint, Radians rotate,
|
INTERNAL void applyRotationToVertexes(v2 pos, v2 pivotPoint, Radians rotate,
|
||||||
Vertex *vertexList, i32 vertexListSize)
|
Vertex *vertexList, i32 vertexListSize)
|
||||||
{
|
{
|
||||||
|
if (rotate == 0) return;
|
||||||
// NOTE(doyle): Move the world origin to the base position of the object.
|
// 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
|
// Then move the origin to the pivot point (e.g. center of object) and
|
||||||
// rotate from that point.
|
// rotate from that point.
|
||||||
@ -238,7 +239,6 @@ INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size,
|
|||||||
|
|
||||||
result.vertex[3].pos = V2(vertexPair.z, vertexPair.y); // Bottom right
|
result.vertex[3].pos = V2(vertexPair.z, vertexPair.y); // Bottom right
|
||||||
result.vertex[3].texCoord = V2(texRectNdc.z, texRectNdc.y);
|
result.vertex[3].texCoord = V2(texRectNdc.z, texRectNdc.y);
|
||||||
if (rotate == 0) return result;
|
|
||||||
|
|
||||||
// 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
|
||||||
@ -266,7 +266,6 @@ INTERNAL RenderTriangle_ createRenderTriangle(Renderer *renderer,
|
|||||||
result.vertex[2].pos = triangle.points[2];
|
result.vertex[2].pos = triangle.points[2];
|
||||||
result.vertex[2].texCoord = V2(texRectNdc.z, texRectNdc.w);
|
result.vertex[2].texCoord = V2(texRectNdc.z, texRectNdc.w);
|
||||||
|
|
||||||
if (rotate == 0) return result;
|
|
||||||
applyRotationToVertexes(triangle.points[0], pivotPoint, rotate,
|
applyRotationToVertexes(triangle.points[0], pivotPoint, rotate,
|
||||||
result.vertex, ARRAY_COUNT(result.vertex));
|
result.vertex, ARRAY_COUNT(result.vertex));
|
||||||
|
|
||||||
@ -286,35 +285,38 @@ INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *group)
|
|||||||
{
|
{
|
||||||
ASSERT(group->mode < rendermode_invalid);
|
ASSERT(group->mode < rendermode_invalid);
|
||||||
|
|
||||||
u32 drawMethod = GL_TRIANGLE_STRIP;
|
|
||||||
if (group->flags & renderflag_wireframe)
|
if (group->flags & renderflag_wireframe)
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
else
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
GL_CHECK_ERROR();
|
||||||
|
|
||||||
|
if (group->flags & renderflag_no_texture)
|
||||||
{
|
{
|
||||||
drawMethod = GL_LINE_LOOP;
|
|
||||||
renderer->activeShaderId =
|
renderer->activeShaderId =
|
||||||
renderer->shaderList[shaderlist_default_no_tex];
|
renderer->shaderList[shaderlist_default_no_tex];
|
||||||
|
shader_use(renderer->activeShaderId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
renderer->activeShaderId = renderer->shaderList[shaderlist_default];
|
renderer->activeShaderId = renderer->shaderList[shaderlist_default];
|
||||||
|
shader_use(renderer->activeShaderId);
|
||||||
|
Texture *tex = group->tex;
|
||||||
|
if (tex)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex->id);
|
||||||
|
shader_uniformSet1i(renderer->activeShaderId, "tex", 0);
|
||||||
|
GL_CHECK_ERROR();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shader_use(renderer->activeShaderId);
|
|
||||||
|
|
||||||
/* Set color modulation value */
|
/* Set color modulation value */
|
||||||
shader_uniformSetVec4f(renderer->activeShaderId, "spriteColor",
|
shader_uniformSetVec4f(renderer->activeShaderId, "spriteColor",
|
||||||
group->color);
|
group->color);
|
||||||
GL_CHECK_ERROR();
|
|
||||||
|
|
||||||
Texture *tex = group->tex;
|
|
||||||
if (tex)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tex->id);
|
|
||||||
shader_uniformSet1i(renderer->activeShaderId, "tex", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindVertexArray(renderer->vao[group->mode]);
|
glBindVertexArray(renderer->vao[group->mode]);
|
||||||
glDrawArrays(drawMethod, 0, renderer->numVertexesInVbo);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo);
|
||||||
GL_CHECK_ERROR();
|
GL_CHECK_ERROR();
|
||||||
debug_countIncrement(debugcount_drawArrays);
|
debug_countIncrement(debugcount_drawArrays);
|
||||||
|
|
||||||
@ -322,6 +324,7 @@ INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *group)
|
|||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
GL_CHECK_ERROR();
|
GL_CHECK_ERROR();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderTex renderer_createNullRenderTex(AssetManager *const assetManager)
|
RenderTex renderer_createNullRenderTex(AssetManager *const assetManager)
|
||||||
@ -344,44 +347,33 @@ void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size,
|
|||||||
RenderQuad_ quad = createRenderQuad(renderer, posInCameraSpace, size,
|
RenderQuad_ quad = createRenderQuad(renderer, posInCameraSpace, size,
|
||||||
pivotPoint, rotate, *renderTex);
|
pivotPoint, rotate, *renderTex);
|
||||||
|
|
||||||
// addRenderQuadToRenderGroup
|
/*
|
||||||
if (flags & renderflag_wireframe)
|
NOTE(doyle): Entity rendering is always done in two pairs of
|
||||||
{
|
triangles, i.e. quad. To batch render quads as a triangle strip, we
|
||||||
Vertex vertexList[4] = {quad.vertex[0], quad.vertex[1], quad.vertex[3],
|
need to create zero-area triangles which OGL will omit from
|
||||||
quad.vertex[2]};
|
rendering. Render groups are initialised with 1 degenerate vertex and
|
||||||
addVertexToRenderGroup(renderer, renderTex->tex, color, vertexList,
|
then the first two vertexes sent to the render group are the same to
|
||||||
ARRAY_COUNT(vertexList), rendermode_quad,
|
form 1 zero-area triangle strip.
|
||||||
flags);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
NOTE(doyle): Entity rendering is always done in two pairs of
|
|
||||||
triangles, i.e. quad. To batch render quads as a triangle strip, we
|
|
||||||
need to create zero-area triangles which OGL will omit from
|
|
||||||
rendering. Render groups are initialised with 1 degenerate vertex and
|
|
||||||
then the first two vertexes sent to the render group are the same to
|
|
||||||
form 1 zero-area triangle strip.
|
|
||||||
|
|
||||||
A degenerate vertex has to be copied from the last vertex in the
|
A degenerate vertex has to be copied from the last vertex in the
|
||||||
rendering quad, to repeat this process as more entities are
|
rendering quad, to repeat this process as more entities are
|
||||||
renderered.
|
renderered.
|
||||||
|
|
||||||
Alternative implementation is recognising if the rendered
|
Alternative implementation is recognising if the rendered
|
||||||
entity is the first in its render group, then we don't need to init
|
entity is the first in its render group, then we don't need to init
|
||||||
a degenerate vertex, and only at the end of its vertex list. But on
|
a degenerate vertex, and only at the end of its vertex list. But on
|
||||||
subsequent renders, we need a degenerate vertex at the front to
|
subsequent renders, we need a degenerate vertex at the front to
|
||||||
create the zero-area triangle strip.
|
create the zero-area triangle strip.
|
||||||
|
|
||||||
|
The first has been chosen for simplicity of code, at the cost of
|
||||||
|
1 degenerate vertex at the start of each render group.
|
||||||
|
*/
|
||||||
|
|
||||||
The first has been chosen for simplicity of code, at the cost of
|
|
||||||
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, flags);
|
ARRAY_COUNT(vertexList), rendermode_quad, flags);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer_triangle(Renderer *const renderer, Rect camera,
|
void renderer_triangle(Renderer *const renderer, Rect camera,
|
||||||
@ -401,9 +393,13 @@ void renderer_triangle(Renderer *const renderer, Rect camera,
|
|||||||
RenderTriangle_ renderTriangle = createRenderTriangle(
|
RenderTriangle_ renderTriangle = createRenderTriangle(
|
||||||
renderer, triangleInCamSpace, pivotPoint, rotate, *renderTex);
|
renderer, triangleInCamSpace, pivotPoint, rotate, *renderTex);
|
||||||
|
|
||||||
addVertexToRenderGroup(
|
// NOTE(doyle): Create degenerate vertex setup
|
||||||
renderer, renderTex->tex, color, renderTriangle.vertex,
|
Vertex vertexList[5] = {renderTriangle.vertex[0], renderTriangle.vertex[0],
|
||||||
ARRAY_COUNT(renderTriangle.vertex), rendermode_triangle, flags);
|
renderTriangle.vertex[1], renderTriangle.vertex[2],
|
||||||
|
renderTriangle.vertex[2]};
|
||||||
|
|
||||||
|
addVertexToRenderGroup(renderer, renderTex->tex, color, vertexList,
|
||||||
|
ARRAY_COUNT(vertexList), rendermode_triangle, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera,
|
void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera,
|
||||||
@ -474,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, Radians rotate, v4 color, RenderFlags flags)
|
v2 pivotPoint, Degrees rotate, v4 color, RenderFlags flags)
|
||||||
{
|
{
|
||||||
// TODO(doyle): Batch into render groups
|
// TODO(doyle): Batch into render groups
|
||||||
|
|
||||||
@ -518,8 +514,36 @@ void renderer_entity(Renderer *renderer, Rect camera, Entity *entity,
|
|||||||
renderTex.texRect = texRect;
|
renderTex.texRect = texRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer_rect(renderer, camera, entity->pos, entity->size, pivotPoint,
|
Radians totalRotation = DEGREES_TO_RADIANS((entity->rotation + rotate));
|
||||||
entity->rotation + rotate, &renderTex, color, flags);
|
if (entity->renderMode == rendermode_quad)
|
||||||
|
{
|
||||||
|
renderer_rect(renderer, camera, entity->pos, entity->size,
|
||||||
|
pivotPoint, totalRotation, &renderTex,
|
||||||
|
color, flags);
|
||||||
|
}
|
||||||
|
else if (entity->renderMode == rendermode_triangle)
|
||||||
|
{
|
||||||
|
TrianglePoints triangle = {0};
|
||||||
|
|
||||||
|
v2 entityPWithOffset = v2_add(entity->pos, entity->offset);
|
||||||
|
v2 triangleTopPoint =
|
||||||
|
V2(entityPWithOffset.x + (entity->size.w * 0.5f),
|
||||||
|
entityPWithOffset.y + entity->size.h);
|
||||||
|
|
||||||
|
v2 triangleRightSide =
|
||||||
|
V2(entityPWithOffset.x + entity->size.w, entityPWithOffset.y);
|
||||||
|
|
||||||
|
triangle.points[0] = entityPWithOffset;
|
||||||
|
triangle.points[1] = triangleRightSide;
|
||||||
|
triangle.points[2] = triangleTopPoint;
|
||||||
|
|
||||||
|
renderer_triangle(renderer, camera, triangle, pivotPoint,
|
||||||
|
totalRotation, &renderTex, color, flags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(INVALID_CODE_PATH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@ typedef struct GameState {
|
|||||||
i32 entityIndex;
|
i32 entityIndex;
|
||||||
f32 pixelsPerMeter;
|
f32 pixelsPerMeter;
|
||||||
|
|
||||||
|
v2 worldSize;
|
||||||
|
|
||||||
Rect camera;
|
Rect camera;
|
||||||
|
|
||||||
AssetManager assetManager;
|
AssetManager assetManager;
|
||||||
|
@ -27,6 +27,7 @@ void debug_recursivePrintXmlTree(XmlNode *root, i32 levelsDeep);
|
|||||||
|
|
||||||
void debug_countIncrement(enum DebugCount id);
|
void debug_countIncrement(enum DebugCount id);
|
||||||
void debug_clearCounter();
|
void debug_clearCounter();
|
||||||
|
|
||||||
#define DEBUG_LOG(string) debug_consoleLog(string, __FILE__, __LINE__);
|
#define DEBUG_LOG(string) debug_consoleLog(string, __FILE__, __LINE__);
|
||||||
void debug_consoleLog(char *string, char *file, int lineNum);
|
void debug_consoleLog(char *string, char *file, int lineNum);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "Dengine/Assets.h"
|
#include "Dengine/Assets.h"
|
||||||
#include "Dengine/Common.h"
|
#include "Dengine/Common.h"
|
||||||
|
#include "Dengine/Renderer.h"
|
||||||
|
|
||||||
typedef struct AudioRenderer AudioRenderer;
|
typedef struct AudioRenderer AudioRenderer;
|
||||||
|
|
||||||
@ -40,12 +41,16 @@ typedef struct Entity
|
|||||||
i32 numChilds;
|
i32 numChilds;
|
||||||
|
|
||||||
v2 pos;
|
v2 pos;
|
||||||
v2 velocity;
|
v2 dP;
|
||||||
|
|
||||||
v2 hitbox;
|
v2 hitbox;
|
||||||
v2 size;
|
v2 size;
|
||||||
|
v2 offset;
|
||||||
|
|
||||||
|
enum RenderMode renderMode;
|
||||||
|
|
||||||
f32 scale;
|
f32 scale;
|
||||||
f32 rotation;
|
Degrees rotation;
|
||||||
|
|
||||||
b32 invisible;
|
b32 invisible;
|
||||||
|
|
||||||
|
@ -7,11 +7,12 @@
|
|||||||
#define MATH_PI 3.14159265359f
|
#define MATH_PI 3.14159265359f
|
||||||
#define SQUARED(x) (x * x)
|
#define SQUARED(x) (x * x)
|
||||||
#define ABS(x) ((x) > 0 ? (x) : -(x))
|
#define ABS(x) ((x) > 0 ? (x) : -(x))
|
||||||
#define DEGREES_TO_RADIANS(x) (x * (MATH_PI / 180.0f))
|
#define DEGREES_TO_RADIANS(x) ((x * (MATH_PI / 180.0f)))
|
||||||
#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;
|
typedef f32 Radians;
|
||||||
|
typedef f32 Degrees;
|
||||||
|
|
||||||
INTERNAL inline f32 math_acosf(f32 a)
|
INTERNAL inline f32 math_acosf(f32 a)
|
||||||
{
|
{
|
||||||
@ -19,12 +20,31 @@ INTERNAL inline f32 math_acosf(f32 a)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL inline Radians math_cosf(Radians a)
|
||||||
|
{
|
||||||
|
Radians result = cosf(a);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL inline Radians math_sinf(Radians a)
|
||||||
|
{
|
||||||
|
Radians result = sinf(a);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
INTERNAL inline f32 math_atan2f(f32 y, f32 x)
|
INTERNAL inline f32 math_atan2f(f32 y, f32 x)
|
||||||
{
|
{
|
||||||
f32 result = atan2f(y, x);
|
f32 result = atan2f(y, x);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL inline f32 math_tanf(Radians angle)
|
||||||
|
{
|
||||||
|
f32 result = tanf(angle);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* VECTORS */
|
/* VECTORS */
|
||||||
typedef union v2
|
typedef union v2
|
||||||
{
|
{
|
||||||
|
@ -32,6 +32,7 @@ typedef struct TrianglePoints {
|
|||||||
typedef u32 RenderFlags;
|
typedef u32 RenderFlags;
|
||||||
enum RenderFlag {
|
enum RenderFlag {
|
||||||
renderflag_wireframe = 0x1,
|
renderflag_wireframe = 0x1,
|
||||||
|
renderflag_no_texture = 0x2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RenderMode
|
enum RenderMode
|
||||||
@ -47,6 +48,7 @@ typedef struct RenderGroup
|
|||||||
b32 init;
|
b32 init;
|
||||||
RenderFlags flags;
|
RenderFlags flags;
|
||||||
enum RenderMode mode;
|
enum RenderMode mode;
|
||||||
|
u32 glRenderMode;
|
||||||
|
|
||||||
Texture *tex;
|
Texture *tex;
|
||||||
v4 color;
|
v4 color;
|
||||||
@ -112,7 +114,7 @@ inline void renderer_staticString(Renderer *const renderer, MemoryArena_ *arena,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void renderer_entity(Renderer *renderer, Rect camera, Entity *entity,
|
void renderer_entity(Renderer *renderer, Rect camera, Entity *entity,
|
||||||
v2 pivotPoint, Radians rotate, v4 color,
|
v2 pivotPoint, Degrees rotate, v4 color,
|
||||||
RenderFlags flags);
|
RenderFlags flags);
|
||||||
|
|
||||||
void renderer_renderGroups(Renderer *renderer);
|
void renderer_renderGroups(Renderer *renderer);
|
||||||
|
Loading…
Reference in New Issue
Block a user