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 = | ||||
| 	    asset_loadTTFont(assetManager, arena, "C:/Windows/Fonts/Arialbd.ttf"); | ||||
| 
 | ||||
| 	if (result) { | ||||
| 		ASSERT(TRUE); | ||||
| 	} | ||||
| 	if (result) ASSERT(TRUE); | ||||
| } | ||||
| 
 | ||||
| void initRenderer(GameState *state, v2 windowSize) { | ||||
| @ -76,11 +73,12 @@ void initRenderer(GameState *state, v2 windowSize) { | ||||
| 	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++) | ||||
| 	{ | ||||
| 		// Bind buffers and configure vao, vao automatically intercepts
 | ||||
| 		// glBindCalls and associates the state with that buffer for us
 | ||||
| 		glBindVertexArray(renderer->vao[rendermode_quad]); | ||||
| 		glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[rendermode_quad]); | ||||
| 		glBindVertexArray(renderer->vao[mode]); | ||||
| 		glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[mode]); | ||||
| 
 | ||||
| 		glEnableVertexAttribArray(0); | ||||
| 		u32 numVertexElements = 4; | ||||
| @ -92,20 +90,6 @@ void initRenderer(GameState *state, v2 windowSize) { | ||||
| 		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 */ | ||||
| 	GL_CHECK_ERROR(); | ||||
| 
 | ||||
| @ -183,37 +167,44 @@ INTERNAL b32 getKeyStatus(KeyState *key, enum ReadKeyType readType, | ||||
| void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | ||||
|                                   v2 windowSize, f32 dt) | ||||
| { | ||||
| 	if (!state->init) { | ||||
| 	if (!state->init) | ||||
| 	{ | ||||
| 
 | ||||
| 		memory_arenaInit(&state->persistentArena, memory->persistent, | ||||
| 		                 memory->persistentSize); | ||||
| 		memory_arenaInit(&state->transientArena, memory->transient, | ||||
| 		                 memory->transientSize); | ||||
| 
 | ||||
| 		initAssetManager(state); | ||||
| 		initRenderer(state, windowSize); | ||||
| 
 | ||||
| 		state->pixelsPerMeter = 70.0f; | ||||
| 
 | ||||
| 		{ // Init ship entity
 | ||||
| 			Entity *ship    = &state->entityList[state->entityIndex++]; | ||||
| 			ship->id        = 0; | ||||
| 			ship->pos       = V2(100.0f, 100.0f); | ||||
| 			ship->hitbox    = V2(100.0f, 100.0f); | ||||
| 			ship->size      = V2(100.0f, 100.0f); | ||||
| 			ship->scale     = 1; | ||||
| 			ship->type      = entitytype_ship; | ||||
| 			ship->direction = direction_null; | ||||
| 			ship->tex       = NULL; | ||||
| 			ship->collides  = FALSE; | ||||
| 			Entity *ship     = &state->entityList[state->entityIndex++]; | ||||
| 			ship->id         = 0; | ||||
| 			ship->pos        = V2(100, 100); | ||||
| 			ship->size       = V2(25.0f, 50.0f); | ||||
| 			ship->hitbox     = ship->size; | ||||
| 			ship->offset     = v2_scale(ship->size, 0.5f); | ||||
| 			ship->scale      = 1; | ||||
| 			ship->type       = entitytype_ship; | ||||
| 			ship->direction  = direction_null; | ||||
| 			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->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; | ||||
| 		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]; | ||||
| 		ASSERT(entity->type != entitytype_invalid); | ||||
| 
 | ||||
| 		v2 pivotPoint = {0}; | ||||
| 		if (entity->type == entitytype_ship) { | ||||
| 
 | ||||
| 
 | ||||
| 			v2 acceleration = {0}; | ||||
| 			v2 ddP = {0}; | ||||
| 			if (getKeyStatus(&state->input.keys[keycode_up], readkeytype_repeat, | ||||
| 			                 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], | ||||
| 			                 readkeytype_repeat, 0.0f, dt)) | ||||
| 			{ | ||||
| 				acceleration.y = -1.0f; | ||||
| 				ddP = v2_normalise(direction); | ||||
| 			} | ||||
| 
 | ||||
| 			if (getKeyStatus(&state->input.keys[keycode_left], | ||||
| 			                 readkeytype_repeat, 0.0f, dt)) | ||||
| 			{ | ||||
| 				acceleration.x = -1.0f; | ||||
| 				entity->rotation += (120.0f) * dt; | ||||
| 			} | ||||
| 
 | ||||
| 			if (getKeyStatus(&state->input.keys[keycode_right], | ||||
| 			                 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
 | ||||
| 				// diagonal using pythagoras theorem on a unit triangle 1^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 | ||||
| 			    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 resistance = v2_scale(oldVelocity, 4.0f); | ||||
| 			acceleration = v2_sub(acceleration, resistance); | ||||
| 			v2 oldDp = entity->dP; | ||||
| 			v2 resistance = v2_scale(oldDp, 2.0f); | ||||
| 			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 halfAccelerationDtSquared = | ||||
| 			    v2_scale(halfAcceleration, (SQUARED(dt))); | ||||
| 			v2 oldVelocityDt = v2_scale(oldVelocity, dt); | ||||
| 			v2 oldPos = entity->pos; | ||||
| 			entity->pos      = v2_add( | ||||
| 			    v2_add(halfAccelerationDtSquared, oldVelocityDt), oldPos); | ||||
| 			v2 ddPHalf          = v2_scale(ddP, 0.5f); | ||||
| 			v2 ddPHalfDtSquared = v2_scale(ddPHalf, (SQUARED(dt))); | ||||
| 			v2 oldDpDt          = v2_scale(oldDp, dt); | ||||
| 			v2 oldPos           = entity->pos; | ||||
| 			entity->pos = v2_add(v2_add(ddPHalfDtSquared, oldDpDt), oldPos); | ||||
| 
 | ||||
| 			pivotPoint = v2_scale(entity->size, 0.5f); | ||||
| 		} | ||||
| 
 | ||||
| 		RenderFlags flags = renderflag_wireframe; | ||||
| 		renderer_entity(&state->renderer, state->camera, entity, V2(0, 0), | ||||
| 		                0, V4(0.4f, 0.8f, 1.0f, 1.0f), flags); | ||||
| 		if (entity->pos.y >= state->worldSize.h) | ||||
| 		{ | ||||
| 			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}; | ||||
| 	triangle.points[0] = V2(100, 200); | ||||
| 	triangle.points[2] = V2(100, 300); | ||||
| 	triangle.points[1] = V2(200, 100); | ||||
| 	triangle.points[2] = V2(100, 300); | ||||
| 
 | ||||
| 	LOCAL_PERSIST Radians rotation = 0.0f; | ||||
| 	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), | ||||
| 	                  rotation, NULL, V4(1, 1, 1, 1), flags); | ||||
| 
 | ||||
| 	debug_drawUi(state, dt); | ||||
| 	debug_clearCounter(); | ||||
| 
 | ||||
| 	renderer_renderGroups(&state->renderer); | ||||
| } | ||||
|  | ||||
| @ -30,7 +30,7 @@ GLOBAL_VAR DebugState GLOBAL_debug; | ||||
| 
 | ||||
| void debug_init(MemoryArena_ *arena, v2 windowSize, Font font) | ||||
| { | ||||
| 	GLOBAL_debug.font          = font; | ||||
| 	GLOBAL_debug.font = font; | ||||
| 	GLOBAL_debug.callCount = | ||||
| 	    memory_pushBytes(arena, debugcount_num * sizeof(i32)); | ||||
| 	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++) | ||||
| 	{ | ||||
| 		f32 rotate = 0; | ||||
| 		v4 color   = V4(0, 0, 0, 1); | ||||
| 		v4 color   = V4(1, 1, 1, 1); | ||||
| 		renderer_staticString( | ||||
| 		    renderer, arena, &GLOBAL_debug.font, GLOBAL_debug.debugStrings[i], | ||||
| 		    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) | ||||
| { | ||||
| 	updateAndRenderDebugStack(&state->renderer, &state->transientArena, dt); | ||||
| 	renderConsole(&state->renderer, &state->transientArena); | ||||
| 	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
 | ||||
| 			// request wireframe mode- we can't use degenerate vertexes for line
 | ||||
| 			// mode
 | ||||
| 			if (!(flags & renderflag_wireframe)) group->vertexIndex++; | ||||
| 			group->vertexIndex++; | ||||
| 			group->init  = TRUE; | ||||
| 			group->tex   = tex; | ||||
| 			group->color = color; | ||||
| @ -158,6 +158,7 @@ INTERNAL void bufferRenderGroupToGL(Renderer *renderer, RenderGroup *group) | ||||
| INTERNAL void applyRotationToVertexes(v2 pos, v2 pivotPoint, Radians rotate, | ||||
|                                       Vertex *vertexList, i32 vertexListSize) | ||||
| { | ||||
| 	if (rotate == 0) return; | ||||
| 	// 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
 | ||||
| 	// 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].texCoord = V2(texRectNdc.z, texRectNdc.y); | ||||
| 	if (rotate == 0) return result; | ||||
| 
 | ||||
| 	// NOTE(doyle): Precalculate rotation on vertex positions
 | ||||
| 	// 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].texCoord  = V2(texRectNdc.z, texRectNdc.w); | ||||
| 
 | ||||
| 	if (rotate == 0) return result; | ||||
| 	applyRotationToVertexes(triangle.points[0], pivotPoint, rotate, | ||||
| 	                        result.vertex, ARRAY_COUNT(result.vertex)); | ||||
| 
 | ||||
| @ -286,35 +285,38 @@ INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *group) | ||||
| { | ||||
| 	ASSERT(group->mode < rendermode_invalid); | ||||
| 
 | ||||
| 	u32 drawMethod = GL_TRIANGLE_STRIP; | ||||
| 	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->shaderList[shaderlist_default_no_tex]; | ||||
| 		shader_use(renderer->activeShaderId); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		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 */ | ||||
| 	shader_uniformSetVec4f(renderer->activeShaderId, "spriteColor", | ||||
| 	                       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]); | ||||
| 	glDrawArrays(drawMethod, 0, renderer->numVertexesInVbo); | ||||
| 	glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo); | ||||
| 	GL_CHECK_ERROR(); | ||||
| 	debug_countIncrement(debugcount_drawArrays); | ||||
| 
 | ||||
| @ -322,6 +324,7 @@ INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *group) | ||||
| 	glBindVertexArray(0); | ||||
| 	glBindTexture(GL_TEXTURE_2D, 0); | ||||
| 	GL_CHECK_ERROR(); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 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, | ||||
| 	                                    pivotPoint, rotate, *renderTex); | ||||
| 
 | ||||
| 	// addRenderQuadToRenderGroup
 | ||||
| 	if (flags & renderflag_wireframe) | ||||
| 	{ | ||||
| 		Vertex vertexList[4] = {quad.vertex[0], quad.vertex[1], quad.vertex[3], | ||||
| 		                        quad.vertex[2]}; | ||||
| 		addVertexToRenderGroup(renderer, renderTex->tex, color, vertexList, | ||||
| 		                       ARRAY_COUNT(vertexList), rendermode_quad, | ||||
| 		                       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. | ||||
| 	/*
 | ||||
| 	   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 | ||||
| 		   rendering quad, to repeat this process as more entities are | ||||
| 		   renderered. | ||||
| 	   A degenerate vertex has to be copied from the last vertex in the | ||||
| 	   rendering quad, to repeat this process as more entities are | ||||
| 	   renderered. | ||||
| 
 | ||||
| 		   Alternative implementation is recognising if the rendered | ||||
| 		   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 | ||||
| 		   subsequent renders, we need a degenerate vertex at the front to | ||||
| 		   create the zero-area triangle strip. | ||||
| 	   Alternative implementation is recognising if the rendered | ||||
| 	   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 | ||||
| 	   subsequent renders, we need a degenerate vertex at the front to | ||||
| 	   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], | ||||
| 		                        quad.vertex[2], quad.vertex[3], quad.vertex[3]}; | ||||
| 		addVertexToRenderGroup(renderer, renderTex->tex, color, vertexList, | ||||
| 		                       ARRAY_COUNT(vertexList), rendermode_quad, flags); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void renderer_triangle(Renderer *const renderer, Rect camera, | ||||
| @ -401,9 +393,13 @@ void renderer_triangle(Renderer *const renderer, Rect camera, | ||||
| 	RenderTriangle_ renderTriangle = createRenderTriangle( | ||||
| 	    renderer, triangleInCamSpace, pivotPoint, rotate, *renderTex); | ||||
| 
 | ||||
| 	addVertexToRenderGroup( | ||||
| 	    renderer, renderTex->tex, color, renderTriangle.vertex, | ||||
| 	    ARRAY_COUNT(renderTriangle.vertex), rendermode_triangle, flags); | ||||
| 	// NOTE(doyle): Create degenerate vertex setup
 | ||||
| 	Vertex vertexList[5] = {renderTriangle.vertex[0], renderTriangle.vertex[0], | ||||
| 	                        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, | ||||
| @ -474,7 +470,7 @@ void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | ||||
| } | ||||
| 
 | ||||
| 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
 | ||||
| 
 | ||||
| @ -518,8 +514,36 @@ void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, | ||||
| 			renderTex.texRect = texRect; | ||||
| 		} | ||||
| 
 | ||||
| 		renderer_rect(renderer, camera, entity->pos, entity->size, pivotPoint, | ||||
| 		              entity->rotation + rotate, &renderTex, color, flags); | ||||
| 		Radians totalRotation = DEGREES_TO_RADIANS((entity->rotation + rotate)); | ||||
| 		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; | ||||
| 	f32 pixelsPerMeter; | ||||
| 
 | ||||
| 	v2 worldSize; | ||||
| 
 | ||||
| 	Rect camera; | ||||
| 
 | ||||
| 	AssetManager assetManager; | ||||
|  | ||||
| @ -27,6 +27,7 @@ void debug_recursivePrintXmlTree(XmlNode *root, i32 levelsDeep); | ||||
| 
 | ||||
| void debug_countIncrement(enum DebugCount id); | ||||
| void debug_clearCounter(); | ||||
| 
 | ||||
| #define DEBUG_LOG(string) debug_consoleLog(string, __FILE__, __LINE__); | ||||
| void debug_consoleLog(char *string, char *file, int lineNum); | ||||
| 
 | ||||
|  | ||||
| @ -3,6 +3,7 @@ | ||||
| 
 | ||||
| #include "Dengine/Assets.h" | ||||
| #include "Dengine/Common.h" | ||||
| #include "Dengine/Renderer.h" | ||||
| 
 | ||||
| typedef struct AudioRenderer AudioRenderer; | ||||
| 
 | ||||
| @ -40,12 +41,16 @@ typedef struct Entity | ||||
| 	i32 numChilds; | ||||
| 
 | ||||
| 	v2 pos; | ||||
| 	v2 velocity; | ||||
| 	v2 dP; | ||||
| 
 | ||||
| 	v2 hitbox; | ||||
| 	v2 size; | ||||
| 	v2 offset; | ||||
| 
 | ||||
| 	enum RenderMode renderMode; | ||||
| 
 | ||||
| 	f32 scale; | ||||
| 	f32 rotation; | ||||
| 	Degrees rotation; | ||||
| 
 | ||||
| 	b32 invisible; | ||||
| 
 | ||||
|  | ||||
| @ -7,11 +7,12 @@ | ||||
| #define MATH_PI 3.14159265359f | ||||
| #define SQUARED(x) (x * x) | ||||
| #define ABS(x) ((x) > 0 ? (x) : -(x)) | ||||
| #define DEGREES_TO_RADIANS(x) (x * (MATH_PI / 180.0f)) | ||||
| #define RADIANS_TO_DEGREES(x) (x * (180.0f / MATH_PI)) | ||||
| #define DEGREES_TO_RADIANS(x) ((x * (MATH_PI / 180.0f))) | ||||
| #define RADIANS_TO_DEGREES(x) ((x * (180.0f / MATH_PI))) | ||||
| #define SQRT(x) (sqrtf(x)) | ||||
| 
 | ||||
| typedef f32 Radians; | ||||
| typedef f32 Degrees; | ||||
| 
 | ||||
| INTERNAL inline f32 math_acosf(f32 a) | ||||
| { | ||||
| @ -19,12 +20,31 @@ INTERNAL inline f32 math_acosf(f32 a) | ||||
| 	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) | ||||
| { | ||||
| 	f32 result = atan2f(y, x); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| INTERNAL inline f32 math_tanf(Radians angle) | ||||
| { | ||||
| 	f32 result = tanf(angle); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* VECTORS */ | ||||
| typedef union v2 | ||||
| { | ||||
|  | ||||
| @ -32,6 +32,7 @@ typedef struct TrianglePoints { | ||||
| typedef u32 RenderFlags; | ||||
| enum RenderFlag { | ||||
| 	renderflag_wireframe = 0x1, | ||||
| 	renderflag_no_texture = 0x2, | ||||
| }; | ||||
| 
 | ||||
| enum RenderMode | ||||
| @ -47,6 +48,7 @@ typedef struct RenderGroup | ||||
| 	b32 init; | ||||
| 	RenderFlags flags; | ||||
| 	enum RenderMode mode; | ||||
| 	u32 glRenderMode; | ||||
| 
 | ||||
| 	Texture *tex; | ||||
| 	v4 color; | ||||
| @ -112,7 +114,7 @@ inline void renderer_staticString(Renderer *const renderer, MemoryArena_ *arena, | ||||
| } | ||||
| 
 | ||||
| void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, | ||||
|                      v2 pivotPoint, Radians rotate, v4 color, | ||||
|                      v2 pivotPoint, Degrees rotate, v4 color, | ||||
|                      RenderFlags flags); | ||||
| 
 | ||||
| void renderer_renderGroups(Renderer *renderer); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user