Add primitive triangle rendering code
This commit is contained in:
		
							parent
							
								
									4795fe1cb1
								
							
						
					
					
						commit
						6d67485d49
					
				
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										120
									
								
								src/Asteroid.c
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								src/Asteroid.c
									
									
									
									
									
								
							| @ -61,26 +61,41 @@ void initRenderer(GameState *state, v2 windowSize) { | |||||||
| 	GL_CHECK_ERROR(); | 	GL_CHECK_ERROR(); | ||||||
| 
 | 
 | ||||||
| 	/* Create buffers */ | 	/* Create buffers */ | ||||||
| 	glGenVertexArrays(1, &renderer->vao); | 	glGenVertexArrays(ARRAY_COUNT(renderer->vao), renderer->vao); | ||||||
| 	glGenBuffers(1, &renderer->vbo); | 	glGenBuffers(ARRAY_COUNT(renderer->vbo), renderer->vbo); | ||||||
| 	GL_CHECK_ERROR(); | 	GL_CHECK_ERROR(); | ||||||
| 
 | 
 | ||||||
| 	/* Bind buffers */ | 	{ | ||||||
| 	glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo); | 		// Bind buffers and configure vao, vao automatically intercepts
 | ||||||
| 	glBindVertexArray(renderer->vao); | 		// glBindCalls and associates the state with that buffer for us
 | ||||||
|  | 		glBindVertexArray(renderer->vao[rendermode_quad]); | ||||||
|  | 		glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[rendermode_quad]); | ||||||
| 
 | 
 | ||||||
| 	/* Configure VAO */ | 		glEnableVertexAttribArray(0); | ||||||
| 	u32 numVertexElements = 4; | 		u32 numVertexElements = 4; | ||||||
| 	u32 stride            = sizeof(Vertex); | 		u32 stride            = sizeof(Vertex); | ||||||
| 	glVertexAttribPointer(0, numVertexElements, GL_FLOAT, GL_FALSE, stride, |  | ||||||
| 	                      (GLvoid *)0); |  | ||||||
| 	glEnableVertexAttribArray(0); |  | ||||||
| 
 | 
 | ||||||
| 	GL_CHECK_ERROR(); | 		glVertexAttribPointer(0, numVertexElements, GL_FLOAT, | ||||||
|  | 		                      GL_FALSE, stride, (GLvoid *)0); | ||||||
|  | 		glBindBuffer(GL_ARRAY_BUFFER, 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 */ | ||||||
| 	glBindBuffer(GL_ARRAY_BUFFER, 0); |  | ||||||
| 	glBindVertexArray(0); |  | ||||||
| 	GL_CHECK_ERROR(); | 	GL_CHECK_ERROR(); | ||||||
| 
 | 
 | ||||||
| 	// TODO(doyle): Lazy allocate render group capacity
 | 	// TODO(doyle): Lazy allocate render group capacity
 | ||||||
| @ -167,6 +182,8 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | |||||||
| 		initAssetManager(state); | 		initAssetManager(state); | ||||||
| 		initRenderer(state, windowSize); | 		initRenderer(state, windowSize); | ||||||
| 
 | 
 | ||||||
|  | 		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; | ||||||
| @ -183,6 +200,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | |||||||
| 		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->init = TRUE; | ||||||
| 	} | 	} | ||||||
| 	{ | 	{ | ||||||
| @ -217,25 +235,75 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory, | |||||||
| 
 | 
 | ||||||
| 		if (entity->type == entitytype_ship) { | 		if (entity->type == entitytype_ship) { | ||||||
| 
 | 
 | ||||||
| 			{ // Parse input
 |  | ||||||
| 				if (getKeyStatus(&state->input.keys[keycode_up], |  | ||||||
| 				                 readkeytype_repeat, 0.0f, dt)) |  | ||||||
| 				{ |  | ||||||
| 					entity->pos.y += 10.0f; |  | ||||||
| 				} |  | ||||||
| 
 | 
 | ||||||
| 				if (getKeyStatus(&state->input.keys[keycode_down], | 			v2 acceleration = {0}; | ||||||
| 				                 readkeytype_repeat, 0.0f, dt)) | 			if (getKeyStatus(&state->input.keys[keycode_up], readkeytype_repeat, | ||||||
| 				{ | 			                 0.0f, dt)) | ||||||
| 					entity->pos.y -= 10.0f; | 			{ | ||||||
| 				} | 				acceleration.y = 1.0f; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			if (getKeyStatus(&state->input.keys[keycode_down], | ||||||
|  | 			                 readkeytype_repeat, 0.0f, dt)) | ||||||
|  | 			{ | ||||||
|  | 				acceleration.y = -1.0f; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (getKeyStatus(&state->input.keys[keycode_left], | ||||||
|  | 			                 readkeytype_repeat, 0.0f, dt)) | ||||||
|  | 			{ | ||||||
|  | 				acceleration.x = -1.0f; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (getKeyStatus(&state->input.keys[keycode_right], | ||||||
|  | 			                 readkeytype_repeat, 0.0f, dt)) | ||||||
|  | 			{ | ||||||
|  | 				acceleration.x = 1.0f; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (acceleration.x != 0.0f && acceleration.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); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			/*
 | ||||||
|  | 			    Assuming acceleration A over t time, then integrate twice to get | ||||||
|  | 
 | ||||||
|  | 			    newVelocity = a*t + oldVelocity | ||||||
|  | 			    newPos = (a*t^2)/2 + oldVelocity*t + oldPos | ||||||
|  | 			*/ | ||||||
|  | 
 | ||||||
|  | 			acceleration = v2_scale(acceleration, state->pixelsPerMeter * 25); | ||||||
|  | 
 | ||||||
|  | 			v2 oldVelocity = entity->velocity; | ||||||
|  | 			v2 resistance = v2_scale(oldVelocity, 4.0f); | ||||||
|  | 			acceleration = v2_sub(acceleration, resistance); | ||||||
|  | 
 | ||||||
|  | 			entity->velocity = v2_add(v2_scale(acceleration, dt), oldVelocity); | ||||||
|  | 
 | ||||||
|  | 			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); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		renderer_entity(&state->renderer, state->camera, entity, V2(0, 0), 0, | 		renderer_entity(&state->renderer, state->camera, entity, V2(0, 0), 0, | ||||||
| 		                V4(1.0f, 1.0f, 1.0f, 1.0f)); | 		                 V4(0.0f, 1.0f, 1.0f, 1.0f)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	RenderTex nullRenderTex = renderer_createNullRenderTex(&state->assetManager); | ||||||
|  | 	TrianglePoints triangle = {0}; | ||||||
|  | 	triangle.points[0] = V2(100, 200); | ||||||
|  | 	triangle.points[2] = V2(100, 100); | ||||||
|  | 	triangle.points[1] = V2(200, 100); | ||||||
|  | 	renderer_triangle(&state->renderer, state->camera, triangle, V2(0, 0), 0, | ||||||
|  | 	                  nullRenderTex, V4(1, 1, 1, 1)); | ||||||
|  | 
 | ||||||
| 	renderer_renderGroups(&state->renderer); | 	renderer_renderGroups(&state->renderer); | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										155
									
								
								src/Renderer.c
									
									
									
									
									
								
							
							
						
						
									
										155
									
								
								src/Renderer.c
									
									
									
									
									
								
							| @ -10,8 +10,19 @@ | |||||||
| 
 | 
 | ||||||
| #define RENDER_BOUNDING_BOX FALSE | #define RENDER_BOUNDING_BOX FALSE | ||||||
| 
 | 
 | ||||||
|  | typedef struct RenderQuad | ||||||
|  | { | ||||||
|  | 	Vertex vertex[4]; | ||||||
|  | } RenderQuad_; | ||||||
|  | 
 | ||||||
|  | typedef struct RenderTriangle | ||||||
|  | { | ||||||
|  | 	Vertex vertex[3]; | ||||||
|  | } RenderTriangle_; | ||||||
|  | 
 | ||||||
| INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color, | INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color, | ||||||
|                                      Vertex *vertexList, i32 numVertexes) |                                      Vertex *vertexList, i32 numVertexes, | ||||||
|  |                                      enum RenderMode targetRenderMode) | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| @ -32,7 +43,7 @@ INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color, | |||||||
| 			/* If the textures match and have the same color modulation, we can
 | 			/* If the textures match and have the same color modulation, we can
 | ||||||
| 			 * add these vertices to the current group */ | 			 * add these vertices to the current group */ | ||||||
| 			if (group->tex->id == tex->id && | 			if (group->tex->id == tex->id && | ||||||
| 			    v4_equals(group->color, color)) | 			    v4_equals(group->color, color) && group->mode == targetRenderMode) | ||||||
| 			{ | 			{ | ||||||
| 				groupIsValid = TRUE; | 				groupIsValid = TRUE; | ||||||
| 			} | 			} | ||||||
| @ -46,6 +57,7 @@ INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color, | |||||||
| 			group->vertexIndex++; | 			group->vertexIndex++; | ||||||
| 			group->tex   = tex; | 			group->tex   = tex; | ||||||
| 			group->color = color; | 			group->color = color; | ||||||
|  | 			group->mode  = targetRenderMode; | ||||||
| 
 | 
 | ||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 			debug_countIncrement(debugcount_renderGroups); | 			debug_countIncrement(debugcount_renderGroups); | ||||||
| @ -90,37 +102,6 @@ INTERNAL void addVertexToRenderGroup(Renderer *renderer, Texture *tex, v4 color, | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| INTERNAL inline void addRenderQuadToRenderGroup(Renderer *renderer, |  | ||||||
|                                                 RenderQuad_ quad, |  | ||||||
|                                                 Texture *tex, v4 color) |  | ||||||
| { |  | ||||||
| 	/*
 |  | ||||||
| 	   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. |  | ||||||
| 
 |  | ||||||
| 	   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. |  | ||||||
|    */ |  | ||||||
| 	Vertex vertexList[6] = {quad.vertex[0], quad.vertex[0], quad.vertex[1], |  | ||||||
| 	                        quad.vertex[2], quad.vertex[3], quad.vertex[3]}; |  | ||||||
| 	addVertexToRenderGroup(renderer, tex, color, vertexList, |  | ||||||
| 	                       ARRAY_COUNT(vertexList)); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| INTERNAL inline void flipTexCoord(v4 *texCoords, b32 flipX, b32 flipY) | INTERNAL inline void flipTexCoord(v4 *texCoords, b32 flipX, b32 flipY) | ||||||
| { | { | ||||||
| 	if (flipX) | 	if (flipX) | ||||||
| @ -138,24 +119,19 @@ INTERNAL inline void flipTexCoord(v4 *texCoords, b32 flipX, b32 flipY) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| INTERNAL void updateBufferObject(Renderer *const renderer, | INTERNAL void bufferRenderGroupToGL(Renderer *renderer, RenderGroup *group) | ||||||
|                                  const Vertex *const vertexList, |  | ||||||
|                                  const i32 numVertex) |  | ||||||
| { | { | ||||||
|  | 	Vertex *vertexList = group->vertexList; | ||||||
|  | 	i32 numVertex = group->vertexIndex; | ||||||
|  | 
 | ||||||
| 	// TODO(doyle): We assume that vbo and vao are assigned
 | 	// TODO(doyle): We assume that vbo and vao are assigned
 | ||||||
| 	renderer->numVertexesInVbo = numVertex; | 	renderer->numVertexesInVbo = numVertex; | ||||||
| 
 | 	glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo[group->mode]); | ||||||
| 	glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo); |  | ||||||
| 	glBufferData(GL_ARRAY_BUFFER, numVertex * sizeof(Vertex), vertexList, | 	glBufferData(GL_ARRAY_BUFFER, numVertex * sizeof(Vertex), vertexList, | ||||||
| 	             GL_STREAM_DRAW); | 	             GL_STREAM_DRAW); | ||||||
| 	glBindBuffer(GL_ARRAY_BUFFER, 0); | 	glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| INTERNAL void bufferRenderGroupToGL(Renderer *renderer, RenderGroup *group) |  | ||||||
| { |  | ||||||
| 	updateBufferObject(renderer, group->vertexList, group->vertexIndex); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size, | INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size, | ||||||
|                                       v2 pivotPoint, f32 rotate, |                                       v2 pivotPoint, f32 rotate, | ||||||
|                                       RenderTex renderTex) |                                       RenderTex renderTex) | ||||||
| @ -237,6 +213,39 @@ INTERNAL RenderQuad_ createRenderQuad(Renderer *renderer, v2 pos, v2 size, | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | INTERNAL RenderTriangle_ createRenderTriangle(Renderer *renderer, | ||||||
|  |                                               TrianglePoints triangle, | ||||||
|  |                                               v2 pivotPoint, f32 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}; | ||||||
|  | 
 | ||||||
|  | 	result.vertex[0].pos       = triangle.points[0]; | ||||||
|  | 	result.vertex[0].texCoord  = V2(texRectNdc.x, texRectNdc.w); | ||||||
|  | 
 | ||||||
|  | 	result.vertex[1].pos       = triangle.points[1]; | ||||||
|  | 	result.vertex[1].texCoord  = V2(texRectNdc.x, texRectNdc.y); | ||||||
|  | 
 | ||||||
|  | 	result.vertex[2].pos       = triangle.points[2]; | ||||||
|  | 	result.vertex[2].texCoord  = V2(texRectNdc.z, texRectNdc.w); | ||||||
|  | 
 | ||||||
|  | 	if (rotate == 0) return result; | ||||||
|  | 
 | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| INTERNAL inline RenderQuad_ | INTERNAL inline RenderQuad_ | ||||||
| createDefaultTexQuad(Renderer *renderer, RenderTex renderTex) | createDefaultTexQuad(Renderer *renderer, RenderTex renderTex) | ||||||
| { | { | ||||||
| @ -248,6 +257,7 @@ createDefaultTexQuad(Renderer *renderer, RenderTex renderTex) | |||||||
| 
 | 
 | ||||||
| INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *renderGroup) | INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *renderGroup) | ||||||
| { | { | ||||||
|  | 	ASSERT(renderGroup->mode < rendermode_invalid); | ||||||
| 	/* Load transformation matrix */ | 	/* Load transformation matrix */ | ||||||
| 	shader_use(renderer->shader); | 	shader_use(renderer->shader); | ||||||
| 	GL_CHECK_ERROR(); | 	GL_CHECK_ERROR(); | ||||||
| @ -255,10 +265,11 @@ INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *renderGroup) | |||||||
| 	/* Set color modulation value */ | 	/* Set color modulation value */ | ||||||
| 	shader_uniformSetVec4f(renderer->shader, "spriteColor", | 	shader_uniformSetVec4f(renderer->shader, "spriteColor", | ||||||
| 	                       renderGroup->color); | 	                       renderGroup->color); | ||||||
|  | 	GL_CHECK_ERROR(); | ||||||
| 
 | 
 | ||||||
|     /* Send draw calls */ |     /* Send draw calls */ | ||||||
| #if RENDER_BOUNDING_BOX | #if RENDER_BOUNDING_BOX | ||||||
| 	glBindVertexArray(renderer->vao); | 	glBindVertexArray(renderer->vao[renderGroup->mode]); | ||||||
| 	glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo); | 	glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo); | ||||||
| 	glBindVertexArray(0); | 	glBindVertexArray(0); | ||||||
| #endif | #endif | ||||||
| @ -271,8 +282,9 @@ INTERNAL void renderGLBufferedData(Renderer *renderer, RenderGroup *renderGroup) | |||||||
| 		shader_uniformSet1i(renderer->shader, "tex", 0); | 		shader_uniformSet1i(renderer->shader, "tex", 0); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	glBindVertexArray(renderer->vao); | 	glBindVertexArray(renderer->vao[renderGroup->mode]); | ||||||
| 	glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo); | 	glDrawArrays(GL_TRIANGLE_STRIP, 0, renderer->numVertexesInVbo); | ||||||
|  | 	GL_CHECK_ERROR(); | ||||||
| 
 | 
 | ||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 	debug_countIncrement(debugcount_drawArrays); | 	debug_countIncrement(debugcount_drawArrays); | ||||||
| @ -298,7 +310,56 @@ void renderer_rect(Renderer *const renderer, Rect camera, v2 pos, v2 size, | |||||||
| 	v2 posInCameraSpace = v2_sub(pos, camera.pos); | 	v2 posInCameraSpace = v2_sub(pos, camera.pos); | ||||||
| 	RenderQuad_ quad    = createRenderQuad(renderer, posInCameraSpace, size, | 	RenderQuad_ quad    = createRenderQuad(renderer, posInCameraSpace, size, | ||||||
| 	                                    pivotPoint, rotate, renderTex); | 	                                    pivotPoint, rotate, renderTex); | ||||||
| 	addRenderQuadToRenderGroup(renderer, quad, renderTex.tex, color); | 
 | ||||||
|  | 	{ // addRenderQuadToRenderGroup
 | ||||||
|  | 		/*
 | ||||||
|  | 		   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. | ||||||
|  | 
 | ||||||
|  | 		   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. | ||||||
|  | 		   */ | ||||||
|  | 		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); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void renderer_triangle(Renderer *const renderer, Rect camera, | ||||||
|  |                        TrianglePoints triangle, v2 pivotPoint, f32 rotate, | ||||||
|  |                        RenderTex renderTex, v4 color) | ||||||
|  | { | ||||||
|  | 	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); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	RenderTriangle_ renderTriangle = createRenderTriangle( | ||||||
|  | 	    renderer, triangleInCamSpace, pivotPoint, rotate, renderTex); | ||||||
|  | 
 | ||||||
|  | 	addVertexToRenderGroup( | ||||||
|  | 	    renderer, renderTex.tex, color, renderTriangle.vertex, | ||||||
|  | 	    ARRAY_COUNT(renderTriangle.vertex), rendermode_triangle); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | ||||||
| @ -361,7 +422,7 @@ void renderer_string(Renderer *const renderer, MemoryArena_ *arena, Rect camera, | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		addVertexToRenderGroup(renderer, tex, color, vertexList, | 		addVertexToRenderGroup(renderer, tex, color, vertexList, | ||||||
| 		                       numVertexesToAlloc); | 		                       numVertexesToAlloc, rendermode_quad); | ||||||
| 		// TODO(doyle): Mem free
 | 		// TODO(doyle): Mem free
 | ||||||
| 		// PLATFORM_MEM_FREE(arena, vertexList,
 | 		// PLATFORM_MEM_FREE(arena, vertexList,
 | ||||||
| 		//                  sizeof(Vertex) * numVertexesToAlloc);
 | 		//                  sizeof(Vertex) * numVertexesToAlloc);
 | ||||||
|  | |||||||
| @ -233,7 +233,7 @@ i32 main(void) | |||||||
| 			char textBuffer[256]; | 			char textBuffer[256]; | ||||||
| 			snprintf(textBuffer, ARRAY_COUNT(textBuffer), | 			snprintf(textBuffer, ARRAY_COUNT(textBuffer), | ||||||
| 			         "Dengine | %f ms/f | %f fps | Entity Count: %d", | 			         "Dengine | %f ms/f | %f fps | Entity Count: %d", | ||||||
| 			         msPerFrame, framesPerSecond, 0); | 			         msPerFrame, framesPerSecond, gameState.entityIndex); | ||||||
| 
 | 
 | ||||||
| 			glfwSetWindowTitle(window, textBuffer); | 			glfwSetWindowTitle(window, textBuffer); | ||||||
| 			titleUpdateFrequencyInSeconds = 0.5f; | 			titleUpdateFrequencyInSeconds = 0.5f; | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ typedef struct GameState { | |||||||
| 
 | 
 | ||||||
| 	Entity entityList[1024]; | 	Entity entityList[1024]; | ||||||
| 	i32 entityIndex; | 	i32 entityIndex; | ||||||
|  | 	f32 pixelsPerMeter; | ||||||
| 
 | 
 | ||||||
| 	Rect camera; | 	Rect camera; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -39,8 +39,8 @@ typedef struct Entity | |||||||
| 	i32 childIds[8]; | 	i32 childIds[8]; | ||||||
| 	i32 numChilds; | 	i32 numChilds; | ||||||
| 
 | 
 | ||||||
| 	v2 pos;  // Position
 | 	v2 pos; | ||||||
| 	v2 dPos; // Velocity
 | 	v2 velocity; | ||||||
| 	v2 hitbox; | 	v2 hitbox; | ||||||
| 	v2 size; | 	v2 size; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -24,25 +24,36 @@ typedef struct RenderTex | |||||||
| 	v4 texRect; | 	v4 texRect; | ||||||
| } RenderTex; | } RenderTex; | ||||||
| 
 | 
 | ||||||
| typedef struct RenderQuad | typedef struct TrianglePoints { | ||||||
| { | 	v2 points[3]; | ||||||
| 	Vertex vertex[4]; | } TrianglePoints; | ||||||
| } RenderQuad_; |  | ||||||
| 
 | 
 | ||||||
| typedef struct RenderGroup | typedef struct RenderGroup | ||||||
| { | { | ||||||
|  | 	enum RenderMode mode; | ||||||
| 	Texture *tex; | 	Texture *tex; | ||||||
| 	v4 color; | 	v4 color; | ||||||
| 
 | 
 | ||||||
| 	Vertex *vertexList; | 	Vertex *vertexList; | ||||||
| 	i32 vertexIndex; | 	i32 vertexIndex; | ||||||
|  | 
 | ||||||
| } RenderGroup; | } RenderGroup; | ||||||
| 
 | 
 | ||||||
|  | enum RenderMode | ||||||
|  | { | ||||||
|  | 	rendermode_quad, | ||||||
|  | 	rendermode_triangle, | ||||||
|  | 	rendermode_count, | ||||||
|  | 	rendermode_invalid, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| typedef struct Renderer | typedef struct Renderer | ||||||
| { | { | ||||||
| 	Shader *shader; | 	Shader *shader; | ||||||
| 	u32 vao; | 
 | ||||||
| 	u32 vbo; | 	u32 vao[rendermode_count]; | ||||||
|  | 	u32 vbo[rendermode_count]; | ||||||
|  | 
 | ||||||
| 	i32 numVertexesInVbo; | 	i32 numVertexesInVbo; | ||||||
| 	v2 vertexNdcFactor; | 	v2 vertexNdcFactor; | ||||||
| 	v2 size; | 	v2 size; | ||||||
| @ -52,7 +63,8 @@ typedef struct Renderer | |||||||
| } Renderer; | } Renderer; | ||||||
| 
 | 
 | ||||||
| // TODO(doyle): Use z-index occluding for rendering
 | // TODO(doyle): Use z-index occluding for rendering
 | ||||||
| RenderTex renderer_createNullRenderTex(AssetManager *const assetManager); | RenderTex | ||||||
|  | renderer_createNullRenderTex(AssetManager *const assetManager); | ||||||
| 
 | 
 | ||||||
| // TODO(doyle): Clean up lines
 | // TODO(doyle): Clean up lines
 | ||||||
| // Renderer::~Renderer() { glDeleteVertexArrays(1, &this->quadVAO); }
 | // Renderer::~Renderer() { glDeleteVertexArrays(1, &this->quadVAO); }
 | ||||||
| @ -68,6 +80,10 @@ inline void renderer_staticRect(Renderer *const renderer, v2 pos, v2 size, | |||||||
| 	              renderTex, color); | 	              renderTex, color); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void renderer_triangle(Renderer *const renderer, Rect camera, | ||||||
|  |                        TrianglePoints triangle, v2 pivotPoint, f32 rotate, | ||||||
|  |                        RenderTex renderTex, v4 color); | ||||||
|  | 
 | ||||||
| void renderer_string(Renderer *const renderer, MemoryArena_ *arena, | void renderer_string(Renderer *const renderer, MemoryArena_ *arena, | ||||||
|                      Rect camera, Font *const font, |                      Rect camera, Font *const font, | ||||||
|                      const char *const string, v2 pos, v2 pivotPoint, |                      const char *const string, v2 pos, v2 pivotPoint, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user