Fix triangle rendering and wireframe
This commit is contained in:
		
							parent
							
								
									339ae38b38
								
							
						
					
					
						commit
						21bf650298
					
				
							
								
								
									
										161
									
								
								src/Asteroid.c
									
									
									
									
									
								
							
							
						
						
									
										161
									
								
								src/Asteroid.c
									
									
									
									
									
								
							| @ -42,10 +42,7 @@ void initAssetManager(GameState *state) | |||||||
| 
 | 
 | ||||||
| 	i32 result = | 	i32 result = | ||||||
| 	    asset_loadTTFont(assetManager, arena, "C:/Windows/Fonts/Arialbd.ttf"); | 	    asset_loadTTFont(assetManager, arena, "C:/Windows/Fonts/Arialbd.ttf"); | ||||||
| 
 | 	if (result) ASSERT(TRUE); | ||||||
| 	if (result) { |  | ||||||
| 		ASSERT(TRUE); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void initRenderer(GameState *state, v2 windowSize) { | void initRenderer(GameState *state, v2 windowSize) { | ||||||
| @ -76,11 +73,12 @@ void initRenderer(GameState *state, v2 windowSize) { | |||||||
| 	glGenBuffers(ARRAY_COUNT(renderer->vbo), renderer->vbo); | 	glGenBuffers(ARRAY_COUNT(renderer->vbo), renderer->vbo); | ||||||
| 	GL_CHECK_ERROR(); | 	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++) | ||||||
| 	{ | 	{ | ||||||
| 		// Bind buffers and configure vao, vao automatically intercepts
 | 		glBindVertexArray(renderer->vao[mode]); | ||||||
| 		// glBindCalls and associates the state with that buffer for us
 | 		glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[mode]); | ||||||
| 		glBindVertexArray(renderer->vao[rendermode_quad]); |  | ||||||
| 		glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[rendermode_quad]); |  | ||||||
| 
 | 
 | ||||||
| 		glEnableVertexAttribArray(0); | 		glEnableVertexAttribArray(0); | ||||||
| 		u32 numVertexElements = 4; | 		u32 numVertexElements = 4; | ||||||
| @ -92,20 +90,6 @@ void initRenderer(GameState *state, v2 windowSize) { | |||||||
| 		glBindVertexArray(0); | 		glBindVertexArray(0); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	{ |  | ||||||
| 		glBindVertexArray(renderer->vao[rendermode_triangle]); |  | ||||||
| 		glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[rendermode_triangle]); |  | ||||||
| 
 |  | ||||||
| 		glEnableVertexAttribArray(0); |  | ||||||
| 		u32 numVertexElements = 3; |  | ||||||
| 		u32 stride            = sizeof(Vertex); |  | ||||||
| 
 |  | ||||||
| 		glVertexAttribPointer(0, numVertexElements, GL_FLOAT, |  | ||||||
| 		                      GL_FALSE, stride, (GLvoid *)0); |  | ||||||
| 		glBindBuffer(GL_ARRAY_BUFFER, 0); |  | ||||||
| 		glBindVertexArray(0); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/* Unbind */ | 	/* Unbind */ | ||||||
| 	GL_CHECK_ERROR(); | 	GL_CHECK_ERROR(); | ||||||
| 
 | 
 | ||||||
| @ -183,37 +167,44 @@ INTERNAL b32 getKeyStatus(KeyState *key, enum ReadKeyType readType, | |||||||
| void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | ||||||
|                                   v2 windowSize, f32 dt) |                                   v2 windowSize, f32 dt) | ||||||
| { | { | ||||||
| 	if (!state->init) { | 	if (!state->init) | ||||||
|  | 	{ | ||||||
| 
 | 
 | ||||||
| 		memory_arenaInit(&state->persistentArena, memory->persistent, | 		memory_arenaInit(&state->persistentArena, memory->persistent, | ||||||
| 		                 memory->persistentSize); | 		                 memory->persistentSize); | ||||||
| 		memory_arenaInit(&state->transientArena, memory->transient, |  | ||||||
| 		                 memory->transientSize); |  | ||||||
| 
 |  | ||||||
| 		initAssetManager(state); | 		initAssetManager(state); | ||||||
| 		initRenderer(state, windowSize); | 		initRenderer(state, windowSize); | ||||||
| 
 | 
 | ||||||
| 		state->pixelsPerMeter = 70.0f; | 		state->pixelsPerMeter = 70.0f; | ||||||
| 
 | 
 | ||||||
| 		{ // Init ship entity
 | 		{ // Init ship entity
 | ||||||
| 			Entity *ship    = &state->entityList[state->entityIndex++]; | 			Entity *ship     = &state->entityList[state->entityIndex++]; | ||||||
| 			ship->id        = 0; | 			ship->id         = 0; | ||||||
| 			ship->pos       = V2(100.0f, 100.0f); | 			ship->pos        = V2(100, 100); | ||||||
| 			ship->hitbox    = V2(100.0f, 100.0f); | 			ship->size       = V2(25.0f, 50.0f); | ||||||
| 			ship->size      = V2(100.0f, 100.0f); | 			ship->hitbox     = ship->size; | ||||||
| 			ship->scale     = 1; | 			ship->offset     = v2_scale(ship->size, 0.5f); | ||||||
| 			ship->type      = entitytype_ship; | 			ship->scale      = 1; | ||||||
| 			ship->direction = direction_null; | 			ship->type       = entitytype_ship; | ||||||
| 			ship->tex       = NULL; | 			ship->direction  = direction_null; | ||||||
| 			ship->collides  = FALSE; | 			ship->renderMode = rendermode_triangle; | ||||||
|  | 			ship->tex        = NULL; | ||||||
|  | 			ship->collides   = FALSE; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		state->camera.pos = V2(0, 0); | 		state->camera.pos  = V2(0, 0); | ||||||
| 		state->camera.size = state->renderer.size; | 		state->camera.size = state->renderer.size; | ||||||
|  | 		state->init        = TRUE; | ||||||
| 
 | 
 | ||||||
|  | 		state->worldSize = windowSize; | ||||||
| 
 | 
 | ||||||
| 		state->init = TRUE; | 		debug_init(&state->persistentArena, windowSize, | ||||||
|  | 		           state->assetManager.font); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	memory_arenaInit(&state->transientArena, memory->transient, | ||||||
|  | 	                 memory->transientSize); | ||||||
|  | 
 | ||||||
| 	{ | 	{ | ||||||
| 		KeyState *keys = state->input.keys; | 		KeyState *keys = state->input.keys; | ||||||
| 		for (enum KeyCode code = 0; code < keycode_count; code++) | 		for (enum KeyCode code = 0; code < keycode_count; code++) | ||||||
| @ -244,40 +235,40 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | |||||||
| 		Entity *entity = &state->entityList[i]; | 		Entity *entity = &state->entityList[i]; | ||||||
| 		ASSERT(entity->type != entitytype_invalid); | 		ASSERT(entity->type != entitytype_invalid); | ||||||
| 
 | 
 | ||||||
|  | 		v2 pivotPoint = {0}; | ||||||
| 		if (entity->type == entitytype_ship) { | 		if (entity->type == entitytype_ship) { | ||||||
| 
 | 
 | ||||||
| 
 | 			v2 ddP = {0}; | ||||||
| 			v2 acceleration = {0}; |  | ||||||
| 			if (getKeyStatus(&state->input.keys[keycode_up], readkeytype_repeat, | 			if (getKeyStatus(&state->input.keys[keycode_up], readkeytype_repeat, | ||||||
| 			                 0.0f, dt)) | 			                 0.0f, dt)) | ||||||
| 			{ | 			{ | ||||||
| 				acceleration.y = 1.0f; | 				// TODO(doyle): Renderer creates upfacing triangles by default,
 | ||||||
| 			} | 				// but we need to offset rotation so that our base "0 degrees"
 | ||||||
|  | 				// is right facing for trig to work
 | ||||||
|  | 				Radians rotation = DEGREES_TO_RADIANS((entity->rotation + 90.0f)); | ||||||
|  | 				v2 direction     = V2(math_cosf(rotation), math_sinf(rotation)); | ||||||
| 
 | 
 | ||||||
| 			if (getKeyStatus(&state->input.keys[keycode_down], | 				ddP = v2_normalise(direction); | ||||||
| 			                 readkeytype_repeat, 0.0f, dt)) |  | ||||||
| 			{ |  | ||||||
| 				acceleration.y = -1.0f; |  | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (getKeyStatus(&state->input.keys[keycode_left], | 			if (getKeyStatus(&state->input.keys[keycode_left], | ||||||
| 			                 readkeytype_repeat, 0.0f, dt)) | 			                 readkeytype_repeat, 0.0f, dt)) | ||||||
| 			{ | 			{ | ||||||
| 				acceleration.x = -1.0f; | 				entity->rotation += (120.0f) * dt; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (getKeyStatus(&state->input.keys[keycode_right], | 			if (getKeyStatus(&state->input.keys[keycode_right], | ||||||
| 			                 readkeytype_repeat, 0.0f, dt)) | 			                 readkeytype_repeat, 0.0f, dt)) | ||||||
| 			{ | 			{ | ||||||
| 				acceleration.x = 1.0f; | 				entity->rotation -= (120.0f) * dt; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (acceleration.x != 0.0f && acceleration.y != 0.0f) | 			if (ddP.x != 0.0f && ddP.y != 0.0f) | ||||||
| 			{ | 			{ | ||||||
| 				// NOTE(doyle): Cheese it and pre-compute the vector for
 | 				// NOTE(doyle): Cheese it and pre-compute the vector for
 | ||||||
| 				// diagonal using pythagoras theorem on a unit triangle 1^2
 | 				// diagonal using pythagoras theorem on a unit triangle 1^2
 | ||||||
| 				// + 1^2 = c^2
 | 				// + 1^2 = c^2
 | ||||||
| 				acceleration = v2_scale(acceleration, 0.70710678118f); | 				ddP = v2_scale(ddP, 0.70710678118f); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			/*
 | 			/*
 | ||||||
| @ -285,41 +276,77 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | |||||||
| 
 | 
 | ||||||
| 			    newVelocity = a*t + oldVelocity | 			    newVelocity = a*t + oldVelocity | ||||||
| 			    newPos = (a*t^2)/2 + oldVelocity*t + oldPos | 			    newPos = (a*t^2)/2 + oldVelocity*t + oldPos | ||||||
|  | 
 | ||||||
| 			*/ | 			*/ | ||||||
| 
 | 
 | ||||||
| 			acceleration = v2_scale(acceleration, state->pixelsPerMeter * 25); | 			ddP = v2_scale(ddP, state->pixelsPerMeter * 25); | ||||||
| 
 | 
 | ||||||
| 			v2 oldVelocity = entity->velocity; | 			v2 oldDp = entity->dP; | ||||||
| 			v2 resistance = v2_scale(oldVelocity, 4.0f); | 			v2 resistance = v2_scale(oldDp, 2.0f); | ||||||
| 			acceleration = v2_sub(acceleration, resistance); | 			ddP = v2_sub(ddP, resistance); | ||||||
| 
 | 
 | ||||||
| 			entity->velocity = v2_add(v2_scale(acceleration, dt), oldVelocity); | 			entity->dP = v2_add(v2_scale(ddP, dt), oldDp); | ||||||
| 
 | 
 | ||||||
| 			v2 halfAcceleration = v2_scale(acceleration, 0.5f); | 			v2 ddPHalf          = v2_scale(ddP, 0.5f); | ||||||
| 			v2 halfAccelerationDtSquared = | 			v2 ddPHalfDtSquared = v2_scale(ddPHalf, (SQUARED(dt))); | ||||||
| 			    v2_scale(halfAcceleration, (SQUARED(dt))); | 			v2 oldDpDt          = v2_scale(oldDp, dt); | ||||||
| 			v2 oldVelocityDt = v2_scale(oldVelocity, dt); | 			v2 oldPos           = entity->pos; | ||||||
| 			v2 oldPos = entity->pos; | 			entity->pos = v2_add(v2_add(ddPHalfDtSquared, oldDpDt), oldPos); | ||||||
| 			entity->pos      = v2_add( | 
 | ||||||
| 			    v2_add(halfAccelerationDtSquared, oldVelocityDt), oldPos); | 			pivotPoint = v2_scale(entity->size, 0.5f); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		RenderFlags flags = renderflag_wireframe; | 		if (entity->pos.y >= state->worldSize.h) | ||||||
| 		renderer_entity(&state->renderer, state->camera, entity, V2(0, 0), | 		{ | ||||||
| 		                0, V4(0.4f, 0.8f, 1.0f, 1.0f), flags); | 			entity->pos.y = 0; | ||||||
|  | 		} | ||||||
|  | 		else if (entity->pos.y < 0) | ||||||
|  | 		{ | ||||||
|  | 			entity->pos.y = state->worldSize.h; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (entity->pos.x >= state->worldSize.w) | ||||||
|  | 		{ | ||||||
|  | 			entity->pos.x = 0; | ||||||
|  | 		} | ||||||
|  | 		else if (entity->pos.x < 0) | ||||||
|  | 		{ | ||||||
|  | 			entity->pos.x = state->worldSize.w; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		DEBUG_PUSH_VAR("Pos: %5.2f, %5.2f", entity->pos, "v2"); | ||||||
|  | 		DEBUG_PUSH_VAR("Velocity: %5.2f, %5.2f", entity->dP, "v2"); | ||||||
|  | 		DEBUG_PUSH_VAR("Rotation: %5.2f", entity->rotation, "f32"); | ||||||
|  | 
 | ||||||
|  | 		RenderFlags flags = renderflag_wireframe | renderflag_no_texture; | ||||||
|  | 		renderer_entity(&state->renderer, state->camera, entity, pivotPoint, 0, | ||||||
|  | 		                 V4(0.4f, 0.8f, 1.0f, 1.0f), flags); | ||||||
|  | 
 | ||||||
|  | 		v2 rightAlignedP = v2_add(entity->pos, entity->hitbox); | ||||||
|  | 		renderer_rect(&state->renderer, state->camera, rightAlignedP, V2(10, 10), | ||||||
|  | 		              V2(0, 0), DEGREES_TO_RADIANS(entity->rotation), NULL, | ||||||
|  | 		              V4(0.4f, 0.8f, 1.0f, 1.0f), flags); | ||||||
|  | 
 | ||||||
|  | 		v2 leftAlignedP = entity->pos; | ||||||
|  | 		renderer_rect(&state->renderer, state->camera, leftAlignedP, V2(10, 10), | ||||||
|  | 		              V2(0, 0), DEGREES_TO_RADIANS(entity->rotation), NULL, | ||||||
|  | 		              V4(0.4f, 0.8f, 1.0f, 1.0f), flags); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	TrianglePoints triangle = {0}; | 	TrianglePoints triangle = {0}; | ||||||
| 	triangle.points[0] = V2(100, 200); | 	triangle.points[0] = V2(100, 200); | ||||||
| 	triangle.points[2] = V2(100, 300); |  | ||||||
| 	triangle.points[1] = V2(200, 100); | 	triangle.points[1] = V2(200, 100); | ||||||
|  | 	triangle.points[2] = V2(100, 300); | ||||||
| 
 | 
 | ||||||
| 	LOCAL_PERSIST Radians rotation = 0.0f; | 	LOCAL_PERSIST Radians rotation = 0.0f; | ||||||
| 	rotation += DEGREES_TO_RADIANS(((60.0f) * dt)); | 	rotation += DEGREES_TO_RADIANS(((60.0f) * dt)); | ||||||
| 
 | 
 | ||||||
| 	RenderFlags flags = renderflag_wireframe; | 	RenderFlags flags = renderflag_wireframe | renderflag_no_texture; | ||||||
| 	renderer_triangle(&state->renderer, state->camera, triangle, V2(0, 0), | 	renderer_triangle(&state->renderer, state->camera, triangle, V2(0, 0), | ||||||
| 	                  rotation, NULL, V4(1, 1, 1, 1), flags); | 	                  rotation, NULL, V4(1, 1, 1, 1), flags); | ||||||
| 
 | 
 | ||||||
|  | 	debug_drawUi(state, dt); | ||||||
|  | 	debug_clearCounter(); | ||||||
|  | 
 | ||||||
| 	renderer_renderGroups(&state->renderer); | 	renderer_renderGroups(&state->renderer); | ||||||
| } | } | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ GLOBAL_VAR DebugState GLOBAL_debug; | |||||||
| 
 | 
 | ||||||
| void debug_init(MemoryArena_ *arena, v2 windowSize, Font font) | void debug_init(MemoryArena_ *arena, v2 windowSize, Font font) | ||||||
| { | { | ||||||
| 	GLOBAL_debug.font          = font; | 	GLOBAL_debug.font = font; | ||||||
| 	GLOBAL_debug.callCount = | 	GLOBAL_debug.callCount = | ||||||
| 	    memory_pushBytes(arena, debugcount_num * sizeof(i32)); | 	    memory_pushBytes(arena, debugcount_num * sizeof(i32)); | ||||||
| 	GLOBAL_debug.stringLineGap = CAST(f32) font.verticalSpacing; | 	GLOBAL_debug.stringLineGap = CAST(f32) font.verticalSpacing; | ||||||
| @ -228,7 +228,7 @@ INTERNAL void updateAndRenderDebugStack(Renderer *renderer, MemoryArena_ *arena, | |||||||
| 	for (i32 i = 0; i < GLOBAL_debug.numDebugStrings; i++) | 	for (i32 i = 0; i < GLOBAL_debug.numDebugStrings; i++) | ||||||
| 	{ | 	{ | ||||||
| 		f32 rotate = 0; | 		f32 rotate = 0; | ||||||
| 		v4 color   = V4(0, 0, 0, 1); | 		v4 color   = V4(1, 1, 1, 1); | ||||||
| 		renderer_staticString( | 		renderer_staticString( | ||||||
| 		    renderer, arena, &GLOBAL_debug.font, GLOBAL_debug.debugStrings[i], | 		    renderer, arena, &GLOBAL_debug.font, GLOBAL_debug.debugStrings[i], | ||||||
| 		    GLOBAL_debug.currStringP, V2(0, 0), rotate, color, 0); | 		    GLOBAL_debug.currStringP, V2(0, 0), rotate, color, 0); | ||||||
| @ -270,5 +270,7 @@ 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); | ||||||
| 	debug_clearCounter(); | 	debug_clearCounter(); | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										130
									
								
								src/Renderer.c
									
									
									
									
									
								
							
							
						
						
									
										130
									
								
								src/Renderer.c
									
									
									
									
									
								
							| @ -75,7 +75,7 @@ INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color, | |||||||
| 			// NOTE(doyle): Mark first vertex as degenerate vertex, but where we
 | 			// NOTE(doyle): Mark first vertex as degenerate vertex, but where we
 | ||||||
| 			// request wireframe mode- we can't use degenerate vertexes for line
 | 			// request wireframe mode- we can't use degenerate vertexes for line
 | ||||||
| 			// mode
 | 			// mode
 | ||||||
| 			if (!(flags & renderflag_wireframe)) group->vertexIndex++; | 			group->vertexIndex++; | ||||||
| 			group->init  = TRUE; | 			group->init  = TRUE; | ||||||
| 			group->tex   = tex; | 			group->tex   = tex; | ||||||
| 			group->color = color; | 			group->color = color; | ||||||
| @ -158,6 +158,7 @@ INTERNAL void bufferRenderGroupToGL(Renderer *renderer, RenderGroup *group) | |||||||
| INTERNAL void applyRotationToVertexes(v2 pos, v2 pivotPoint, Radians rotate, | INTERNAL void applyRotationToVertexes(v2 pos, v2 pivotPoint, Radians rotate, | ||||||
|                                       Vertex *vertexList, i32 vertexListSize) |                                       Vertex *vertexList, i32 vertexListSize) | ||||||
| { | { | ||||||
|  | 	if (rotate == 0) return; | ||||||
| 	// NOTE(doyle): Move the world origin to the base position of the object.
 | 	// NOTE(doyle): Move the world origin to the base position of the object.
 | ||||||
| 	// Then move the origin to the pivot point (e.g. center of object) and
 | 	// Then move the origin to the pivot point (e.g. center of object) and
 | ||||||
| 	// rotate from that point.
 | 	// rotate from that point.
 | ||||||
| @ -238,7 +239,6 @@ INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size, | |||||||
| 
 | 
 | ||||||
| 	result.vertex[3].pos      = V2(vertexPair.z, vertexPair.y); // Bottom right
 | 	result.vertex[3].pos      = V2(vertexPair.z, vertexPair.y); // Bottom right
 | ||||||
| 	result.vertex[3].texCoord = V2(texRectNdc.z, texRectNdc.y); | 	result.vertex[3].texCoord = V2(texRectNdc.z, texRectNdc.y); | ||||||
| 	if (rotate == 0) return result; |  | ||||||
| 
 | 
 | ||||||
| 	// NOTE(doyle): Precalculate rotation on vertex positions
 | 	// NOTE(doyle): Precalculate rotation on vertex positions
 | ||||||
| 	// NOTE(doyle): No translation/scale matrix as we pre-calculate it from
 | 	// NOTE(doyle): No translation/scale matrix as we pre-calculate it from
 | ||||||
| @ -266,7 +266,6 @@ INTERNAL RenderTriangle_ createRenderTriangle(Renderer *renderer, | |||||||
| 	result.vertex[2].pos       = triangle.points[2]; | 	result.vertex[2].pos       = triangle.points[2]; | ||||||
| 	result.vertex[2].texCoord  = V2(texRectNdc.z, texRectNdc.w); | 	result.vertex[2].texCoord  = V2(texRectNdc.z, texRectNdc.w); | ||||||
| 
 | 
 | ||||||
| 	if (rotate == 0) return result; |  | ||||||
| 	applyRotationToVertexes(triangle.points[0], pivotPoint, rotate, | 	applyRotationToVertexes(triangle.points[0], pivotPoint, rotate, | ||||||
| 	                        result.vertex, ARRAY_COUNT(result.vertex)); | 	                        result.vertex, ARRAY_COUNT(result.vertex)); | ||||||
| 
 | 
 | ||||||
| @ -286,35 +285,38 @@ INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *group) | |||||||
| { | { | ||||||
| 	ASSERT(group->mode < rendermode_invalid); | 	ASSERT(group->mode < rendermode_invalid); | ||||||
| 
 | 
 | ||||||
| 	u32 drawMethod = GL_TRIANGLE_STRIP; |  | ||||||
| 	if (group->flags & renderflag_wireframe) | 	if (group->flags & renderflag_wireframe) | ||||||
|  | 		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||||||
|  | 	else | ||||||
|  | 		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | ||||||
|  | 	GL_CHECK_ERROR(); | ||||||
|  | 
 | ||||||
|  | 	if (group->flags & renderflag_no_texture) | ||||||
| 	{ | 	{ | ||||||
| 		drawMethod = GL_LINE_LOOP; |  | ||||||
| 		renderer->activeShaderId = | 		renderer->activeShaderId = | ||||||
| 		    renderer->shaderList[shaderlist_default_no_tex]; | 		    renderer->shaderList[shaderlist_default_no_tex]; | ||||||
|  | 		shader_use(renderer->activeShaderId); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		renderer->activeShaderId = renderer->shaderList[shaderlist_default]; | 		renderer->activeShaderId = renderer->shaderList[shaderlist_default]; | ||||||
|  | 		shader_use(renderer->activeShaderId); | ||||||
|  | 		Texture *tex = group->tex; | ||||||
|  | 		if (tex) | ||||||
|  | 		{ | ||||||
|  | 			glActiveTexture(GL_TEXTURE0); | ||||||
|  | 			glBindTexture(GL_TEXTURE_2D, tex->id); | ||||||
|  | 			shader_uniformSet1i(renderer->activeShaderId, "tex", 0); | ||||||
|  | 			GL_CHECK_ERROR(); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	shader_use(renderer->activeShaderId); |  | ||||||
| 
 |  | ||||||
| 	/* Set color modulation value */ | 	/* Set color modulation value */ | ||||||
| 	shader_uniformSetVec4f(renderer->activeShaderId, "spriteColor", | 	shader_uniformSetVec4f(renderer->activeShaderId, "spriteColor", | ||||||
| 	                       group->color); | 	                       group->color); | ||||||
| 	GL_CHECK_ERROR(); |  | ||||||
| 
 |  | ||||||
| 	Texture *tex = group->tex; |  | ||||||
| 	if (tex) |  | ||||||
| 	{ |  | ||||||
| 		glActiveTexture(GL_TEXTURE0); |  | ||||||
| 		glBindTexture(GL_TEXTURE_2D, tex->id); |  | ||||||
| 		shader_uniformSet1i(renderer->activeShaderId, "tex", 0); |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	glBindVertexArray(renderer->vao[group->mode]); | 	glBindVertexArray(renderer->vao[group->mode]); | ||||||
| 	glDrawArrays(drawMethod, 0, renderer->numVertexesInVbo); | 	glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo); | ||||||
| 	GL_CHECK_ERROR(); | 	GL_CHECK_ERROR(); | ||||||
| 	debug_countIncrement(debugcount_drawArrays); | 	debug_countIncrement(debugcount_drawArrays); | ||||||
| 
 | 
 | ||||||
| @ -322,6 +324,7 @@ INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *group) | |||||||
| 	glBindVertexArray(0); | 	glBindVertexArray(0); | ||||||
| 	glBindTexture(GL_TEXTURE_2D, 0); | 	glBindTexture(GL_TEXTURE_2D, 0); | ||||||
| 	GL_CHECK_ERROR(); | 	GL_CHECK_ERROR(); | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RenderTex renderer_createNullRenderTex(AssetManager *const assetManager) | RenderTex renderer_createNullRenderTex(AssetManager *const assetManager) | ||||||
| @ -344,44 +347,33 @@ void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size, | |||||||
| 	RenderQuad_ quad = createRenderQuad(renderer, posInCameraSpace, size, | 	RenderQuad_ quad = createRenderQuad(renderer, posInCameraSpace, size, | ||||||
| 	                                    pivotPoint, rotate, *renderTex); | 	                                    pivotPoint, rotate, *renderTex); | ||||||
| 
 | 
 | ||||||
| 	// addRenderQuadToRenderGroup
 | 	/*
 | ||||||
| 	if (flags & renderflag_wireframe) | 	   NOTE(doyle): Entity rendering is always done in two pairs of | ||||||
| 	{ | 	   triangles, i.e. quad. To batch render quads as a triangle strip, we | ||||||
| 		Vertex vertexList[4] = {quad.vertex[0], quad.vertex[1], quad.vertex[3], | 	   need to create zero-area triangles which OGL will omit from | ||||||
| 		                        quad.vertex[2]}; | 	   rendering. Render groups are initialised with 1 degenerate vertex and | ||||||
| 		addVertexToRenderGroup(renderer, renderTex->tex, color, vertexList, | 	   then the first two vertexes sent to the render group are the same to | ||||||
| 		                       ARRAY_COUNT(vertexList), rendermode_quad, | 	   form 1 zero-area triangle strip. | ||||||
| 		                       flags); |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		/*
 |  | ||||||
| 		   NOTE(doyle): Entity rendering is always done in two pairs of |  | ||||||
| 		   triangles, i.e. quad. To batch render quads as a triangle strip, we |  | ||||||
| 		   need to create zero-area triangles which OGL will omit from |  | ||||||
| 		   rendering. Render groups are initialised with 1 degenerate vertex and |  | ||||||
| 		   then the first two vertexes sent to the render group are the same to |  | ||||||
| 		   form 1 zero-area triangle strip. |  | ||||||
| 
 | 
 | ||||||
| 		   A degenerate vertex has to be copied from the last vertex in the | 	   A degenerate vertex has to be copied from the last vertex in the | ||||||
| 		   rendering quad, to repeat this process as more entities are | 	   rendering quad, to repeat this process as more entities are | ||||||
| 		   renderered. | 	   renderered. | ||||||
| 
 | 
 | ||||||
| 		   Alternative implementation is recognising if the rendered | 	   Alternative implementation is recognising if the rendered | ||||||
| 		   entity is the first in its render group, then we don't need to init | 	   entity is the first in its render group, then we don't need to init | ||||||
| 		   a degenerate vertex, and only at the end of its vertex list. But on | 	   a degenerate vertex, and only at the end of its vertex list. But on | ||||||
| 		   subsequent renders, we need a degenerate vertex at the front to | 	   subsequent renders, we need a degenerate vertex at the front to | ||||||
| 		   create the zero-area triangle strip. | 	   create the zero-area triangle strip. | ||||||
|  | 
 | ||||||
|  | 	   The first has been chosen for simplicity of code, at the cost of | ||||||
|  | 	   1 degenerate vertex at the start of each render group. | ||||||
|  | 	   */ | ||||||
| 
 | 
 | ||||||
| 		   The first has been chosen for simplicity of code, at the cost of |  | ||||||
| 		   1 degenerate vertex at the start of each render group. |  | ||||||
| 		   */ |  | ||||||
| 
 | 
 | ||||||
| 		Vertex vertexList[6] = {quad.vertex[0], quad.vertex[0], quad.vertex[1], | 		Vertex vertexList[6] = {quad.vertex[0], quad.vertex[0], quad.vertex[1], | ||||||
| 		                        quad.vertex[2], quad.vertex[3], quad.vertex[3]}; | 		                        quad.vertex[2], quad.vertex[3], quad.vertex[3]}; | ||||||
| 		addVertexToRenderGroup(renderer, renderTex->tex, color, vertexList, | 		addVertexToRenderGroup(renderer, renderTex->tex, color, vertexList, | ||||||
| 		                       ARRAY_COUNT(vertexList), rendermode_quad, flags); | 		                       ARRAY_COUNT(vertexList), rendermode_quad, flags); | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void renderer_triangle(Renderer *const renderer, Rect camera, | void renderer_triangle(Renderer *const renderer, Rect camera, | ||||||
| @ -401,9 +393,13 @@ void renderer_triangle(Renderer *const renderer, Rect camera, | |||||||
| 	RenderTriangle_ renderTriangle = createRenderTriangle( | 	RenderTriangle_ renderTriangle = createRenderTriangle( | ||||||
| 	    renderer, triangleInCamSpace, pivotPoint, rotate, *renderTex); | 	    renderer, triangleInCamSpace, pivotPoint, rotate, *renderTex); | ||||||
| 
 | 
 | ||||||
| 	addVertexToRenderGroup( | 	// NOTE(doyle): Create degenerate vertex setup
 | ||||||
| 	    renderer, renderTex->tex, color, renderTriangle.vertex, | 	Vertex vertexList[5] = {renderTriangle.vertex[0], renderTriangle.vertex[0], | ||||||
| 	    ARRAY_COUNT(renderTriangle.vertex), rendermode_triangle, flags); | 	                        renderTriangle.vertex[1], renderTriangle.vertex[2], | ||||||
|  | 	                        renderTriangle.vertex[2]}; | ||||||
|  | 
 | ||||||
|  | 	addVertexToRenderGroup(renderer, renderTex->tex, color, vertexList, | ||||||
|  | 	                       ARRAY_COUNT(vertexList), rendermode_triangle, flags); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | ||||||
| @ -474,7 +470,7 @@ void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, | void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, | ||||||
|                      v2 pivotPoint, Radians rotate, v4 color, RenderFlags flags) |                      v2 pivotPoint, Degrees rotate, v4 color, RenderFlags flags) | ||||||
| { | { | ||||||
| 	// TODO(doyle): Batch into render groups
 | 	// TODO(doyle): Batch into render groups
 | ||||||
| 
 | 
 | ||||||
| @ -518,8 +514,36 @@ void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, | |||||||
| 			renderTex.texRect = texRect; | 			renderTex.texRect = texRect; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		renderer_rect(renderer, camera, entity->pos, entity->size, pivotPoint, | 		Radians totalRotation = DEGREES_TO_RADIANS((entity->rotation + rotate)); | ||||||
| 		              entity->rotation + rotate, &renderTex, color, flags); | 		if (entity->renderMode == rendermode_quad) | ||||||
|  | 		{ | ||||||
|  | 			renderer_rect(renderer, camera, entity->pos, entity->size, | ||||||
|  | 			              pivotPoint, totalRotation, &renderTex, | ||||||
|  | 			              color, flags); | ||||||
|  | 		} | ||||||
|  | 		else if (entity->renderMode == rendermode_triangle) | ||||||
|  | 		{ | ||||||
|  | 			TrianglePoints triangle = {0}; | ||||||
|  | 
 | ||||||
|  | 			v2 entityPWithOffset = v2_add(entity->pos, entity->offset); | ||||||
|  | 			v2 triangleTopPoint = | ||||||
|  | 			    V2(entityPWithOffset.x + (entity->size.w * 0.5f), | ||||||
|  | 			       entityPWithOffset.y + entity->size.h); | ||||||
|  | 
 | ||||||
|  | 			v2 triangleRightSide = | ||||||
|  | 			    V2(entityPWithOffset.x + entity->size.w, entityPWithOffset.y); | ||||||
|  | 
 | ||||||
|  | 			triangle.points[0] = entityPWithOffset; | ||||||
|  | 			triangle.points[1] = triangleRightSide; | ||||||
|  | 			triangle.points[2] = triangleTopPoint; | ||||||
|  | 
 | ||||||
|  | 			renderer_triangle(renderer, camera, triangle, pivotPoint, | ||||||
|  | 			                  totalRotation, &renderTex, color, flags); | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			ASSERT(INVALID_CODE_PATH); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -15,6 +15,8 @@ typedef struct GameState { | |||||||
| 	i32 entityIndex; | 	i32 entityIndex; | ||||||
| 	f32 pixelsPerMeter; | 	f32 pixelsPerMeter; | ||||||
| 
 | 
 | ||||||
|  | 	v2 worldSize; | ||||||
|  | 
 | ||||||
| 	Rect camera; | 	Rect camera; | ||||||
| 
 | 
 | ||||||
| 	AssetManager assetManager; | 	AssetManager assetManager; | ||||||
|  | |||||||
| @ -27,6 +27,7 @@ void debug_recursivePrintXmlTree(XmlNode *root, i32 levelsDeep); | |||||||
| 
 | 
 | ||||||
| void debug_countIncrement(enum DebugCount id); | void debug_countIncrement(enum DebugCount id); | ||||||
| void debug_clearCounter(); | 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); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| 
 | 
 | ||||||
| #include "Dengine/Assets.h" | #include "Dengine/Assets.h" | ||||||
| #include "Dengine/Common.h" | #include "Dengine/Common.h" | ||||||
|  | #include "Dengine/Renderer.h" | ||||||
| 
 | 
 | ||||||
| typedef struct AudioRenderer AudioRenderer; | typedef struct AudioRenderer AudioRenderer; | ||||||
| 
 | 
 | ||||||
| @ -40,12 +41,16 @@ typedef struct Entity | |||||||
| 	i32 numChilds; | 	i32 numChilds; | ||||||
| 
 | 
 | ||||||
| 	v2 pos; | 	v2 pos; | ||||||
| 	v2 velocity; | 	v2 dP; | ||||||
|  | 
 | ||||||
| 	v2 hitbox; | 	v2 hitbox; | ||||||
| 	v2 size; | 	v2 size; | ||||||
|  | 	v2 offset; | ||||||
|  | 
 | ||||||
|  | 	enum RenderMode renderMode; | ||||||
| 
 | 
 | ||||||
| 	f32 scale; | 	f32 scale; | ||||||
| 	f32 rotation; | 	Degrees rotation; | ||||||
| 
 | 
 | ||||||
| 	b32 invisible; | 	b32 invisible; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -7,11 +7,12 @@ | |||||||
| #define MATH_PI 3.14159265359f | #define MATH_PI 3.14159265359f | ||||||
| #define SQUARED(x) (x * x) | #define SQUARED(x) (x * x) | ||||||
| #define ABS(x) ((x) > 0 ? (x) : -(x)) | #define ABS(x) ((x) > 0 ? (x) : -(x)) | ||||||
| #define DEGREES_TO_RADIANS(x) (x * (MATH_PI / 180.0f)) | #define DEGREES_TO_RADIANS(x) ((x * (MATH_PI / 180.0f))) | ||||||
| #define RADIANS_TO_DEGREES(x) (x * (180.0f / MATH_PI)) | #define RADIANS_TO_DEGREES(x) ((x * (180.0f / MATH_PI))) | ||||||
| #define SQRT(x) (sqrtf(x)) | #define SQRT(x) (sqrtf(x)) | ||||||
| 
 | 
 | ||||||
| typedef f32 Radians; | typedef f32 Radians; | ||||||
|  | typedef f32 Degrees; | ||||||
| 
 | 
 | ||||||
| INTERNAL inline f32 math_acosf(f32 a) | INTERNAL inline f32 math_acosf(f32 a) | ||||||
| { | { | ||||||
| @ -19,12 +20,31 @@ INTERNAL inline f32 math_acosf(f32 a) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | INTERNAL inline Radians math_cosf(Radians a) | ||||||
|  | { | ||||||
|  | 	Radians result = cosf(a); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | INTERNAL inline Radians math_sinf(Radians a) | ||||||
|  | { | ||||||
|  | 	Radians result = sinf(a); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| INTERNAL inline f32 math_atan2f(f32 y, f32 x) | INTERNAL inline f32 math_atan2f(f32 y, f32 x) | ||||||
| { | { | ||||||
| 	f32 result = atan2f(y, x); | 	f32 result = atan2f(y, x); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | INTERNAL inline f32 math_tanf(Radians angle) | ||||||
|  | { | ||||||
|  | 	f32 result = tanf(angle); | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /* VECTORS */ | /* VECTORS */ | ||||||
| typedef union v2 | typedef union v2 | ||||||
| { | { | ||||||
|  | |||||||
| @ -32,6 +32,7 @@ typedef struct TrianglePoints { | |||||||
| typedef u32 RenderFlags; | typedef u32 RenderFlags; | ||||||
| enum RenderFlag { | enum RenderFlag { | ||||||
| 	renderflag_wireframe = 0x1, | 	renderflag_wireframe = 0x1, | ||||||
|  | 	renderflag_no_texture = 0x2, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| enum RenderMode | enum RenderMode | ||||||
| @ -47,6 +48,7 @@ typedef struct RenderGroup | |||||||
| 	b32 init; | 	b32 init; | ||||||
| 	RenderFlags flags; | 	RenderFlags flags; | ||||||
| 	enum RenderMode mode; | 	enum RenderMode mode; | ||||||
|  | 	u32 glRenderMode; | ||||||
| 
 | 
 | ||||||
| 	Texture *tex; | 	Texture *tex; | ||||||
| 	v4 color; | 	v4 color; | ||||||
| @ -112,7 +114,7 @@ inline void renderer_staticString(Renderer *const renderer, MemoryArena_ *arena, | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, | void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, | ||||||
|                      v2 pivotPoint, Radians rotate, v4 color, |                      v2 pivotPoint, Degrees rotate, v4 color, | ||||||
|                      RenderFlags flags); |                      RenderFlags flags); | ||||||
| 
 | 
 | ||||||
| void renderer_renderGroups(Renderer *renderer); | void renderer_renderGroups(Renderer *renderer); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user