diff --git a/src/Renderer.c b/src/Renderer.c index 44f151f..c62cb64 100644 --- a/src/Renderer.c +++ b/src/Renderer.c @@ -10,13 +10,39 @@ #define RENDER_BOUNDING_BOX FALSE -typedef struct RenderQuad +INTERNAL addToRenderGroup(Renderer *renderer, Texture *texture, + RenderQuad renderQuad) { - // Vertex composition - // x, y: Coordinates - // z, w: Texture Coords - v4 vertex[4]; -} RenderQuad; + /* Find vacant/matching render group */ + RenderGroup *targetGroup = NULL; + for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++) + { + RenderGroup *group = &renderer->groups[i]; + if (group->tex == NULL || group->tex->id == texture->id) + { + if (!group->tex) group->tex = texture; + targetGroup = &renderer->groups[i]; + break; + } + } + + /* Valid group, add to the render group for rendering */ + if (targetGroup) + { + if (targetGroup->quadIndex < ARRAY_COUNT(targetGroup->quads)) + { + targetGroup->quads[targetGroup->quadIndex++] = renderQuad; + } + else + { + // TODO(doyle): Log no remaining render quad slots in group + } + } + else + { + // TODO(doyle): Log no remaining render groups + } +} INTERNAL inline void flipTexCoord(v4 *texCoords, b32 flipX, b32 flipY) { @@ -48,6 +74,11 @@ INTERNAL void updateBufferObject(Renderer *const renderer, glBindBuffer(GL_ARRAY_BUFFER, 0); } +INTERNAL void bufferRenderGroupToGL(Renderer *renderer, RenderGroup *group) +{ + updateBufferObject(renderer, group->quads, group->quadIndex); +} + INTERNAL RenderQuad createTexQuad(Renderer *renderer, v4 quadRect, RenderTex renderTex) { @@ -204,9 +235,7 @@ void renderer_string(Renderer *const renderer, MemoryArena *arena, Rect camera, pos.y = baseline - (charMetric.offset.y); const v4 charRectOnScreen = - math_getRect(pos, V2(CAST(f32) font->maxSize.w, - CAST(f32) font->maxSize.h)); - + math_getRect(pos, font->maxSize); pos.x += charMetric.advance; /* Get texture out */ @@ -254,7 +283,6 @@ void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, char *frameName = anim->frameList[entityAnim->currFrame]; SubTexture animRect = asset_getAtlasSubTex(anim->atlas, frameName); - // TODO(doyle): Switch to rect v4 animTexRect = {0}; animTexRect.vec2[0] = animRect.rect.pos; animTexRect.vec2[1] = v2_add(animRect.rect.pos, animRect.rect.size); @@ -267,13 +295,44 @@ void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, } RenderTex renderTex = {entity->tex, animTexRect}; - RenderQuad entityQuad = - createDefaultTexQuad(renderer, renderTex); - updateBufferObject(renderer, &entityQuad, 1); +#if RENDERER_USE_RENDER_GROUPS + // TODO(doyle): getRect needs a better name + v2 posInCameraSpace = v2_sub(entity->pos, camera.pos); + v4 entityVertexOnScreen = math_getRect(posInCameraSpace, entity->size); + RenderQuad entityQuad = + createTexQuad(renderer, entityVertexOnScreen, renderTex); + + addToRenderGroup(renderer, entity->tex, entityQuad); +#else + RenderQuad entityQuad = createDefaultTexQuad(renderer, renderTex); + // TODO(doyle): getRect needs a better name + updateBufferObject(renderer, &entityQuad, 1); v2 posInCameraSpace = v2_sub(entity->pos, camera.pos); renderObject(renderer, posInCameraSpace, entity->size, pivotPoint, entity->rotation + rotate, color, entity->tex); +#endif + } +} + +void renderer_renderGroups(Renderer *renderer) +{ + for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++) + { + RenderGroup *currGroup = &renderer->groups[i]; + if (currGroup->tex) + { + bufferRenderGroupToGL(renderer, currGroup); + + v2 pivotPoint = V2(0, 0); + f32 rotate = 0; + v4 color = V4(1, 1, 1, 1); + renderObject(renderer, V2(0.0f, 0.0f), renderer->size, pivotPoint, + rotate, color, currGroup->tex); + + RenderGroup clear = {0}; + *currGroup = clear; + } } } diff --git a/src/WorldTraveller.c b/src/WorldTraveller.c index 2718bb7..149391f 100644 --- a/src/WorldTraveller.c +++ b/src/WorldTraveller.c @@ -640,7 +640,7 @@ INTERNAL void entityInit(GameState *state, v2 windowSize) entity_addAnim(assetManager, hero, "claudeRipperBlast"); entity_addAnim(assetManager, hero, "claudeAirSlash"); - entity_setActiveAnim(eventQueue, hero, "claudeBattleIdle"); + entity_setActiveAnim(eventQueue, hero, "claudeIdle"); /* Create a NPC */ pos = V2(hero->pos.x * 3, CAST(f32) state->tileSize); @@ -2071,22 +2071,15 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) { entity_updateAnim(eventQueue, entity, dt); /* Calculate region to render */ - - if (entity->type == entitytype_weapon) - { - renderer_entity(renderer, camera, entity, - v2_scale(entity->size, 0.5f), 0, - V4(1, 1, 1, 1.0f)); - } - else - { - renderer_entity(renderer, camera, entity, - v2_scale(entity->size, 0.5f), 0, - V4(1, 1, 1, 1)); - } + renderer_entity(renderer, camera, entity, + v2_scale(entity->size, 0.5f), 0, V4(1, 1, 1, 1.0f)); } } +#if RENDERER_USE_RENDER_GROUPS + renderer_renderGroups(renderer); +#endif + /* ***************************************** * Process Events From Entity Update Loop diff --git a/src/include/Dengine/Renderer.h b/src/include/Dengine/Renderer.h index 209662a..4f9589e 100644 --- a/src/include/Dengine/Renderer.h +++ b/src/include/Dengine/Renderer.h @@ -12,6 +12,28 @@ typedef struct MemoryArena MemoryArena; typedef struct Shader Shader; typedef struct Texture Texture; +typedef struct RenderQuad +{ + // Vertex composition + // x, y: Coordinates - of entity on screen + // z, w: Texture Coords - of texture for this quad + v4 vertex[4]; +} RenderQuad; + +typedef struct RenderTex +{ + Texture *tex; + // TODO(doyle): Switch to rect + v4 texRect; +} RenderTex; + +typedef struct RenderGroup +{ + Texture *tex; + RenderQuad quads[100]; + i32 quadIndex; +} RenderGroup; + typedef struct Renderer { Shader *shader; @@ -20,15 +42,11 @@ typedef struct Renderer i32 numVertexesInVbo; v2 vertexNdcFactor; v2 size; + + RenderGroup groups[100]; } Renderer; -typedef struct RenderTex -{ - Texture *tex; - - // TODO(doyle): Switch to rect - v4 texRect; -} RenderTex; +#define RENDERER_USE_RENDER_GROUPS TRUE // TODO(doyle): Use z-index occluding for rendering RenderTex renderer_createNullRenderTex(AssetManager *const assetManager); @@ -64,4 +82,6 @@ inline void renderer_staticString(Renderer *const renderer, MemoryArena *arena, void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, v2 pivotPoint, f32 rotate, v4 color); +void renderer_renderGroups(Renderer *renderer); + #endif