Add tile grid and atlas concept to game
This commit is contained in:
parent
b7063963b8
commit
e638724c75
@ -8,14 +8,20 @@ GLOBAL_VAR AssetManager assetManager;
|
|||||||
|
|
||||||
Texture *asset_getTexture(const enum TexList type)
|
Texture *asset_getTexture(const enum TexList type)
|
||||||
{
|
{
|
||||||
// NOTE(doyle): Since we're using a map, the count of an object can
|
|
||||||
// only be 1 or 0
|
|
||||||
if (type < texlist_count)
|
if (type < texlist_count)
|
||||||
return &assetManager.textures[type];
|
return &assetManager.textures[type];
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TexAtlas *asset_getTextureAtlas(const enum TexList type)
|
||||||
|
{
|
||||||
|
if (type < texlist_count)
|
||||||
|
return &assetManager.texAtlas[type];
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const i32 asset_loadTextureImage(const char *const path, const enum TexList type)
|
const i32 asset_loadTextureImage(const char *const path, const enum TexList type)
|
||||||
{
|
{
|
||||||
/* Open the texture image */
|
/* Open the texture image */
|
||||||
|
@ -2,16 +2,23 @@
|
|||||||
#include <Dengine/Renderer.h>
|
#include <Dengine/Renderer.h>
|
||||||
|
|
||||||
void renderer_entity(Renderer *renderer, Entity *entity, f32 rotate, v3 color)
|
void renderer_entity(Renderer *renderer, Entity *entity, f32 rotate, v3 color)
|
||||||
|
{
|
||||||
|
renderer_object(renderer, entity->pos, entity->size, rotate, color,
|
||||||
|
entity->tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderer_object(Renderer *renderer, v2 pos, v2 size, f32 rotate, v3 color,
|
||||||
|
Texture *tex)
|
||||||
{
|
{
|
||||||
shader_use(renderer->shader);
|
shader_use(renderer->shader);
|
||||||
mat4 transMatrix = mat4_translate(entity->pos.x, entity->pos.y, 0.0f);
|
mat4 transMatrix = mat4_translate(pos.x, pos.y, 0.0f);
|
||||||
mat4 rotateMatrix = mat4_rotate(rotate, 0.0f, 0.0f, 1.0f);
|
mat4 rotateMatrix = mat4_rotate(rotate, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
// NOTE(doyle): We draw everything as a unit square in OGL. Scale it to size
|
// NOTE(doyle): We draw everything as a unit square in OGL. Scale it to size
|
||||||
// TODO(doyle): We should have a notion of hitbox size and texture size
|
// TODO(doyle): We should have a notion of hitbox size and texture size
|
||||||
// we're going to render so we can draw textures that may be bigger than the
|
// we're going to render so we can draw textures that may be bigger than the
|
||||||
// entity, (slightly) but keep a consistent bounding box
|
// entity, (slightly) but keep a consistent bounding box
|
||||||
mat4 scaleMatrix = mat4_scale(entity->size.x, entity->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));
|
||||||
shader_uniformSetMat4fv(renderer->shader, "model", model);
|
shader_uniformSetMat4fv(renderer->shader, "model", model);
|
||||||
@ -21,9 +28,12 @@ void renderer_entity(Renderer *renderer, Entity *entity, f32 rotate, v3 color)
|
|||||||
// this->shader->uniformSetVec3f("spriteColor", color);
|
// this->shader->uniformSetVec3f("spriteColor", color);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, entity->tex->id);
|
|
||||||
shader_uniformSet1i(renderer->shader, "tex", 0);
|
if (tex)
|
||||||
glCheckError();
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex->id);
|
||||||
|
shader_uniformSet1i(renderer->shader, "tex", 0);
|
||||||
|
}
|
||||||
|
|
||||||
glBindVertexArray(renderer->vao);
|
glBindVertexArray(renderer->vao);
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
@ -32,11 +32,45 @@ void worldTraveller_gameInit(GameState *state)
|
|||||||
/* Initialise assets */
|
/* Initialise assets */
|
||||||
asset_loadTextureImage(
|
asset_loadTextureImage(
|
||||||
"data/textures/WorldTraveller/TerraSprite1024.png", texlist_hero);
|
"data/textures/WorldTraveller/TerraSprite1024.png", texlist_hero);
|
||||||
|
|
||||||
|
asset_loadTextureImage(
|
||||||
|
"data/textures/WorldTraveller/Terrain.png", texlist_terrain);
|
||||||
|
TexAtlas *terrainAtlas = asset_getTextureAtlas(texlist_terrain);
|
||||||
|
f32 atlasTileSize = 128.0f;
|
||||||
|
terrainAtlas->texRect[terraincoords_ground] =
|
||||||
|
V4(384.0f, 512.0f, 384.0f + atlasTileSize, 512.0f + atlasTileSize);
|
||||||
|
|
||||||
asset_loadShaderFiles("data/shaders/sprite.vert.glsl",
|
asset_loadShaderFiles("data/shaders/sprite.vert.glsl",
|
||||||
"data/shaders/sprite.frag.glsl", shaderlist_sprite);
|
"data/shaders/sprite.frag.glsl", shaderlist_sprite);
|
||||||
glCheckError();
|
glCheckError();
|
||||||
|
|
||||||
state->state = state_active;
|
state->state = state_active;
|
||||||
|
state->tileSize = 32;
|
||||||
|
state->currWorldIndex = 0;
|
||||||
|
|
||||||
|
/* Init world tiles */
|
||||||
|
i32 highestSquaredValue = 1;
|
||||||
|
while (squared(highestSquaredValue) < ARRAY_COUNT(state->world[0].tiles))
|
||||||
|
highestSquaredValue++;
|
||||||
|
|
||||||
|
const i32 worldSize = highestSquaredValue - 1;
|
||||||
|
|
||||||
|
// NOTE(doyle): Origin is center of the world
|
||||||
|
for (i32 i = 0; i < ARRAY_COUNT(state->world); i++)
|
||||||
|
{
|
||||||
|
for (i32 y = 0; y < worldSize; y++)
|
||||||
|
{
|
||||||
|
for (i32 x = 0; x < worldSize; x++)
|
||||||
|
{
|
||||||
|
i32 packedDimension = y * worldSize + x;
|
||||||
|
World *world = state->world;
|
||||||
|
|
||||||
|
world[i].texType = texlist_terrain;
|
||||||
|
world[i].tiles[packedDimension].pos =
|
||||||
|
V2(CAST(f32) x, CAST(f32) y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Init hero */
|
/* Init hero */
|
||||||
Entity heroEnt = {V2(0.0f, 0.0f),
|
Entity heroEnt = {V2(0.0f, 0.0f),
|
||||||
@ -268,9 +302,27 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
|
|||||||
parseInput(state, dt);
|
parseInput(state, dt);
|
||||||
glCheckError();
|
glCheckError();
|
||||||
|
|
||||||
|
World *world = &state->world[state->currWorldIndex];
|
||||||
|
TexAtlas *worldAtlas = asset_getTextureAtlas(world->texType);
|
||||||
|
Texture *worldTex = asset_getTexture(world->texType);
|
||||||
|
|
||||||
|
f32 ndcFactor = 1.0f / CAST(f32)worldTex->width;
|
||||||
|
for (i32 i = 0; i < ARRAY_COUNT(world->tiles); i++)
|
||||||
|
{
|
||||||
|
Tile tile = world->tiles[i];
|
||||||
|
v2 tileSize = V2(CAST(f32)state->tileSize, CAST(f32)state->tileSize);
|
||||||
|
v2 tilePosInPixel = v2_scale(tile.pos, tileSize.x);
|
||||||
|
|
||||||
|
v4 texNDC =
|
||||||
|
v4_scale(worldAtlas->texRect[terraincoords_ground], ndcFactor);
|
||||||
|
updateBufferObject(state->renderer.vbo, texNDC);
|
||||||
|
renderer_object(&state->renderer, tilePosInPixel, tileSize, 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];
|
||||||
f32 ndcFactor = 1.0f / CAST(f32) hero->tex->width;
|
ndcFactor = 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++)
|
||||||
|
@ -80,7 +80,6 @@ int main()
|
|||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
GameState worldTraveller = {0};
|
GameState worldTraveller = {0};
|
||||||
worldTraveller.state = state_active;
|
|
||||||
worldTraveller.width = CAST(i32)frameBufferSize.x;
|
worldTraveller.width = CAST(i32)frameBufferSize.x;
|
||||||
worldTraveller.height = CAST(i32)frameBufferSize.y;
|
worldTraveller.height = CAST(i32)frameBufferSize.y;
|
||||||
|
|
||||||
@ -94,7 +93,7 @@ int main()
|
|||||||
#if 0
|
#if 0
|
||||||
// TODO(doyle): Get actual monitor refresh rate
|
// TODO(doyle): Get actual monitor refresh rate
|
||||||
i32 monitorRefreshHz = 60;
|
i32 monitorRefreshHz = 60;
|
||||||
f32 targetSecondsPerFrame = 1.0f / static_cast<f32>(monitorRefreshHz);
|
f32 targetSecondsPerFrame = 1.0f / CAST(f32)(monitorRefreshHz);
|
||||||
#else
|
#else
|
||||||
// TODO(doyle): http://gafferongames.com/game-physics/fix-your-timestep/
|
// TODO(doyle): http://gafferongames.com/game-physics/fix-your-timestep/
|
||||||
// NOTE(doyle): Prevent glfwSwapBuffer until a vertical retrace has
|
// NOTE(doyle): Prevent glfwSwapBuffer until a vertical retrace has
|
||||||
@ -125,7 +124,7 @@ int main()
|
|||||||
// TODO(doyle): Busy waiting, should sleep
|
// TODO(doyle): Busy waiting, should sleep
|
||||||
while (secondsElapsed < targetSecondsPerFrame)
|
while (secondsElapsed < targetSecondsPerFrame)
|
||||||
{
|
{
|
||||||
endTime = static_cast<f32>(glfwGetTime());
|
endTime = CAST(f32)(glfwGetTime());
|
||||||
secondsElapsed = endTime - startTime;
|
secondsElapsed = endTime - startTime;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
enum TexList
|
enum TexList
|
||||||
{
|
{
|
||||||
texlist_hero,
|
texlist_hero,
|
||||||
|
texlist_terrain,
|
||||||
texlist_count,
|
texlist_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -16,10 +17,24 @@ enum ShaderList
|
|||||||
shaderlist_count,
|
shaderlist_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TerrainCoords
|
||||||
|
{
|
||||||
|
terraincoords_ground,
|
||||||
|
terraincoords_count,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct TexAtlas
|
||||||
|
{
|
||||||
|
// TODO(doyle): String hash based lookup
|
||||||
|
v4 texRect[16];
|
||||||
|
|
||||||
|
} TexAtlas;
|
||||||
|
|
||||||
// TODO(doyle): Switch to hash based lookup
|
// TODO(doyle): Switch to hash based lookup
|
||||||
typedef struct AssetManager
|
typedef struct AssetManager
|
||||||
{
|
{
|
||||||
Texture textures[256];
|
Texture textures[256];
|
||||||
|
TexAtlas texAtlas[256];
|
||||||
Shader shaders[256];
|
Shader shaders[256];
|
||||||
} AssetManager;
|
} AssetManager;
|
||||||
|
|
||||||
@ -27,6 +42,7 @@ extern AssetManager assetManager;
|
|||||||
|
|
||||||
/* Texture */
|
/* Texture */
|
||||||
Texture *asset_getTexture(const enum TexList type);
|
Texture *asset_getTexture(const enum TexList type);
|
||||||
|
TexAtlas *asset_getTextureAtlas(const enum TexList type);
|
||||||
const i32 asset_loadTextureImage(const char *const path,
|
const i32 asset_loadTextureImage(const char *const path,
|
||||||
const enum TexList type);
|
const enum TexList type);
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ typedef struct Entity
|
|||||||
SpriteAnim anim[16];
|
SpriteAnim anim[16];
|
||||||
i32 freeAnimIndex;
|
i32 freeAnimIndex;
|
||||||
i32 currAnimIndex;
|
i32 currAnimIndex;
|
||||||
|
|
||||||
} Entity;
|
} Entity;
|
||||||
|
|
||||||
INTERNAL inline v4 getEntityScreenRect(Entity entity)
|
INTERNAL inline v4 getEntityScreenRect(Entity entity)
|
||||||
|
@ -15,4 +15,7 @@ typedef struct Renderer
|
|||||||
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,
|
||||||
|
Texture *tex);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,9 +12,20 @@ enum State
|
|||||||
{
|
{
|
||||||
state_active,
|
state_active,
|
||||||
state_menu,
|
state_menu,
|
||||||
state_win
|
state_win,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct Tile
|
||||||
|
{
|
||||||
|
v2 pos;
|
||||||
|
} Tile;
|
||||||
|
|
||||||
|
typedef struct World
|
||||||
|
{
|
||||||
|
Tile tiles[2048];
|
||||||
|
enum TexList texType;
|
||||||
|
} World;
|
||||||
|
|
||||||
typedef struct GameState
|
typedef struct GameState
|
||||||
{
|
{
|
||||||
enum State state;
|
enum State state;
|
||||||
@ -24,6 +35,10 @@ typedef struct GameState
|
|||||||
Renderer renderer;
|
Renderer renderer;
|
||||||
i32 heroIndex;
|
i32 heroIndex;
|
||||||
|
|
||||||
|
World world[4];
|
||||||
|
i32 currWorldIndex;
|
||||||
|
i32 tileSize;
|
||||||
|
|
||||||
// TODO(doyle): Make size of list dynamic
|
// TODO(doyle): Make size of list dynamic
|
||||||
Entity entityList[256];
|
Entity entityList[256];
|
||||||
i32 freeEntityIndex;
|
i32 freeEntityIndex;
|
||||||
|
Loading…
Reference in New Issue
Block a user