static void LoadModel(rhi_cmdlist cmd, const char* name, byteview indices, uint32_t indexCount, byteview pos, byteview normal, byteview texCoord) { uint64_t ModelId = HashBytes64(name, strlen(name)); uint64_t index = 0; for (uint64_t lo = 0, hi = Game->ModelsCount; lo < hi; ) { index = lo + (hi - lo) / 2; DASSERT(Game->Models[index].id != ModelId, "hash collision"); if (Game->Models[index].id < ModelId) lo = index + 1; else hi = index; } model_data* Model = INSERT(Game->Models, COUNT(Game->Models), Game->ModelsCount, index); Model->id = ModelId; Model->IndexCount = indexCount; { ASSERT((pos.size) == (normal.size)); ASSERT((pos.size / 3) == (texCoord.size / 2)); uint32_t vertexCount = pos.size / 4; uint32_t stride = 4 * (3 + 3 + 2); uint32_t bufferSize = stride * vertexCount; uint8_t *uploadMemory = GpuCmdCopyStaticVertices(cmd, bufferSize, &Model->VertexBufferOffset); Swizzle3(uploadMemory, vertexCount, pos, 12, normal, 12, texCoord, 8); } { uint32_t bufferSize = indices.size; uint8_t* uploadMemory = GpuCmdCopyStaticIndices(cmd, bufferSize, &Model->IndexBufferOffset); memcpy(uploadMemory, indices.data, bufferSize); } } static model_data* FindModel(uint64_t ModelId) { uint64_t index; for (uint64_t lo = 0, hi = Game->ModelsCount; lo < hi; ) { index = lo + (hi - lo) / 2; if (Game->Models[index].id == ModelId) return &Game->Models[index]; if (Game->Models[index].id < ModelId) lo = index + 1; else hi = index; } return 0; } static void ModelCmdBind(alloc* Scratch, rhi_cmdlist cmd, uint64_t id) { model_data* Model = FindModel(id); GpuCmdBindStaticMeshVertexBuffer(Scratch, cmd, Model->VertexBufferOffset); GpuCmdBindStaticMeshIndexBuffer(cmd, Model->IndexBufferOffset); } static void ModelCmdDraw(rhi_cmdlist cmd, uint64_t id) { model_data* Model = FindModel(id); Rhi_CmdDrawIndexed(cmd, Model->IndexCount, 0, 1, 0, 0); }