Add proper wireframe mode, rotation to triangle
This commit is contained in:
		
							parent
							
								
									6d67485d49
								
							
						
					
					
						commit
						981d87a2d7
					
				| @ -193,7 +193,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | ||||
| 			ship->scale     = 1; | ||||
| 			ship->type      = entitytype_ship; | ||||
| 			ship->direction = direction_null; | ||||
| 			ship->tex       = asset_getTex(&state->assetManager, "nullTex"); | ||||
| 			ship->tex       = NULL; | ||||
| 			ship->collides  = FALSE; | ||||
| 		} | ||||
| 
 | ||||
| @ -293,17 +293,22 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | ||||
| 			    v2_add(halfAccelerationDtSquared, oldVelocityDt), oldPos); | ||||
| 		} | ||||
| 
 | ||||
| 		renderer_entity(&state->renderer, state->camera, entity, V2(0, 0), 0, | ||||
| 		                 V4(0.0f, 1.0f, 1.0f, 1.0f)); | ||||
| 		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); | ||||
| 	} | ||||
| 
 | ||||
| 	RenderTex nullRenderTex = renderer_createNullRenderTex(&state->assetManager); | ||||
| 	TrianglePoints triangle = {0}; | ||||
| 	triangle.points[0] = V2(100, 200); | ||||
| 	triangle.points[2] = V2(100, 100); | ||||
| 	triangle.points[2] = V2(100, 300); | ||||
| 	triangle.points[1] = V2(200, 100); | ||||
| 	renderer_triangle(&state->renderer, state->camera, triangle, V2(0, 0), 0, | ||||
| 	                  nullRenderTex, V4(1, 1, 1, 1)); | ||||
| 
 | ||||
| 	LOCAL_PERSIST Radians rotation = 0.0f; | ||||
| 	rotation += DEGREES_TO_RADIANS(((60.0f) * dt)); | ||||
| 
 | ||||
| 	RenderFlags flags = renderflag_wireframe; | ||||
| 	renderer_triangle(&state->renderer, state->camera, triangle, V2(0, 0), | ||||
| 	                  rotation, NULL, V4(1, 1, 1, 1), flags); | ||||
| 
 | ||||
| 	renderer_renderGroups(&state->renderer); | ||||
| } | ||||
|  | ||||
| @ -229,9 +229,9 @@ INTERNAL void updateAndRenderDebugStack(Renderer *renderer, MemoryArena_ *arena, | ||||
| 	{ | ||||
| 		f32 rotate = 0; | ||||
| 		v4 color   = V4(0, 0, 0, 1); | ||||
| 		renderer_staticString(renderer, arena, &GLOBAL_debug.font, | ||||
| 		                      GLOBAL_debug.debugStrings[i], | ||||
| 		                      GLOBAL_debug.currStringP, V2(0, 0), rotate, color); | ||||
| 		renderer_staticString( | ||||
| 		    renderer, arena, &GLOBAL_debug.font, GLOBAL_debug.debugStrings[i], | ||||
| 		    GLOBAL_debug.currStringP, V2(0, 0), rotate, color, 0); | ||||
| 		GLOBAL_debug.currStringP.y -= (0.9f * GLOBAL_debug.stringLineGap); | ||||
| 	} | ||||
| 
 | ||||
| @ -263,7 +263,7 @@ INTERNAL void renderConsole(Renderer *renderer, MemoryArena_ *arena) | ||||
| 		v4 color   = V4(0, 0, 0, 1); | ||||
| 		renderer_staticString(renderer, arena, &GLOBAL_debug.font, | ||||
| 		                      GLOBAL_debug.console[i], consoleStrP, | ||||
| 		                      V2(0, 0), rotate, color); | ||||
| 		                      V2(0, 0), rotate, color, 0); | ||||
| 		consoleStrP.y -= (0.9f * GLOBAL_debug.stringLineGap); | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										281
									
								
								src/Renderer.c
									
									
									
									
									
								
							
							
						
						
									
										281
									
								
								src/Renderer.c
									
									
									
									
									
								
							| @ -8,8 +8,6 @@ | ||||
| #include "Dengine/Shader.h" | ||||
| #include "Dengine/Texture.h" | ||||
| 
 | ||||
| #define RENDER_BOUNDING_BOX FALSE | ||||
| 
 | ||||
| typedef struct RenderQuad | ||||
| { | ||||
| 	Vertex vertex[4]; | ||||
| @ -22,7 +20,8 @@ typedef struct RenderTriangle | ||||
| 
 | ||||
| INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color, | ||||
|                                      Vertex *vertexList, i32 numVertexes, | ||||
|                                      enum RenderMode targetRenderMode) | ||||
|                                      enum RenderMode targetRenderMode, | ||||
|                                      RenderFlags flags) | ||||
| { | ||||
| 
 | ||||
| #ifdef DENGINE_DEBUG | ||||
| @ -38,26 +37,50 @@ INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color, | ||||
| 	{ | ||||
| 		RenderGroup *group = &renderer->groups[i]; | ||||
| 		b32 groupIsValid = FALSE; | ||||
| 		if (group->tex) | ||||
| 		if (group->init) | ||||
| 		{ | ||||
| 			/* If the textures match and have the same color modulation, we can
 | ||||
| 			 * add these vertices to the current group */ | ||||
| 			if (group->tex->id == tex->id && | ||||
| 			    v4_equals(group->color, color) && group->mode == targetRenderMode) | ||||
| 
 | ||||
| 			b32 renderModeMatches = FALSE; | ||||
| 			if (group->mode == targetRenderMode) renderModeMatches = TRUE; | ||||
| 
 | ||||
| 			b32 colorMatches = FALSE; | ||||
| 			if (v4_equals(group->color, color)) colorMatches = TRUE; | ||||
| 
 | ||||
| 			b32 flagsMatches = FALSE; | ||||
| 			if (group->flags == flags) flagsMatches = TRUE; | ||||
| 
 | ||||
| 			b32 texMatches = TRUE; | ||||
| 			if (!tex && !group->tex) | ||||
| 			{ | ||||
| 				groupIsValid = TRUE; | ||||
| 				texMatches = TRUE; | ||||
| 			} | ||||
| 			else if (tex && group->tex) | ||||
| 			{ | ||||
| 				if (group->tex->id == tex->id) | ||||
| 				{ | ||||
| 					texMatches = TRUE; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if (texMatches && colorMatches && renderModeMatches && flagsMatches) | ||||
| 				groupIsValid = TRUE; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* New group, unused so initialise it */ | ||||
| 			groupIsValid = TRUE; | ||||
| 
 | ||||
| 			// NOTE(doyle): Mark first vertex as degenerate vertex
 | ||||
| 			group->vertexIndex++; | ||||
| 			// 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->init  = TRUE; | ||||
| 			group->tex   = tex; | ||||
| 			group->color = color; | ||||
| 			group->mode  = targetRenderMode; | ||||
| 			group->flags = flags; | ||||
| 
 | ||||
| #ifdef DENGINE_DEBUG | ||||
| 			debug_countIncrement(debugcount_renderGroups); | ||||
| @ -132,8 +155,54 @@ INTERNAL void bufferRenderGroupToGL(Renderer *renderer, RenderGroup *group) | ||||
| 	glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||
| } | ||||
| 
 | ||||
| INTERNAL void applyRotationToVertexes(v2 pos, v2 pivotPoint, Radians rotate, | ||||
|                                       Vertex *vertexList, i32 vertexListSize) | ||||
| { | ||||
| 	// 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.
 | ||||
| 	v2 pointOfRotation = v2_add(pivotPoint, pos); | ||||
| 
 | ||||
| 	mat4 rotateMat = mat4_translate(pointOfRotation.x, pointOfRotation.y, 0.0f); | ||||
| 	rotateMat      = mat4_mul(rotateMat, mat4_rotate(rotate, 0.0f, 0.0f, 1.0f)); | ||||
| 	rotateMat      = mat4_mul(rotateMat, mat4_translate(-pointOfRotation.x, | ||||
| 	                                               -pointOfRotation.y, 0.0f)); | ||||
| 	for (i32 i = 0; i < vertexListSize; i++) | ||||
| 	{ | ||||
| 		// NOTE(doyle): Manual matrix multiplication since vertex pos is 2D and
 | ||||
| 		// matrix is 4D
 | ||||
| 		v2 oldP = vertexList[i].pos; | ||||
| 		v2 newP = {0}; | ||||
| 
 | ||||
| 		newP.x = (oldP.x * rotateMat.e[0][0]) + (oldP.y * rotateMat.e[1][0]) + | ||||
| 		         (rotateMat.e[3][0]); | ||||
| 		newP.y = (oldP.x * rotateMat.e[0][1]) + (oldP.y * rotateMat.e[1][1]) + | ||||
| 		         (rotateMat.e[3][1]); | ||||
| 
 | ||||
| 		vertexList[i].pos = newP; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| INTERNAL v4 getTexRectNormaliseDeviceCoords(RenderTex renderTex) | ||||
| { | ||||
| 	/* Convert texture coordinates to normalised texture coordinates */ | ||||
| 	v4 result = renderTex.texRect; | ||||
| 	if (renderTex.tex) | ||||
| 	{ | ||||
| 		v2 texNdcFactor = | ||||
| 		    V2(1.0f / renderTex.tex->width, 1.0f / renderTex.tex->height); | ||||
| 		result.e[0] *= texNdcFactor.w; | ||||
| 		result.e[1] *= texNdcFactor.h; | ||||
| 		result.e[2] *= texNdcFactor.w; | ||||
| 		result.e[3] *= texNdcFactor.h; | ||||
| 	} | ||||
| 
 | ||||
| 	return result; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size, | ||||
|                                       v2 pivotPoint, f32 rotate, | ||||
|                                       v2 pivotPoint, Radians rotate, | ||||
|                                       RenderTex renderTex) | ||||
| { | ||||
| 	/*
 | ||||
| @ -152,18 +221,7 @@ INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size, | ||||
| 	v4 vertexPair       = {0}; | ||||
| 	vertexPair.vec2[0]  = pos; | ||||
| 	vertexPair.vec2[1]  = v2_add(pos, size); | ||||
| 
 | ||||
| 	/* Convert texture coordinates to normalised texture coordinates */ | ||||
| 	v4 texRectNdc = renderTex.texRect; | ||||
| 	if (renderTex.tex) | ||||
| 	{ | ||||
| 		v2 texNdcFactor = | ||||
| 		    V2(1.0f / renderTex.tex->width, 1.0f / renderTex.tex->height); | ||||
| 		texRectNdc.e[0] *= texNdcFactor.w; | ||||
| 		texRectNdc.e[1] *= texNdcFactor.h; | ||||
| 		texRectNdc.e[2] *= texNdcFactor.w; | ||||
| 		texRectNdc.e[3] *= texNdcFactor.h; | ||||
| 	} | ||||
| 	v4 texRectNdc = getTexRectNormaliseDeviceCoords(renderTex); | ||||
| 
 | ||||
| 	// NOTE(doyle): Create a quad composed of 4 vertexes to be rendered as
 | ||||
| 	// a triangle strip using vertices v0, v1, v2, then v2, v1, v3 (note the
 | ||||
| @ -185,53 +243,20 @@ INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size, | ||||
| 	// NOTE(doyle): Precalculate rotation on vertex positions
 | ||||
| 	// NOTE(doyle): No translation/scale matrix as we pre-calculate it from
 | ||||
| 	// entity data and work in world space until GLSL uses the projection matrix
 | ||||
| 
 | ||||
| 	// 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.
 | ||||
| 	v2 pointOfRotation = v2_add(pivotPoint, pos); | ||||
| 
 | ||||
| 	mat4 rotateMat = mat4_translate(pointOfRotation.x, pointOfRotation.y, 0.0f); | ||||
| 	rotateMat      = mat4_mul(rotateMat, mat4_rotate(rotate, 0.0f, 0.0f, 1.0f)); | ||||
| 	rotateMat      = mat4_mul(rotateMat, mat4_translate(-pointOfRotation.x, | ||||
| 	                                               -pointOfRotation.y, 0.0f)); | ||||
| 	for (i32 i = 0; i < ARRAY_COUNT(result.vertex); i++) | ||||
| 	{ | ||||
| 		// NOTE(doyle): Manual matrix multiplication since vertex pos is 2D and
 | ||||
| 		// matrix is 4D
 | ||||
| 		v2 oldP = result.vertex[i].pos; | ||||
| 		v2 newP = {0}; | ||||
| 
 | ||||
| 		newP.x = (oldP.x * rotateMat.e[0][0]) + (oldP.y * rotateMat.e[1][0]) + | ||||
| 		         (rotateMat.e[3][0]); | ||||
| 		newP.y = (oldP.x * rotateMat.e[0][1]) + (oldP.y * rotateMat.e[1][1]) + | ||||
| 		         (rotateMat.e[3][1]); | ||||
| 
 | ||||
| 		result.vertex[i].pos = newP; | ||||
| 	} | ||||
| 
 | ||||
| 	applyRotationToVertexes(pos, pivotPoint, rotate, result.vertex, | ||||
| 	                        ARRAY_COUNT(result.vertex)); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| INTERNAL RenderTriangle_ createRenderTriangle(Renderer *renderer, | ||||
|                                               TrianglePoints triangle, | ||||
|                                               v2 pivotPoint, f32 rotate, | ||||
|                                               v2 pivotPoint, Radians rotate, | ||||
|                                               RenderTex renderTex) | ||||
| { | ||||
| 	/* Convert texture coordinates to normalised texture coordinates */ | ||||
| 	v4 texRectNdc = renderTex.texRect; | ||||
| 	if (renderTex.tex) | ||||
| 	{ | ||||
| 		v2 texNdcFactor = | ||||
| 		    V2(1.0f / renderTex.tex->width, 1.0f / renderTex.tex->height); | ||||
| 		texRectNdc.e[0] *= texNdcFactor.w; | ||||
| 		texRectNdc.e[1] *= texNdcFactor.h; | ||||
| 		texRectNdc.e[2] *= texNdcFactor.w; | ||||
| 		texRectNdc.e[3] *= texNdcFactor.h; | ||||
| 	} | ||||
| 	 | ||||
| 	RenderTriangle_ result = {0}; | ||||
| 	v4 texRectNdc = getTexRectNormaliseDeviceCoords(renderTex); | ||||
| 
 | ||||
| 	RenderTriangle_ result = {0}; | ||||
| 	result.vertex[0].pos       = triangle.points[0]; | ||||
| 	result.vertex[0].texCoord  = V2(texRectNdc.x, texRectNdc.w); | ||||
| 
 | ||||
| @ -242,39 +267,34 @@ INTERNAL RenderTriangle_ createRenderTriangle(Renderer *renderer, | ||||
| 	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)); | ||||
| 
 | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| INTERNAL inline RenderQuad_ | ||||
| createDefaultTexQuad(Renderer *renderer, RenderTex renderTex) | ||||
| createDefaultTexQuad(Renderer *renderer, RenderTex *renderTex) | ||||
| { | ||||
| 	RenderQuad_ result = {0}; | ||||
| 	result = createRenderQuad(renderer, V2(0, 0), V2(0, 0), V2(0, 0), | ||||
| 	                          0.0f, renderTex); | ||||
| 	                          0.0f, *renderTex); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *renderGroup) | ||||
| INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *group) | ||||
| { | ||||
| 	ASSERT(renderGroup->mode < rendermode_invalid); | ||||
| 	ASSERT(group->mode < rendermode_invalid); | ||||
| 	/* Load transformation matrix */ | ||||
| 	shader_use(renderer->shader); | ||||
| 	GL_CHECK_ERROR(); | ||||
| 
 | ||||
| 	/* Set color modulation value */ | ||||
| 	shader_uniformSetVec4f(renderer->shader, "spriteColor", | ||||
| 	                       renderGroup->color); | ||||
| 	                       group->color); | ||||
| 	GL_CHECK_ERROR(); | ||||
| 
 | ||||
|     /* Send draw calls */ | ||||
| #if RENDER_BOUNDING_BOX | ||||
| 	glBindVertexArray(renderer->vao[renderGroup->mode]); | ||||
| 	glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo); | ||||
| 	glBindVertexArray(0); | ||||
| #endif | ||||
| 
 | ||||
| 	Texture *tex = renderGroup->tex; | ||||
| 	Texture *tex = group->tex; | ||||
| 	if (tex) | ||||
| 	{ | ||||
| 		glActiveTexture(GL_TEXTURE0); | ||||
| @ -282,13 +302,17 @@ INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *renderGroup) | ||||
| 		shader_uniformSet1i(renderer->shader, "tex", 0); | ||||
| 	} | ||||
| 
 | ||||
| 	glBindVertexArray(renderer->vao[renderGroup->mode]); | ||||
| 	glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo); | ||||
| 	GL_CHECK_ERROR(); | ||||
| 	glBindVertexArray(renderer->vao[group->mode]); | ||||
| 
 | ||||
| #ifdef DENGINE_DEBUG | ||||
| 	u32 drawMethod = GL_TRIANGLE_STRIP; | ||||
| 	if (group->flags & renderflag_wireframe) | ||||
| 	{ | ||||
| 		drawMethod = GL_LINE_LOOP; | ||||
| 	} | ||||
| 
 | ||||
| 	glDrawArrays(drawMethod, 0, renderer->numVertexesInVbo); | ||||
| 	GL_CHECK_ERROR(); | ||||
| 	debug_countIncrement(debugcount_drawArrays); | ||||
| #endif | ||||
| 
 | ||||
| 	/* Unbind */ | ||||
| 	glBindVertexArray(0); | ||||
| @ -304,14 +328,29 @@ RenderTex renderer_createNullRenderTex(AssetManager *const assetManager) | ||||
| } | ||||
| 
 | ||||
| void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size, | ||||
|                    v2 pivotPoint, f32 rotate, RenderTex renderTex, v4 color) | ||||
|                    v2 pivotPoint, Radians rotate, RenderTex *renderTex, v4 color, | ||||
|                    RenderFlags flags) | ||||
| { | ||||
| 	// NOTE(doyle): Bottom left and top right position of quad in world space
 | ||||
| 	v2 posInCameraSpace = v2_sub(pos, camera.pos); | ||||
| 	RenderQuad_ quad    = createRenderQuad(renderer, posInCameraSpace, size, | ||||
| 	                                    pivotPoint, rotate, renderTex); | ||||
| 
 | ||||
| 	{ // addRenderQuadToRenderGroup
 | ||||
| 	RenderTex emptyRenderTex = {0}; | ||||
| 	if (!renderTex) renderTex = &emptyRenderTex; | ||||
| 
 | ||||
| 	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 | ||||
| @ -333,38 +372,39 @@ void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size, | ||||
| 		   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); | ||||
| 		addVertexToRenderGroup(renderer, renderTex->tex, color, vertexList, | ||||
| 		                       ARRAY_COUNT(vertexList), rendermode_quad, flags); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void renderer_triangle(Renderer *const renderer, Rect camera, | ||||
|                        TrianglePoints triangle, v2 pivotPoint, f32 rotate, | ||||
|                        RenderTex renderTex, v4 color) | ||||
|                        TrianglePoints triangle, v2 pivotPoint, Radians rotate, | ||||
|                        RenderTex *renderTex, v4 color, RenderFlags flags) | ||||
| { | ||||
| 	TrianglePoints triangleInCamSpace = {0}; | ||||
| 	ASSERT(ARRAY_COUNT(triangle.points) == | ||||
| 	       ARRAY_COUNT(triangleInCamSpace.points)); | ||||
| 
 | ||||
| 	for (i32 i = 0; i < ARRAY_COUNT(triangleInCamSpace.points); i++) | ||||
| 	{ | ||||
| 		triangleInCamSpace.points[i] = v2_sub(triangle.points[i], camera.pos); | ||||
| 	} | ||||
| 
 | ||||
| 	RenderTex emptyRenderTex = {0}; | ||||
| 	if (!renderTex) renderTex = &emptyRenderTex; | ||||
| 
 | ||||
| 	RenderTriangle_ renderTriangle = createRenderTriangle( | ||||
| 	    renderer, triangleInCamSpace, pivotPoint, rotate, renderTex); | ||||
| 	    renderer, triangleInCamSpace, pivotPoint, rotate, *renderTex); | ||||
| 
 | ||||
| 	addVertexToRenderGroup( | ||||
| 	    renderer, renderTex.tex, color, renderTriangle.vertex, | ||||
| 	    ARRAY_COUNT(renderTriangle.vertex), rendermode_triangle); | ||||
| 	    renderer, renderTex->tex, color, renderTriangle.vertex, | ||||
| 	    ARRAY_COUNT(renderTriangle.vertex), rendermode_triangle, flags); | ||||
| } | ||||
| 
 | ||||
| void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | ||||
|                      Font *const font, const char *const string, v2 pos, | ||||
|                      v2 pivotPoint, f32 rotate, v4 color) | ||||
|                      v2 pivotPoint, Radians rotate, v4 color, RenderFlags flags) | ||||
| { | ||||
| 	i32 strLen = common_strlen(string); | ||||
| 	if (strLen <= 0) return; | ||||
| @ -422,7 +462,7 @@ void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | ||||
| 		} | ||||
| 
 | ||||
| 		addVertexToRenderGroup(renderer, tex, color, vertexList, | ||||
| 		                       numVertexesToAlloc, rendermode_quad); | ||||
| 		                       numVertexesToAlloc, rendermode_quad, flags); | ||||
| 		// TODO(doyle): Mem free
 | ||||
| 		// PLATFORM_MEM_FREE(arena, vertexList,
 | ||||
| 		//                  sizeof(Vertex) * numVertexesToAlloc);
 | ||||
| @ -430,7 +470,7 @@ void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | ||||
| } | ||||
| 
 | ||||
| void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, | ||||
|                      v2 pivotPoint, f32 rotate, v4 color) | ||||
|                      v2 pivotPoint, Radians rotate, v4 color, RenderFlags flags) | ||||
| { | ||||
| 	// TODO(doyle): Batch into render groups
 | ||||
| 
 | ||||
| @ -442,33 +482,40 @@ void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, | ||||
| 	if (math_pointInRect(camera, leftAlignedP) || | ||||
| 	    math_pointInRect(camera, rightAlignedP)) | ||||
| 	{ | ||||
| 		EntityAnim *entityAnim = &entity->animList[entity->animListIndex]; | ||||
| 
 | ||||
| 		v4 texRect = {0}; | ||||
| 		if (entityAnim->anim) | ||||
| 		RenderTex renderTex = {0}; | ||||
| 		if (entity->tex) | ||||
| 		{ | ||||
| 			Animation *anim        = entityAnim->anim; | ||||
| 			char *frameName        = anim->frameList[entityAnim->currFrame]; | ||||
| 			SubTexture subTex    = asset_getAtlasSubTex(anim->atlas, frameName); | ||||
| 			EntityAnim *entityAnim = &entity->animList[entity->animListIndex]; | ||||
| 			v4 texRect = {0}; | ||||
| 			if (entityAnim->anim) | ||||
| 			{ | ||||
| 				Animation *anim = entityAnim->anim; | ||||
| 				char *frameName = anim->frameList[entityAnim->currFrame]; | ||||
| 				SubTexture subTex = | ||||
| 				    asset_getAtlasSubTex(anim->atlas, frameName); | ||||
| 
 | ||||
| 			texRect.vec2[0] = subTex.rect.pos; | ||||
| 			texRect.vec2[1] = v2_add(subTex.rect.pos, subTex.rect.size); | ||||
| 			flipTexCoord(&texRect, entity->flipX, entity->flipY); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			texRect = V4(0.0f, 0.0f, (f32)entity->tex->width, | ||||
| 			             (f32)entity->tex->height); | ||||
| 				texRect.vec2[0] = subTex.rect.pos; | ||||
| 				texRect.vec2[1] = v2_add(subTex.rect.pos, subTex.rect.size); | ||||
| 				flipTexCoord(&texRect, entity->flipX, entity->flipY); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				texRect = V4(0.0f, 0.0f, (f32)entity->tex->width, | ||||
| 				             (f32)entity->tex->height); | ||||
| 			} | ||||
| 
 | ||||
| 			if (entity->direction == direction_east) | ||||
| 			{ | ||||
| 				flipTexCoord(&texRect, TRUE, FALSE); | ||||
| 			} | ||||
| 
 | ||||
| 			renderTex.tex = entity->tex; | ||||
| 			renderTex.texRect = texRect; | ||||
| 		} | ||||
| 
 | ||||
| 		if (entity->direction == direction_east) | ||||
| 		{ | ||||
| 			flipTexCoord(&texRect, TRUE, FALSE); | ||||
| 		} | ||||
| 
 | ||||
| 		RenderTex renderTex = {entity->tex, texRect}; | ||||
| 		renderer_rect(renderer, camera, entity->pos, entity->size, pivotPoint, | ||||
| 		              entity->rotation + rotate, renderTex, color); | ||||
| 		              entity->rotation + rotate, &renderTex, color, flags); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -477,7 +524,7 @@ void renderer_renderGroups(Renderer *renderer) | ||||
| 	for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++) | ||||
| 	{ | ||||
| 		RenderGroup *currGroup = &renderer->groups[i]; | ||||
| 		if (currGroup->tex) | ||||
| 		if (currGroup->init) | ||||
| 		{ | ||||
| 			bufferRenderGroupToGL(renderer, currGroup); | ||||
| 			renderGLBufferedData(renderer, currGroup); | ||||
|  | ||||
| @ -67,13 +67,14 @@ i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena, | ||||
| 	if (uiState->kbdItem == id) | ||||
| 	{ | ||||
| 		// Draw outline
 | ||||
| 		renderer_staticRect( | ||||
| 		    renderer, v2_add(V2(-2, -2), v2_add(buttonOffset, rect.pos)), | ||||
| 		    v2_add(V2(4, 4), rect.size), V2(0, 0), 0, renderTex, buttonColor); | ||||
| 		renderer_staticRect(renderer, | ||||
| 		                    v2_add(V2(-2, -2), v2_add(buttonOffset, rect.pos)), | ||||
| 		                    v2_add(V2(4, 4), rect.size), V2(0, 0), 0, &renderTex, | ||||
| 		                    buttonColor, 0); | ||||
| 	} | ||||
| 
 | ||||
| 	renderer_staticRect(renderer, v2_add(buttonOffset, rect.pos), rect.size, | ||||
| 	                    V2(0, 0), 0, renderTex, buttonColor); | ||||
| 	                    V2(0, 0), 0, &renderTex, buttonColor, 0); | ||||
| 
 | ||||
| 	if (label) | ||||
| 	{ | ||||
| @ -95,7 +96,7 @@ i32 userInterface_button(UiState *const uiState, MemoryArena_ *const arena, | ||||
| 
 | ||||
| 		labelPos = v2_add(labelPos, buttonOffset); | ||||
| 		renderer_staticString(renderer, arena, font, label, labelPos, V2(0, 0), | ||||
| 		                      0, V4(0, 0, 0, 1)); | ||||
| 		                      0, V4(0, 0, 0, 1), 0); | ||||
| 	} | ||||
| 
 | ||||
| 	// After renderering before click check, see if we need to process keys
 | ||||
| @ -169,12 +170,12 @@ i32 userInterface_scrollbar(UiState *const uiState, | ||||
| 		// Draw outline
 | ||||
| 		renderer_staticRect(renderer, v2_add(V2(-2, -2), scrollBarRect.pos), | ||||
| 		                    v2_add(V2(4, 4), scrollBarRect.size), V2(0, 0), 0, | ||||
| 		                    renderTex, V4(1, 0, 0, 1)); | ||||
| 		                    &renderTex, V4(1, 0, 0, 1), 0); | ||||
| 	} | ||||
| 
 | ||||
| 	// Render scroll bar background
 | ||||
| 	renderer_staticRect(renderer, scrollBarRect.pos, scrollBarRect.size, | ||||
| 	                    V2(0, 0), 0, renderTex, V4(0.75f, 0.5f, 0.5f, 1)); | ||||
| 	                    V2(0, 0), 0, &renderTex, V4(0.75f, 0.5f, 0.5f, 1), 0); | ||||
| 
 | ||||
| 	// Render scroll bar slider
 | ||||
| 	v2 sliderSize   = V2(16, 16); | ||||
| @ -190,8 +191,8 @@ i32 userInterface_scrollbar(UiState *const uiState, | ||||
| 	else | ||||
| 		sliderColor = V4(0.0f, 1.0f, 0, 1); | ||||
| 
 | ||||
| 	renderer_staticRect(renderer, sliderPos, sliderSize, V2(0, 0), 0, renderTex, | ||||
| 	                    sliderColor); | ||||
| 	renderer_staticRect(renderer, sliderPos, sliderSize, V2(0, 0), 0, &renderTex, | ||||
| 	                    sliderColor, 0); | ||||
| 
 | ||||
| 	if (uiState->kbdItem == id) | ||||
| 	{ | ||||
| @ -283,27 +284,27 @@ i32 userInterface_textField(UiState *const uiState, MemoryArena_ *const arena, | ||||
| 		// Draw outline
 | ||||
| 		renderer_staticRect(renderer, v2_add(V2(-2, -2), rect.pos), | ||||
| 		                    v2_add(V2(4, 4), rect.size), V2(0, 0), 0, | ||||
| 		                    renderTex, V4(1.0f, 0, 0, 1)); | ||||
| 		                    &renderTex, V4(1.0f, 0, 0, 1), 0); | ||||
| 	} | ||||
| 
 | ||||
| 	// Render text field
 | ||||
| 	renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0, | ||||
| 	                    renderTex, V4(0.75f, 0.5f, 0.5f, 1)); | ||||
| 	                    &renderTex, V4(0.75f, 0.5f, 0.5f, 1), 0); | ||||
| 
 | ||||
| 	if (uiState->activeItem == id || uiState->hotItem == id) | ||||
| 	{ | ||||
| 		renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0, | ||||
| 		                    renderTex, V4(0.75f, 0.75f, 0.0f, 1)); | ||||
| 		                    &renderTex, V4(0.75f, 0.75f, 0.0f, 1), 0); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0, | ||||
| 		                    renderTex, V4(0.5f, 0.5f, 0.5f, 1)); | ||||
| 		                    &renderTex, V4(0.5f, 0.5f, 0.5f, 1), 0); | ||||
| 	} | ||||
| 
 | ||||
| 	v2 strPos = rect.pos; | ||||
| 	renderer_staticString(renderer, arena, font, string, strPos, V2(0, 0), 0, | ||||
| 	                      V4(0, 0, 0, 1)); | ||||
| 	                      V4(0, 0, 0, 1), 0); | ||||
| 
 | ||||
| 	if (uiState->kbdItem == id) | ||||
| 	{ | ||||
| @ -365,11 +366,11 @@ i32 userInterface_window(UiState *const uiState, MemoryArena_ *const arena, | ||||
| 	Rect rect = window->rect; | ||||
| 	RenderTex nullRenderTex = renderer_createNullRenderTex(assetManager); | ||||
| 	renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0, | ||||
| 	                    nullRenderTex, V4(0.25f, 0.25f, 0.5f, 0.5f)); | ||||
| 	                    &nullRenderTex, V4(0.25f, 0.25f, 0.5f, 0.5f), 0); | ||||
| 
 | ||||
| 	v2 menuTitleP = v2_add(rect.pos, V2(0, rect.size.h - 10)); | ||||
| 	renderer_staticString(renderer, arena, font, window->title, menuTitleP, | ||||
| 	                      V2(0, 0), 0, V4(0, 0, 0, 1)); | ||||
| 	                      V2(0, 0), 0, V4(0, 0, 0, 1), 0); | ||||
| 
 | ||||
| 	/* Draw window elements */ | ||||
| 	i32 firstActiveChildId = -1; | ||||
|  | ||||
| @ -200,7 +200,7 @@ i32 main(void) | ||||
| 		glfwPollEvents(); | ||||
| 
 | ||||
| 		/* Rendering commands here*/ | ||||
| 		glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | ||||
| 		glClearColor(0.2f, 0.2f, 0.2f, 1.0f); | ||||
| 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||
| 
 | ||||
| 		asteroid_gameUpdateAndRender(&gameState, &memory, windowSize, | ||||
|  | ||||
| @ -11,6 +11,8 @@ | ||||
| #define RADIANS_TO_DEGREES(x) (x * (180.0f / MATH_PI)) | ||||
| #define SQRT(x) (sqrtf(x)) | ||||
| 
 | ||||
| typedef f32 Radians; | ||||
| 
 | ||||
| INTERNAL inline f32 math_acosf(f32 a) | ||||
| { | ||||
| 	f32 result = acosf(a); | ||||
|  | ||||
| @ -28,16 +28,10 @@ typedef struct TrianglePoints { | ||||
| 	v2 points[3]; | ||||
| } TrianglePoints; | ||||
| 
 | ||||
| typedef struct RenderGroup | ||||
| { | ||||
| 	enum RenderMode mode; | ||||
| 	Texture *tex; | ||||
| 	v4 color; | ||||
| 
 | ||||
| 	Vertex *vertexList; | ||||
| 	i32 vertexIndex; | ||||
| 
 | ||||
| } RenderGroup; | ||||
| typedef u32 RenderFlags; | ||||
| enum RenderFlag { | ||||
| 	renderflag_wireframe = 0x1, | ||||
| }; | ||||
| 
 | ||||
| enum RenderMode | ||||
| { | ||||
| @ -47,6 +41,20 @@ enum RenderMode | ||||
| 	rendermode_invalid, | ||||
| }; | ||||
| 
 | ||||
| typedef struct RenderGroup | ||||
| { | ||||
| 	b32 init; | ||||
| 	RenderFlags flags; | ||||
| 	enum RenderMode mode; | ||||
| 
 | ||||
| 	Texture *tex; | ||||
| 	v4 color; | ||||
| 
 | ||||
| 	Vertex *vertexList; | ||||
| 	i32 vertexIndex; | ||||
| 
 | ||||
| } RenderGroup; | ||||
| 
 | ||||
| typedef struct Renderer | ||||
| { | ||||
| 	Shader *shader; | ||||
| @ -62,6 +70,7 @@ typedef struct Renderer | ||||
| 	i32 groupCapacity; | ||||
| } Renderer; | ||||
| 
 | ||||
| 
 | ||||
| // TODO(doyle): Use z-index occluding for rendering
 | ||||
| RenderTex | ||||
| renderer_createNullRenderTex(AssetManager *const assetManager); | ||||
| @ -69,37 +78,40 @@ renderer_createNullRenderTex(AssetManager *const assetManager); | ||||
| // TODO(doyle): Clean up lines
 | ||||
| // Renderer::~Renderer() { glDeleteVertexArrays(1, &this->quadVAO); }
 | ||||
| void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size, | ||||
|                    v2 pivotPoint, f32 rotate, RenderTex renderTex, v4 color); | ||||
|                    v2 pivotPoint, Radians rotate, RenderTex *renderTex, v4 color, | ||||
|                    RenderFlags flags); | ||||
| 
 | ||||
| inline void renderer_staticRect(Renderer *const renderer, v2 pos, v2 size, | ||||
|                                 v2 pivotPoint, f32 rotate, RenderTex renderTex, | ||||
|                                 v4 color) | ||||
|                                 v2 pivotPoint, Radians rotate, RenderTex *renderTex, | ||||
|                                 v4 color, RenderFlags flags) | ||||
| { | ||||
| 	Rect staticCamera = {V2(0, 0), renderer->size}; | ||||
| 	renderer_rect(renderer, staticCamera, pos, size, pivotPoint, rotate, | ||||
| 	              renderTex, color); | ||||
| 	              renderTex, color, flags); | ||||
| } | ||||
| 
 | ||||
| void renderer_triangle(Renderer *const renderer, Rect camera, | ||||
|                        TrianglePoints triangle, v2 pivotPoint, f32 rotate, | ||||
|                        RenderTex renderTex, v4 color); | ||||
|                        TrianglePoints triangle, v2 pivotPoint, Radians rotate, | ||||
|                        RenderTex *renderTex, v4 color, RenderFlags flags); | ||||
| 
 | ||||
| void renderer_string(Renderer *const renderer, MemoryArena_ *arena, | ||||
|                      Rect camera, Font *const font, | ||||
|                      const char *const string, v2 pos, v2 pivotPoint, | ||||
|                      f32 rotate, v4 color); | ||||
|                      Radians rotate, v4 color, RenderFlags flags); | ||||
| 
 | ||||
| inline void renderer_staticString(Renderer *const renderer, MemoryArena_ *arena, | ||||
|                                   Font *const font, const char *const string, | ||||
|                                   v2 pos, v2 pivotPoint, f32 rotate, v4 color) | ||||
|                                   v2 pos, v2 pivotPoint, Radians rotate, v4 color, | ||||
|                                   RenderFlags flags) | ||||
| { | ||||
| 	Rect staticCamera = {V2(0, 0), renderer->size}; | ||||
| 	renderer_string(renderer, arena, staticCamera, font, string, pos, | ||||
| 	                pivotPoint, rotate, color); | ||||
| 	                pivotPoint, rotate, color, flags); | ||||
| } | ||||
| 
 | ||||
| void renderer_entity(Renderer *renderer, Rect camera, Entity *entity, | ||||
|                      v2 pivotPoint, f32 rotate, v4 color); | ||||
|                      v2 pivotPoint, Radians rotate, v4 color, | ||||
|                      RenderFlags flags); | ||||
| 
 | ||||
| void renderer_renderGroups(Renderer *renderer); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user