Fix incorrect indexing into vertex array for model
Wavefront model obj format indexes starting from 1, offset during load by -1 to make all indexes be 0 based.
This commit is contained in:
		
							parent
							
								
									2c745d3571
								
							
						
					
					
						commit
						237e73253a
					
				| @ -71,9 +71,9 @@ FILE_SCOPE bool ObjWaveFrontInit(WavefrontObj *const obj, const i32 vertexInitCa | ||||
| } | ||||
| 
 | ||||
| FILE_SCOPE bool ObjWavefrontLoad(const PlatformAPI api, PlatformMemory *const memory, | ||||
|                                  const char *const path) | ||||
|                                  const char *const path, WavefrontObj *const obj) | ||||
| { | ||||
| 	if (!memory || ! path) return false; | ||||
| 	if (!memory || !path || !obj) return false; | ||||
| 
 | ||||
| 	PlatformFile file = {}; | ||||
| 	if (!api.FileOpen(path, &file, PlatformFilePermissionFlag_Read)) | ||||
| @ -98,8 +98,7 @@ FILE_SCOPE bool ObjWavefrontLoad(const PlatformAPI api, PlatformMemory *const me | ||||
| 		WavefrontVertexType_Normal, | ||||
| 	}; | ||||
| 
 | ||||
| 	WavefrontObj obj = {}; | ||||
| 	if (!ObjWaveFrontInit(&obj)) | ||||
| 	if (!ObjWaveFrontInit(obj)) | ||||
| 	{ | ||||
| 		DqnMemStack_EndTempRegion(tmpMemRegion); | ||||
| 		return false; | ||||
| @ -160,15 +159,15 @@ FILE_SCOPE bool ObjWavefrontLoad(const PlatformAPI api, PlatformMemory *const me | ||||
| 				DQN_ASSERT(vIndex == 3 || vIndex == 4); | ||||
| 				if (type == WavefrontVertexType_Geometric) | ||||
| 				{ | ||||
| 					DqnArray_Push(&obj.geometryArray, v4); | ||||
| 					DqnArray_Push(&obj->geometryArray, v4); | ||||
| 				} | ||||
| 				else if (type == WavefrontVertexType_Texture) | ||||
| 				{ | ||||
| 					DqnArray_Push(&obj.texUVArray, v4.xyz); | ||||
| 					DqnArray_Push(&obj->texUVArray, v4.xyz); | ||||
| 				} | ||||
| 				else if (type == WavefrontVertexType_Normal) | ||||
| 				{ | ||||
| 					DqnArray_Push(&obj.normalArray, v4.xyz); | ||||
| 					DqnArray_Push(&obj->normalArray, v4.xyz); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| @ -239,7 +238,9 @@ FILE_SCOPE bool ObjWavefrontLoad(const PlatformAPI api, PlatformMemory *const me | ||||
| 						i32 numLen = (i32)((size_t)scan - (size_t)numStartPtr); | ||||
| 						if (numLen > 0) | ||||
| 						{ | ||||
| 							i32 index = (i32)Dqn_StrToI64(numStartPtr, numLen); | ||||
| 							// NOTE(doyle): Obj format starts indexing from 1,
 | ||||
| 							// so offset by -1 to make it zero-based indexes.
 | ||||
| 							i32 index = (i32)Dqn_StrToI64(numStartPtr, numLen) - 1; | ||||
| 
 | ||||
| 							if (type == WavefrontVertexType_Geometric) | ||||
| 							{ | ||||
| @ -274,13 +275,13 @@ FILE_SCOPE bool ObjWavefrontLoad(const PlatformAPI api, PlatformMemory *const me | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					if (obj.model.faces.count == 7470 || obj.model.faces.count == 2491) | ||||
| 					if (obj->model.faces.count == 7470 || obj->model.faces.count == 2491) | ||||
| 					{ | ||||
| 						int x = 5; | ||||
| 					} | ||||
| 				} | ||||
| 				DQN_ASSERT(numVertexesParsed >= 3); | ||||
| 				DQN_ASSERT(DqnArray_Push(&obj.model.faces, face)); | ||||
| 				DQN_ASSERT(DqnArray_Push(&obj->model.faces, face)); | ||||
| 			} | ||||
| 			break; | ||||
| 
 | ||||
| @ -307,14 +308,14 @@ FILE_SCOPE bool ObjWavefrontLoad(const PlatformAPI api, PlatformMemory *const me | ||||
| 				if (scan) | ||||
| 				{ | ||||
| 					i32 nameLen = (i32)((size_t)scan - (size_t)namePtr); | ||||
| 					DQN_ASSERT(obj.model.groupNameIndex + 1 < DQN_ARRAY_COUNT(obj.model.groupName)); | ||||
| 					DQN_ASSERT(obj->model.groupNameIndex + 1 < DQN_ARRAY_COUNT(obj->model.groupName)); | ||||
| 
 | ||||
| 					DQN_ASSERT(!obj.model.groupName[obj.model.groupNameIndex]); | ||||
| 					obj.model.groupName[obj.model.groupNameIndex++] = (char *)DqnMemStack_Allocate( | ||||
| 					DQN_ASSERT(!obj->model.groupName[obj->model.groupNameIndex]); | ||||
| 					obj->model.groupName[obj->model.groupNameIndex++] = (char *)DqnMemStack_Allocate( | ||||
| 					    &memory->permMemStack, (nameLen + 1) * sizeof(char)); | ||||
| 
 | ||||
| 					for (i32 i = 0; i < nameLen; i++) | ||||
| 						obj.model.groupName[obj.model.groupNameIndex - 1][i] = namePtr[i]; | ||||
| 						obj->model.groupName[obj->model.groupNameIndex - 1][i] = namePtr[i]; | ||||
| 
 | ||||
| 					while (scan && (*scan == ' ' || *scan == '\n')) | ||||
| 						scan++; | ||||
| @ -342,7 +343,7 @@ FILE_SCOPE bool ObjWavefrontLoad(const PlatformAPI api, PlatformMemory *const me | ||||
| 
 | ||||
| 					i32 numLen               = (i32)((size_t)scan - (size_t)numStartPtr); | ||||
| 					i32 groupSmoothing       = (i32)Dqn_StrToI64(numStartPtr, numLen); | ||||
| 					obj.model.groupSmoothing = groupSmoothing; | ||||
| 					obj->model.groupSmoothing = groupSmoothing; | ||||
| 				} | ||||
| 
 | ||||
| 				while (scan && *scan == ' ' || *scan == '\n') scan++; | ||||
| @ -1479,6 +1480,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer, | ||||
| 	} | ||||
| 
 | ||||
| 	DTR_DEBUG_TIMED_FUNCTION(); | ||||
| 	LOCAL_PERSIST WavefrontObj waveObj = {}; | ||||
| 	if (!memory->isInit) | ||||
| 	{ | ||||
| 		TestStrToF32Converter(); | ||||
| @ -1505,10 +1507,70 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer, | ||||
| 		int x = 5; | ||||
| 		DqnMemStack_EndTempRegion(tmp); | ||||
| 
 | ||||
| 		ObjWavefrontLoad(input->api, memory, "african_head.obj"); | ||||
| #if 0 | ||||
| 		DQN_ASSERT(ObjWavefrontLoad(input->api, memory, "african_head.obj", &waveObj)); | ||||
| #endif | ||||
| 	} | ||||
| 	DTRRender_Clear(renderBuffer, DqnV3_3f(0, 0, 0)); | ||||
| 
 | ||||
| #if 1 | ||||
| 	DqnV4 modelCol = DqnV4_4f(1, 1, 1, 1); | ||||
| 	for (i32 i = 0; i < waveObj.model.faces.count; i++) | ||||
| 	{ | ||||
| 		WavefrontModelFace face = waveObj.model.faces.data[i]; | ||||
| 		DQN_ASSERT(face.vertexArray.count == 3); | ||||
| 
 | ||||
| #if 0 | ||||
| 		i32 vertAIndex = face.vertexArray.data[0]; | ||||
| 		i32 vertBIndex = face.vertexArray.data[1]; | ||||
| 		i32 vertCIndex = face.vertexArray.data[2]; | ||||
| 
 | ||||
| 		DqnV4 vertA = waveObj.geometryArray.data[vertAIndex]; | ||||
| 		DqnV4 vertB = waveObj.geometryArray.data[vertBIndex]; | ||||
| 		DqnV4 vertC = waveObj.geometryArray.data[vertCIndex]; | ||||
| 
 | ||||
| 		vertA.x *= (renderBuffer->width * 0.5f); | ||||
| 		vertA.y *= (renderBuffer->height * 0.5f); | ||||
| 
 | ||||
| 		vertB.x *= (renderBuffer->width * 0.5f); | ||||
| 		vertB.y *= (renderBuffer->height * 0.5f); | ||||
| 
 | ||||
| 		vertC.x *= (renderBuffer->width * 0.5f); | ||||
| 		vertC.y *= (renderBuffer->height * 0.5f); | ||||
| 
 | ||||
| 		vertA.x += (renderBuffer->width * 0.5f); | ||||
| 		vertA.y += (renderBuffer->height * 0.5f); | ||||
| 
 | ||||
| 		vertB.x += (renderBuffer->width * 0.5f); | ||||
| 		vertB.y += (renderBuffer->height * 0.5f); | ||||
| 
 | ||||
| 		vertC.x += (renderBuffer->width * 0.5f); | ||||
| 		vertC.y += (renderBuffer->height * 0.5f); | ||||
| 
 | ||||
| 		DTRRender_Triangle(renderBuffer, vertA.xy, vertB.xy, vertC.xy, modelCol); | ||||
| #else | ||||
| 		const i32 NUM_VERTEXES = 3; | ||||
| 		for (i32 j = 0; j < NUM_VERTEXES; j++) | ||||
| 		{ | ||||
| 			i32 vertAIndex = face.vertexArray.data[j]; | ||||
| 			i32 vertBIndex = face.vertexArray.data[(j + 1) % NUM_VERTEXES]; | ||||
| 
 | ||||
| 			DqnV4 vertA = waveObj.geometryArray.data[vertAIndex]; | ||||
| 			DqnV4 vertB = waveObj.geometryArray.data[vertBIndex]; | ||||
| 
 | ||||
| 			vertA.x = (vertA.x * (renderBuffer->width * 0.5f)) + renderBuffer->width * 0.5f; | ||||
| 			vertA.y = (vertA.y * (renderBuffer->height * 0.5f)) + renderBuffer->height * 0.5f; | ||||
| 
 | ||||
| 			vertB.x = (vertB.x * (renderBuffer->width * 0.5f)) + renderBuffer->width * 0.5f; | ||||
| 			vertB.y = (vertB.y * (renderBuffer->height * 0.5f)) + renderBuffer->height * 0.5f; | ||||
| 
 | ||||
| 			DTRRender_Line(renderBuffer, DqnV2i_V2(vertA.xy), DqnV2i_V2(vertB.xy), modelCol); | ||||
| 		} | ||||
| #endif | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| #if 0 | ||||
| #if 1 | ||||
| 	DqnV4 colorRed = DqnV4_4f(0.8f, 0, 0, 1); | ||||
| 	DqnV2i bufferMidP = | ||||
| @ -1563,6 +1625,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer, | ||||
| 
 | ||||
| #else | ||||
| 	CompAssignment(renderBuffer, input, memory); | ||||
| #endif | ||||
| #endif | ||||
| 	DTRDebug_Update(state, renderBuffer, input, memory); | ||||
| } | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| #include "dqn.h" | ||||
| #define DTR_DEBUG 1 | ||||
| #ifdef DTR_DEBUG | ||||
| 	#define DTR_DEBUG_RENDER             1 | ||||
| 	#define DTR_DEBUG_RENDER             0 | ||||
| 
 | ||||
| 	#define DTR_DEBUG_PROFILING          1 | ||||
| 	#ifdef DTR_DEBUG_PROFILING | ||||
|  | ||||
							
								
								
									
										33
									
								
								src/dqn.h
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								src/dqn.h
									
									
									
									
									
								
							| @ -129,11 +129,12 @@ DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedMem (DqnMemStack *const stack, u8 * | ||||
| DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedSize(DqnMemStack *const stack, size_t size, const bool zeroClear, const u32 byteAlign = 4); // Single allocation from platform, no further allocations, returns NULL of allocate if out of space
 | ||||
| DQN_FILE_SCOPE bool DqnMemStack_Init             (DqnMemStack *const stack, size_t size, const bool zeroClear, const u32 byteAlign = 4); // Allocates from platform dynamically as space runs out
 | ||||
| 
 | ||||
| DQN_FILE_SCOPE void *DqnMemStack_Allocate       (DqnMemStack *const stack, size_t size);              // Returns NULL if out of space and stack is using fixed memory/size, or platform allocation fails
 | ||||
| DQN_FILE_SCOPE void  DqnMemStack_Free           (DqnMemStack *const stack);                           // Frees all blocks belonging to this stack
 | ||||
| DQN_FILE_SCOPE void *DqnMemStack_Allocate       (DqnMemStack *const stack, size_t size);             // Returns NULL if out of space and stack is using fixed memory/size, or platform allocation fails
 | ||||
| DQN_FILE_SCOPE bool  DqnMemStack_Pop            (DqnMemStack *const stack, void *ptr, size_t size);  // Frees the given ptr. It MUST be the last allocated item in the stack
 | ||||
| DQN_FILE_SCOPE void  DqnMemStack_Free           (DqnMemStack *const stack);                          // Frees all blocks belonging to this stack
 | ||||
| DQN_FILE_SCOPE bool  DqnMemStack_FreeStackBlock (DqnMemStack *const stack, DqnMemStackBlock *block); // Frees the specified block, returns false if block doesn't belong
 | ||||
| DQN_FILE_SCOPE bool  DqnMemStack_FreeLastBlock  (DqnMemStack *const stack);                           // Frees the last-most memory block. If last block, free that block, next allocate will attach a block.
 | ||||
| DQN_FILE_SCOPE void  DqnMemStack_ClearCurrBlock (DqnMemStack *const stack, const bool zeroClear);     // Reset the current memory block usage to 0
 | ||||
| DQN_FILE_SCOPE bool  DqnMemStack_FreeLastBlock  (DqnMemStack *const stack);                          // Frees the last-most memory block. If last block, free that block, next allocate will attach a block.
 | ||||
| DQN_FILE_SCOPE void  DqnMemStack_ClearCurrBlock (DqnMemStack *const stack, const bool zeroClear);    // Reset the current memory block usage to 0
 | ||||
| 
 | ||||
| // TempMemStack is only required for the function. Once BeginTempRegion() is called, subsequent allocation calls can be made using the original stack.
 | ||||
| // Upon EndTempRegion() the original stack will free any additional blocks it allocated during the temp region and revert to the original
 | ||||
| @ -547,8 +548,12 @@ DQN_FILE_SCOPE DqnV3i DqnV3i_3f(f32 x, f32 y, f32 z); | ||||
| // Vec4
 | ||||
| ////////////////////////////////////////////////////////////////////////////////
 | ||||
| typedef union DqnV4 { | ||||
| 	struct { f32 x, y, z, w; }; | ||||
| 	struct | ||||
| 	{ | ||||
| 		f32 x, y, z, w; | ||||
| 	}; | ||||
| 	DqnV3 xyz; | ||||
| 	DqnV2 xy; | ||||
| 
 | ||||
| 	struct { f32 r, g, b, a; }; | ||||
| 	DqnV3 rgb; | ||||
| @ -1498,8 +1503,22 @@ DQN_FILE_SCOPE void *DqnMemStack_Allocate(DqnMemStack *const stack, size_t size) | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| DQN_FILE_SCOPE bool DqnMemStack_FreeStackBlock(DqnMemStack *const stack, | ||||
|                                                  DqnMemStackBlock *block) | ||||
| DQN_FILE_SCOPE bool DqnMemStack_Pop(DqnMemStack *const stack, void *ptr, size_t size) | ||||
| { | ||||
| 	if (!stack || !stack->block) return false; | ||||
| 
 | ||||
| 	u8 *currPtr = stack->block->memory + stack->block->used; | ||||
| 	DQN_ASSERT((u8 *)ptr >= stack->block->memory && ptr < currPtr); | ||||
| 
 | ||||
| 	size_t calcSize = (size_t)currPtr - (size_t)ptr; | ||||
| 	DQN_ASSERT(calcSize == size); | ||||
| 
 | ||||
| 	stack->block->used -= size; | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| DQN_FILE_SCOPE bool DqnMemStack_FreeStackBlock(DqnMemStack *const stack, DqnMemStackBlock *block) | ||||
| { | ||||
| 	if (!stack || !block || !stack->block) return false; | ||||
| 	if (stack->flags & DqnMemStackFlag_IsFixedMemoryFromUser) return false; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user