From 064d17d34c30335b1abf1dbdaa325411b0cb18eb Mon Sep 17 00:00:00 2001 From: Doyle Thai Date: Thu, 17 Nov 2016 18:15:36 +1100 Subject: [PATCH] Asteroid data merged to entity and display Asteroids move and are a part of the entity sytem. Added some debug markers for memory usage and fixed a bug in logic causing degenerate triangles to show up depending on the angle of approach towards the origin. --- src/Asteroid.c | 189 ++++++++++++++++++++++++--------- src/Debug.c | 15 +++ src/Renderer.c | 65 ++++++++---- src/include/Dengine/Entity.h | 8 ++ src/include/Dengine/Renderer.h | 13 ++- 5 files changed, 212 insertions(+), 78 deletions(-) diff --git a/src/Asteroid.c b/src/Asteroid.c index c0c2863..0a4e7ad 100644 --- a/src/Asteroid.c +++ b/src/Asteroid.c @@ -241,27 +241,24 @@ Basis getDefaultBasis(Entity *entity) #include #include -v2 *createAsteroidVertexList(MemoryArena_ *arena, v2 pos, i32 iterations) +v2 *createAsteroidVertexList(MemoryArena_ *arena, i32 iterations, + i32 asteroidRadius) { f32 iterationAngle = 360.0f / iterations; iterationAngle = DEGREES_TO_RADIANS(iterationAngle); v2 *result = memory_pushBytes(arena, iterations * sizeof(v2)); - srand(time(NULL)); for (i32 i = 0; i < iterations; i++) { - i32 randValue = rand(); - i32 asteroidRadius = (randValue % 100) + 50; - + i32 randValue = rand(); result[i] = V2(math_cosf(iterationAngle * i) * asteroidRadius, math_sinf(iterationAngle * i) * asteroidRadius); - result[i] = v2_add(result[i], pos); #if 1 - f32 displacementDist = 0.25f * asteroidRadius; + f32 displacementDist = 0.50f * asteroidRadius; i32 vertexDisplacement = - randValue % (i32)displacementDist + (i32)(displacementDist * 0.1f); + randValue % (i32)displacementDist + (i32)(displacementDist * 0.25f); i32 quadrantSize = iterations / 4; @@ -296,16 +293,17 @@ v2 *createAsteroidVertexList(MemoryArena_ *arena, v2 pos, i32 iterations) return result; } -LOCAL_PERSIST v2 *asteroidVertexList = NULL; -LOCAL_PERSIST f32 updateAsteroidListTimerThreshold = 1.0f; -LOCAL_PERSIST f32 updateAsteroidListTimer = 1.0f; void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, v2 windowSize, f32 dt) { i32 iterations = 16; + + memory_arenaInit(&state->transientArena, memory->transient, + memory->transientSize); + if (!state->init) { - + srand(time(NULL)); memory_arenaInit(&state->persistentArena, memory->persistent, memory->persistentSize); initAssetManager(state); @@ -314,8 +312,8 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, state->pixelsPerMeter = 70.0f; { // Init ship entity - Entity *ship = &state->entityList[state->entityIndex++]; - ship->id = 0; + Entity *ship = &state->entityList[state->entityIndex]; + ship->id = state->entityIndex++; ship->pos = V2(0, 0); ship->size = V2(25.0f, 50.0f); ship->hitbox = ship->size; @@ -325,7 +323,35 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, ship->direction = direction_null; ship->renderMode = rendermode_triangle; ship->tex = NULL; - ship->collides = FALSE; + ship->collides = TRUE; + + i32 numAsteroids = 10; + for (i32 i = 0; i < numAsteroids; i++) + { + Entity *asteroid = &state->entityList[state->entityIndex]; + asteroid->id = state->entityIndex++; + + i32 randValue = rand(); + i32 randX = (randValue % (i32)windowSize.w); + i32 randY = (randValue % (i32)windowSize.h); + asteroid->pos = V2i(randX, randY); + + asteroid->size = V2(100.0f, 100.0f); + asteroid->hitbox = asteroid->size; + asteroid->offset = v2_scale(asteroid->size, 0.5f); + asteroid->scale = 1; + asteroid->type = entitytype_asteroid; + asteroid->direction = direction_null; + asteroid->renderMode = rendermode_polygon; + + asteroid->numVertexPoints = 16; + asteroid->vertexPoints = createAsteroidVertexList( + &state->persistentArena, asteroid->numVertexPoints, + (i32)(asteroid->size.x * 0.5f)); + + asteroid->tex = NULL; + asteroid->collides = TRUE; + } } state->camera.min = V2(0, 0); @@ -336,20 +362,6 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, debug_init(&state->persistentArena, windowSize, state->assetManager.font); - - asteroidVertexList = - createAsteroidVertexList(&state->persistentArena, V2(500, 500), 16); - } - - memory_arenaInit(&state->transientArena, memory->transient, - memory->transientSize); - - updateAsteroidListTimer -= dt; - if (updateAsteroidListTimer < 0) - { - asteroidVertexList = createAsteroidVertexList(&state->persistentArena, - V2(500, 500), iterations); - updateAsteroidListTimer = updateAsteroidListTimerThreshold; } { @@ -411,19 +423,20 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, ddP = direction; } + Degrees rotationsPerSecond = 180.0f; if (getKeyStatus(&state->input.keys[keycode_left], readkeytype_repeat, 0.0f, dt)) { - entity->rotation += (120.0f) * dt; + entity->rotation += (rotationsPerSecond) * dt; } if (getKeyStatus(&state->input.keys[keycode_right], readkeytype_repeat, 0.0f, dt)) { - entity->rotation -= (120.0f) * dt; + entity->rotation -= (rotationsPerSecond) * dt; } - if (ddP.x != 0.0f && ddP.y != 0.0f) + if (ddP.x > 0.0f && ddP.y > 0.0f) { // NOTE(doyle): Cheese it and pre-compute the vector for // diagonal using pythagoras theorem on a unit triangle 1^2 @@ -441,9 +454,9 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, ddP = v2_scale(ddP, state->pixelsPerMeter * 25); - v2 oldDp = entity->dP; + v2 oldDp = entity->dP; v2 resistance = v2_scale(oldDp, 2.0f); - ddP = v2_sub(ddP, resistance); + ddP = v2_sub(ddP, resistance); entity->dP = v2_add(v2_scale(ddP, dt), oldDp); @@ -458,22 +471,102 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, 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); - - Basis entityBasis = getDefaultBasis(entity); - renderer_rect(&state->renderer, state->camera, entityBasis.basis, - V2(4, 4), entityBasis.pivotPoint, - DEGREES_TO_RADIANS(entity->rotation), NULL, - V4(1.0f, 0, 0, 1.0f), flags); } - } + else if (entity->type == entitytype_asteroid) + { - renderer_polygon(&state->renderer, &state->transientArena, state->camera, - asteroidVertexList, iterations, V2(0, 0), 0, NULL, - V4(0.0f, 0.0f, 1.0f, 1.0f), 0); + i32 randValue = rand(); + if (entity->direction == direction_null) + { + entity->direction = randValue % direction_count; + } + + v2 ddP = {0}; + switch (entity->direction) + { + case direction_north: + { + ddP.y = 1.0f; + } + break; + + case direction_northwest: + { + ddP.x = 1.0f; + ddP.y = 1.0f; + } + break; + + case direction_west: + { + ddP.x = -1.0f; + } + break; + + case direction_southwest: + { + ddP.x = -1.0f; + ddP.y = -1.0f; + } + break; + + case direction_south: + { + ddP.y = -1.0f; + } + break; + + case direction_southeast: + { + ddP.x = 1.0f; + ddP.y = -1.0f; + } + break; + + case direction_east: + { + ddP.x = 1.0f; + } + break; + + case direction_northeast: + { + ddP.x = 1.0f; + ddP.y = 1.0f; + } + break; + + default: + { + ASSERT(INVALID_CODE_PATH); + } + break; + } + + f32 dirOffset = (randValue % 10) / 100.0f; + v2_scale(ddP, dirOffset); + ASSERT(ddP.x <= 1.0f && ddP.y <= 1.0f); + + entity->dP = v2_scale(ddP, state->pixelsPerMeter * 2); + v2 ddPHalf = v2_scale(ddP, 0.5f); + v2 ddPHalfDtSquared = v2_scale(ddPHalf, (SQUARED(dt))); + + v2 dPDt = v2_scale(entity->dP, dt); + + entity->pos = v2_add(v2_add(ddPHalfDtSquared, dPDt), entity->pos); + } + + RenderFlags flags = renderflag_wireframe | renderflag_no_texture; + renderer_entity(&state->renderer, &state->transientArena, state->camera, + entity, pivotPoint, 0, V4(0.4f, 0.8f, 1.0f, 1.0f), + flags); + + Basis entityBasis = getDefaultBasis(entity); + renderer_rect(&state->renderer, state->camera, entityBasis.basis, + V2(4, 4), entityBasis.pivotPoint, + DEGREES_TO_RADIANS(entity->rotation), NULL, + V4(1.0f, 0, 0, 1.0f), flags); + } TrianglePoints triangle = {0}; triangle.points[0] = V2(100, 200); diff --git a/src/Debug.c b/src/Debug.c index 64ac6d2..ba6a8e3 100644 --- a/src/Debug.c +++ b/src/Debug.c @@ -272,5 +272,20 @@ void debug_drawUi(GameState *state, f32 dt) { updateAndRenderDebugStack(&state->renderer, &state->transientArena, dt); renderConsole(&state->renderer, &state->transientArena); + + MemoryArena_ *transient = &state->transientArena; + i32 transientSizeInKbs = transient->size / 1024; + i32 transientUsedInKbs = transient->used / 1024; + v2 transientUsage = V2i(transientUsedInKbs, transientSizeInKbs); + DEBUG_PUSH_VAR("Transient Size: %.0f", transient->size, "f32"); + DEBUG_PUSH_VAR("Transient Usage: %.0f/%.0f", transientUsage, "v2"); + + MemoryArena_ *persistent = &state->persistentArena; + i32 persistentSizeInKbs = persistent->size / 1024; + i32 persistentUsedInKbs = persistent->used / 1024; + v2 persistentUsage = V2i(persistentUsedInKbs, persistentSizeInKbs); + DEBUG_PUSH_VAR("Permanent Size: %.0f", persistent->size, "f32"); + DEBUG_PUSH_VAR("Permanent Usage: %.0f/%.0f", persistentUsage, "v2"); + debug_clearCounter(); } diff --git a/src/Renderer.c b/src/Renderer.c index be78ff5..ca0c07f 100644 --- a/src/Renderer.c +++ b/src/Renderer.c @@ -72,10 +72,9 @@ INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color, /* New group, unused so initialise it */ groupIsValid = TRUE; - // NOTE(doyle): Mark first vertex as degenerate vertex, but where we - // request wireframe mode- we can't use degenerate vertexes for line - // mode - group->vertexIndex++; + // NOTE(doyle): Mark first vertex as degenerate vertex + group->vertexList[group->vertexIndex++] = vertexList[0]; + group->init = TRUE; group->tex = tex; group->color = color; @@ -376,7 +375,7 @@ void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size, ARRAY_COUNT(vertexList), rendermode_quad, flags); } -void renderer_polygon(Renderer *const renderer, MemoryArena_ *arena, Rect camera, +void renderer_polygon(Renderer *const renderer, Rect camera, v2 *polygonPoints, i32 numPoints, v2 pivotPoint, Radians rotate, RenderTex *renderTex, v4 color, RenderFlags flags) @@ -390,9 +389,6 @@ void renderer_polygon(Renderer *const renderer, MemoryArena_ *arena, Rect camera if (!renderTex) renderTex = &emptyRenderTex; i32 numTrisInTriangulation = numPoints - 2; - RenderTriangle_ *polygonTriangulation = memory_pushBytes( - arena, (sizeof(RenderTriangle_) * numTrisInTriangulation)); - v2 triangulationBaseP = polygonPoints[0]; i32 triangulationIndex = 0; @@ -402,24 +398,29 @@ void renderer_polygon(Renderer *const renderer, MemoryArena_ *arena, Rect camera addVertexToRenderGroup(renderer, renderTex->tex, color, &triangulationBaseVertex, 1, rendermode_polygon, flags); + RenderTriangle_ lastRenderTriForDegeneration = {0}; for (i32 i = 1; triangulationIndex < numTrisInTriangulation; i++) { - RenderTriangle_ *tri = &polygonTriangulation[triangulationIndex++]; - tri->vertex[0].pos = triangulationBaseP; - tri->vertex[1].pos = polygonPoints[i + 1]; - tri->vertex[2].pos = polygonPoints[i]; + RenderTriangle_ tri = {0}; + tri.vertex[0].pos = triangulationBaseP; + tri.vertex[1].pos = polygonPoints[i + 1]; + tri.vertex[2].pos = polygonPoints[i]; - addVertexToRenderGroup(renderer, renderTex->tex, color, tri->vertex, 3, + addVertexToRenderGroup(renderer, renderTex->tex, color, tri.vertex, + ARRAY_COUNT(tri.vertex), rendermode_polygon, + flags); + + if (triangulationIndex++ >= numTrisInTriangulation) + { + lastRenderTriForDegeneration = tri; + } + } + for (i32 i = 0; i < 3; i++) + { + addVertexToRenderGroup(renderer, renderTex->tex, color, + &lastRenderTriForDegeneration.vertex[2], 1, rendermode_polygon, flags); } - RenderTriangle_ tri = polygonTriangulation[numTrisInTriangulation-1]; - addVertexToRenderGroup(renderer, renderTex->tex, color, &tri.vertex[2], 1, - rendermode_polygon, flags); - /* - // NOTE(doyle): Create degenerate vertex setup - Vertex triVertexList[5] = {tri->vertex[0], tri->vertex[0], tri->vertex[1], - tri->vertex[2], tri->vertex[2]}; - */ } void renderer_triangle(Renderer *const renderer, Rect camera, @@ -515,8 +516,9 @@ void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, } } -void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, - v2 pivotPoint, Degrees rotate, v4 color, RenderFlags flags) +void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena, + Rect camera, Entity *entity, v2 pivotPoint, Degrees rotate, + v4 color, RenderFlags flags) { // TODO(doyle): Add early exit on entities out of camera bounds Radians totalRotation = DEGREES_TO_RADIANS((entity->rotation + rotate)); @@ -573,6 +575,23 @@ void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, renderer_triangle(renderer, camera, triangle, pivotPoint, totalRotation, &renderTex, color, flags); } + else if (entity->renderMode == rendermode_polygon) + { + ASSERT(entity->numVertexPoints > 3); + ASSERT(entity->vertexPoints); + + v2 *offsetVertexPoints = memory_pushBytes( + transientArena, entity->numVertexPoints * sizeof(v2)); + for (i32 i = 0; i < entity->numVertexPoints; i++) + { + offsetVertexPoints[i] = + v2_add(entity->vertexPoints[i], entity->pos); + } + + renderer_polygon(renderer, camera, offsetVertexPoints, + entity->numVertexPoints, pivotPoint, totalRotation, + &renderTex, color, flags); + } else { ASSERT(INVALID_CODE_PATH); diff --git a/src/include/Dengine/Entity.h b/src/include/Dengine/Entity.h index 3682147..396b2ea 100644 --- a/src/include/Dengine/Entity.h +++ b/src/include/Dengine/Entity.h @@ -10,9 +10,14 @@ typedef struct AudioRenderer AudioRenderer; enum Direction { direction_north, + direction_northwest, direction_west, + direction_southwest, direction_south, + direction_southeast, direction_east, + direction_northeast, + direction_count, direction_null, direction_num, }; @@ -21,6 +26,7 @@ enum EntityType { entitytype_invalid, entitytype_ship, + entitytype_asteroid, entitytype_count, }; @@ -48,6 +54,8 @@ typedef struct Entity v2 offset; enum RenderMode renderMode; + v2 *vertexPoints; + i32 numVertexPoints; f32 scale; Degrees rotation; diff --git a/src/include/Dengine/Renderer.h b/src/include/Dengine/Renderer.h index 7a92723..639559f 100644 --- a/src/include/Dengine/Renderer.h +++ b/src/include/Dengine/Renderer.h @@ -88,10 +88,9 @@ void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size, v2 pivotPoint, Radians rotate, RenderTex *renderTex, v4 color, RenderFlags flags); -void renderer_polygon(Renderer *const renderer, MemoryArena_ *arena, - Rect camera, v2 *polygonPoints, i32 numPoints, - v2 pivotPoint, Radians rotate, RenderTex *renderTex, - v4 color, RenderFlags flags); +void renderer_polygon(Renderer *const renderer, Rect camera, v2 *polygonPoints, + i32 numPoints, v2 pivotPoint, Radians rotate, + RenderTex *renderTex, v4 color, RenderFlags flags); inline void renderer_staticRect(Renderer *const renderer, v2 pos, v2 size, v2 pivotPoint, Radians rotate, @@ -122,9 +121,9 @@ inline void renderer_staticString(Renderer *const renderer, MemoryArena_ *arena, pivotPoint, rotate, color, flags); } -void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, - v2 pivotPoint, Degrees rotate, v4 color, - RenderFlags flags); +void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena, + Rect camera, Entity *entity, v2 pivotPoint, Degrees rotate, + v4 color, RenderFlags flags); void renderer_renderGroups(Renderer *renderer);