Add basic start screen
Adding a start screen led to cleaning up some initialisation processes. Dengine now formally initialises subsystems from the respective .h files instead of ad-hoc from the main game file.
This commit is contained in:
parent
c61b2022ce
commit
2fb2e6db5b
@ -22,6 +22,34 @@
|
|||||||
#include "Dengine/OpenGL.h"
|
#include "Dengine/OpenGL.h"
|
||||||
#include "Dengine/Platform.h"
|
#include "Dengine/Platform.h"
|
||||||
|
|
||||||
|
void asset_init(AssetManager *assetManager, MemoryArena_ *arena)
|
||||||
|
{
|
||||||
|
i32 texAtlasEntries = 8;
|
||||||
|
assetManager->texAtlas.size = texAtlasEntries;
|
||||||
|
assetManager->texAtlas.entries =
|
||||||
|
memory_pushBytes(arena, texAtlasEntries * sizeof(HashTableEntry));
|
||||||
|
|
||||||
|
i32 animEntries = 1024;
|
||||||
|
assetManager->anims.size = animEntries;
|
||||||
|
assetManager->anims.entries =
|
||||||
|
memory_pushBytes(arena, animEntries * sizeof(HashTableEntry));
|
||||||
|
|
||||||
|
i32 texEntries = 32;
|
||||||
|
assetManager->textures.size = texEntries;
|
||||||
|
assetManager->textures.entries =
|
||||||
|
memory_pushBytes(arena, texEntries * sizeof(HashTableEntry));
|
||||||
|
|
||||||
|
/* Create empty 1x1 4bpp black texture */
|
||||||
|
u32 bitmap = (0xFF << 24) | (0xFF << 16) | (0xFF << 8) | (0xFF << 0);
|
||||||
|
Texture *tex = asset_getFreeTexSlot(assetManager, arena, "nullTex");
|
||||||
|
*tex = texture_gen(1, 1, 4, CAST(u8 *)(&bitmap));
|
||||||
|
|
||||||
|
i32 audioEntries = 32;
|
||||||
|
assetManager->audio.size = audioEntries;
|
||||||
|
assetManager->audio.entries =
|
||||||
|
memory_pushBytes(arena, audioEntries * sizeof(HashTableEntry));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*********************************
|
*********************************
|
||||||
* Hash Table Operations
|
* Hash Table Operations
|
||||||
|
263
src/Asteroid.c
263
src/Asteroid.c
@ -1,32 +1,12 @@
|
|||||||
#include "Dengine/Asteroid.h"
|
#include "Dengine/Asteroid.h"
|
||||||
#include "Dengine/Debug.h"
|
#include "Dengine/Debug.h"
|
||||||
|
|
||||||
void initAssetManager(GameState *state)
|
INTERNAL void loadGameAssets(GameState *state)
|
||||||
{
|
{
|
||||||
AssetManager *assetManager = &state->assetManager;
|
AssetManager *assetManager = &state->assetManager;
|
||||||
MemoryArena_ *arena = &state->persistentArena;
|
MemoryArena_ *arena = &state->persistentArena;
|
||||||
|
|
||||||
i32 texAtlasEntries = 8;
|
{ // Init font assets
|
||||||
assetManager->texAtlas.size = texAtlasEntries;
|
|
||||||
assetManager->texAtlas.entries =
|
|
||||||
memory_pushBytes(arena, texAtlasEntries * sizeof(HashTableEntry));
|
|
||||||
|
|
||||||
i32 animEntries = 1024;
|
|
||||||
assetManager->anims.size = animEntries;
|
|
||||||
assetManager->anims.entries =
|
|
||||||
memory_pushBytes(arena, animEntries * sizeof(HashTableEntry));
|
|
||||||
|
|
||||||
{ // Init texture assets
|
|
||||||
i32 texEntries = 32;
|
|
||||||
assetManager->textures.size = texEntries;
|
|
||||||
assetManager->textures.entries =
|
|
||||||
memory_pushBytes(arena, texEntries * sizeof(HashTableEntry));
|
|
||||||
|
|
||||||
/* Create empty 1x1 4bpp black texture */
|
|
||||||
u32 bitmap = (0xFF << 24) | (0xFF << 16) | (0xFF << 8) | (0xFF << 0);
|
|
||||||
Texture *tex = asset_getFreeTexSlot(assetManager, arena, "nullTex");
|
|
||||||
*tex = texture_gen(1, 1, 4, CAST(u8 *)(&bitmap));
|
|
||||||
|
|
||||||
i32 result =
|
i32 result =
|
||||||
asset_loadTTFont(assetManager, arena, &state->transientArena,
|
asset_loadTTFont(assetManager, arena, &state->transientArena,
|
||||||
"C:/Windows/Fonts/Arialbd.ttf", "Arial", 15);
|
"C:/Windows/Fonts/Arialbd.ttf", "Arial", 15);
|
||||||
@ -43,12 +23,6 @@ void initAssetManager(GameState *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{ // Init audio assets
|
{ // Init audio assets
|
||||||
|
|
||||||
i32 audioEntries = 32;
|
|
||||||
assetManager->audio.size = audioEntries;
|
|
||||||
assetManager->audio.entries =
|
|
||||||
memory_pushBytes(arena, audioEntries * sizeof(HashTableEntry));
|
|
||||||
|
|
||||||
i32 result = asset_loadVorbis(assetManager, arena,
|
i32 result = asset_loadVorbis(assetManager, arena,
|
||||||
"data/audio/Asteroids/bang_large.ogg",
|
"data/audio/Asteroids/bang_large.ogg",
|
||||||
"bang_large");
|
"bang_large");
|
||||||
@ -88,66 +62,6 @@ void initAssetManager(GameState *state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initRenderer(GameState *state, v2 windowSize)
|
|
||||||
{
|
|
||||||
AssetManager *assetManager = &state->assetManager;
|
|
||||||
Renderer *renderer = &state->renderer;
|
|
||||||
renderer->size = windowSize;
|
|
||||||
|
|
||||||
// NOTE(doyle): Value to map a screen coordinate to NDC coordinate
|
|
||||||
renderer->vertexNdcFactor =
|
|
||||||
V2(1.0f / renderer->size.w, 1.0f / renderer->size.h);
|
|
||||||
renderer->groupIndexForVertexBatch = -1;
|
|
||||||
|
|
||||||
const mat4 projection =
|
|
||||||
mat4_ortho(0.0f, renderer->size.w, 0.0f, renderer->size.h, 0.0f, 1.0f);
|
|
||||||
for (i32 i = 0; i < shaderlist_count; i++)
|
|
||||||
{
|
|
||||||
renderer->shaderList[i] = asset_getShader(assetManager, i);
|
|
||||||
shader_use(renderer->shaderList[i]);
|
|
||||||
shader_uniformSetMat4fv(renderer->shaderList[i], "projection",
|
|
||||||
projection);
|
|
||||||
GL_CHECK_ERROR();
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer->activeShaderId = renderer->shaderList[shaderlist_default];
|
|
||||||
GL_CHECK_ERROR();
|
|
||||||
|
|
||||||
/* Create buffers */
|
|
||||||
glGenVertexArrays(ARRAY_COUNT(renderer->vao), renderer->vao);
|
|
||||||
glGenBuffers(ARRAY_COUNT(renderer->vbo), renderer->vbo);
|
|
||||||
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++)
|
|
||||||
{
|
|
||||||
glBindVertexArray(renderer->vao[mode]);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[mode]);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
u32 numVertexElements = 4;
|
|
||||||
u32 stride = sizeof(RenderVertex);
|
|
||||||
|
|
||||||
glVertexAttribPointer(0, numVertexElements, GL_FLOAT,
|
|
||||||
GL_FALSE, stride, (GLvoid *)0);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unbind */
|
|
||||||
GL_CHECK_ERROR();
|
|
||||||
|
|
||||||
// TODO(doyle): Lazy allocate render group capacity
|
|
||||||
renderer->groupCapacity = 4096;
|
|
||||||
for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++)
|
|
||||||
{
|
|
||||||
renderer->groups[i].vertexList =
|
|
||||||
memory_pushBytes(&state->persistentArena,
|
|
||||||
renderer->groupCapacity * sizeof(RenderVertex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
v2 *createAsteroidVertexList(MemoryArena_ *arena, i32 iterations,
|
v2 *createAsteroidVertexList(MemoryArena_ *arena, i32 iterations,
|
||||||
@ -434,19 +348,19 @@ INTERNAL void addAsteroidWithSpec(World *world, enum AsteroidSize asteroidSize,
|
|||||||
// generated
|
// generated
|
||||||
// to float back into game space
|
// to float back into game space
|
||||||
v2 newP = V2i(randX, randY);
|
v2 newP = V2i(randX, randY);
|
||||||
if (math_pointInRect(topLeftQuadrant, newP))
|
if (math_rect_contains_p(topLeftQuadrant, newP))
|
||||||
{
|
{
|
||||||
newP.y += midpoint.y;
|
newP.y += midpoint.y;
|
||||||
}
|
}
|
||||||
else if (math_pointInRect(botLeftQuadrant, newP))
|
else if (math_rect_contains_p(botLeftQuadrant, newP))
|
||||||
{
|
{
|
||||||
newP.x -= midpoint.x;
|
newP.x -= midpoint.x;
|
||||||
}
|
}
|
||||||
else if (math_pointInRect(topRightQuadrant, newP))
|
else if (math_rect_contains_p(topRightQuadrant, newP))
|
||||||
{
|
{
|
||||||
newP.y -= midpoint.y;
|
newP.y -= midpoint.y;
|
||||||
}
|
}
|
||||||
else if (math_pointInRect(botRightQuadrant, newP))
|
else if (math_rect_contains_p(botRightQuadrant, newP))
|
||||||
{
|
{
|
||||||
newP.x += midpoint.x;
|
newP.x += midpoint.x;
|
||||||
}
|
}
|
||||||
@ -556,22 +470,11 @@ INTERNAL void deleteEntity(World *world, i32 entityIndex)
|
|||||||
world->entityList[--world->entityIndex] = emptyEntity;
|
world->entityList[--world->entityIndex] = emptyEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
INTERNAL void gameUpdate(GameState *state, Memory *memory, f32 dt)
|
||||||
v2 windowSize, f32 dt)
|
|
||||||
{
|
{
|
||||||
MemoryIndex globalTransientArenaSize =
|
|
||||||
(MemoryIndex)((f32)memory->transientSize * 0.5f);
|
|
||||||
memory_arenaInit(&state->transientArena, memory->transient,
|
|
||||||
globalTransientArenaSize);
|
|
||||||
|
|
||||||
World *world = &state->world;
|
World *world = &state->world;
|
||||||
if (!state->init)
|
if (!world->init)
|
||||||
{
|
{
|
||||||
srand((u32)time(NULL));
|
|
||||||
initAssetManager(state);
|
|
||||||
initRenderer(state, windowSize);
|
|
||||||
audio_init(&state->audioManager);
|
|
||||||
|
|
||||||
world->pixelsPerMeter = 70.0f;
|
world->pixelsPerMeter = 70.0f;
|
||||||
|
|
||||||
MemoryIndex entityArenaSize =
|
MemoryIndex entityArenaSize =
|
||||||
@ -580,6 +483,10 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
u8 *arenaBase = state->transientArena.base + state->transientArena.size;
|
u8 *arenaBase = state->transientArena.base + state->transientArena.size;
|
||||||
memory_arenaInit(&world->entityArena, arenaBase, entityArenaSize);
|
memory_arenaInit(&world->entityArena, arenaBase, entityArenaSize);
|
||||||
|
|
||||||
|
world->camera.min = V2(0, 0);
|
||||||
|
world->camera.max = state->renderer.size;
|
||||||
|
world->worldSize = state->renderer.size;
|
||||||
|
|
||||||
{ // Init null entity
|
{ // Init null entity
|
||||||
Entity *nullEntity = &world->entityList[world->entityIndex++];
|
Entity *nullEntity = &world->entityList[world->entityIndex++];
|
||||||
nullEntity->id = world->entityIdCounter++;
|
nullEntity->id = world->entityIdCounter++;
|
||||||
@ -598,7 +505,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
{ // Init ship entity
|
{ // Init ship entity
|
||||||
Entity *ship = &world->entityList[world->entityIndex++];
|
Entity *ship = &world->entityList[world->entityIndex++];
|
||||||
ship->id = world->entityIdCounter++;
|
ship->id = world->entityIdCounter++;
|
||||||
ship->pos = V2(100, 100);
|
ship->pos = math_rect_get_centre(world->camera);
|
||||||
ship->size = V2(25.0f, 50.0f);
|
ship->size = V2(25.0f, 50.0f);
|
||||||
ship->hitbox = ship->size;
|
ship->hitbox = ship->size;
|
||||||
ship->offset = v2_scale(ship->size, -0.5f);
|
ship->offset = v2_scale(ship->size, -0.5f);
|
||||||
@ -636,20 +543,20 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
entitytype_asteroid_large, TRUE);
|
entitytype_asteroid_large, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
world->camera.min = V2(0, 0);
|
world->init = TRUE;
|
||||||
world->camera.max = state->renderer.size;
|
world->onInitAsteroidSpawnTimer = 1.0f;
|
||||||
world->worldSize = windowSize;
|
|
||||||
|
|
||||||
state->init = TRUE;
|
|
||||||
|
|
||||||
Font *arial15 = asset_getFont(&state->assetManager, "Arial", 15);
|
|
||||||
debug_init(&state->persistentArena, windowSize, *arial15);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (world->onInitAsteroidSpawnTimer > 0)
|
||||||
|
{
|
||||||
|
world->onInitAsteroidSpawnTimer -= dt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for (u32 i = world->asteroidCounter; i < world->numAsteroids; i++)
|
for (u32 i = world->asteroidCounter; i < world->numAsteroids; i++)
|
||||||
addAsteroid(world, (rand() % asteroidsize_count));
|
addAsteroid(world, (rand() % asteroidsize_count));
|
||||||
|
}
|
||||||
platform_processInputBuffer(&state->input, dt);
|
|
||||||
|
|
||||||
if (platform_queryKey(&state->input.keys[keycode_left_square_bracket],
|
if (platform_queryKey(&state->input.keys[keycode_left_square_bracket],
|
||||||
readkeytype_repeat, 0.2f))
|
readkeytype_repeat, 0.2f))
|
||||||
@ -804,7 +711,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
}
|
}
|
||||||
else if (entity->type == entitytype_bullet)
|
else if (entity->type == entitytype_bullet)
|
||||||
{
|
{
|
||||||
if (!math_pointInRect(world->camera, entity->pos))
|
if (!math_rect_contains_p(world->camera, entity->pos))
|
||||||
{
|
{
|
||||||
deleteEntity(world, i--);
|
deleteEntity(world, i--);
|
||||||
continue;
|
continue;
|
||||||
@ -991,39 +898,6 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
collideColor, flags);
|
collideColor, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Draw Ui
|
|
||||||
UiState *uiState = &state->uiState;
|
|
||||||
MemoryArena_ *transientArena = &state->transientArena;
|
|
||||||
AssetManager *assetManager = &state->assetManager;
|
|
||||||
Renderer *renderer = &state->renderer;
|
|
||||||
InputBuffer *inputBuffer = &state->input;
|
|
||||||
|
|
||||||
renderer_rect(renderer, world->camera, V2(0, 0), renderer->size,
|
|
||||||
V2(0, 0), 0, NULL, V4(0, 0, 0, 0.5f),
|
|
||||||
renderflag_no_texture);
|
|
||||||
|
|
||||||
Font *arial15 = asset_getFontCreateSizeOnDemand(
|
|
||||||
assetManager, &state->persistentArena, transientArena, "Arial", 15);
|
|
||||||
Font *arial25 = asset_getFontCreateSizeOnDemand(
|
|
||||||
assetManager, &state->persistentArena, transientArena, "Arial", 40);
|
|
||||||
|
|
||||||
v2 titleP = V2(20, renderer->size.h - 100);
|
|
||||||
renderer_staticString(renderer, transientArena, arial25,
|
|
||||||
"Asteroids", titleP, V2(0, 0), 0, V4(1, 0, 0, 1),
|
|
||||||
0);
|
|
||||||
|
|
||||||
userInterface_beginState(uiState);
|
|
||||||
|
|
||||||
Rect buttonRect = {V2(20, 20), V2(40, 40)};
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
userInterface_button(uiState, transientArena, assetManager, renderer,
|
|
||||||
arial15, *inputBuffer, 0, buttonRect,
|
|
||||||
"test button");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
userInterface_endState(uiState, inputBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i32 i = 0; i < world->numAudioRenderers; i++)
|
for (i32 i = 0; i < world->numAudioRenderers; i++)
|
||||||
{
|
{
|
||||||
@ -1031,11 +905,94 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
audio_updateAndPlay(&state->transientArena, &state->audioManager,
|
audio_updateAndPlay(&state->transientArena, &state->audioManager,
|
||||||
audioRenderer);
|
audioRenderer);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL void startMenuUpdate(GameState *state, Memory *memory, f32 dt)
|
||||||
|
{
|
||||||
|
UiState *uiState = &state->uiState;
|
||||||
|
MemoryArena_ *transientArena = &state->transientArena;
|
||||||
|
AssetManager *assetManager = &state->assetManager;
|
||||||
|
Renderer *renderer = &state->renderer;
|
||||||
|
World *world = &state->world;
|
||||||
|
InputBuffer *inputBuffer = &state->input;
|
||||||
|
|
||||||
|
Font *arial15 = asset_getFontCreateSizeOnDemand(
|
||||||
|
assetManager, &state->persistentArena, transientArena, "Arial", 15);
|
||||||
|
Font *arial25 = asset_getFontCreateSizeOnDemand(
|
||||||
|
assetManager, &state->persistentArena, transientArena, "Arial", 40);
|
||||||
|
|
||||||
|
f32 margin = 20.0f;
|
||||||
|
f32 padding = 20.0f;
|
||||||
|
v2 titleP = V2(margin, renderer->size.h - 100 + margin);
|
||||||
|
renderer_staticString(renderer, transientArena, arial25, "Asteroids",
|
||||||
|
titleP, V2(0, 0), 0, V4(1, 0, 0, 1), 0);
|
||||||
|
|
||||||
|
userInterface_beginState(uiState);
|
||||||
|
|
||||||
|
Rect buttonRect = {0};
|
||||||
|
buttonRect.min = V2(margin, margin);
|
||||||
|
buttonRect.max = V2(margin + 100, margin + 40);
|
||||||
|
buttonRect = math_rect_shift(buttonRect, V2(0, titleP.y - 100));
|
||||||
|
if (userInterface_button(uiState, transientArena, assetManager, renderer,
|
||||||
|
arial15, *inputBuffer, 1, buttonRect,
|
||||||
|
"Start Game"))
|
||||||
|
{
|
||||||
|
state->appState = appstate_game;
|
||||||
|
}
|
||||||
|
|
||||||
|
userInterface_endState(uiState, inputBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||||
|
v2 windowSize, f32 dt)
|
||||||
|
{
|
||||||
|
MemoryIndex globalTransientArenaSize =
|
||||||
|
(MemoryIndex)((f32)memory->transientSize * 0.5f);
|
||||||
|
memory_arenaInit(&state->transientArena, memory->transient,
|
||||||
|
globalTransientArenaSize);
|
||||||
|
|
||||||
|
if (!state->init)
|
||||||
|
{
|
||||||
|
srand((u32)time(NULL));
|
||||||
|
asset_init(&state->assetManager, &state->persistentArena);
|
||||||
|
audio_init(&state->audioManager);
|
||||||
|
|
||||||
|
// NOTE(doyle): Load game assets must be before init_renderer so that
|
||||||
|
// shaders are available for the renderer configuration
|
||||||
|
loadGameAssets(state);
|
||||||
|
renderer_init(&state->renderer, &state->assetManager,
|
||||||
|
&state->persistentArena, windowSize);
|
||||||
|
|
||||||
|
Font *arial15 = asset_getFont(&state->assetManager, "Arial", 15);
|
||||||
|
debug_init(&state->persistentArena, windowSize, *arial15);
|
||||||
|
|
||||||
|
state->appState = appstate_start_menu;
|
||||||
|
state->init = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_processInputBuffer(&state->input, dt);
|
||||||
|
|
||||||
|
switch (state->appState)
|
||||||
|
{
|
||||||
|
case appstate_start_menu:
|
||||||
|
{
|
||||||
|
startMenuUpdate(state, memory, dt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case appstate_game:
|
||||||
|
{
|
||||||
|
gameUpdate(state, memory, dt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
ASSERT(INVALID_CODE_PATH);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#if 1
|
|
||||||
debug_drawUi(state, dt);
|
debug_drawUi(state, dt);
|
||||||
debug_clearCounter();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
renderer_renderGroups(&state->renderer);
|
renderer_renderGroups(&state->renderer);
|
||||||
}
|
}
|
||||||
|
18
src/Debug.c
18
src/Debug.c
@ -95,12 +95,6 @@ void debug_countIncrement(i32 id)
|
|||||||
GLOBAL_debug.callCount[id]++;
|
GLOBAL_debug.callCount[id]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug_clearCounter()
|
|
||||||
{
|
|
||||||
for (i32 i = 0; i < debugcount_num; i++)
|
|
||||||
GLOBAL_debug.callCount[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void debug_consoleLog(char *string, char *file, int lineNum)
|
void debug_consoleLog(char *string, char *file, int lineNum)
|
||||||
{
|
{
|
||||||
@ -260,7 +254,7 @@ INTERNAL void renderConsole(Renderer *renderer, MemoryArena_ *arena)
|
|||||||
for (i32 i = 0; i < maxConsoleLines; i++)
|
for (i32 i = 0; i < maxConsoleLines; i++)
|
||||||
{
|
{
|
||||||
f32 rotate = 0;
|
f32 rotate = 0;
|
||||||
v4 color = V4(0, 0, 0, 1);
|
v4 color = V4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
renderer_staticString(renderer, arena, &GLOBAL_debug.font,
|
renderer_staticString(renderer, arena, &GLOBAL_debug.font,
|
||||||
GLOBAL_debug.console[i], consoleStrP,
|
GLOBAL_debug.console[i], consoleStrP,
|
||||||
V2(0, 0), rotate, color, 0);
|
V2(0, 0), rotate, color, 0);
|
||||||
@ -270,9 +264,6 @@ 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);
|
|
||||||
|
|
||||||
{ // Print Memory Arena Info
|
{ // Print Memory Arena Info
|
||||||
DEBUG_PUSH_STRING("== MEMORY ARENAS ==");
|
DEBUG_PUSH_STRING("== MEMORY ARENAS ==");
|
||||||
MemoryArena_ *transient = &state->transientArena;
|
MemoryArena_ *transient = &state->transientArena;
|
||||||
@ -298,5 +289,10 @@ void debug_drawUi(GameState *state, f32 dt)
|
|||||||
DEBUG_PUSH_VAR("Num Vertex: %d",
|
DEBUG_PUSH_VAR("Num Vertex: %d",
|
||||||
GLOBAL_debug.callCount[debugcount_numVertex], "i32");
|
GLOBAL_debug.callCount[debugcount_numVertex], "i32");
|
||||||
|
|
||||||
debug_clearCounter();
|
updateAndRenderDebugStack(&state->renderer, &state->transientArena, dt);
|
||||||
|
renderConsole(&state->renderer, &state->transientArena);
|
||||||
|
|
||||||
|
{ // Clear debug call counters
|
||||||
|
for (i32 i = 0; i < debugcount_num; i++) GLOBAL_debug.callCount[i] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,64 @@
|
|||||||
#include "Dengine/Shader.h"
|
#include "Dengine/Shader.h"
|
||||||
#include "Dengine/Texture.h"
|
#include "Dengine/Texture.h"
|
||||||
|
|
||||||
|
void renderer_init(Renderer *renderer, AssetManager *assetManager,
|
||||||
|
MemoryArena_ *persistentArena, v2 windowSize)
|
||||||
|
{
|
||||||
|
renderer->size = windowSize;
|
||||||
|
// NOTE(doyle): Value to map a screen coordinate to NDC coordinate
|
||||||
|
renderer->vertexNdcFactor =
|
||||||
|
V2(1.0f / renderer->size.w, 1.0f / renderer->size.h);
|
||||||
|
renderer->groupIndexForVertexBatch = -1;
|
||||||
|
|
||||||
|
const mat4 projection =
|
||||||
|
mat4_ortho(0.0f, renderer->size.w, 0.0f, renderer->size.h, 0.0f, 1.0f);
|
||||||
|
for (i32 i = 0; i < shaderlist_count; i++)
|
||||||
|
{
|
||||||
|
renderer->shaderList[i] = asset_getShader(assetManager, i);
|
||||||
|
shader_use(renderer->shaderList[i]);
|
||||||
|
shader_uniformSetMat4fv(renderer->shaderList[i], "projection",
|
||||||
|
projection);
|
||||||
|
GL_CHECK_ERROR();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer->activeShaderId = renderer->shaderList[shaderlist_default];
|
||||||
|
GL_CHECK_ERROR();
|
||||||
|
|
||||||
|
/* Create buffers */
|
||||||
|
glGenVertexArrays(ARRAY_COUNT(renderer->vao), renderer->vao);
|
||||||
|
glGenBuffers(ARRAY_COUNT(renderer->vbo), renderer->vbo);
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
glBindVertexArray(renderer->vao[mode]);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[mode]);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
u32 numVertexElements = 4;
|
||||||
|
u32 stride = sizeof(RenderVertex);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, numVertexElements, GL_FLOAT,
|
||||||
|
GL_FALSE, stride, (GLvoid *)0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unbind */
|
||||||
|
GL_CHECK_ERROR();
|
||||||
|
|
||||||
|
// TODO(doyle): Lazy allocate render group capacity
|
||||||
|
renderer->groupCapacity = 4096;
|
||||||
|
for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++)
|
||||||
|
{
|
||||||
|
renderer->groups[i].vertexList = memory_pushBytes(
|
||||||
|
persistentArena, renderer->groupCapacity * sizeof(RenderVertex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct RenderQuad
|
typedef struct RenderQuad
|
||||||
{
|
{
|
||||||
RenderVertex vertexList[4];
|
RenderVertex vertexList[4];
|
||||||
@ -548,8 +606,8 @@ void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera,
|
|||||||
v2_add(pos, V2((CAST(f32) font->maxSize.w * CAST(f32) strLen),
|
v2_add(pos, V2((CAST(f32) font->maxSize.w * CAST(f32) strLen),
|
||||||
CAST(f32) font->maxSize.h));
|
CAST(f32) font->maxSize.h));
|
||||||
v2 leftAlignedP = pos;
|
v2 leftAlignedP = pos;
|
||||||
if (math_pointInRect(camera, leftAlignedP) ||
|
if (math_rect_contains_p(camera, leftAlignedP) ||
|
||||||
math_pointInRect(camera, rightAlignedP))
|
math_rect_contains_p(camera, rightAlignedP))
|
||||||
{
|
{
|
||||||
i32 vertexIndex = 0;
|
i32 vertexIndex = 0;
|
||||||
i32 numVertexPerQuad = 4;
|
i32 numVertexPerQuad = 4;
|
||||||
@ -659,6 +717,7 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(doyle): We have no notion of sort order!!
|
||||||
void renderer_renderGroups(Renderer *renderer)
|
void renderer_renderGroups(Renderer *renderer)
|
||||||
{
|
{
|
||||||
for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++)
|
for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++)
|
||||||
|
@ -34,7 +34,7 @@ i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
const InputBuffer input, const i32 id, const Rect rect,
|
const InputBuffer input, const i32 id, const Rect rect,
|
||||||
const char *const label)
|
const char *const label)
|
||||||
{
|
{
|
||||||
if (math_pointInRect(rect, input.mouseP))
|
if (math_rect_contains_p(rect, input.mouseP))
|
||||||
{
|
{
|
||||||
uiState->hotItem = id;
|
uiState->hotItem = id;
|
||||||
if (uiState->activeItem == 0)
|
if (uiState->activeItem == 0)
|
||||||
@ -55,41 +55,39 @@ i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
v2 buttonOffset = V2(0, 0);
|
v2 buttonOffset = V2(0, 0);
|
||||||
v4 buttonColor = V4(1, 1, 1, 1);
|
v4 buttonColor = V4(0, 0, 0, 1);
|
||||||
if (uiState->hotItem == id)
|
if (uiState->hotItem == id)
|
||||||
{
|
{
|
||||||
if (uiState->activeItem == id)
|
if (uiState->activeItem == id)
|
||||||
{
|
{
|
||||||
buttonOffset = V2(1, 1);
|
buttonOffset = V2(1, 1);
|
||||||
buttonColor = V4(1.0f, 0, 0, 1);
|
buttonColor = V4(0.8f, 0.8f, 0.8f, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO(doyle): Optional add effect on button hover
|
// NOTE(doyle): Hover effect
|
||||||
buttonColor = V4(1.0f, 0, 0, 1);
|
buttonColor = V4(0.05f, 0.05f, 0.05f, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
buttonColor = V4(1.0f, 0, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If no widget has keyboard focus, take it */
|
/* If no widget has keyboard focus, take it */
|
||||||
if (uiState->kbdItem == 0)
|
if (uiState->kbdItem == 0)
|
||||||
uiState->kbdItem = id;
|
uiState->kbdItem = id;
|
||||||
|
|
||||||
|
v2 rectSize = math_rect_get_size(rect);
|
||||||
/* If we have keyboard focus, show it */
|
/* If we have keyboard focus, show it */
|
||||||
if (uiState->kbdItem == id)
|
if (uiState->kbdItem == id)
|
||||||
{
|
{
|
||||||
// Draw outline
|
// Draw outline
|
||||||
renderer_staticRect(renderer,
|
renderer_staticRect(renderer,
|
||||||
v2_add(V2(-2, -2), v2_add(buttonOffset, rect.min)),
|
v2_add(V2(-2, -2), v2_add(buttonOffset, rect.min)),
|
||||||
v2_add(V2(4, 4), rect.max), V2(0, 0), 0, NULL,
|
v2_add(V2(4, 4), rectSize), V2(0, 0), 0, NULL,
|
||||||
buttonColor, renderflag_no_texture);
|
buttonColor, renderflag_no_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer_staticRect(renderer, v2_add(buttonOffset, rect.min), rect.max,
|
renderer_staticRect(renderer, v2_add(buttonOffset, rect.min),
|
||||||
V2(0, 0), 0, NULL, buttonColor, renderflag_no_texture);
|
rectSize, V2(0, 0), 0, NULL,
|
||||||
|
buttonColor, renderflag_no_texture);
|
||||||
|
|
||||||
if (label)
|
if (label)
|
||||||
{
|
{
|
||||||
@ -97,21 +95,23 @@ i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
v2 labelPos = rect.min;
|
v2 labelPos = rect.min;
|
||||||
|
|
||||||
// Initially position the label to half the width of the button
|
// Initially position the label to half the width of the button
|
||||||
labelPos.x += (rect.max.w * 0.5f);
|
labelPos.x += (rectSize.w * 0.5f);
|
||||||
|
|
||||||
// Move the label pos back half the length of the string (i.e.
|
// Move the label pos back half the length of the string (i.e.
|
||||||
// center it)
|
// center it)
|
||||||
labelPos.x -= (CAST(f32) labelDim.w * 0.5f);
|
labelPos.x -= (CAST(f32) labelDim.w * 0.5f);
|
||||||
|
|
||||||
if (labelDim.h < rect.max.h)
|
if (labelDim.h < rectSize.h)
|
||||||
{
|
{
|
||||||
labelPos.y += (rect.max.h * 0.5f);
|
labelPos.y += (rectSize.h * 0.5f);
|
||||||
labelPos.y -= (CAST(f32)labelDim.h * 0.5f);
|
labelPos.y -= (CAST(f32)labelDim.h * 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(doyle): We're using odd colors to overcome z-sorting by forcing
|
||||||
|
// button text into another render group
|
||||||
labelPos = v2_add(labelPos, buttonOffset);
|
labelPos = v2_add(labelPos, buttonOffset);
|
||||||
renderer_staticString(renderer, arena, font, label, labelPos, V2(0, 0),
|
renderer_staticString(renderer, arena, font, label, labelPos, V2(0, 0),
|
||||||
0, V4(0, 0, 0, 1), 0);
|
0, V4(0.9f, 0.9f, 0.9f, 0.9f), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// After renderering before click check, see if we need to process keys
|
// After renderering before click check, see if we need to process keys
|
||||||
@ -159,7 +159,7 @@ i32 userInterface_scrollbar(UiState *const uiState,
|
|||||||
ASSERT(*value <= maxValue);
|
ASSERT(*value <= maxValue);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (math_pointInRect(scrollBarRect, input.mouseP))
|
if (math_rect_contains_p(scrollBarRect, input.mouseP))
|
||||||
{
|
{
|
||||||
uiState->hotItem = id;
|
uiState->hotItem = id;
|
||||||
if (uiState->activeItem == 0)
|
if (uiState->activeItem == 0)
|
||||||
@ -178,17 +178,18 @@ i32 userInterface_scrollbar(UiState *const uiState,
|
|||||||
if (uiState->kbdItem == 0)
|
if (uiState->kbdItem == 0)
|
||||||
uiState->kbdItem = id;
|
uiState->kbdItem = id;
|
||||||
|
|
||||||
|
v2 rectSize = math_rect_get_size(scrollBarRect);
|
||||||
/* If we have keyboard focus, show it */
|
/* If we have keyboard focus, show it */
|
||||||
if (uiState->kbdItem == id)
|
if (uiState->kbdItem == id)
|
||||||
{
|
{
|
||||||
// Draw outline
|
// Draw outline
|
||||||
renderer_staticRect(renderer, v2_add(V2(-2, -2), scrollBarRect.min),
|
renderer_staticRect(renderer, v2_add(V2(-2, -2), scrollBarRect.min),
|
||||||
v2_add(V2(4, 4), scrollBarRect.max), V2(0, 0), 0,
|
v2_add(V2(4, 4), rectSize), V2(0, 0), 0,
|
||||||
&renderTex, V4(1, 0, 0, 1), 0);
|
&renderTex, V4(1, 0, 0, 1), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render scroll bar background
|
// Render scroll bar background
|
||||||
renderer_staticRect(renderer, scrollBarRect.min, scrollBarRect.max,
|
renderer_staticRect(renderer, scrollBarRect.min, rectSize,
|
||||||
V2(0, 0), 0, &renderTex, V4(0.75f, 0.5f, 0.5f, 1), 0);
|
V2(0, 0), 0, &renderTex, V4(0.75f, 0.5f, 0.5f, 1), 0);
|
||||||
|
|
||||||
// Render scroll bar slider
|
// Render scroll bar slider
|
||||||
@ -197,7 +198,7 @@ i32 userInterface_scrollbar(UiState *const uiState,
|
|||||||
|
|
||||||
f32 sliderPercentageOffset = (CAST(f32) *value / CAST(f32) maxValue);
|
f32 sliderPercentageOffset = (CAST(f32) *value / CAST(f32) maxValue);
|
||||||
f32 sliderYOffsetToBar =
|
f32 sliderYOffsetToBar =
|
||||||
(scrollBarRect.max.h - sliderSize.h) * sliderPercentageOffset;
|
(rectSize.h - sliderSize.h) * sliderPercentageOffset;
|
||||||
v2 sliderPos = v2_add(scrollBarRect.min, V2(0, sliderYOffsetToBar));
|
v2 sliderPos = v2_add(scrollBarRect.min, V2(0, sliderYOffsetToBar));
|
||||||
|
|
||||||
if (uiState->hotItem == id || uiState->activeItem == id)
|
if (uiState->hotItem == id || uiState->activeItem == id)
|
||||||
@ -247,11 +248,11 @@ i32 userInterface_scrollbar(UiState *const uiState,
|
|||||||
// Bounds check
|
// Bounds check
|
||||||
if (mouseYRelToRect < 0)
|
if (mouseYRelToRect < 0)
|
||||||
mouseYRelToRect = 0;
|
mouseYRelToRect = 0;
|
||||||
else if (mouseYRelToRect > scrollBarRect.max.h)
|
else if (mouseYRelToRect > rectSize.h)
|
||||||
mouseYRelToRect = scrollBarRect.max.h;
|
mouseYRelToRect = rectSize.h;
|
||||||
|
|
||||||
f32 newSliderPercentOffset =
|
f32 newSliderPercentOffset =
|
||||||
(CAST(f32) mouseYRelToRect / scrollBarRect.max.h);
|
(CAST(f32) mouseYRelToRect / rectSize.h);
|
||||||
|
|
||||||
i32 newValue = CAST(i32)(newSliderPercentOffset * CAST(f32)maxValue);
|
i32 newValue = CAST(i32)(newSliderPercentOffset * CAST(f32)maxValue);
|
||||||
if (newValue != *value)
|
if (newValue != *value)
|
||||||
@ -273,7 +274,7 @@ i32 userInterface_textField(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
i32 strLen = common_strlen(string);
|
i32 strLen = common_strlen(string);
|
||||||
b32 changed = FALSE;
|
b32 changed = FALSE;
|
||||||
|
|
||||||
if (math_pointInRect(rect, input.mouseP))
|
if (math_rect_contains_p(rect, input.mouseP))
|
||||||
{
|
{
|
||||||
uiState->hotItem = id;
|
uiState->hotItem = id;
|
||||||
if (uiState->activeItem == 0)
|
if (uiState->activeItem == 0)
|
||||||
@ -290,27 +291,28 @@ i32 userInterface_textField(UiState *const uiState, MemoryArena_ *const arena,
|
|||||||
if (uiState->kbdItem == 0)
|
if (uiState->kbdItem == 0)
|
||||||
uiState->kbdItem = id;
|
uiState->kbdItem = id;
|
||||||
|
|
||||||
|
v2 rectSize = math_rect_get_size(rect);
|
||||||
/* If we have keyboard focus, show it */
|
/* If we have keyboard focus, show it */
|
||||||
if (uiState->kbdItem == id)
|
if (uiState->kbdItem == id)
|
||||||
{
|
{
|
||||||
// Draw outline
|
// Draw outline
|
||||||
renderer_staticRect(renderer, v2_add(V2(-2, -2), rect.min),
|
renderer_staticRect(renderer, v2_add(V2(-2, -2), rect.min),
|
||||||
v2_add(V2(4, 4), rect.max), V2(0, 0), 0,
|
v2_add(V2(4, 4), rectSize), V2(0, 0), 0,
|
||||||
NULL, V4(1.0f, 0, 0, 1), 0);
|
NULL, V4(1.0f, 0, 0, 1), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render text field
|
// Render text field
|
||||||
renderer_staticRect(renderer, rect.min, rect.max, V2(0, 0), 0, NULL,
|
renderer_staticRect(renderer, rect.min, rectSize, V2(0, 0), 0, NULL,
|
||||||
V4(0.75f, 0.5f, 0.5f, 1), 0);
|
V4(0.75f, 0.5f, 0.5f, 1), 0);
|
||||||
|
|
||||||
if (uiState->activeItem == id || uiState->hotItem == id)
|
if (uiState->activeItem == id || uiState->hotItem == id)
|
||||||
{
|
{
|
||||||
renderer_staticRect(renderer, rect.min, rect.max, V2(0, 0), 0,
|
renderer_staticRect(renderer, rect.min, rectSize, V2(0, 0), 0,
|
||||||
NULL, V4(0.75f, 0.75f, 0.0f, 1), 0);
|
NULL, V4(0.75f, 0.75f, 0.0f, 1), 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
renderer_staticRect(renderer, rect.min, rect.max, V2(0, 0), 0,
|
renderer_staticRect(renderer, rect.min, rectSize, V2(0, 0), 0,
|
||||||
NULL, V4(0.5f, 0.5f, 0.5f, 1), 0);
|
NULL, V4(0.5f, 0.5f, 0.5f, 1), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,9 @@ typedef struct AssetManager
|
|||||||
} AssetManager;
|
} AssetManager;
|
||||||
|
|
||||||
#define MAX_TEXTURE_SIZE 1024
|
#define MAX_TEXTURE_SIZE 1024
|
||||||
|
|
||||||
|
void asset_init(AssetManager *assetManager, MemoryArena_ *arena);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*********************************
|
*********************************
|
||||||
* Texture Operations
|
* Texture Operations
|
||||||
|
@ -10,8 +10,21 @@
|
|||||||
#include "Dengine/Renderer.h"
|
#include "Dengine/Renderer.h"
|
||||||
#include "Dengine/UserInterface.h"
|
#include "Dengine/UserInterface.h"
|
||||||
|
|
||||||
|
enum AppState
|
||||||
|
{
|
||||||
|
appstate_start_menu,
|
||||||
|
appstate_game,
|
||||||
|
appstate_count,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct World
|
typedef struct World
|
||||||
{
|
{
|
||||||
|
b32 init;
|
||||||
|
|
||||||
|
// NOTE(doyle): Grace period when game starts before asteroids start
|
||||||
|
// spawning
|
||||||
|
f32 onInitAsteroidSpawnTimer;
|
||||||
|
|
||||||
MemoryArena_ entityArena;
|
MemoryArena_ entityArena;
|
||||||
|
|
||||||
v2 *entityVertexListCache[entitytype_count];
|
v2 *entityVertexListCache[entitytype_count];
|
||||||
@ -43,6 +56,8 @@ typedef struct World
|
|||||||
typedef struct GameState {
|
typedef struct GameState {
|
||||||
b32 init;
|
b32 init;
|
||||||
|
|
||||||
|
enum AppState appState;
|
||||||
|
|
||||||
MemoryArena_ transientArena;
|
MemoryArena_ transientArena;
|
||||||
MemoryArena_ persistentArena;
|
MemoryArena_ persistentArena;
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ void debug_init(MemoryArena_ *arena, v2 windowSize, Font font);
|
|||||||
void debug_recursivePrintXmlTree(XmlNode *root, i32 levelsDeep);
|
void debug_recursivePrintXmlTree(XmlNode *root, i32 levelsDeep);
|
||||||
|
|
||||||
void debug_countIncrement(enum DebugCount id);
|
void debug_countIncrement(enum DebugCount id);
|
||||||
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);
|
||||||
|
@ -347,14 +347,14 @@ INTERNAL inline v4 mat4_mul_v4(const mat4 a, const v4 b)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL inline b32 math_pointInRect(Rect rect, v2 point)
|
INTERNAL inline b32 math_rect_contains_p(Rect rect, v2 p)
|
||||||
{
|
{
|
||||||
b32 outsideOfRectX = FALSE;
|
b32 outsideOfRectX = FALSE;
|
||||||
if (point.x < rect.min.x || point.x > (rect.min.x + rect.max.w))
|
if (p.x < rect.min.x || p.x > rect.max.w)
|
||||||
outsideOfRectX = TRUE;
|
outsideOfRectX = TRUE;
|
||||||
|
|
||||||
b32 outsideOfRectY = FALSE;
|
b32 outsideOfRectY = FALSE;
|
||||||
if (point.y < rect.min.y || point.y > (rect.min.y + rect.max.h))
|
if (p.y < rect.min.y || p.y > rect.max.h)
|
||||||
outsideOfRectY = TRUE;
|
outsideOfRectY = TRUE;
|
||||||
|
|
||||||
if (outsideOfRectX || outsideOfRectY) return FALSE;
|
if (outsideOfRectX || outsideOfRectY) return FALSE;
|
||||||
@ -362,24 +362,43 @@ INTERNAL inline b32 math_pointInRect(Rect rect, v2 point)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
INTERNAL inline v4 math_getRect(v2 origin, v2 size)
|
INTERNAL inline Rect math_rect_create(v2 origin, v2 size)
|
||||||
{
|
{
|
||||||
v2 upperRightBound = v2_add(origin, V2(size.x, size.y));
|
Rect result = {0};
|
||||||
v4 result = V4(origin.x, origin.y, upperRightBound.x, upperRightBound.y);
|
result.min = origin;
|
||||||
|
result.max = v2_add(origin, size);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL inline v2 math_getRectSize(v4 rect)
|
INTERNAL inline v2 math_rect_get_size(Rect rect)
|
||||||
{
|
{
|
||||||
f32 width = ABS(rect.x - rect.z);
|
f32 width = ABS(rect.max.x - rect.min.x);
|
||||||
f32 height = ABS(rect.y - rect.w);
|
f32 height = ABS(rect.max.y - rect.min.y);
|
||||||
|
|
||||||
v2 result = V2(width, height);
|
v2 result = V2(width, height);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL inline v2 math_rect_get_centre(Rect rect)
|
||||||
|
{
|
||||||
|
f32 sumX = rect.min.x + rect.max.x;
|
||||||
|
f32 sumY = rect.min.y + rect.max.y;
|
||||||
|
v2 result = v2_scale(V2(sumX, sumY), 0.5f);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL inline Rect math_rect_shift(Rect rect, v2 shift)
|
||||||
|
{
|
||||||
|
Rect result = {0};
|
||||||
|
result.min = v2_add(rect.min, shift);
|
||||||
|
result.max = v2_add(rect.max, shift);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
INTERNAL inline void math_applyRotationToVertexes(v2 pos, v2 pivotPoint,
|
INTERNAL inline void math_applyRotationToVertexes(v2 pos, v2 pivotPoint,
|
||||||
Radians rotate,
|
Radians rotate,
|
||||||
v2 *vertexList,
|
v2 *vertexList,
|
||||||
|
@ -85,6 +85,8 @@ typedef struct Renderer
|
|||||||
i32 groupCapacity;
|
i32 groupCapacity;
|
||||||
} Renderer;
|
} Renderer;
|
||||||
|
|
||||||
|
void renderer_init(Renderer *renderer, AssetManager *assetManager,
|
||||||
|
MemoryArena_ *persistentArena, v2 windowSize);
|
||||||
|
|
||||||
RenderTex renderer_createNullRenderTex(AssetManager *const assetManager);
|
RenderTex renderer_createNullRenderTex(AssetManager *const assetManager);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user