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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user