Improve allocation compactness and add DTRMesh
This commit is contained in:
parent
254d80749b
commit
4d2a7a7c06
@ -968,26 +968,26 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
|
||||
DqnMemStack *const tempStack = &memory->tempStack;
|
||||
DQN_ASSERT(memory->context);
|
||||
state = (DTRState *)memory->context;
|
||||
DTRAsset_FontToBitmapLoad(input->api, memory, &state->font, "Roboto-bold.ttf",
|
||||
DqnV2i_2i(256, 256), DqnV2i_2i(' ', '~'), 12);
|
||||
DTRAsset_BitmapLoad(input->api, assetStack,
|
||||
DTRAsset_LoadFontToBitmap(input->api, &memory->mainStack, tempStack, &state->font,
|
||||
"Roboto-bold.ttf", DqnV2i_2i(256, 256), DqnV2i_2i(' ', '~'), 12);
|
||||
DTRAsset_LoadBitmap(input->api, assetStack,
|
||||
tempStack, &state->bitmap, "tree00.bmp");
|
||||
|
||||
if (DTR_DEBUG)
|
||||
{
|
||||
DTRBitmap test = {};
|
||||
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);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
DTRDebug_TestWavefFaceAndVertexParser(&state->obj);
|
||||
DTRDebug_TestMeshFaceAndVertexParser(&state->mesh);
|
||||
}
|
||||
|
||||
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 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);
|
||||
|
||||
for (i32 i = 0; i < waveObj->faces.count; i++)
|
||||
for (u32 i = 0; i < mesh->numFaces; i++)
|
||||
{
|
||||
if (i == 852)
|
||||
{
|
||||
int BreakHere = 0;
|
||||
}
|
||||
DTRWavefModelFace face = waveObj->faces.data[i];
|
||||
DQN_ASSERT(face.vertexIndexArray.count == 3);
|
||||
i32 vertAIndex = face.vertexIndexArray.data[0];
|
||||
i32 vertBIndex = face.vertexIndexArray.data[1];
|
||||
i32 vertCIndex = face.vertexIndexArray.data[2];
|
||||
DTRMeshFace face = mesh->faces[i];
|
||||
DQN_ASSERT(face.numVertexIndex == 3);
|
||||
i32 vertAIndex = face.vertexIndex[0];
|
||||
i32 vertBIndex = face.vertexIndex[1];
|
||||
i32 vertCIndex = face.vertexIndex[2];
|
||||
|
||||
DqnV4 vertA = waveObj->geometryArray.data[vertAIndex];
|
||||
DqnV4 vertB = waveObj->geometryArray.data[vertBIndex];
|
||||
DqnV4 vertC = waveObj->geometryArray.data[vertCIndex];
|
||||
DQN_ASSERT(vertAIndex < waveObj->geometryArray.count);
|
||||
DQN_ASSERT(vertBIndex < waveObj->geometryArray.count);
|
||||
DQN_ASSERT(vertCIndex < waveObj->geometryArray.count);
|
||||
DqnV4 vertA = mesh->vertexes[vertAIndex];
|
||||
DqnV4 vertB = mesh->vertexes[vertBIndex];
|
||||
DqnV4 vertC = mesh->vertexes[vertCIndex];
|
||||
// TODO(doyle): Some models have -ve indexes to refer to relative
|
||||
// vertices. We should resolve that to positive indexes at run time.
|
||||
DQN_ASSERT(vertAIndex < (i32)mesh->numVertexes);
|
||||
DQN_ASSERT(vertBIndex < (i32)mesh->numVertexes);
|
||||
DQN_ASSERT(vertCIndex < (i32)mesh->numVertexes);
|
||||
|
||||
DqnV4 vertAB = vertB - 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.y = (f32)(i32)(screenVC.y + 0.5f);
|
||||
|
||||
i32 textureAIndex = face.textureIndexArray.data[0];
|
||||
i32 textureBIndex = face.textureIndexArray.data[1];
|
||||
i32 textureCIndex = face.textureIndexArray.data[2];
|
||||
i32 textureAIndex = face.texIndex[0];
|
||||
i32 textureBIndex = face.texIndex[1];
|
||||
i32 textureCIndex = face.texIndex[2];
|
||||
|
||||
DqnV2 texA = waveObj->textureArray.data[textureAIndex].xy;
|
||||
DqnV2 texB = waveObj->textureArray.data[textureBIndex].xy;
|
||||
DqnV2 texC = waveObj->textureArray.data[textureCIndex].xy;
|
||||
DQN_ASSERT(textureAIndex < waveObj->textureArray.count);
|
||||
DQN_ASSERT(textureBIndex < waveObj->textureArray.count);
|
||||
DQN_ASSERT(textureCIndex < waveObj->textureArray.count);
|
||||
DqnV2 texA = mesh->texUV[textureAIndex].xy;
|
||||
DqnV2 texB = mesh->texUV[textureBIndex].xy;
|
||||
DqnV2 texC = mesh->texUV[textureCIndex].xy;
|
||||
DQN_ASSERT(textureAIndex < (i32)mesh->numTexUV);
|
||||
DQN_ASSERT(textureBIndex < (i32)mesh->numTexUV);
|
||||
DQN_ASSERT(textureCIndex < (i32)mesh->numTexUV);
|
||||
|
||||
bool DEBUG_SIMPLE_MODE = false;
|
||||
if (DTR_DEBUG && DEBUG_SIMPLE_MODE)
|
||||
@ -1107,7 +1105,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
|
||||
else
|
||||
{
|
||||
DTRRender_TexturedTriangle(&renderBuffer, screenVA, screenVB, screenVC, texA, texB,
|
||||
texC, &state->objTex, modelCol);
|
||||
texC, &state->mesh.tex, modelCol);
|
||||
}
|
||||
|
||||
bool DEBUG_WIREFRAME = false;
|
||||
@ -1157,6 +1155,6 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
|
||||
DqnMemStack_EndTempRegion(transMemTmpRegion);
|
||||
DqnMemStack_ClearCurrBlock(&memory->tempStack, true);
|
||||
|
||||
DQN_ASSERT(memory->tempStack.tempStackCount == 0);
|
||||
DQN_ASSERT(memory->mainStack.tempStackCount == 0);
|
||||
for (i32 i = 0; i < DQN_ARRAY_COUNT(memory->stacks); i++)
|
||||
DQN_ASSERT(memory->stacks[i].tempStackCount == 0);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ typedef struct DTRState
|
||||
{
|
||||
DTRFont font;
|
||||
DTRBitmap bitmap;
|
||||
DTRWavefModel obj;
|
||||
DTRBitmap objTex;
|
||||
DTRMesh mesh;
|
||||
} DTRState;
|
||||
#endif
|
||||
|
@ -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(),
|
||||
const i32 vertexInitCapacity = 1000, const i32 faceInitCapacity = 1000)
|
||||
const i32 vertexInitCapacity = 1000,
|
||||
const i32 faceInitCapacity = 1000)
|
||||
{
|
||||
if (!obj) return false;
|
||||
|
||||
@ -140,10 +162,10 @@ FILE_SCOPE bool WavefModelInit(DTRWavefModel *const obj,
|
||||
return initialised;
|
||||
}
|
||||
|
||||
FILE_SCOPE inline DTRWavefModelFace
|
||||
FILE_SCOPE inline WavefModelFace
|
||||
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.textureIndexArray, capacity, memAPI));
|
||||
DQN_ASSERT(DqnArray_Init(&result.normalIndexArray, capacity, memAPI));
|
||||
@ -151,29 +173,24 @@ WavefModelFaceInit(i32 capacity = 3, DqnMemAPI memAPI = DqnMemAPI_DefaultUseCall
|
||||
return result;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!memory || !path || !obj) return false;
|
||||
if (!memStack || !path || !mesh) return false;
|
||||
|
||||
PlatformFile file = {};
|
||||
if (!api.FileOpen(path, &file, PlatformFilePermissionFlag_Read, PlatformFileAction_OpenOnly))
|
||||
return false; // TODO(doyle): Logging
|
||||
|
||||
// TODO(doyle): Make arrays use given memory not malloc
|
||||
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(&memory->tempStack);
|
||||
DqnTempMemStack tmpAssetRegion = DqnMemStack_BeginTempRegion(&memory->assetStack);
|
||||
|
||||
u8 *rawBytes = (u8 *)DqnMemStack_Push(&memory->tempStack, file.size);
|
||||
bool result = false;
|
||||
DqnTempMemStack tmpAssetRegion = DqnMemStack_BeginTempRegion(memStack);
|
||||
u8 *rawBytes = (u8 *)DqnMemStack_Push(memStack, file.size);
|
||||
size_t bytesRead = api.FileRead(&file, rawBytes, file.size);
|
||||
size_t fileSize = file.size;
|
||||
api.FileClose(&file);
|
||||
if (bytesRead != file.size)
|
||||
{
|
||||
// TODO(doyle): Logging
|
||||
DqnMemStack_EndTempRegion(tmpMemRegion);
|
||||
return false;
|
||||
}
|
||||
|
||||
DqnMemAPI memAPI = {};
|
||||
memAPI.callback = AssetDqnArrayMemAPICallback;
|
||||
memAPI.userContext = memStack;
|
||||
|
||||
enum WavefVertexType {
|
||||
WavefVertexType_Invalid,
|
||||
@ -182,15 +199,11 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
|
||||
WavefVertexType_Normal,
|
||||
};
|
||||
|
||||
DqnMemAPI memAPI = {};
|
||||
memAPI.callback = AssetDqnArrayMemAPICallback;
|
||||
memAPI.userContext = &memory->assetStack;
|
||||
WavefModel dummy_ = {};
|
||||
WavefModel *obj = &dummy_;
|
||||
|
||||
if (!WavefModelInit(obj, memAPI))
|
||||
{
|
||||
DqnMemStack_EndTempRegion(tmpMemRegion);
|
||||
return false;
|
||||
}
|
||||
if (bytesRead != file.size) goto cleanup;
|
||||
if (!WavefModelInit(obj, memAPI)) goto cleanup;
|
||||
|
||||
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++;
|
||||
if (!scan) continue;
|
||||
|
||||
DTRWavefModelFace face = WavefModelFaceInit(3, memAPI);
|
||||
WavefModelFace face = WavefModelFaceInit(3, memAPI);
|
||||
i32 numVertexesParsed = 0;
|
||||
bool moreVertexesToParse = true;
|
||||
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->groupName[obj->groupNameIndex]);
|
||||
obj->groupName[obj->groupNameIndex++] = (char *)DqnMemStack_Push(
|
||||
&memory->mainStack, (nameLen + 1) * sizeof(char));
|
||||
obj->groupName[obj->groupNameIndex++] =
|
||||
(char *)DqnMemStack_Push(memStack, (nameLen + 1) * sizeof(char));
|
||||
|
||||
for (i32 i = 0; i < nameLen; i++)
|
||||
obj->groupName[obj->groupNameIndex - 1][i] = namePtr[i];
|
||||
@ -460,26 +473,19 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Recompact Allocations
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
u8 *geometryPtr = (u8 *)obj->geometryArray.data;
|
||||
u8 *texturePtr = (u8 *)obj->textureArray.data;
|
||||
u8 *normalPtr = (u8 *)obj->normalArray.data;
|
||||
|
||||
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 texIndexItemSize = sizeof(obj->faces.data[0].textureIndexArray.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++)
|
||||
{
|
||||
DTRWavefModelFace *face = &obj->faces.data[i];
|
||||
WavefModelFace *face = &obj->faces.data[i];
|
||||
|
||||
size_t vertIndexSize = face->vertexIndexArray.count * vertIndexItemSize;
|
||||
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
|
||||
// their own memory block.
|
||||
DqnMemStackBlock *modelBlock =
|
||||
DqnMemStack_AllocateCompatibleBlock(&memory->assetStack, totalModelSize);
|
||||
DqnMemStack_AllocateCompatibleBlock(memStack, totalModelSize);
|
||||
if (modelBlock)
|
||||
{
|
||||
if (DqnMemStack_AttachBlock(&memory->assetStack, modelBlock))
|
||||
if (DqnMemStack_AttachBlock(memStack, modelBlock))
|
||||
{
|
||||
u8 *newGeometryPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, geometrySize);
|
||||
u8 *newTexturePtr = (u8 *)DqnMemStack_Push(&memory->assetStack, textureSize);
|
||||
u8 *newNormalPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, normalSize);
|
||||
u8 *newFacePtr = (u8 *)DqnMemStack_Push(&memory->assetStack, 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;
|
||||
mesh->vertexes = (DqnV4 *)DqnMemStack_Push(memStack, geometrySize);
|
||||
mesh->texUV = (DqnV3 *)DqnMemStack_Push(memStack, textureSize);
|
||||
mesh->normals = (DqnV3 *)DqnMemStack_Push(memStack, normalSize);
|
||||
mesh->faces = (DTRMeshFace *)DqnMemStack_Push(memStack, faceSize);
|
||||
|
||||
obj->geometryArray.capacity = obj->geometryArray.count;
|
||||
obj->normalArray.capacity = obj->normalArray.count;
|
||||
obj->textureArray.capacity = obj->textureArray.count;
|
||||
obj->faces.capacity = obj->faces.count;
|
||||
mesh->numVertexes = (u32)obj->geometryArray.count;
|
||||
mesh->numTexUV = (u32)obj->textureArray.count;
|
||||
mesh->numNormals = (u32)obj->normalArray.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++)
|
||||
{
|
||||
DTRWavefModelFace *face = &obj->faces.data[i];
|
||||
WavefModelFace *face = &obj->faces.data[i];
|
||||
DTRMeshFace *const meshFace = &mesh->faces[i];
|
||||
|
||||
size_t vertIndexSize = face->vertexIndexArray.count * vertIndexItemSize;
|
||||
size_t texIndexSize = face->textureIndexArray.count * texIndexItemSize;
|
||||
size_t normIndexSize = face->normalIndexArray.count * normIndexItemSize;
|
||||
|
||||
u8 *newVertIndexPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, vertIndexSize);
|
||||
u8 *newTexIndexPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, texIndexSize);
|
||||
u8 *newNormIndexPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, normIndexSize);
|
||||
meshFace->vertexIndex = (i32 *)DqnMemStack_Push(memStack, vertIndexSize);
|
||||
meshFace->texIndex = (i32 *)DqnMemStack_Push(memStack, texIndexSize);
|
||||
meshFace->normalIndex = (i32 *)DqnMemStack_Push(memStack, normIndexSize);
|
||||
|
||||
MemcopyInternal(newVertIndexPtr, (u8 *)face->vertexIndexArray.data, vertIndexSize);
|
||||
MemcopyInternal(newTexIndexPtr, (u8 *)face->textureIndexArray.data, texIndexSize);
|
||||
MemcopyInternal(newNormIndexPtr, (u8 *)face->normalIndexArray.data, normIndexSize);
|
||||
MemcopyInternal((u8 *)meshFace->vertexIndex, (u8 *)face->vertexIndexArray.data, vertIndexSize);
|
||||
MemcopyInternal((u8 *)meshFace->texIndex, (u8 *)face->textureIndexArray.data, texIndexSize);
|
||||
MemcopyInternal((u8 *)meshFace->normalIndex, (u8 *)face->normalIndexArray.data, normIndexSize);
|
||||
|
||||
face->vertexIndexArray.data = (i32 *)newVertIndexPtr;
|
||||
face->textureIndexArray.data = (i32 *)newTexIndexPtr;
|
||||
face->normalIndexArray.data = (i32 *)newNormIndexPtr;
|
||||
|
||||
face->vertexIndexArray.capacity = face->vertexIndexArray.count;
|
||||
face->textureIndexArray.capacity = face->textureIndexArray.count;
|
||||
face->normalIndexArray.capacity = face->normalIndexArray.count;
|
||||
meshFace->numVertexIndex = (u32)face->vertexIndexArray.count;
|
||||
meshFace->numTexIndex = (u32)face->textureIndexArray.count;
|
||||
meshFace->numNormalIndex = (u32)face->normalIndexArray.count;
|
||||
}
|
||||
|
||||
// NOTE: Detach the block, because the stack is in a temp region.
|
||||
// End the temp region and reattach the compact model block.
|
||||
DqnMemStack_DetachBlock(&memory->assetStack, modelBlock);
|
||||
DqnMemStack_DetachBlock(memStack, modelBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -556,90 +557,81 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
|
||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||
}
|
||||
|
||||
DqnMemStack_EndTempRegion(tmpMemRegion);
|
||||
DqnMemStack_EndTempRegion(tmpAssetRegion);
|
||||
DqnMemStack_ClearCurrBlock(&memory->assetStack, true);
|
||||
if (modelBlock)
|
||||
{
|
||||
DqnMemStackBlock *firstBlock = memory->assetStack.block;
|
||||
DqnMemStack_DetachBlock(&memory->assetStack, memory->assetStack.block);
|
||||
result = true;
|
||||
DqnMemStackBlock *firstBlock = memStack->block;
|
||||
DqnMemStack_DetachBlock(memStack, memStack->block);
|
||||
|
||||
DqnMemStack_AttachBlock(&memory->assetStack, modelBlock);
|
||||
DqnMemStack_AttachBlock(&memory->assetStack, firstBlock);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
DqnMemStack_AttachBlock(memStack, modelBlock);
|
||||
DqnMemStack_AttachBlock(memStack, firstBlock);
|
||||
}
|
||||
|
||||
bool DTRAsset_FontToBitmapLoad(const PlatformAPI api, PlatformMemory *const memory,
|
||||
DTRFont *const font, const char *const path, const DqnV2i bitmapDim,
|
||||
cleanup:
|
||||
api.FileClose(&file);
|
||||
if(!result) DqnMemStack_EndTempRegion(tmpAssetRegion);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!memory || !font || !path) return false;
|
||||
if (!memStack || !font || !path) return false;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Load font data
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
DTRFont loadedFont = {};
|
||||
loadedFont.bitmapDim = bitmapDim;
|
||||
loadedFont.codepointRange = codepointRange;
|
||||
loadedFont.sizeInPt = sizeInPt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Load font data
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
PlatformFile file = {};
|
||||
if (!api.FileOpen(path, &file, PlatformFilePermissionFlag_Read, PlatformFileAction_OpenOnly))
|
||||
return false; // TODO(doyle): Logging
|
||||
|
||||
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(&memory->tempStack);
|
||||
u8 *fontBuf = (u8 *)DqnMemStack_Push(&memory->tempStack, file.size);
|
||||
size_t bytesRead = api.FileRead(&file, fontBuf, file.size);
|
||||
api.FileClose(&file);
|
||||
if (bytesRead != file.size)
|
||||
{
|
||||
// TODO(doyle): Logging
|
||||
DqnMemStack_EndTempRegion(tmpMemRegion);
|
||||
return false;
|
||||
}
|
||||
bool result = false;
|
||||
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(tmpMemStack);
|
||||
u8 *rawBytes = (u8 *)DqnMemStack_Push(tmpMemStack, file.size);
|
||||
size_t bytesRead = api.FileRead(&file, rawBytes, file.size);
|
||||
|
||||
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);
|
||||
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
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
loadedFont.bitmap = (u8 *)DqnMemStack_Push(
|
||||
&memory->mainStack,
|
||||
(size_t)(loadedFont.bitmapDim.w * loadedFont.bitmapDim.h));
|
||||
loadedFont.bitmap =
|
||||
(u8 *)DqnMemStack_Push(memStack, (size_t)(loadedFont.bitmapDim.w * loadedFont.bitmapDim.h));
|
||||
|
||||
stbtt_pack_context fontPackContext = {};
|
||||
if (stbtt_PackBegin(&fontPackContext, loadedFont.bitmap, bitmapDim.w,
|
||||
bitmapDim.h, 0, 1, NULL) == 1)
|
||||
{
|
||||
// stbtt_PackSetOversampling(&fontPackContext, 2, 2);
|
||||
|
||||
i32 numCodepoints =
|
||||
(i32)((codepointRange.max + 1) - codepointRange.min);
|
||||
|
||||
result = true;
|
||||
i32 numCodepoints = (i32)((codepointRange.max + 1) - codepointRange.min);
|
||||
loadedFont.atlas = (stbtt_packedchar *)DqnMemStack_Push(
|
||||
&memory->mainStack, numCodepoints * sizeof(stbtt_packedchar));
|
||||
stbtt_PackFontRange(&fontPackContext, fontBuf, 0,
|
||||
memStack, numCodepoints * sizeof(stbtt_packedchar));
|
||||
stbtt_PackFontRange(&fontPackContext, rawBytes, 0,
|
||||
STBTT_POINT_SIZE(sizeInPt), (i32)codepointRange.min,
|
||||
numCodepoints, loadedFont.atlas);
|
||||
stbtt_PackEnd(&fontPackContext);
|
||||
DqnMemStack_EndTempRegion(tmpMemRegion);
|
||||
}
|
||||
else
|
||||
{
|
||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||
DqnMemStack_EndTempRegion(tmpMemRegion);
|
||||
return false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@ -669,7 +661,12 @@ bool DTRAsset_FontToBitmapLoad(const PlatformAPI api, PlatformMemory *const memo
|
||||
#endif
|
||||
|
||||
*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
|
||||
#include "external/stb_image.h"
|
||||
|
||||
bool DTRAsset_BitmapLoad(const PlatformAPI api, DqnMemStack *const bitmapMemStack,
|
||||
DqnMemStack *const tempStack, DTRBitmap *bitmap,
|
||||
const char *const path)
|
||||
bool DTRAsset_LoadBitmap(const PlatformAPI api, DqnMemStack *const memStack,
|
||||
DqnMemStack *const tempStack, DTRBitmap *bitmap, const char *const path)
|
||||
{
|
||||
if (!bitmap || !bitmapMemStack || !tempStack) return false;
|
||||
if (!bitmap || !memStack || !tempStack) return false;
|
||||
|
||||
bool result = false;
|
||||
PlatformFile file = {};
|
||||
@ -737,8 +733,8 @@ bool DTRAsset_BitmapLoad(const PlatformAPI api, DqnMemStack *const bitmapMemStac
|
||||
if (bytesRead != file.size) goto cleanup;
|
||||
|
||||
// IMPORTANT(doyle): Look at this line!!! To remind you anytime you think of modifying code here
|
||||
globalSTBImageAllocator = bitmapMemStack;
|
||||
size_t usageBeforeSTB = bitmapMemStack->block->used;
|
||||
globalSTBImageAllocator = memStack;
|
||||
size_t usageBeforeSTB = memStack->block->used;
|
||||
|
||||
const u32 FORCE_4_BPP = 4;
|
||||
bitmap->bytesPerPixel = FORCE_4_BPP;
|
||||
@ -749,11 +745,11 @@ bool DTRAsset_BitmapLoad(const PlatformAPI api, DqnMemStack *const bitmapMemStac
|
||||
|
||||
result = true;
|
||||
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);
|
||||
pixels = dest;
|
||||
}
|
||||
|
@ -6,26 +6,40 @@
|
||||
#include "dqn.h"
|
||||
#include "external/stb_truetype.h"
|
||||
|
||||
typedef struct DTRWavefModelFace
|
||||
typedef struct DTRBitmap
|
||||
{
|
||||
DqnArray<i32> vertexIndexArray;
|
||||
DqnArray<i32> textureIndexArray;
|
||||
DqnArray<i32> normalIndexArray;
|
||||
} DTRWavefModelFace;
|
||||
u8 *memory;
|
||||
DqnV2i dim;
|
||||
i32 bytesPerPixel;
|
||||
} DTRBitmap;
|
||||
|
||||
typedef struct DTRWavefModel
|
||||
typedef struct DTRMeshFace
|
||||
{
|
||||
DqnArray<DqnV4> geometryArray;
|
||||
DqnArray<DqnV3> textureArray;
|
||||
DqnArray<DqnV3> normalArray;
|
||||
i32 *vertexIndex;
|
||||
u32 numVertexIndex;
|
||||
|
||||
// TODO(doyle): Fixed size
|
||||
char *groupName[16];
|
||||
i32 groupNameIndex;
|
||||
i32 groupSmoothing;
|
||||
i32 *texIndex;
|
||||
u32 numTexIndex;
|
||||
|
||||
DqnArray<DTRWavefModelFace> faces;
|
||||
} DTRWavefModel;
|
||||
i32 *normalIndex;
|
||||
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
|
||||
{
|
||||
@ -37,15 +51,8 @@ typedef struct DTRFont
|
||||
stbtt_packedchar *atlas;
|
||||
} DTRFont;
|
||||
|
||||
typedef struct DTRBitmap
|
||||
{
|
||||
u8 *memory;
|
||||
DqnV2i dim;
|
||||
i32 bytesPerPixel;
|
||||
} DTRBitmap;
|
||||
|
||||
void DTRAsset_InitGlobalState ();
|
||||
bool DTRAsset_WavefModelLoad (const PlatformAPI api, PlatformMemory *const memory, DTRWavefModel *const obj, 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_BitmapLoad (const PlatformAPI api, DqnMemStack *const bitmapMemStack, DqnMemStack *const transMemStack, DTRBitmap *bitmap, const char *const path);
|
||||
bool DTRAsset_LoadWavefrontObj(const PlatformAPI api, DqnMemStack *const memStack, DTRMesh *const mesh, const char *const path);
|
||||
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_LoadBitmap (const PlatformAPI api, DqnMemStack *const memStack, DqnMemStack *const transMemStack, DTRBitmap *bitmap, const char *const path);
|
||||
#endif
|
||||
|
@ -11,29 +11,29 @@
|
||||
#include <vector>
|
||||
|
||||
DTRDebug globalDebug;
|
||||
void DTRDebug_TestWavefFaceAndVertexParser(DTRWavefModel *const obj)
|
||||
void DTRDebug_TestMeshFaceAndVertexParser(DTRMesh *const mesh)
|
||||
{
|
||||
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");
|
||||
|
||||
DQN_ASSERT(obj->faces.count == model.nfaces());
|
||||
DQN_ASSERT((i64)mesh->numFaces == model.nfaces());
|
||||
for (i32 i = 0; i < model.nfaces(); 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
|
||||
DQN_ASSERT(myFace->vertexIndexArray.data[j] == correctFace[j]);
|
||||
DQN_ASSERT(myFace->vertexIndex[j] == correctFace[j]);
|
||||
|
||||
Vec3f tmp = model.vert(correctFace[j]);
|
||||
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
|
||||
for (i32 k = 0; k < DQN_ARRAY_COUNT(correctVertex.e); k++)
|
||||
|
@ -34,13 +34,6 @@
|
||||
#define DTR_DEBUG_PROFILING 1
|
||||
#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
|
||||
{
|
||||
DTRDebugCounter_SetPixels,
|
||||
@ -56,9 +49,9 @@ enum DTRDebugCycleCount
|
||||
|
||||
typedef struct DTRDebug
|
||||
{
|
||||
DTRFont *font;
|
||||
DTRRenderBuffer *renderBuffer;
|
||||
PlatformInput *input;
|
||||
struct DTRFont *font;
|
||||
struct DTRRenderBuffer *renderBuffer;
|
||||
struct PlatformInput *input;
|
||||
|
||||
DqnV4 displayColor;
|
||||
DqnV2 displayP;
|
||||
@ -71,10 +64,10 @@ typedef struct DTRDebug
|
||||
|
||||
extern DTRDebug globalDebug;
|
||||
|
||||
void DTRDebug_TestWavefFaceAndVertexParser(DTRWavefObj *const obj);
|
||||
void DTRDebug_DumpZBuffer (DTRRenderBuffer *const renderBuffer, DqnMemStack *const transMemStack);
|
||||
void DTRDebug_TestMeshFaceAndVertexParser(struct DTRMesh *const mesh);
|
||||
void DTRDebug_DumpZBuffer (struct DTRRenderBuffer *const renderBuffer, struct DqnMemStack *const transMemStack);
|
||||
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_EndCycleCount (enum DTRDebugCycleCount tag);
|
||||
void inline DTRDebug_CounterIncrement (enum DTRDebugCounter tag);
|
||||
|
Loading…
Reference in New Issue
Block a user