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,
|
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 = {};
|
PlatformFile file = {};
|
||||||
if (!api.FileOpen(path, &file, PlatformFilePermissionFlag_Read))
|
if (!api.FileOpen(path, &file, PlatformFilePermissionFlag_Read))
|
||||||
@ -98,8 +98,7 @@ FILE_SCOPE bool ObjWavefrontLoad(const PlatformAPI api, PlatformMemory *const me
|
|||||||
WavefrontVertexType_Normal,
|
WavefrontVertexType_Normal,
|
||||||
};
|
};
|
||||||
|
|
||||||
WavefrontObj obj = {};
|
if (!ObjWaveFrontInit(obj))
|
||||||
if (!ObjWaveFrontInit(&obj))
|
|
||||||
{
|
{
|
||||||
DqnMemStack_EndTempRegion(tmpMemRegion);
|
DqnMemStack_EndTempRegion(tmpMemRegion);
|
||||||
return false;
|
return false;
|
||||||
@ -160,15 +159,15 @@ FILE_SCOPE bool ObjWavefrontLoad(const PlatformAPI api, PlatformMemory *const me
|
|||||||
DQN_ASSERT(vIndex == 3 || vIndex == 4);
|
DQN_ASSERT(vIndex == 3 || vIndex == 4);
|
||||||
if (type == WavefrontVertexType_Geometric)
|
if (type == WavefrontVertexType_Geometric)
|
||||||
{
|
{
|
||||||
DqnArray_Push(&obj.geometryArray, v4);
|
DqnArray_Push(&obj->geometryArray, v4);
|
||||||
}
|
}
|
||||||
else if (type == WavefrontVertexType_Texture)
|
else if (type == WavefrontVertexType_Texture)
|
||||||
{
|
{
|
||||||
DqnArray_Push(&obj.texUVArray, v4.xyz);
|
DqnArray_Push(&obj->texUVArray, v4.xyz);
|
||||||
}
|
}
|
||||||
else if (type == WavefrontVertexType_Normal)
|
else if (type == WavefrontVertexType_Normal)
|
||||||
{
|
{
|
||||||
DqnArray_Push(&obj.normalArray, v4.xyz);
|
DqnArray_Push(&obj->normalArray, v4.xyz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -239,7 +238,9 @@ FILE_SCOPE bool ObjWavefrontLoad(const PlatformAPI api, PlatformMemory *const me
|
|||||||
i32 numLen = (i32)((size_t)scan - (size_t)numStartPtr);
|
i32 numLen = (i32)((size_t)scan - (size_t)numStartPtr);
|
||||||
if (numLen > 0)
|
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)
|
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;
|
int x = 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DQN_ASSERT(numVertexesParsed >= 3);
|
DQN_ASSERT(numVertexesParsed >= 3);
|
||||||
DQN_ASSERT(DqnArray_Push(&obj.model.faces, face));
|
DQN_ASSERT(DqnArray_Push(&obj->model.faces, face));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -307,14 +308,14 @@ FILE_SCOPE bool ObjWavefrontLoad(const PlatformAPI api, PlatformMemory *const me
|
|||||||
if (scan)
|
if (scan)
|
||||||
{
|
{
|
||||||
i32 nameLen = (i32)((size_t)scan - (size_t)namePtr);
|
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]);
|
DQN_ASSERT(!obj->model.groupName[obj->model.groupNameIndex]);
|
||||||
obj.model.groupName[obj.model.groupNameIndex++] = (char *)DqnMemStack_Allocate(
|
obj->model.groupName[obj->model.groupNameIndex++] = (char *)DqnMemStack_Allocate(
|
||||||
&memory->permMemStack, (nameLen + 1) * sizeof(char));
|
&memory->permMemStack, (nameLen + 1) * sizeof(char));
|
||||||
|
|
||||||
for (i32 i = 0; i < nameLen; i++)
|
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'))
|
while (scan && (*scan == ' ' || *scan == '\n'))
|
||||||
scan++;
|
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 numLen = (i32)((size_t)scan - (size_t)numStartPtr);
|
||||||
i32 groupSmoothing = (i32)Dqn_StrToI64(numStartPtr, numLen);
|
i32 groupSmoothing = (i32)Dqn_StrToI64(numStartPtr, numLen);
|
||||||
obj.model.groupSmoothing = groupSmoothing;
|
obj->model.groupSmoothing = groupSmoothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (scan && *scan == ' ' || *scan == '\n') scan++;
|
while (scan && *scan == ' ' || *scan == '\n') scan++;
|
||||||
@ -1479,6 +1480,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DTR_DEBUG_TIMED_FUNCTION();
|
DTR_DEBUG_TIMED_FUNCTION();
|
||||||
|
LOCAL_PERSIST WavefrontObj waveObj = {};
|
||||||
if (!memory->isInit)
|
if (!memory->isInit)
|
||||||
{
|
{
|
||||||
TestStrToF32Converter();
|
TestStrToF32Converter();
|
||||||
@ -1505,10 +1507,70 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer,
|
|||||||
int x = 5;
|
int x = 5;
|
||||||
DqnMemStack_EndTempRegion(tmp);
|
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));
|
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
|
#if 1
|
||||||
DqnV4 colorRed = DqnV4_4f(0.8f, 0, 0, 1);
|
DqnV4 colorRed = DqnV4_4f(0.8f, 0, 0, 1);
|
||||||
DqnV2i bufferMidP =
|
DqnV2i bufferMidP =
|
||||||
@ -1563,6 +1625,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const renderBuffer,
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
CompAssignment(renderBuffer, input, memory);
|
CompAssignment(renderBuffer, input, memory);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
DTRDebug_Update(state, renderBuffer, input, memory);
|
DTRDebug_Update(state, renderBuffer, input, memory);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "dqn.h"
|
#include "dqn.h"
|
||||||
#define DTR_DEBUG 1
|
#define DTR_DEBUG 1
|
||||||
#ifdef DTR_DEBUG
|
#ifdef DTR_DEBUG
|
||||||
#define DTR_DEBUG_RENDER 1
|
#define DTR_DEBUG_RENDER 0
|
||||||
|
|
||||||
#define DTR_DEBUG_PROFILING 1
|
#define DTR_DEBUG_PROFILING 1
|
||||||
#ifdef DTR_DEBUG_PROFILING
|
#ifdef DTR_DEBUG_PROFILING
|
||||||
|
25
src/dqn.h
25
src/dqn.h
@ -130,6 +130,7 @@ DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedSize(DqnMemStack *const stack, size
|
|||||||
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 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_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 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_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 bool DqnMemStack_FreeLastBlock (DqnMemStack *const stack); // Frees the last-most memory block. If last block, free that block, next allocate will attach a block.
|
||||||
@ -547,8 +548,12 @@ DQN_FILE_SCOPE DqnV3i DqnV3i_3f(f32 x, f32 y, f32 z);
|
|||||||
// Vec4
|
// Vec4
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
typedef union DqnV4 {
|
typedef union DqnV4 {
|
||||||
struct { f32 x, y, z, w; };
|
struct
|
||||||
|
{
|
||||||
|
f32 x, y, z, w;
|
||||||
|
};
|
||||||
DqnV3 xyz;
|
DqnV3 xyz;
|
||||||
|
DqnV2 xy;
|
||||||
|
|
||||||
struct { f32 r, g, b, a; };
|
struct { f32 r, g, b, a; };
|
||||||
DqnV3 rgb;
|
DqnV3 rgb;
|
||||||
@ -1498,8 +1503,22 @@ DQN_FILE_SCOPE void *DqnMemStack_Allocate(DqnMemStack *const stack, size_t size)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE bool DqnMemStack_FreeStackBlock(DqnMemStack *const stack,
|
DQN_FILE_SCOPE bool DqnMemStack_Pop(DqnMemStack *const stack, void *ptr, size_t size)
|
||||||
DqnMemStackBlock *block)
|
{
|
||||||
|
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 || !block || !stack->block) return false;
|
||||||
if (stack->flags & DqnMemStackFlag_IsFixedMemoryFromUser) return false;
|
if (stack->flags & DqnMemStackFlag_IsFixedMemoryFromUser) return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user