Improve allocation compactness and add DTRMesh

This commit is contained in:
Doyle Thai 2017-05-26 22:25:09 +10:00
parent 254d80749b
commit 4d2a7a7c06
6 changed files with 218 additions and 225 deletions

View File

@ -968,26 +968,26 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
DqnMemStack *const tempStack = &memory->tempStack; DqnMemStack *const tempStack = &memory->tempStack;
DQN_ASSERT(memory->context); DQN_ASSERT(memory->context);
state = (DTRState *)memory->context; state = (DTRState *)memory->context;
DTRAsset_FontToBitmapLoad(input->api, memory, &state->font, "Roboto-bold.ttf", DTRAsset_LoadFontToBitmap(input->api, &memory->mainStack, tempStack, &state->font,
DqnV2i_2i(256, 256), DqnV2i_2i(' ', '~'), 12); "Roboto-bold.ttf", DqnV2i_2i(256, 256), DqnV2i_2i(' ', '~'), 12);
DTRAsset_BitmapLoad(input->api, assetStack, DTRAsset_LoadBitmap(input->api, assetStack,
tempStack, &state->bitmap, "tree00.bmp"); tempStack, &state->bitmap, "tree00.bmp");
if (DTR_DEBUG) if (DTR_DEBUG)
{ {
DTRBitmap test = {}; DTRBitmap test = {};
DqnTempMemStack tmp = DqnMemStack_BeginTempRegion(&memory->tempStack); DqnTempMemStack tmp = DqnMemStack_BeginTempRegion(&memory->tempStack);
DTRAsset_BitmapLoad(input->api, assetStack, &memory->tempStack, &test, "byte_read_check.bmp"); DTRAsset_LoadBitmap(input->api, assetStack, &memory->tempStack, &test, "byte_read_check.bmp");
DqnMemStack_EndTempRegion(tmp); DqnMemStack_EndTempRegion(tmp);
} }
if (DTRAsset_WavefModelLoad(input->api, memory, &state->obj, "african_head.obj")) if (DTRAsset_LoadWavefrontObj(input->api, assetStack, &state->mesh, "african_head.obj"))
{ {
DTRAsset_BitmapLoad(input->api, assetStack, tempStack, &state->objTex, DTRAsset_LoadBitmap(input->api, assetStack, tempStack, &state->mesh.tex,
"african_head_diffuse.tga"); "african_head_diffuse.tga");
} }
DTRDebug_TestWavefFaceAndVertexParser(&state->obj); DTRDebug_TestMeshFaceAndVertexParser(&state->mesh);
} }
DqnTempMemStack transMemTmpRegion = DqnMemStack_BeginTempRegion(&memory->tempStack); DqnTempMemStack transMemTmpRegion = DqnMemStack_BeginTempRegion(&memory->tempStack);
@ -1043,27 +1043,25 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
const DqnV3 LIGHT = DqnV3_3i(0, 0, -1); const DqnV3 LIGHT = DqnV3_3i(0, 0, -1);
const f32 MODEL_SCALE = DQN_MIN(renderBuffer.width, renderBuffer.height) * 0.5f; const f32 MODEL_SCALE = DQN_MIN(renderBuffer.width, renderBuffer.height) * 0.5f;
DTRWavefModel *const waveObj = &state->obj; DTRMesh *const mesh = &state->mesh;
DqnV3 modelP = DqnV3_3f(renderBuffer.width * 0.5f, renderBuffer.height * 0.5f, 0); DqnV3 modelP = DqnV3_3f(renderBuffer.width * 0.5f, renderBuffer.height * 0.5f, 0);
for (i32 i = 0; i < waveObj->faces.count; i++) for (u32 i = 0; i < mesh->numFaces; i++)
{ {
if (i == 852) DTRMeshFace face = mesh->faces[i];
{ DQN_ASSERT(face.numVertexIndex == 3);
int BreakHere = 0; i32 vertAIndex = face.vertexIndex[0];
} i32 vertBIndex = face.vertexIndex[1];
DTRWavefModelFace face = waveObj->faces.data[i]; i32 vertCIndex = face.vertexIndex[2];
DQN_ASSERT(face.vertexIndexArray.count == 3);
i32 vertAIndex = face.vertexIndexArray.data[0];
i32 vertBIndex = face.vertexIndexArray.data[1];
i32 vertCIndex = face.vertexIndexArray.data[2];
DqnV4 vertA = waveObj->geometryArray.data[vertAIndex]; DqnV4 vertA = mesh->vertexes[vertAIndex];
DqnV4 vertB = waveObj->geometryArray.data[vertBIndex]; DqnV4 vertB = mesh->vertexes[vertBIndex];
DqnV4 vertC = waveObj->geometryArray.data[vertCIndex]; DqnV4 vertC = mesh->vertexes[vertCIndex];
DQN_ASSERT(vertAIndex < waveObj->geometryArray.count); // TODO(doyle): Some models have -ve indexes to refer to relative
DQN_ASSERT(vertBIndex < waveObj->geometryArray.count); // vertices. We should resolve that to positive indexes at run time.
DQN_ASSERT(vertCIndex < waveObj->geometryArray.count); DQN_ASSERT(vertAIndex < (i32)mesh->numVertexes);
DQN_ASSERT(vertBIndex < (i32)mesh->numVertexes);
DQN_ASSERT(vertCIndex < (i32)mesh->numVertexes);
DqnV4 vertAB = vertB - vertA; DqnV4 vertAB = vertB - vertA;
DqnV4 vertAC = vertC - vertA; DqnV4 vertAC = vertC - vertA;
@ -1088,16 +1086,16 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
screenVC.x = (f32)(i32)(screenVC.x + 0.5f); screenVC.x = (f32)(i32)(screenVC.x + 0.5f);
screenVC.y = (f32)(i32)(screenVC.y + 0.5f); screenVC.y = (f32)(i32)(screenVC.y + 0.5f);
i32 textureAIndex = face.textureIndexArray.data[0]; i32 textureAIndex = face.texIndex[0];
i32 textureBIndex = face.textureIndexArray.data[1]; i32 textureBIndex = face.texIndex[1];
i32 textureCIndex = face.textureIndexArray.data[2]; i32 textureCIndex = face.texIndex[2];
DqnV2 texA = waveObj->textureArray.data[textureAIndex].xy; DqnV2 texA = mesh->texUV[textureAIndex].xy;
DqnV2 texB = waveObj->textureArray.data[textureBIndex].xy; DqnV2 texB = mesh->texUV[textureBIndex].xy;
DqnV2 texC = waveObj->textureArray.data[textureCIndex].xy; DqnV2 texC = mesh->texUV[textureCIndex].xy;
DQN_ASSERT(textureAIndex < waveObj->textureArray.count); DQN_ASSERT(textureAIndex < (i32)mesh->numTexUV);
DQN_ASSERT(textureBIndex < waveObj->textureArray.count); DQN_ASSERT(textureBIndex < (i32)mesh->numTexUV);
DQN_ASSERT(textureCIndex < waveObj->textureArray.count); DQN_ASSERT(textureCIndex < (i32)mesh->numTexUV);
bool DEBUG_SIMPLE_MODE = false; bool DEBUG_SIMPLE_MODE = false;
if (DTR_DEBUG && DEBUG_SIMPLE_MODE) if (DTR_DEBUG && DEBUG_SIMPLE_MODE)
@ -1107,7 +1105,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
else else
{ {
DTRRender_TexturedTriangle(&renderBuffer, screenVA, screenVB, screenVC, texA, texB, DTRRender_TexturedTriangle(&renderBuffer, screenVA, screenVB, screenVC, texA, texB,
texC, &state->objTex, modelCol); texC, &state->mesh.tex, modelCol);
} }
bool DEBUG_WIREFRAME = false; bool DEBUG_WIREFRAME = false;
@ -1157,6 +1155,6 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
DqnMemStack_EndTempRegion(transMemTmpRegion); DqnMemStack_EndTempRegion(transMemTmpRegion);
DqnMemStack_ClearCurrBlock(&memory->tempStack, true); DqnMemStack_ClearCurrBlock(&memory->tempStack, true);
DQN_ASSERT(memory->tempStack.tempStackCount == 0); for (i32 i = 0; i < DQN_ARRAY_COUNT(memory->stacks); i++)
DQN_ASSERT(memory->mainStack.tempStackCount == 0); DQN_ASSERT(memory->stacks[i].tempStackCount == 0);
} }

View File

@ -10,9 +10,8 @@ typedef void DTR_UpdateFunction(struct PlatformRenderBuffer *const renderBuffer,
typedef struct DTRState typedef struct DTRState
{ {
DTRFont font; DTRFont font;
DTRBitmap bitmap; DTRBitmap bitmap;
DTRWavefModel obj; DTRMesh mesh;
DTRBitmap objTex;
} DTRState; } DTRState;
#endif #endif

View File

@ -116,9 +116,31 @@ FILE_SCOPE void AssetDqnArrayMemAPICallback(DqnMemAPICallbackInfo info, DqnMemAP
} }
} }
FILE_SCOPE bool WavefModelInit(DTRWavefModel *const obj, typedef struct WavefModelFace
{
DqnArray<i32> vertexIndexArray;
DqnArray<i32> textureIndexArray;
DqnArray<i32> normalIndexArray;
} WavefModelFace;
typedef struct WavefModel
{
DqnArray<DqnV4> geometryArray;
DqnArray<DqnV3> textureArray;
DqnArray<DqnV3> normalArray;
// TODO(doyle): Fixed size
char *groupName[16];
i32 groupNameIndex;
i32 groupSmoothing;
DqnArray<WavefModelFace> faces;
} WavefModel;
FILE_SCOPE bool WavefModelInit(WavefModel *const obj,
DqnMemAPI memAPI = DqnMemAPI_DefaultUseCalloc(), DqnMemAPI memAPI = DqnMemAPI_DefaultUseCalloc(),
const i32 vertexInitCapacity = 1000, const i32 faceInitCapacity = 1000) const i32 vertexInitCapacity = 1000,
const i32 faceInitCapacity = 1000)
{ {
if (!obj) return false; if (!obj) return false;
@ -140,10 +162,10 @@ FILE_SCOPE bool WavefModelInit(DTRWavefModel *const obj,
return initialised; return initialised;
} }
FILE_SCOPE inline DTRWavefModelFace FILE_SCOPE inline WavefModelFace
WavefModelFaceInit(i32 capacity = 3, DqnMemAPI memAPI = DqnMemAPI_DefaultUseCalloc()) WavefModelFaceInit(i32 capacity = 3, DqnMemAPI memAPI = DqnMemAPI_DefaultUseCalloc())
{ {
DTRWavefModelFace result = {}; WavefModelFace result = {};
DQN_ASSERT(DqnArray_Init(&result.vertexIndexArray, capacity, memAPI)); DQN_ASSERT(DqnArray_Init(&result.vertexIndexArray, capacity, memAPI));
DQN_ASSERT(DqnArray_Init(&result.textureIndexArray, capacity, memAPI)); DQN_ASSERT(DqnArray_Init(&result.textureIndexArray, capacity, memAPI));
DQN_ASSERT(DqnArray_Init(&result.normalIndexArray, capacity, memAPI)); DQN_ASSERT(DqnArray_Init(&result.normalIndexArray, capacity, memAPI));
@ -151,29 +173,24 @@ WavefModelFaceInit(i32 capacity = 3, DqnMemAPI memAPI = DqnMemAPI_DefaultUseCall
return result; return result;
} }
bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory, bool DTRAsset_LoadWavefrontObj(const PlatformAPI api, DqnMemStack *const memStack,
DTRWavefModel *const obj, const char *const path) DTRMesh *const mesh, const char *const path)
{ {
if (!memory || !path || !obj) return false; if (!memStack || !path || !mesh) return false;
PlatformFile file = {}; PlatformFile file = {};
if (!api.FileOpen(path, &file, PlatformFilePermissionFlag_Read, PlatformFileAction_OpenOnly)) if (!api.FileOpen(path, &file, PlatformFilePermissionFlag_Read, PlatformFileAction_OpenOnly))
return false; // TODO(doyle): Logging return false; // TODO(doyle): Logging
// TODO(doyle): Make arrays use given memory not malloc bool result = false;
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(&memory->tempStack); DqnTempMemStack tmpAssetRegion = DqnMemStack_BeginTempRegion(memStack);
DqnTempMemStack tmpAssetRegion = DqnMemStack_BeginTempRegion(&memory->assetStack); u8 *rawBytes = (u8 *)DqnMemStack_Push(memStack, file.size);
size_t bytesRead = api.FileRead(&file, rawBytes, file.size);
size_t fileSize = file.size;
u8 *rawBytes = (u8 *)DqnMemStack_Push(&memory->tempStack, file.size); DqnMemAPI memAPI = {};
size_t bytesRead = api.FileRead(&file, rawBytes, file.size); memAPI.callback = AssetDqnArrayMemAPICallback;
size_t fileSize = file.size; memAPI.userContext = memStack;
api.FileClose(&file);
if (bytesRead != file.size)
{
// TODO(doyle): Logging
DqnMemStack_EndTempRegion(tmpMemRegion);
return false;
}
enum WavefVertexType { enum WavefVertexType {
WavefVertexType_Invalid, WavefVertexType_Invalid,
@ -182,15 +199,11 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
WavefVertexType_Normal, WavefVertexType_Normal,
}; };
DqnMemAPI memAPI = {}; WavefModel dummy_ = {};
memAPI.callback = AssetDqnArrayMemAPICallback; WavefModel *obj = &dummy_;
memAPI.userContext = &memory->assetStack;
if (!WavefModelInit(obj, memAPI)) if (bytesRead != file.size) goto cleanup;
{ if (!WavefModelInit(obj, memAPI)) goto cleanup;
DqnMemStack_EndTempRegion(tmpMemRegion);
return false;
}
for (char *scan = (char *)rawBytes; scan && scan < ((char *)rawBytes + fileSize);) for (char *scan = (char *)rawBytes; scan && scan < ((char *)rawBytes + fileSize);)
{ {
@ -309,7 +322,7 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
while (scan && (*scan == ' ' || *scan == '\n')) scan++; while (scan && (*scan == ' ' || *scan == '\n')) scan++;
if (!scan) continue; if (!scan) continue;
DTRWavefModelFace face = WavefModelFaceInit(3, memAPI); WavefModelFace face = WavefModelFaceInit(3, memAPI);
i32 numVertexesParsed = 0; i32 numVertexesParsed = 0;
bool moreVertexesToParse = true; bool moreVertexesToParse = true;
while (moreVertexesToParse) while (moreVertexesToParse)
@ -397,8 +410,8 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
DQN_ASSERT(obj->groupNameIndex + 1 < DQN_ARRAY_COUNT(obj->groupName)); DQN_ASSERT(obj->groupNameIndex + 1 < DQN_ARRAY_COUNT(obj->groupName));
DQN_ASSERT(!obj->groupName[obj->groupNameIndex]); DQN_ASSERT(!obj->groupName[obj->groupNameIndex]);
obj->groupName[obj->groupNameIndex++] = (char *)DqnMemStack_Push( obj->groupName[obj->groupNameIndex++] =
&memory->mainStack, (nameLen + 1) * sizeof(char)); (char *)DqnMemStack_Push(memStack, (nameLen + 1) * sizeof(char));
for (i32 i = 0; i < nameLen; i++) for (i32 i = 0; i < nameLen; i++)
obj->groupName[obj->groupNameIndex - 1][i] = namePtr[i]; obj->groupName[obj->groupNameIndex - 1][i] = namePtr[i];
@ -460,26 +473,19 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Recompact Allocations // Recompact Allocations
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
u8 *geometryPtr = (u8 *)obj->geometryArray.data; size_t geometrySize = sizeof(obj->geometryArray.data[0]) * obj->geometryArray.count;
u8 *texturePtr = (u8 *)obj->textureArray.data; size_t textureSize = sizeof(obj->textureArray.data[0]) * obj->textureArray.count;
u8 *normalPtr = (u8 *)obj->normalArray.data; size_t normalSize = sizeof(obj->normalArray.data[0]) * obj->normalArray.count;
size_t faceSize = sizeof(obj->faces.data[0]) * obj->faces.count;
size_t geometrySize = sizeof(obj->geometryArray.data[0]) * obj->geometryArray.count;
size_t textureSize = sizeof(obj->textureArray.data[0]) * obj->textureArray.count;
size_t normalSize = sizeof(obj->normalArray.data[0]) * obj->normalArray.count;
u8 *facePtr = (u8 *)obj->faces.data;
size_t faceSize = sizeof(obj->faces.data[0]) * obj->faces.count;
size_t totalModelSize = geometrySize + textureSize + normalSize + faceSize;
size_t vertIndexItemSize = sizeof(obj->faces.data[0].vertexIndexArray.data[0]); size_t vertIndexItemSize = sizeof(obj->faces.data[0].vertexIndexArray.data[0]);
size_t texIndexItemSize = sizeof(obj->faces.data[0].textureIndexArray.data[0]); size_t texIndexItemSize = sizeof(obj->faces.data[0].textureIndexArray.data[0]);
size_t normIndexItemSize = sizeof(obj->faces.data[0].normalIndexArray.data[0]); size_t normIndexItemSize = sizeof(obj->faces.data[0].normalIndexArray.data[0]);
size_t totalModelSize = geometrySize + textureSize + normalSize + faceSize;
{ {
for (i32 i = 0; i < obj->faces.count; i++) for (i32 i = 0; i < obj->faces.count; i++)
{ {
DTRWavefModelFace *face = &obj->faces.data[i]; WavefModelFace *face = &obj->faces.data[i];
size_t vertIndexSize = face->vertexIndexArray.count * vertIndexItemSize; size_t vertIndexSize = face->vertexIndexArray.count * vertIndexItemSize;
size_t texIndexSize = face->textureIndexArray.count * texIndexItemSize; size_t texIndexSize = face->textureIndexArray.count * texIndexItemSize;
@ -492,56 +498,51 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
// IMPORTANT(doyle): We always allocate a new block, so each assets owns // IMPORTANT(doyle): We always allocate a new block, so each assets owns
// their own memory block. // their own memory block.
DqnMemStackBlock *modelBlock = DqnMemStackBlock *modelBlock =
DqnMemStack_AllocateCompatibleBlock(&memory->assetStack, totalModelSize); DqnMemStack_AllocateCompatibleBlock(memStack, totalModelSize);
if (modelBlock) if (modelBlock)
{ {
if (DqnMemStack_AttachBlock(&memory->assetStack, modelBlock)) if (DqnMemStack_AttachBlock(memStack, modelBlock))
{ {
u8 *newGeometryPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, geometrySize); mesh->vertexes = (DqnV4 *)DqnMemStack_Push(memStack, geometrySize);
u8 *newTexturePtr = (u8 *)DqnMemStack_Push(&memory->assetStack, textureSize); mesh->texUV = (DqnV3 *)DqnMemStack_Push(memStack, textureSize);
u8 *newNormalPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, normalSize); mesh->normals = (DqnV3 *)DqnMemStack_Push(memStack, normalSize);
u8 *newFacePtr = (u8 *)DqnMemStack_Push(&memory->assetStack, faceSize); mesh->faces = (DTRMeshFace *)DqnMemStack_Push(memStack, faceSize);
MemcopyInternal(newGeometryPtr, geometryPtr, geometrySize);
MemcopyInternal(newTexturePtr, texturePtr, textureSize);
MemcopyInternal(newNormalPtr, normalPtr, normalSize);
MemcopyInternal(newFacePtr, facePtr, faceSize);
obj->geometryArray.data = (DqnV4 *)newGeometryPtr;
obj->normalArray.data = (DqnV3 *)newNormalPtr;
obj->textureArray.data = (DqnV3 *)newTexturePtr;
obj->faces.data = (DTRWavefModelFace *)newFacePtr;
obj->geometryArray.capacity = obj->geometryArray.count; mesh->numVertexes = (u32)obj->geometryArray.count;
obj->normalArray.capacity = obj->normalArray.count; mesh->numTexUV = (u32)obj->textureArray.count;
obj->textureArray.capacity = obj->textureArray.count; mesh->numNormals = (u32)obj->normalArray.count;
obj->faces.capacity = obj->faces.count; mesh->numFaces = (u32)obj->faces.count;
MemcopyInternal((u8 *)mesh->vertexes, (u8 *)obj->geometryArray.data, geometrySize);
MemcopyInternal((u8 *)mesh->texUV, (u8 *)obj->textureArray.data, textureSize);
MemcopyInternal((u8 *)mesh->normals, (u8 *)obj->normalArray.data, normalSize);
MemcopyInternal((u8 *)mesh->faces, (u8 *)obj->faces.data, faceSize);
for (i32 i = 0; i < obj->faces.count; i++) for (i32 i = 0; i < obj->faces.count; i++)
{ {
DTRWavefModelFace *face = &obj->faces.data[i]; WavefModelFace *face = &obj->faces.data[i];
size_t vertIndexSize = face->vertexIndexArray.count * vertIndexItemSize; DTRMeshFace *const meshFace = &mesh->faces[i];
size_t texIndexSize = face->textureIndexArray.count * texIndexItemSize;
size_t normIndexSize = face->normalIndexArray.count * normIndexItemSize;
u8 *newVertIndexPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, vertIndexSize); size_t vertIndexSize = face->vertexIndexArray.count * vertIndexItemSize;
u8 *newTexIndexPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, texIndexSize); size_t texIndexSize = face->textureIndexArray.count * texIndexItemSize;
u8 *newNormIndexPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, normIndexSize); size_t normIndexSize = face->normalIndexArray.count * normIndexItemSize;
MemcopyInternal(newVertIndexPtr, (u8 *)face->vertexIndexArray.data, vertIndexSize); meshFace->vertexIndex = (i32 *)DqnMemStack_Push(memStack, vertIndexSize);
MemcopyInternal(newTexIndexPtr, (u8 *)face->textureIndexArray.data, texIndexSize); meshFace->texIndex = (i32 *)DqnMemStack_Push(memStack, texIndexSize);
MemcopyInternal(newNormIndexPtr, (u8 *)face->normalIndexArray.data, normIndexSize); meshFace->normalIndex = (i32 *)DqnMemStack_Push(memStack, normIndexSize);
face->vertexIndexArray.data = (i32 *)newVertIndexPtr; MemcopyInternal((u8 *)meshFace->vertexIndex, (u8 *)face->vertexIndexArray.data, vertIndexSize);
face->textureIndexArray.data = (i32 *)newTexIndexPtr; MemcopyInternal((u8 *)meshFace->texIndex, (u8 *)face->textureIndexArray.data, texIndexSize);
face->normalIndexArray.data = (i32 *)newNormIndexPtr; MemcopyInternal((u8 *)meshFace->normalIndex, (u8 *)face->normalIndexArray.data, normIndexSize);
face->vertexIndexArray.capacity = face->vertexIndexArray.count; meshFace->numVertexIndex = (u32)face->vertexIndexArray.count;
face->textureIndexArray.capacity = face->textureIndexArray.count; meshFace->numTexIndex = (u32)face->textureIndexArray.count;
face->normalIndexArray.capacity = face->normalIndexArray.count; meshFace->numNormalIndex = (u32)face->normalIndexArray.count;
} }
// NOTE: Detach the block, because the stack is in a temp region. // NOTE: Detach the block, because the stack is in a temp region.
// End the temp region and reattach the compact model block. // End the temp region and reattach the compact model block.
DqnMemStack_DetachBlock(&memory->assetStack, modelBlock); DqnMemStack_DetachBlock(memStack, modelBlock);
} }
else else
{ {
@ -556,90 +557,81 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
DQN_ASSERT(DQN_INVALID_CODE_PATH); DQN_ASSERT(DQN_INVALID_CODE_PATH);
} }
DqnMemStack_EndTempRegion(tmpMemRegion);
DqnMemStack_EndTempRegion(tmpAssetRegion); DqnMemStack_EndTempRegion(tmpAssetRegion);
DqnMemStack_ClearCurrBlock(&memory->assetStack, true);
if (modelBlock) if (modelBlock)
{ {
DqnMemStackBlock *firstBlock = memory->assetStack.block; result = true;
DqnMemStack_DetachBlock(&memory->assetStack, memory->assetStack.block); DqnMemStackBlock *firstBlock = memStack->block;
DqnMemStack_DetachBlock(memStack, memStack->block);
DqnMemStack_AttachBlock(&memory->assetStack, modelBlock); DqnMemStack_AttachBlock(memStack, modelBlock);
DqnMemStack_AttachBlock(&memory->assetStack, firstBlock); DqnMemStack_AttachBlock(memStack, firstBlock);
return true;
}
else
{
return false;
} }
cleanup:
api.FileClose(&file);
if(!result) DqnMemStack_EndTempRegion(tmpAssetRegion);
return result;
} }
bool DTRAsset_FontToBitmapLoad(const PlatformAPI api, PlatformMemory *const memory, bool DTRAsset_LoadFontToBitmap(const PlatformAPI api, DqnMemStack *const memStack,
DTRFont *const font, const char *const path, const DqnV2i bitmapDim, DqnMemStack *const tmpMemStack, DTRFont *const font,
const char *const path, const DqnV2i bitmapDim,
const DqnV2i codepointRange, const f32 sizeInPt) const DqnV2i codepointRange, const f32 sizeInPt)
{ {
if (!memory || !font || !path) return false; if (!memStack || !font || !path) return false;
////////////////////////////////////////////////////////////////////////////
// Load font data
////////////////////////////////////////////////////////////////////////////
DTRFont loadedFont = {}; DTRFont loadedFont = {};
loadedFont.bitmapDim = bitmapDim; loadedFont.bitmapDim = bitmapDim;
loadedFont.codepointRange = codepointRange; loadedFont.codepointRange = codepointRange;
loadedFont.sizeInPt = sizeInPt; loadedFont.sizeInPt = sizeInPt;
////////////////////////////////////////////////////////////////////////////
// Load font data
////////////////////////////////////////////////////////////////////////////
PlatformFile file = {}; PlatformFile file = {};
if (!api.FileOpen(path, &file, PlatformFilePermissionFlag_Read, PlatformFileAction_OpenOnly)) if (!api.FileOpen(path, &file, PlatformFilePermissionFlag_Read, PlatformFileAction_OpenOnly))
return false; // TODO(doyle): Logging return false; // TODO(doyle): Logging
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(&memory->tempStack); bool result = false;
u8 *fontBuf = (u8 *)DqnMemStack_Push(&memory->tempStack, file.size); DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(tmpMemStack);
size_t bytesRead = api.FileRead(&file, fontBuf, file.size); u8 *rawBytes = (u8 *)DqnMemStack_Push(tmpMemStack, file.size);
api.FileClose(&file); size_t bytesRead = api.FileRead(&file, rawBytes, file.size);
if (bytesRead != file.size)
{
// TODO(doyle): Logging
DqnMemStack_EndTempRegion(tmpMemRegion);
return false;
}
stbtt_fontinfo fontInfo = {}; stbtt_fontinfo fontInfo = {};
if (stbtt_InitFont(&fontInfo, fontBuf, 0) == 0) stbtt_pack_context fontPackContext = {};
if (bytesRead != file.size || stbtt_InitFont(&fontInfo, rawBytes, 0) == 0)
{ {
DQN_ASSERT(DQN_INVALID_CODE_PATH); DQN_ASSERT(DQN_INVALID_CODE_PATH);
return false; goto cleanup;
} }
if (DTR_DEBUG) DQN_ASSERT(stbtt_GetNumberOfFonts(fontBuf) == 1); if (DTR_DEBUG) DQN_ASSERT(stbtt_GetNumberOfFonts(rawBytes) == 1);
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Pack font data to bitmap // Pack font data to bitmap
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
loadedFont.bitmap = (u8 *)DqnMemStack_Push( loadedFont.bitmap =
&memory->mainStack, (u8 *)DqnMemStack_Push(memStack, (size_t)(loadedFont.bitmapDim.w * loadedFont.bitmapDim.h));
(size_t)(loadedFont.bitmapDim.w * loadedFont.bitmapDim.h));
stbtt_pack_context fontPackContext = {};
if (stbtt_PackBegin(&fontPackContext, loadedFont.bitmap, bitmapDim.w, if (stbtt_PackBegin(&fontPackContext, loadedFont.bitmap, bitmapDim.w,
bitmapDim.h, 0, 1, NULL) == 1) bitmapDim.h, 0, 1, NULL) == 1)
{ {
// stbtt_PackSetOversampling(&fontPackContext, 2, 2); // stbtt_PackSetOversampling(&fontPackContext, 2, 2);
result = true;
i32 numCodepoints = i32 numCodepoints = (i32)((codepointRange.max + 1) - codepointRange.min);
(i32)((codepointRange.max + 1) - codepointRange.min); loadedFont.atlas = (stbtt_packedchar *)DqnMemStack_Push(
memStack, numCodepoints * sizeof(stbtt_packedchar));
loadedFont.atlas = (stbtt_packedchar *)DqnMemStack_Push( stbtt_PackFontRange(&fontPackContext, rawBytes, 0,
&memory->mainStack, numCodepoints * sizeof(stbtt_packedchar));
stbtt_PackFontRange(&fontPackContext, fontBuf, 0,
STBTT_POINT_SIZE(sizeInPt), (i32)codepointRange.min, STBTT_POINT_SIZE(sizeInPt), (i32)codepointRange.min,
numCodepoints, loadedFont.atlas); numCodepoints, loadedFont.atlas);
stbtt_PackEnd(&fontPackContext); stbtt_PackEnd(&fontPackContext);
DqnMemStack_EndTempRegion(tmpMemRegion);
} }
else else
{ {
DQN_ASSERT(DQN_INVALID_CODE_PATH); DQN_ASSERT(DQN_INVALID_CODE_PATH);
DqnMemStack_EndTempRegion(tmpMemRegion); goto cleanup;
return false;
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -669,7 +661,12 @@ bool DTRAsset_FontToBitmapLoad(const PlatformAPI api, PlatformMemory *const memo
#endif #endif
*font = loadedFont; *font = loadedFont;
return true;
cleanup:
DqnMemStack_EndTempRegion(tmpMemRegion);
api.FileClose(&file);
return result;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -719,11 +716,10 @@ FILE_SCOPE void *STBImageMalloc(size_t size)
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "external/stb_image.h" #include "external/stb_image.h"
bool DTRAsset_BitmapLoad(const PlatformAPI api, DqnMemStack *const bitmapMemStack, bool DTRAsset_LoadBitmap(const PlatformAPI api, DqnMemStack *const memStack,
DqnMemStack *const tempStack, DTRBitmap *bitmap, DqnMemStack *const tempStack, DTRBitmap *bitmap, const char *const path)
const char *const path)
{ {
if (!bitmap || !bitmapMemStack || !tempStack) return false; if (!bitmap || !memStack || !tempStack) return false;
bool result = false; bool result = false;
PlatformFile file = {}; PlatformFile file = {};
@ -737,8 +733,8 @@ bool DTRAsset_BitmapLoad(const PlatformAPI api, DqnMemStack *const bitmapMemStac
if (bytesRead != file.size) goto cleanup; if (bytesRead != file.size) goto cleanup;
// IMPORTANT(doyle): Look at this line!!! To remind you anytime you think of modifying code here // IMPORTANT(doyle): Look at this line!!! To remind you anytime you think of modifying code here
globalSTBImageAllocator = bitmapMemStack; globalSTBImageAllocator = memStack;
size_t usageBeforeSTB = bitmapMemStack->block->used; size_t usageBeforeSTB = memStack->block->used;
const u32 FORCE_4_BPP = 4; const u32 FORCE_4_BPP = 4;
bitmap->bytesPerPixel = FORCE_4_BPP; bitmap->bytesPerPixel = FORCE_4_BPP;
@ -749,11 +745,11 @@ bool DTRAsset_BitmapLoad(const PlatformAPI api, DqnMemStack *const bitmapMemStac
result = true; result = true;
size_t pixelsSizeInBytes = bitmap->dim.w * bitmap->dim.h * FORCE_4_BPP; size_t pixelsSizeInBytes = bitmap->dim.w * bitmap->dim.h * FORCE_4_BPP;
bitmapMemStack->block->used = usageBeforeSTB; memStack->block->used = usageBeforeSTB;
if ((usageBeforeSTB + pixelsSizeInBytes) < bitmapMemStack->block->size) if ((usageBeforeSTB + pixelsSizeInBytes) < memStack->block->size)
{ {
u8 *dest = bitmapMemStack->block->memory + bitmapMemStack->block->used; u8 *dest = memStack->block->memory + memStack->block->used;
MemcopyInternal(dest, pixels, pixelsSizeInBytes); MemcopyInternal(dest, pixels, pixelsSizeInBytes);
pixels = dest; pixels = dest;
} }

View File

@ -6,26 +6,40 @@
#include "dqn.h" #include "dqn.h"
#include "external/stb_truetype.h" #include "external/stb_truetype.h"
typedef struct DTRWavefModelFace typedef struct DTRBitmap
{ {
DqnArray<i32> vertexIndexArray; u8 *memory;
DqnArray<i32> textureIndexArray; DqnV2i dim;
DqnArray<i32> normalIndexArray; i32 bytesPerPixel;
} DTRWavefModelFace; } DTRBitmap;
typedef struct DTRWavefModel typedef struct DTRMeshFace
{ {
DqnArray<DqnV4> geometryArray; i32 *vertexIndex;
DqnArray<DqnV3> textureArray; u32 numVertexIndex;
DqnArray<DqnV3> normalArray;
// TODO(doyle): Fixed size i32 *texIndex;
char *groupName[16]; u32 numTexIndex;
i32 groupNameIndex;
i32 groupSmoothing;
DqnArray<DTRWavefModelFace> faces; i32 *normalIndex;
} DTRWavefModel; u32 numNormalIndex;
} DTRMeshFace;
typedef struct DTRMesh
{
DqnV4 *vertexes;
u32 numVertexes;
DqnV3 *texUV;
u32 numTexUV;
DqnV3 *normals;
u32 numNormals;
DTRMeshFace *faces;
u32 numFaces;
DTRBitmap tex;
} DTRMesh;
typedef struct DTRFont typedef struct DTRFont
{ {
@ -37,15 +51,8 @@ typedef struct DTRFont
stbtt_packedchar *atlas; stbtt_packedchar *atlas;
} DTRFont; } DTRFont;
typedef struct DTRBitmap
{
u8 *memory;
DqnV2i dim;
i32 bytesPerPixel;
} DTRBitmap;
void DTRAsset_InitGlobalState (); void DTRAsset_InitGlobalState ();
bool DTRAsset_WavefModelLoad (const PlatformAPI api, PlatformMemory *const memory, DTRWavefModel *const obj, const char *const path); bool DTRAsset_LoadWavefrontObj(const PlatformAPI api, DqnMemStack *const memStack, DTRMesh *const mesh, const char *const path);
bool DTRAsset_FontToBitmapLoad(const PlatformAPI api, PlatformMemory *const memory, DTRFont *const font, const char *const path, const DqnV2i bitmapDim, const DqnV2i codepointRange, const f32 sizeInPt); bool DTRAsset_LoadFontToBitmap(const PlatformAPI api, DqnMemStack *const memStack, DqnMemStack *const tmpMemStack, DTRFont *const font, const char *const path, const DqnV2i bitmapDim, const DqnV2i codepointRange, const f32 sizeInPt);
bool DTRAsset_BitmapLoad (const PlatformAPI api, DqnMemStack *const bitmapMemStack, DqnMemStack *const transMemStack, DTRBitmap *bitmap, const char *const path); bool DTRAsset_LoadBitmap (const PlatformAPI api, DqnMemStack *const memStack, DqnMemStack *const transMemStack, DTRBitmap *bitmap, const char *const path);
#endif #endif

View File

@ -11,29 +11,29 @@
#include <vector> #include <vector>
DTRDebug globalDebug; DTRDebug globalDebug;
void DTRDebug_TestWavefFaceAndVertexParser(DTRWavefModel *const obj) void DTRDebug_TestMeshFaceAndVertexParser(DTRMesh *const mesh)
{ {
if (DTR_DEBUG) if (DTR_DEBUG)
{ {
if (!obj) DQN_ASSERT(DQN_INVALID_CODE_PATH); if (!mesh) DQN_ASSERT(DQN_INVALID_CODE_PATH);
Model model = Model("african_head.obj"); Model model = Model("african_head.obj");
DQN_ASSERT(obj->faces.count == model.nfaces()); DQN_ASSERT((i64)mesh->numFaces == model.nfaces());
for (i32 i = 0; i < model.nfaces(); i++) for (i32 i = 0; i < model.nfaces(); i++)
{ {
std::vector<i32> correctFace = model.face(i); std::vector<i32> correctFace = model.face(i);
DTRWavefModelFace *myFace = &obj->faces.data[i]; DTRMeshFace *myFace = &mesh->faces[i];
DQN_ASSERT(myFace->vertexIndexArray.count == correctFace.size()); DQN_ASSERT(myFace->numVertexIndex == correctFace.size());
for (i32 j = 0; j < myFace->vertexIndexArray.count; j++) for (i32 j = 0; j < (i32)myFace->numVertexIndex; j++)
{ {
// Ensure the vertex index references are correct per face // Ensure the vertex index references are correct per face
DQN_ASSERT(myFace->vertexIndexArray.data[j] == correctFace[j]); DQN_ASSERT(myFace->vertexIndex[j] == correctFace[j]);
Vec3f tmp = model.vert(correctFace[j]); Vec3f tmp = model.vert(correctFace[j]);
DqnV3 correctVertex = DqnV3_3f(tmp[0], tmp[1], tmp[2]); DqnV3 correctVertex = DqnV3_3f(tmp[0], tmp[1], tmp[2]);
DqnV3 myVertex = (obj->geometryArray.data[myFace->vertexIndexArray.data[j]]).xyz; DqnV3 myVertex = (mesh->vertexes[myFace->vertexIndex[j]]).xyz;
// Ensure the vertex values read are correct // Ensure the vertex values read are correct
for (i32 k = 0; k < DQN_ARRAY_COUNT(correctVertex.e); k++) for (i32 k = 0; k < DQN_ARRAY_COUNT(correctVertex.e); k++)

View File

@ -34,13 +34,6 @@
#define DTR_DEBUG_PROFILING 1 #define DTR_DEBUG_PROFILING 1
#endif #endif
typedef struct DTRRenderBuffer DTRRenderBuffer;
typedef struct DTRFont DTRFont;
typedef struct DTRState DTRState;
typedef struct PlatformInput PlatformInput;
typedef struct PlatformMemory PlatformMemory;
typedef struct DTRWavefObj DTRWavefObj;
enum DTRDebugCounter enum DTRDebugCounter
{ {
DTRDebugCounter_SetPixels, DTRDebugCounter_SetPixels,
@ -56,9 +49,9 @@ enum DTRDebugCycleCount
typedef struct DTRDebug typedef struct DTRDebug
{ {
DTRFont *font; struct DTRFont *font;
DTRRenderBuffer *renderBuffer; struct DTRRenderBuffer *renderBuffer;
PlatformInput *input; struct PlatformInput *input;
DqnV4 displayColor; DqnV4 displayColor;
DqnV2 displayP; DqnV2 displayP;
@ -71,12 +64,12 @@ typedef struct DTRDebug
extern DTRDebug globalDebug; extern DTRDebug globalDebug;
void DTRDebug_TestWavefFaceAndVertexParser(DTRWavefObj *const obj); void DTRDebug_TestMeshFaceAndVertexParser(struct DTRMesh *const mesh);
void DTRDebug_DumpZBuffer (DTRRenderBuffer *const renderBuffer, DqnMemStack *const transMemStack); void DTRDebug_DumpZBuffer (struct DTRRenderBuffer *const renderBuffer, struct DqnMemStack *const transMemStack);
void DTRDebug_PushText (const char *const formatStr, ...); void DTRDebug_PushText (const char *const formatStr, ...);
void DTRDebug_Update (DTRState *const state, DTRRenderBuffer *const renderBuffer, PlatformInput *const input, PlatformMemory *const memory); void DTRDebug_Update (struct DTRState *const state, struct DTRRenderBuffer *const renderBuffer, struct PlatformInput *const input, struct PlatformMemory *const memory);
void inline DTRDebug_BeginCycleCount (enum DTRDebugCycleCount tag); void inline DTRDebug_BeginCycleCount (enum DTRDebugCycleCount tag);
void inline DTRDebug_EndCycleCount (enum DTRDebugCycleCount tag); void inline DTRDebug_EndCycleCount (enum DTRDebugCycleCount tag);
void inline DTRDebug_CounterIncrement (enum DTRDebugCounter tag); void inline DTRDebug_CounterIncrement (enum DTRDebugCounter tag);
#endif #endif