Batch tiles to single vbo at render pass
This commit is contained in:
parent
fd3a353fdd
commit
f53325cc6a
Binary file not shown.
@ -21,6 +21,7 @@ void renderer_object(Renderer *renderer, v2 pos, v2 size, f32 rotate, v3 color,
|
|||||||
mat4 scaleMatrix = mat4_scale(size.x, size.y, 1.0f);
|
mat4 scaleMatrix = mat4_scale(size.x, size.y, 1.0f);
|
||||||
|
|
||||||
mat4 model = mat4_mul(transMatrix, mat4_mul(rotateMatrix, scaleMatrix));
|
mat4 model = mat4_mul(transMatrix, mat4_mul(rotateMatrix, scaleMatrix));
|
||||||
|
//mat4 model = mat4_mul(transMatrix, rotateMatrix);
|
||||||
shader_uniformSetMat4fv(renderer->shader, "model", model);
|
shader_uniformSetMat4fv(renderer->shader, "model", model);
|
||||||
glCheckError();
|
glCheckError();
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ void renderer_object(Renderer *renderer, v2 pos, v2 size, f32 rotate, v3 color,
|
|||||||
}
|
}
|
||||||
|
|
||||||
glBindVertexArray(renderer->vao);
|
glBindVertexArray(renderer->vao);
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
@ -6,24 +6,15 @@
|
|||||||
//choose to load assets outside of WorldTraveller!
|
//choose to load assets outside of WorldTraveller!
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void updateBufferObject(GLuint vbo, v4 texNDC)
|
void updateBufferObject(Renderer *renderer, RenderQuad *quads, i32 numQuads)
|
||||||
{
|
{
|
||||||
// TODO(doyle): We assume that vbo and vao are assigned
|
// TODO(doyle): We assume that vbo and vao are assigned
|
||||||
// NOTE(doyle): Draws a series of triangles (three-sided polygons) using
|
const i32 numVertexesInQuad = 4;
|
||||||
// vertices v0, v1, v2, then v2, v1, v3 (note the order)
|
renderer->numVertexesInVbo = numQuads * numVertexesInQuad;
|
||||||
v4 vertices[] = {
|
|
||||||
// x y s t
|
|
||||||
{0.0f, 1.0f, texNDC.x, texNDC.y}, // Top left
|
|
||||||
{0.0f, 0.0f, texNDC.x, texNDC.w}, // Bottom left
|
|
||||||
{1.0f, 1.0f, texNDC.z, texNDC.y}, // Top right
|
|
||||||
{1.0f, 0.0f, texNDC.z, texNDC.w}, // Bottom right
|
|
||||||
};
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
|
|
||||||
// TODO(doyle): glBufferSubData
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW);
|
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, numQuads * sizeof(RenderQuad), quads,
|
||||||
|
GL_STREAM_DRAW);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +297,12 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
|
|||||||
TexAtlas *worldAtlas = asset_getTextureAtlas(world->texType);
|
TexAtlas *worldAtlas = asset_getTextureAtlas(world->texType);
|
||||||
Texture *worldTex = asset_getTexture(world->texType);
|
Texture *worldTex = asset_getTexture(world->texType);
|
||||||
|
|
||||||
f32 ndcFactor = 1.0f / CAST(f32) worldTex->width;
|
f32 texNdcFactor = 1.0f / CAST(f32) worldTex->width;
|
||||||
|
|
||||||
|
RenderQuad worldQuads[ARRAY_COUNT(world->tiles)] = {0};
|
||||||
|
i32 quadIndex = 0;
|
||||||
|
|
||||||
|
const v2 vertexNdcFactor = V2(1.0f / state->width, 1.0f / state->height);
|
||||||
for (i32 i = 0; i < ARRAY_COUNT(world->tiles); i++)
|
for (i32 i = 0; i < ARRAY_COUNT(world->tiles); i++)
|
||||||
{
|
{
|
||||||
Tile tile = world->tiles[i];
|
Tile tile = world->tiles[i];
|
||||||
@ -316,17 +312,30 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
|
|||||||
if ((tilePosInPixel.x < state->width && tilePosInPixel.x >= 0) &&
|
if ((tilePosInPixel.x < state->width && tilePosInPixel.x >= 0) &&
|
||||||
(tilePosInPixel.y < state->height && tilePosInPixel.y >= 0))
|
(tilePosInPixel.y < state->height && tilePosInPixel.y >= 0))
|
||||||
{
|
{
|
||||||
v4 texNDC =
|
const v4 tileTexRect = worldAtlas->texRect[terraincoords_ground];
|
||||||
v4_scale(worldAtlas->texRect[terraincoords_ground], ndcFactor);
|
const v4 texRectNdc = v4_scale(tileTexRect, texNdcFactor);
|
||||||
updateBufferObject(state->renderer.vbo, texNDC);
|
|
||||||
renderer_object(&state->renderer, tilePosInPixel, tileSize, 0.0f,
|
const v4 tileRect = getRect(tilePosInPixel, tileSize);
|
||||||
V3(0, 0, 0), worldTex);
|
v4 tileRectNdc = tileRect;
|
||||||
|
|
||||||
|
tileRectNdc.e[0] *= vertexNdcFactor.w;
|
||||||
|
tileRectNdc.e[1] *= vertexNdcFactor.h;
|
||||||
|
tileRectNdc.e[2] *= vertexNdcFactor.w;
|
||||||
|
tileRectNdc.e[3] *= vertexNdcFactor.h;
|
||||||
|
|
||||||
|
RenderQuad tileQuad = renderer_createQuad(tileRectNdc, texRectNdc);
|
||||||
|
worldQuads[quadIndex++] = tileQuad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v2 screenSize = V2(CAST(f32)state->width, CAST(f32)state->height);
|
||||||
|
updateBufferObject(&state->renderer, worldQuads, quadIndex);
|
||||||
|
renderer_object(&state->renderer, V2(0.0f, 0.0f), screenSize, 0.0f,
|
||||||
|
V3(0, 0, 0), worldTex);
|
||||||
|
|
||||||
// NOTE(doyle): Factor to normalise sprite sheet rect coords to -1, 1
|
// NOTE(doyle): Factor to normalise sprite sheet rect coords to -1, 1
|
||||||
Entity *hero = &state->entityList[state->heroIndex];
|
Entity *hero = &state->entityList[state->heroIndex];
|
||||||
ndcFactor = 1.0f / CAST(f32) hero->tex->width;
|
texNdcFactor = 1.0f / CAST(f32) hero->tex->width;
|
||||||
|
|
||||||
ASSERT(state->freeEntityIndex < ARRAY_COUNT(state->entityList));
|
ASSERT(state->freeEntityIndex < ARRAY_COUNT(state->entityList));
|
||||||
for (i32 i = 0; i < state->freeEntityIndex; i++)
|
for (i32 i = 0; i < state->freeEntityIndex; i++)
|
||||||
@ -344,16 +353,17 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
|
|||||||
anim->currDuration = anim->duration;
|
anim->currDuration = anim->duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
v4 texNDC = v4_scale(currFrameRect, ndcFactor);
|
v4 texRectNdc = v4_scale(currFrameRect, texNdcFactor);
|
||||||
if (entity->direction == direction_east)
|
if (entity->direction == direction_east)
|
||||||
{
|
{
|
||||||
// NOTE(doyle): Flip the x coordinates to flip the tex
|
// NOTE(doyle): Flip the x coordinates to flip the tex
|
||||||
v4 tmpNDC = texNDC;
|
v4 tmp = texRectNdc;
|
||||||
texNDC.x = tmpNDC.z;
|
texRectNdc.x = tmp.z;
|
||||||
texNDC.z = tmpNDC.x;
|
texRectNdc.z = tmp.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBufferObject(state->renderer.vbo, texNDC);
|
RenderQuad quad = renderer_createDefaultQuad(texRectNdc);
|
||||||
|
updateBufferObject(&state->renderer, &quad, 1);
|
||||||
renderer_entity(&state->renderer, entity, 0.0f, V3(0, 0, 0));
|
renderer_entity(&state->renderer, entity, 0.0f, V3(0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,15 +39,21 @@ typedef struct Entity
|
|||||||
i32 currAnimIndex;
|
i32 currAnimIndex;
|
||||||
} Entity;
|
} Entity;
|
||||||
|
|
||||||
INTERNAL inline v4 getEntityScreenRect(Entity entity)
|
INTERNAL inline v4 getRect(v2 origin, v2 size)
|
||||||
{
|
{
|
||||||
v2 entityUpperLeftBound = v2_add(entity.pos, V2(0.0f, entity.size.y));
|
v2 upperLeftBound = v2_add(origin, V2(0.0f, size.y));
|
||||||
v2 entityLowerRightBound = v2_add(entity.pos, V2(entity.size.x, 0.0f));
|
v2 lowerRightBound = v2_add(origin, V2(size.x, 0.0f));
|
||||||
|
|
||||||
v4 result = V4(entityUpperLeftBound.x, entityUpperLeftBound.y,
|
v4 result = V4(upperLeftBound.x, upperLeftBound.y, lowerRightBound.x,
|
||||||
entityLowerRightBound.x, entityLowerRightBound.y);
|
lowerRightBound.y);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL inline v4 getEntityScreenRect(Entity entity)
|
||||||
|
{
|
||||||
|
v4 result = getRect(entity.pos, entity.size);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -10,12 +10,38 @@ typedef struct Renderer
|
|||||||
Shader *shader;
|
Shader *shader;
|
||||||
GLuint vao;
|
GLuint vao;
|
||||||
GLuint vbo;
|
GLuint vbo;
|
||||||
|
i32 numVertexesInVbo;
|
||||||
} Renderer;
|
} Renderer;
|
||||||
|
|
||||||
|
typedef struct RenderQuad
|
||||||
|
{
|
||||||
|
v4 vertex[4];
|
||||||
|
} RenderQuad;
|
||||||
|
|
||||||
void renderer_entity(Renderer *renderer, Entity *entity, f32 rotate,
|
void renderer_entity(Renderer *renderer, Entity *entity, f32 rotate,
|
||||||
v3 color);
|
v3 color);
|
||||||
|
|
||||||
void renderer_object(Renderer *renderer, v2 pos, v2 size, f32 rotate, v3 color,
|
void renderer_object(Renderer *renderer, v2 pos, v2 size, f32 rotate, v3 color,
|
||||||
Texture *tex);
|
Texture *tex);
|
||||||
|
|
||||||
|
INTERNAL inline RenderQuad renderer_createQuad(v4 quadRectNdc, v4 texRectNdc)
|
||||||
|
{
|
||||||
|
// NOTE(doyle): Draws a series of triangles (three-sided polygons) using
|
||||||
|
// vertices v0, v1, v2, then v2, v1, v3 (note the order)
|
||||||
|
RenderQuad result = {0};
|
||||||
|
result.vertex[0] = V4(quadRectNdc.x, quadRectNdc.y, texRectNdc.x, texRectNdc.y); // Top left
|
||||||
|
result.vertex[1] = V4(quadRectNdc.x, quadRectNdc.w, texRectNdc.x, texRectNdc.w); // Bottom left
|
||||||
|
result.vertex[2] = V4(quadRectNdc.z, quadRectNdc.y, texRectNdc.z, texRectNdc.y); // Top right
|
||||||
|
result.vertex[3] = V4(quadRectNdc.z, quadRectNdc.w, texRectNdc.z, texRectNdc.w); // Bottom right
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL inline RenderQuad renderer_createDefaultQuad(v4 texRectNdc)
|
||||||
|
{
|
||||||
|
RenderQuad result = {0};
|
||||||
|
v4 defaultVertices = V4(0.0f, 1.0f, 1.0f, 0.0f);
|
||||||
|
result = renderer_createQuad(defaultVertices, texRectNdc);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user