set up model data loading
This commit is contained in:
parent
3500f657d8
commit
874b5de482
180
src/assets.cpp
180
src/assets.cpp
@ -376,7 +376,7 @@ static inline b32 apChkMag(u32 *magic, u32 expected)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: parse this without the SDK
|
// TODO: parse this without the SDK
|
||||||
static Model *
|
static apModel *
|
||||||
apParseModel(u8 *data)
|
apParseModel(u8 *data)
|
||||||
{
|
{
|
||||||
m3d_t *m3d = m3d_load(data, NULL, NULL, NULL);
|
m3d_t *m3d = m3d_load(data, NULL, NULL, NULL);
|
||||||
@ -399,82 +399,186 @@ apParseModel(u8 *data)
|
|||||||
Printfln("numinlined: %llu", m3d->numinlined);
|
Printfln("numinlined: %llu", m3d->numinlined);
|
||||||
Printfln("numextra: %llu", m3d->numextra);
|
Printfln("numextra: %llu", m3d->numextra);
|
||||||
|
|
||||||
Model *model = (Model *)malloc(sizeof(Model));
|
apModel *model = (apModel *)malloc(sizeof(apModel));
|
||||||
|
|
||||||
model->vertex.count = u64(m3d->numvertex);
|
model->vertices.length = u64(m3d->numface * 3);
|
||||||
model->vertex.data = (Vertex *)malloc(sizeof(Vertex) * model->vertex.count);
|
model->vertices.data = (apVertex *)malloc(sizeof(apVertex) * model->vertices.length);
|
||||||
|
|
||||||
model->index.count = u64(m3d->numface * 3);
|
model->indices.length = u64(m3d->numface * 3);
|
||||||
model->index.data = (u32 *)malloc(sizeof(u32) * model->index.count);
|
model->indices.data = (u32 *)malloc(sizeof(u32) * model->indices.length);
|
||||||
|
|
||||||
model->material.count = u64(m3d->nummaterial);
|
model->materials.length = u64(m3d->nummaterial);
|
||||||
model->material.data = (Material *)malloc(sizeof(Material) * m3d->nummaterial);
|
model->materials.data = (apMaterial *)malloc(sizeof(apMaterial) * m3d->nummaterial);
|
||||||
|
|
||||||
|
model->textures.length = u64(m3d->numtexture);
|
||||||
|
model->textures.data = (apTexData *)malloc(sizeof(apTexData) * m3d->numtexture);
|
||||||
|
|
||||||
|
for (u64 i = 0; i < m3d->numtexture; i += 1)
|
||||||
|
{
|
||||||
|
model->textures.data[i].bytes = m3d->texture[i].d;
|
||||||
|
model->textures.data[i].w = m3d->texture[i].w;
|
||||||
|
model->textures.data[i].h = m3d->texture[i].h;
|
||||||
|
model->textures.data[i].ch = m3d->texture[i].f;
|
||||||
|
|
||||||
|
#ifdef BUILD_DEBUG
|
||||||
|
Assert(i < model->textures.length, "Textures out of bounds access");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
for (u64 i = 0; i < m3d->nummaterial; i += 1)
|
for (u64 i = 0; i < m3d->nummaterial; i += 1)
|
||||||
{
|
{
|
||||||
|
model->materials.data[i].tex.albedo = UINT32_MAX;
|
||||||
|
model->materials.data[i].tex.ambient = UINT32_MAX;
|
||||||
|
model->materials.data[i].tex.specular = UINT32_MAX;
|
||||||
|
|
||||||
for (u64 j = 0; j < m3d->material[i].numprop; j += 1)
|
for (u64 j = 0; j < m3d->material[i].numprop; j += 1)
|
||||||
{
|
{
|
||||||
switch (m3d->material[i].prop[j].type)
|
switch (m3d->material[i].prop[j].type)
|
||||||
{
|
{
|
||||||
case m3dp_Kd:
|
case m3dp_Kd:
|
||||||
{
|
{
|
||||||
U32ColToVec4(&model->material.data[i].color, m3d->material[i].prop[j].value.color);
|
U32ColToVec4(&model->materials.data[i].props.albedo, m3d->material[i].prop[j].value.color);
|
||||||
} break;
|
} break;
|
||||||
case m3dp_Ka:
|
case m3dp_Ka:
|
||||||
{
|
{
|
||||||
U32ColToVec4(&model->material.data[i].ambient, m3d->material[i].prop[j].value.color);
|
U32ColToVec4(&model->materials.data[i].props.ambient, m3d->material[i].prop[j].value.color);
|
||||||
} break;
|
} break;
|
||||||
case m3dp_Ks:
|
case m3dp_Ks:
|
||||||
{
|
{
|
||||||
U32ColToVec4(&model->material.data[i].specular, m3d->material[i].prop[j].value.color);
|
U32ColToVec4(&model->materials.data[i].props.specular, m3d->material[i].prop[j].value.color);
|
||||||
} break;
|
|
||||||
case m3dp_Ke:
|
|
||||||
{
|
|
||||||
U32ColToVec4(&model->material.data[i].emission, m3d->material[i].prop[j].value.color);
|
|
||||||
} break;
|
} break;
|
||||||
case m3dp_Ns:
|
case m3dp_Ns:
|
||||||
{
|
{
|
||||||
model->material.data[i].shininess = m3d->material[i].prop[j].value.fnum;
|
model->materials.data[i].props.shininess = m3d->material[i].prop[j].value.fnum;
|
||||||
} break;
|
} break;
|
||||||
|
case m3dp_map_Kd:
|
||||||
|
{
|
||||||
|
model->materials.data[i].tex.albedo = m3d->material[i].prop[j].value.textureid;
|
||||||
|
} break;
|
||||||
|
case m3dp_map_Ka:
|
||||||
|
{
|
||||||
|
model->materials.data[i].tex.ambient = m3d->material[i].prop[j].value.textureid;
|
||||||
|
} break;
|
||||||
|
case m3dp_map_Ks:
|
||||||
|
{
|
||||||
|
model->materials.data[i].tex.specular = m3d->material[i].prop[j].value.textureid;
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUILD_DEBUG
|
||||||
|
Assert(i < model->materials.length, "Materials out of bounds access");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 num_meshes = 0;
|
||||||
|
u32 last = UINT32_MAX;
|
||||||
|
for (u64 i = 0; i < m3d->numface; i += 1)
|
||||||
|
{
|
||||||
|
if (m3d->face[i].materialid != last)
|
||||||
|
{
|
||||||
|
last = m3d->face[i].materialid;
|
||||||
|
num_meshes += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u64 i = 0; i < m3d->numinlined; i += 1)
|
model->meshes.length = u64(num_meshes);
|
||||||
{
|
model->meshes.data = (apMesh *)malloc(sizeof(apMesh) * num_meshes);
|
||||||
Image texture = apLoadImage(m3d->inlined[i].data, m3d->inlined[i].length);
|
|
||||||
Assert(texture.data != NULL, "Image is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
last = UINT32_MAX;
|
||||||
TODO: replace
|
u32 current_index = 0;
|
||||||
for (u64 i = 0; i < m3d->numvertex; i += 1)
|
for (u64 i = 0, j = 0; i < m3d->numface; i += 1, j += 3)
|
||||||
{
|
{
|
||||||
model->vertex.data[i].pos.x = m3d->vertex[i].x;
|
if (last == UINT32_MAX)
|
||||||
model->vertex.data[i].pos.y = m3d->vertex[i].y;
|
{
|
||||||
model->vertex.data[i].pos.z = m3d->vertex[i].z;
|
model->meshes.data[current_index].mat_idx = m3d->face[i].materialid;
|
||||||
model->vertex.data[i].pos.w = m3d->vertex[i].w;
|
model->meshes.data[current_index].start_idx = 0;
|
||||||
|
last = m3d->face[i].materialid;
|
||||||
|
}
|
||||||
|
else if (m3d->face[i].materialid != last)
|
||||||
|
{
|
||||||
|
model->meshes.data[current_index].length = j - model->meshes.data[current_index].start_idx;
|
||||||
|
current_index += 1;
|
||||||
|
|
||||||
model->vertex.data[i].col.packed = m3d->vertex[i].color;
|
model->meshes.data[current_index].mat_idx = m3d->face[i].materialid;
|
||||||
|
model->meshes.data[current_index].start_idx = j;
|
||||||
|
last = m3d->face[i].materialid;
|
||||||
|
}
|
||||||
|
else if (i == m3d->numface-1)
|
||||||
|
{
|
||||||
|
model->meshes.data[current_index].length = j+3 - model->meshes.data[current_index].start_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BUILD_DEBUG
|
||||||
|
Assert(current_index < model->meshes.length, "Mesh out of bounds access");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u64 i = 0, j = 0; i < m3d->numface; i += 1, j += 3)
|
for (u64 i = 0, j = 0; i < m3d->numface; i += 1, j += 3)
|
||||||
{
|
{
|
||||||
model->index.data[j] = m3d->face[i].vertex[0];
|
model->vertices.data[j+0].pos.x = m3d->vertex[m3d->face[i].vertex[0]].x;
|
||||||
model->index.data[j+1] = m3d->face[i].vertex[1];
|
model->vertices.data[j+0].pos.y = m3d->vertex[m3d->face[i].vertex[0]].y;
|
||||||
model->index.data[j+2] = m3d->face[i].vertex[2];
|
model->vertices.data[j+0].pos.z = m3d->vertex[m3d->face[i].vertex[0]].z;
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
m3d_free(m3d);
|
model->vertices.data[j+1].pos.x = m3d->vertex[m3d->face[i].vertex[1]].x;
|
||||||
|
model->vertices.data[j+1].pos.y = m3d->vertex[m3d->face[i].vertex[1]].y;
|
||||||
|
model->vertices.data[j+1].pos.z = m3d->vertex[m3d->face[i].vertex[1]].z;
|
||||||
|
|
||||||
|
model->vertices.data[j+2].pos.x = m3d->vertex[m3d->face[i].vertex[2]].x;
|
||||||
|
model->vertices.data[j+2].pos.y = m3d->vertex[m3d->face[i].vertex[2]].y;
|
||||||
|
model->vertices.data[j+2].pos.z = m3d->vertex[m3d->face[i].vertex[2]].z;
|
||||||
|
|
||||||
|
model->vertices.data[j+0].normal.x = m3d->vertex[m3d->face[i].normal[0]].x;
|
||||||
|
model->vertices.data[j+0].normal.y = m3d->vertex[m3d->face[i].normal[0]].y;
|
||||||
|
model->vertices.data[j+0].normal.z = m3d->vertex[m3d->face[i].normal[0]].z;
|
||||||
|
|
||||||
|
model->vertices.data[j+1].normal.x = m3d->vertex[m3d->face[i].normal[1]].x;
|
||||||
|
model->vertices.data[j+1].normal.y = m3d->vertex[m3d->face[i].normal[1]].y;
|
||||||
|
model->vertices.data[j+1].normal.z = m3d->vertex[m3d->face[i].normal[1]].z;
|
||||||
|
|
||||||
|
model->vertices.data[j+2].normal.x = m3d->vertex[m3d->face[i].normal[2]].x;
|
||||||
|
model->vertices.data[j+2].normal.y = m3d->vertex[m3d->face[i].normal[2]].y;
|
||||||
|
model->vertices.data[j+2].normal.z = m3d->vertex[m3d->face[i].normal[2]].z;
|
||||||
|
|
||||||
|
model->vertices.data[j+0].uv.x = m3d->tmap[m3d->face[i].texcoord[0]].u;
|
||||||
|
model->vertices.data[j+0].uv.y = m3d->tmap[m3d->face[i].texcoord[0]].v;
|
||||||
|
|
||||||
|
model->vertices.data[j+1].uv.x = m3d->tmap[m3d->face[i].texcoord[1]].u;
|
||||||
|
model->vertices.data[j+1].uv.y = m3d->tmap[m3d->face[i].texcoord[1]].v;
|
||||||
|
|
||||||
|
model->vertices.data[j+2].uv.x = m3d->tmap[m3d->face[i].texcoord[2]].u;
|
||||||
|
model->vertices.data[j+2].uv.y = m3d->tmap[m3d->face[i].texcoord[2]].v;
|
||||||
|
|
||||||
|
model->indices.data[j+0] = j+0;
|
||||||
|
model->indices.data[j+1] = j+1;
|
||||||
|
model->indices.data[j+2] = j+2;
|
||||||
|
|
||||||
|
#ifdef BUILD_DEBUG
|
||||||
|
Assert(j+2 < model->indices.length, "Indices out of bounds access");
|
||||||
|
Assert(j+2 < model->vertices.length, "Vertices out of bounds access");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u64 i = 0; i < model->meshes.length; i += 1)
|
||||||
|
{
|
||||||
|
apMesh *mesh = model->meshes.data + i;
|
||||||
|
Printfln("mat_idx: %llu start_idx: %llu length: %llu", mesh->mat_idx, mesh->start_idx, mesh->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
model->m3d = m3d;
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apFreeModel(Model *model)
|
static void apFreeModel(apModel *model)
|
||||||
{
|
{
|
||||||
free(model->vertex.data);
|
m3d_free(model->m3d);
|
||||||
free(model->index.data);
|
free(model->vertices.data);
|
||||||
|
free(model->indices.data);
|
||||||
|
free(model->meshes.data);
|
||||||
|
free(model->materials.data);
|
||||||
free(model);
|
free(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
93
src/assets.h
93
src/assets.h
@ -11,13 +11,14 @@
|
|||||||
|
|
||||||
// ::Assets::Types::Header::
|
// ::Assets::Types::Header::
|
||||||
|
|
||||||
typedef struct Vertex
|
typedef struct apVertex
|
||||||
{
|
{
|
||||||
f32 v_x, v_y, v_z;
|
Vec3 pos;
|
||||||
f32 n_x, n_y, n_z;
|
Vec3 normal;
|
||||||
f32 uv_x, uv_y;
|
Vec2 uv;
|
||||||
u32 color;
|
} apVertex;
|
||||||
} Vertex;
|
|
||||||
|
ArrayType(apVertex);
|
||||||
|
|
||||||
typedef struct Image
|
typedef struct Image
|
||||||
{
|
{
|
||||||
@ -27,45 +28,57 @@ typedef struct Image
|
|||||||
i32 ch;
|
i32 ch;
|
||||||
} Image;
|
} Image;
|
||||||
|
|
||||||
typedef struct Material
|
typedef struct apMatProps
|
||||||
{
|
{
|
||||||
Vec4 color;
|
Vec4 albedo;
|
||||||
Vec4 ambient;
|
Vec4 ambient;
|
||||||
Vec4 specular;
|
Vec4 specular;
|
||||||
Vec4 emission;
|
|
||||||
f32 shininess;
|
f32 shininess;
|
||||||
} Material;
|
} apMatProps;
|
||||||
|
|
||||||
typedef struct ModelIndex
|
typedef struct apMatTextures
|
||||||
{
|
{
|
||||||
u32 material;
|
u32 albedo;
|
||||||
u32 start;
|
u32 ambient;
|
||||||
u32 count;
|
u32 specular;
|
||||||
} ModelIndex;
|
} apMatTextures;
|
||||||
|
|
||||||
typedef struct Model
|
typedef struct apMaterial
|
||||||
{
|
{
|
||||||
struct
|
apMatProps props;
|
||||||
{
|
apMatTextures tex;
|
||||||
Vertex *data;
|
} apMaterial;
|
||||||
u64 count;
|
|
||||||
} vertex;
|
ArrayType(apMaterial);
|
||||||
struct
|
|
||||||
{
|
typedef struct apMesh
|
||||||
u32 *data;
|
{
|
||||||
u64 count;
|
u64 mat_idx;
|
||||||
} index;
|
u64 start_idx;
|
||||||
struct
|
u64 length;
|
||||||
{
|
} apMesh;
|
||||||
Material *data;
|
|
||||||
u64 count;
|
ArrayType(apMesh);
|
||||||
} material;
|
|
||||||
struct
|
typedef struct apTexData
|
||||||
{
|
{
|
||||||
ModelIndex *data;
|
rawptr bytes;
|
||||||
u64 count;
|
u32 w;
|
||||||
} offset;
|
u32 h;
|
||||||
} Model;
|
u32 ch;
|
||||||
|
} apTexData;
|
||||||
|
|
||||||
|
ArrayType(apTexData);
|
||||||
|
|
||||||
|
typedef struct apModel
|
||||||
|
{
|
||||||
|
apVertexArray vertices;
|
||||||
|
u32Array indices;
|
||||||
|
apMeshArray meshes;
|
||||||
|
apMaterialArray materials;
|
||||||
|
apTexDataArray textures;
|
||||||
|
m3d_t *m3d;
|
||||||
|
} apModel;
|
||||||
|
|
||||||
typedef struct TexMeta
|
typedef struct TexMeta
|
||||||
{
|
{
|
||||||
@ -99,7 +112,7 @@ typedef struct Asset
|
|||||||
{
|
{
|
||||||
const char *cstr;
|
const char *cstr;
|
||||||
u8 *bytes;
|
u8 *bytes;
|
||||||
Model *model;
|
apModel *model;
|
||||||
};
|
};
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
@ -160,5 +173,5 @@ static void apFreeImage(Image *image);
|
|||||||
|
|
||||||
// ::Assets::Models::Functions::Header::
|
// ::Assets::Models::Functions::Header::
|
||||||
|
|
||||||
static Model *apParseModel(u8 *data);
|
static apModel *apParseModel(u8 *data);
|
||||||
static void apFreeModel(Model *model);
|
static void apFreeModel(apModel *model);
|
||||||
|
|||||||
@ -43,6 +43,26 @@ typedef void * rawptr;
|
|||||||
typedef u32 usize;
|
typedef u32 usize;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ArrayType(T) \
|
||||||
|
typedef struct T##Array \
|
||||||
|
{ \
|
||||||
|
T *data; \
|
||||||
|
u64 length; \
|
||||||
|
} T##Array
|
||||||
|
|
||||||
|
#define PtrArrayType(T) \
|
||||||
|
typedef struct T##PtrArray \
|
||||||
|
{ \
|
||||||
|
T **data; \
|
||||||
|
u64 length; \
|
||||||
|
} T##PtrArray
|
||||||
|
|
||||||
|
#define InitArrayType(arr, arena, T, len) \
|
||||||
|
arr.data = MakeArray(arena, T, len); \
|
||||||
|
arr.length = len
|
||||||
|
|
||||||
|
ArrayType(u32);
|
||||||
|
|
||||||
typedef struct String8
|
typedef struct String8
|
||||||
{
|
{
|
||||||
c8 *value;
|
c8 *value;
|
||||||
@ -53,8 +73,23 @@ typedef union
|
|||||||
{
|
{
|
||||||
struct { f32 x, y, z, w; };
|
struct { f32 x, y, z, w; };
|
||||||
struct { f32 r, g, b, a; };
|
struct { f32 r, g, b, a; };
|
||||||
|
f32 array[4];
|
||||||
} Vec4;
|
} Vec4;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct { f32 x, y, z; };
|
||||||
|
struct { f32 r, g, b; };
|
||||||
|
f32 array[3];
|
||||||
|
} Vec3;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct { f32 x, y; };
|
||||||
|
struct { f32 r, g; };
|
||||||
|
f32 array[2];
|
||||||
|
} Vec2;
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
struct { u8 x, y, z, w; };
|
struct { u8 x, y, z, w; };
|
||||||
|
|||||||
@ -259,7 +259,7 @@ TestAssetPack(Arena *arena)
|
|||||||
for (u32 i = 0; i < MODEL_ASSET_MAX; i++, current_asset++)
|
for (u32 i = 0; i < MODEL_ASSET_MAX; i++, current_asset++)
|
||||||
{
|
{
|
||||||
TestAssetIsCorrect(arena, g_Model_Asset_Names[i], files + current_asset, file);
|
TestAssetIsCorrect(arena, g_Model_Asset_Names[i], files + current_asset, file);
|
||||||
Assert(files[current_asset].hash == g_Model_Asset_Hashes[i], "Model asset hash mismatch");
|
Assert(files[current_asset].hash == g_Model_Asset_Hashes[i], "apModel asset hash mismatch");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
118
src/renderer.cpp
118
src/renderer.cpp
@ -11,7 +11,7 @@ PipelineCreateInfo g_Pipeline_Create_Info[] = {
|
|||||||
|
|
||||||
// ::Init::Impl::Start::
|
// ::Init::Impl::Start::
|
||||||
|
|
||||||
MeshBuffer yoder;
|
rIndexedBuffer yoder;
|
||||||
|
|
||||||
static b32
|
static b32
|
||||||
Init(Renderer *renderer)
|
Init(Renderer *renderer)
|
||||||
@ -46,11 +46,26 @@ Init(Renderer *renderer)
|
|||||||
renderer->pipelines[i] = BuildPipeline(g_Pipeline_Create_Info + i);
|
renderer->pipelines[i] = BuildPipeline(g_Pipeline_Create_Info + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
yoder = CreateMeshBuffer("models/yoda");
|
yoder = rLoadModel("models/yoda");
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static b32
|
||||||
|
InitModels(Renderer *renderer)
|
||||||
|
{
|
||||||
|
b32 success = true;
|
||||||
|
|
||||||
|
for (u64 i = 0; i < MODEL_ASSET_MAX; i += 1)
|
||||||
|
{
|
||||||
|
u64 hash = g_Model_Asset_Hashes[i];
|
||||||
|
Asset asset = apLoadWithHash(hash);
|
||||||
|
Assert(asset.model != NULL, "InitModels failure: Model loaded is NULL");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
static PipelineHandle
|
static PipelineHandle
|
||||||
BuildPipeline(PipelineCreateInfo *create_info)
|
BuildPipeline(PipelineCreateInfo *create_info)
|
||||||
@ -142,10 +157,10 @@ CreateShader(int type)
|
|||||||
return (ShaderHandle)glCreateShader(type);
|
return (ShaderHandle)glCreateShader(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MeshBuffer
|
static rIndexedBuffer
|
||||||
CreateMeshBuffer(char *asset)
|
rLoadModel(char *asset)
|
||||||
{
|
{
|
||||||
MeshBuffer mesh = {0};
|
rIndexedBuffer mesh = {0};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
mesh.array = CreateVertexArray();
|
mesh.array = CreateVertexArray();
|
||||||
@ -164,7 +179,7 @@ CreateMeshBuffer(char *asset)
|
|||||||
|
|
||||||
glBufferData(
|
glBufferData(
|
||||||
GL_ARRAY_BUFFER,
|
GL_ARRAY_BUFFER,
|
||||||
data.model->v_count * sizeof(Vertex),
|
data.model->v_count * sizeof(apVertex),
|
||||||
data.model->vertices,
|
data.model->vertices,
|
||||||
GL_STATIC_DRAW
|
GL_STATIC_DRAW
|
||||||
);
|
);
|
||||||
@ -178,10 +193,10 @@ CreateMeshBuffer(char *asset)
|
|||||||
);
|
);
|
||||||
|
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(apVertex), 0);
|
||||||
|
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, col));
|
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(apVertex), (void *)offsetof(apVertex, col));
|
||||||
|
|
||||||
apUnload(asset);
|
apUnload(asset);
|
||||||
|
|
||||||
@ -192,17 +207,86 @@ CreateMeshBuffer(char *asset)
|
|||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
DrawMeshBuffer(MeshBuffer *mesh)
|
|
||||||
{
|
|
||||||
glBindVertexArray(mesh->array);
|
|
||||||
glDrawElements(GL_TRIANGLES, mesh->draw_count, GL_UNSIGNED_INT, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ::Init::Impl::End::
|
// ::Init::Impl::End::
|
||||||
|
|
||||||
|
|
||||||
|
// ::Draw::Impl::Start::
|
||||||
|
|
||||||
|
static void
|
||||||
|
DrawIndexedBuffer(rIndexedBuffer *buffer)
|
||||||
|
{
|
||||||
|
glBindVertexArray(buffer->vao);
|
||||||
|
glDrawElements(GL_TRIANGLES, buffer->icount, GL_UNSIGNED_INT, (void *)buffer->ioffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ::Draw::Impl::End::
|
||||||
|
|
||||||
|
|
||||||
|
// ::Buffers::Impl::Start::
|
||||||
|
|
||||||
|
static rIndexedBuffer
|
||||||
|
CreateIndexedBuffer(rawptr vert_data, u32 vcount, rawptr idx_data, u32 icount)
|
||||||
|
{
|
||||||
|
i32 alignment = GL_NONE;
|
||||||
|
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &alignment);
|
||||||
|
|
||||||
|
u32 vao = GL_NONE;
|
||||||
|
u32 buffer = GL_NONE;
|
||||||
|
|
||||||
|
isize vert_len = isize(vcount * sizeof(apVertex));
|
||||||
|
isize idx_len = isize(icount * sizeof(u32));
|
||||||
|
|
||||||
|
isize vert_len_aligned = Align(vert_len, alignment);
|
||||||
|
isize idx_len_aligned = Align(idx_len, alignment);
|
||||||
|
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
Assert((vert_len_aligned / alignment) == 0, "Buffers are not aligned");
|
||||||
|
Assert((idx_len_aligned / alignment) == 0, "Buffers are not aligned");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
isize vert_offset = 0;
|
||||||
|
isize idx_offset = vert_len_aligned;
|
||||||
|
|
||||||
|
glCreateBuffers(1, &buffer);
|
||||||
|
glNamedBufferStorage(buffer, idx_len_aligned + vert_len_aligned, NULL, GL_DYNAMIC_STORAGE_BIT);
|
||||||
|
|
||||||
|
glNamedBufferSubData(buffer, vert_offset, vert_len, vert_data);
|
||||||
|
glNamedBufferSubData(buffer, idx_offset, idx_len, idx_data);
|
||||||
|
|
||||||
|
glCreateVertexArrays(1, &vao);
|
||||||
|
|
||||||
|
constexpr u32 pos_size = SizeOfMember(apVertex, pos) / sizeof(f32);
|
||||||
|
glEnableVertexArrayAttrib(vao, 0);
|
||||||
|
glVertexArrayAttribBinding(vao, 0, 0);
|
||||||
|
glVertexArrayAttribFormat(vao, 0, pos_size, GL_FLOAT, GL_FALSE, 0);
|
||||||
|
|
||||||
|
constexpr u32 normal_size = SizeOfMember(apVertex, normal) / sizeof(f32);
|
||||||
|
glEnableVertexArrayAttrib(vao, 1);
|
||||||
|
glVertexArrayAttribBinding(vao, 1, 0);
|
||||||
|
glVertexArrayAttribFormat(vao, 1, normal_size, GL_FLOAT, GL_FALSE, offsetof(apVertex, normal));
|
||||||
|
|
||||||
|
constexpr u32 uv_size = SizeOfMember(apVertex, uv) / sizeof(f32);
|
||||||
|
glEnableVertexArrayAttrib(vao, 2);
|
||||||
|
glVertexArrayAttribBinding(vao, 2, 0);
|
||||||
|
glVertexArrayAttribFormat(vao, 2, uv_size, GL_FLOAT, GL_FALSE, offsetof(apVertex, uv));
|
||||||
|
|
||||||
|
glVertexArrayVertexBuffer(vao, 0, buffer, vert_offset, sizeof(apVertex));
|
||||||
|
glVertexArrayElementBuffer(vao, buffer);
|
||||||
|
|
||||||
|
rIndexedBuffer indexed_buffer = {0};
|
||||||
|
indexed_buffer.ioffset = idx_offset;
|
||||||
|
indexed_buffer.icount = icount;
|
||||||
|
indexed_buffer.vao = vao;
|
||||||
|
indexed_buffer.buffer = buffer;
|
||||||
|
|
||||||
|
return indexed_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ::Buffers::Impl::End::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ::Textures::Impl::Start::
|
// ::Textures::Impl::Start::
|
||||||
|
|
||||||
@ -255,12 +339,14 @@ RunCycle(Renderer *renderer)
|
|||||||
{
|
{
|
||||||
while (RGFW_window_checkEvent(renderer->window));
|
while (RGFW_window_checkEvent(renderer->window));
|
||||||
|
|
||||||
|
Asset yoder = apLoad("models/yoda");
|
||||||
|
|
||||||
glUseProgram(renderer->pipelines[PIPELINE_PBR]);
|
glUseProgram(renderer->pipelines[PIPELINE_PBR]);
|
||||||
|
|
||||||
glClearColor(0.1f, 0.8f, 0.4f, 1.0f);
|
glClearColor(0.1f, 0.8f, 0.4f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
DrawMeshBuffer(&yoder);
|
//DrawMeshBuffer(&yoder);
|
||||||
|
|
||||||
RGFW_window_swapBuffers(renderer->window);
|
RGFW_window_swapBuffers(renderer->window);
|
||||||
|
|
||||||
|
|||||||
@ -25,39 +25,60 @@ typedef unsigned int ShaderHandle;
|
|||||||
typedef unsigned int VertexArray;
|
typedef unsigned int VertexArray;
|
||||||
typedef unsigned int UBO;
|
typedef unsigned int UBO;
|
||||||
|
|
||||||
typedef struct MeshBuffer
|
typedef struct rIndexedBuffer
|
||||||
{
|
{
|
||||||
VertexArray array;
|
i64 icount, ioffset;
|
||||||
VertexBuffer vertex;
|
u32 vao, buffer;
|
||||||
IndexBuffer index;
|
} rIndexedBuffer;
|
||||||
u32 draw_count;
|
|
||||||
} MeshBuffer;
|
typedef struct rMesh
|
||||||
|
{
|
||||||
|
rIndexedBuffer buffer;
|
||||||
|
apMatProps material;
|
||||||
|
u32 texture;
|
||||||
|
} rMesh;
|
||||||
|
|
||||||
|
ArrayType(rMesh);
|
||||||
|
|
||||||
|
typedef struct rModel
|
||||||
|
{
|
||||||
|
rMeshArray meshes;
|
||||||
|
} rModel;
|
||||||
|
|
||||||
typedef struct Renderer
|
typedef struct Renderer
|
||||||
{
|
{
|
||||||
RGFW_window *window;
|
RGFW_window *window;
|
||||||
PipelineHandle pipelines[PIPELINE_MAX];
|
PipelineHandle pipelines[PIPELINE_MAX];
|
||||||
MeshBuffer models[MODEL_ASSET_MAX];
|
rIndexedBuffer models[MODEL_ASSET_MAX];
|
||||||
} Renderer;
|
} Renderer;
|
||||||
|
|
||||||
// ::Init::Decl::
|
// ::Init::Decl::
|
||||||
|
|
||||||
static b32 Init(Renderer *renderer);
|
static b32 Init(Renderer *renderer);
|
||||||
|
static b32 InitModels(Renderer *renderer);
|
||||||
static PipelineHandle CreatePipeline();
|
static PipelineHandle CreatePipeline();
|
||||||
static VertexBuffer CreateVertexBuffer();
|
static VertexBuffer CreateVertexBuffer();
|
||||||
static IndexBuffer CreateIndexBuffer();
|
static IndexBuffer CreateIndexBuffer();
|
||||||
static VertexArray CreateVertexArray();
|
static VertexArray CreateVertexArray();
|
||||||
static ShaderHandle CreateShader(int type);
|
static ShaderHandle CreateShader(int type);
|
||||||
static PipelineHandle BuildPipeline(PipelineCreateInfo *create_info);
|
static PipelineHandle BuildPipeline(PipelineCreateInfo *create_info);
|
||||||
static MeshBuffer CreateMeshBuffer(char *asset);
|
|
||||||
static UBO CreateUBO(rawptr data, u32 size);
|
static UBO CreateUBO(rawptr data, u32 size);
|
||||||
static b32 BuildShader(ShaderHandle *handle, char *asset);
|
static b32 BuildShader(ShaderHandle *handle, char *asset);
|
||||||
|
|
||||||
|
// ::Draw::Decl::
|
||||||
|
|
||||||
|
static void DrawIndexedBuffer(rIndexedBuffer *buffer);
|
||||||
|
|
||||||
|
// ::Buffers::Decl::
|
||||||
|
|
||||||
|
static rIndexedBuffer rLoadModel(char *asset);
|
||||||
|
static rIndexedBuffer CreateIndexedBuffer(rawptr vert_data, u32 vcount, rawptr idx_data, u32 icount);
|
||||||
|
|
||||||
// ::Textures::Decl::
|
// ::Textures::Decl::
|
||||||
|
|
||||||
static u32 CreateTexture(rawptr data, u32 width, u32 height);
|
static u32 CreateTexture(rawptr data, u32 width, u32 height, u32 channels);
|
||||||
|
|
||||||
// ::Draw::Decl::
|
// ::Draw::Decl::
|
||||||
|
|
||||||
static void DrawMeshBuffer(MeshBuffer *mesh);
|
static void DrawMeshBuffer(rIndexedBuffer *mesh);
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,25 @@
|
|||||||
#version 460
|
#version 460
|
||||||
|
|
||||||
layout (location = 0) in vec3 in_pos;
|
layout (location = 0) in vec3 in_pos;
|
||||||
layout (location = 1) in vec4 in_color;
|
layout (location = 1) in vec3 in_normal;
|
||||||
|
layout (location = 2) in vec2 in_uv;
|
||||||
|
|
||||||
layout (location = 0) out vec4 out_color;
|
layout (location = 0) out vec4 out_color;
|
||||||
|
layout (location = 1) out vec2 out_uv;
|
||||||
|
|
||||||
|
layout (std140, location = 0) uniform Properties
|
||||||
|
{
|
||||||
|
vec4 color;
|
||||||
|
vec4 ambient;
|
||||||
|
vec4 diffuse;
|
||||||
|
vec4 specular;
|
||||||
|
float shininess;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (binding = 0) uniform sampler2D albedo_texture;
|
||||||
|
layout (binding = 1) uniform sampler2D ambient_texture;
|
||||||
|
layout (binding = 2) uniform sampler2D specular_texture;
|
||||||
|
layout (binding = 3) uniform sampler2D emission_texture;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ====== TODO: Research values here ========
|
// ====== TODO: Research values here ========
|
||||||
// ==========================================
|
// ==========================================
|
||||||
|
|
||||||
struct Vertex {
|
struct apVertex {
|
||||||
vec4 pos;
|
vec4 pos;
|
||||||
vec4 col;
|
vec4 col;
|
||||||
};
|
};
|
||||||
@ -14,7 +14,7 @@ struct GUIVertex {
|
|||||||
};
|
};
|
||||||
|
|
||||||
layout (buffer_reference, std430) readonly buffer VertexBuffer {
|
layout (buffer_reference, std430) readonly buffer VertexBuffer {
|
||||||
Vertex vertices[];
|
apVertex vertices[];
|
||||||
};
|
};
|
||||||
|
|
||||||
layout (set = 0, binding = 0) uniform GlobalUniform {
|
layout (set = 0, binding = 0) uniform GlobalUniform {
|
||||||
|
|||||||
21
src/util.h
21
src/util.h
@ -18,6 +18,9 @@ constexpr u64 HASH_SEED = 5995;
|
|||||||
#define AlignPow2(x, b) (((x) + (b) - 1) & (~((b) - 1)))
|
#define AlignPow2(x, b) (((x) + (b) - 1) & (~((b) - 1)))
|
||||||
#define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0)
|
#define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0)
|
||||||
#define PtrAdd(ptr, add) ((rawptr)(((uintptr)ptr) + ((uintptr)add)))
|
#define PtrAdd(ptr, add) ((rawptr)(((uintptr)ptr) + ((uintptr)add)))
|
||||||
|
#define Align(x, b) ((x / b) == 0 ? (x) : (x + (x % b)))
|
||||||
|
|
||||||
|
#define SizeOfMember(T, M) (sizeof(((T *)0)->M))
|
||||||
|
|
||||||
#define MakeArray(arena, type, count) (type *)(ArenaAlloc(arena, (isize)(sizeof(type)) * (isize)(count)))
|
#define MakeArray(arena, type, count) (type *)(ArenaAlloc(arena, (isize)(sizeof(type)) * (isize)(count)))
|
||||||
#define Len(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
|
#define Len(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
|
||||||
@ -67,24 +70,6 @@ constexpr u64 HASH_SEED = 5995;
|
|||||||
DefIntegerImpl(def); \
|
DefIntegerImpl(def); \
|
||||||
DefFloatImpl(def)
|
DefFloatImpl(def)
|
||||||
|
|
||||||
#define ArrayType(T) \
|
|
||||||
typedef struct T##Array \
|
|
||||||
{ \
|
|
||||||
T *data; \
|
|
||||||
u64 length; \
|
|
||||||
} T##Array
|
|
||||||
|
|
||||||
#define PtrArrayType(T) \
|
|
||||||
typedef struct T##PtrArray \
|
|
||||||
{ \
|
|
||||||
T **data; \
|
|
||||||
u64 length; \
|
|
||||||
} T##PtrArray
|
|
||||||
|
|
||||||
#define InitArrayType(arr, arena, T, len) \
|
|
||||||
arr.data = MakeArray(arena, T, len); \
|
|
||||||
arr.length = len
|
|
||||||
|
|
||||||
// ::String8::
|
// ::String8::
|
||||||
|
|
||||||
static b32 String8Eq(String8 l, String8 r);
|
static b32 String8Eq(String8 l, String8 r);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user