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:
Doyle Thai 2017-05-22 20:54:34 +10:00
parent 2c745d3571
commit 237e73253a
3 changed files with 106 additions and 24 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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;