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

View File

@ -10,9 +10,8 @@ typedef void DTR_UpdateFunction(struct PlatformRenderBuffer *const renderBuffer,
typedef struct DTRState
{
DTRFont font;
DTRBitmap bitmap;
DTRWavefModel obj;
DTRBitmap objTex;
DTRFont font;
DTRBitmap bitmap;
DTRMesh mesh;
} DTRState;
#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(),
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);
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;
u8 *rawBytes = (u8 *)DqnMemStack_Push(&memory->tempStack, 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 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;
size_t faceSize = sizeof(obj->faces.data[0]) * obj->faces.count;
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];
size_t vertIndexSize = face->vertexIndexArray.count * vertIndexItemSize;
size_t texIndexSize = face->textureIndexArray.count * texIndexItemSize;
size_t normIndexSize = face->normalIndexArray.count * normIndexItemSize;
WavefModelFace *face = &obj->faces.data[i];
DTRMeshFace *const meshFace = &mesh->faces[i];
u8 *newVertIndexPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, vertIndexSize);
u8 *newTexIndexPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, texIndexSize);
u8 *newNormIndexPtr = (u8 *)DqnMemStack_Push(&memory->assetStack, normIndexSize);
size_t vertIndexSize = face->vertexIndexArray.count * vertIndexItemSize;
size_t texIndexSize = face->textureIndexArray.count * texIndexItemSize;
size_t normIndexSize = face->normalIndexArray.count * normIndexItemSize;
MemcopyInternal(newVertIndexPtr, (u8 *)face->vertexIndexArray.data, vertIndexSize);
MemcopyInternal(newTexIndexPtr, (u8 *)face->textureIndexArray.data, texIndexSize);
MemcopyInternal(newNormIndexPtr, (u8 *)face->normalIndexArray.data, normIndexSize);
meshFace->vertexIndex = (i32 *)DqnMemStack_Push(memStack, vertIndexSize);
meshFace->texIndex = (i32 *)DqnMemStack_Push(memStack, texIndexSize);
meshFace->normalIndex = (i32 *)DqnMemStack_Push(memStack, normIndexSize);
face->vertexIndexArray.data = (i32 *)newVertIndexPtr;
face->textureIndexArray.data = (i32 *)newTexIndexPtr;
face->normalIndexArray.data = (i32 *)newNormIndexPtr;
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.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);
}
cleanup:
api.FileClose(&file);
if(!result) DqnMemStack_EndTempRegion(tmpAssetRegion);
return result;
}
bool DTRAsset_FontToBitmapLoad(const PlatformAPI api, PlatformMemory *const memory,
DTRFont *const font, const char *const path, const DqnV2i bitmapDim,
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_fontinfo fontInfo = {};
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);
loadedFont.atlas = (stbtt_packedchar *)DqnMemStack_Push(
&memory->mainStack, numCodepoints * sizeof(stbtt_packedchar));
stbtt_PackFontRange(&fontPackContext, fontBuf, 0,
result = true;
i32 numCodepoints = (i32)((codepointRange.max + 1) - codepointRange.min);
loadedFont.atlas = (stbtt_packedchar *)DqnMemStack_Push(
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;
}

View File

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

View File

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

View File

@ -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,12 +64,12 @@ typedef struct DTRDebug
extern DTRDebug globalDebug;
void DTRDebug_TestWavefFaceAndVertexParser(DTRWavefObj *const obj);
void DTRDebug_DumpZBuffer (DTRRenderBuffer *const renderBuffer, 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 inline DTRDebug_BeginCycleCount (enum DTRDebugCycleCount tag);
void inline DTRDebug_EndCycleCount (enum DTRDebugCycleCount tag);
void inline DTRDebug_CounterIncrement (enum DTRDebugCounter tag);
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 (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);
#endif