set up model data loading
This commit is contained in:
parent
3500f657d8
commit
874b5de482
184
src/assets.cpp
184
src/assets.cpp
@ -376,7 +376,7 @@ static inline b32 apChkMag(u32 *magic, u32 expected)
|
||||
}
|
||||
|
||||
// TODO: parse this without the SDK
|
||||
static Model *
|
||||
static apModel *
|
||||
apParseModel(u8 *data)
|
||||
{
|
||||
m3d_t *m3d = m3d_load(data, NULL, NULL, NULL);
|
||||
@ -399,82 +399,186 @@ apParseModel(u8 *data)
|
||||
Printfln("numinlined: %llu", m3d->numinlined);
|
||||
Printfln("numextra: %llu", m3d->numextra);
|
||||
|
||||
Model *model = (Model *)malloc(sizeof(Model));
|
||||
|
||||
model->vertex.count = u64(m3d->numvertex);
|
||||
model->vertex.data = (Vertex *)malloc(sizeof(Vertex) * model->vertex.count);
|
||||
apModel *model = (apModel *)malloc(sizeof(apModel));
|
||||
|
||||
model->index.count = u64(m3d->numface * 3);
|
||||
model->index.data = (u32 *)malloc(sizeof(u32) * model->index.count);
|
||||
model->vertices.length = u64(m3d->numface * 3);
|
||||
model->vertices.data = (apVertex *)malloc(sizeof(apVertex) * model->vertices.length);
|
||||
|
||||
model->material.count = u64(m3d->nummaterial);
|
||||
model->material.data = (Material *)malloc(sizeof(Material) * m3d->nummaterial);
|
||||
model->indices.length = u64(m3d->numface * 3);
|
||||
model->indices.data = (u32 *)malloc(sizeof(u32) * model->indices.length);
|
||||
|
||||
model->materials.length = u64(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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
switch (m3d->material[i].prop[j].type)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
case m3dp_Ks:
|
||||
{
|
||||
U32ColToVec4(&model->material.data[i].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);
|
||||
U32ColToVec4(&model->materials.data[i].props.specular, m3d->material[i].prop[j].value.color);
|
||||
} break;
|
||||
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;
|
||||
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)
|
||||
{
|
||||
Image texture = apLoadImage(m3d->inlined[i].data, m3d->inlined[i].length);
|
||||
Assert(texture.data != NULL, "Image is null");
|
||||
}
|
||||
model->meshes.length = u64(num_meshes);
|
||||
model->meshes.data = (apMesh *)malloc(sizeof(apMesh) * num_meshes);
|
||||
|
||||
/*
|
||||
TODO: replace
|
||||
for (u64 i = 0; i < m3d->numvertex; i += 1)
|
||||
last = UINT32_MAX;
|
||||
u32 current_index = 0;
|
||||
for (u64 i = 0, j = 0; i < m3d->numface; i += 1, j += 3)
|
||||
{
|
||||
model->vertex.data[i].pos.x = m3d->vertex[i].x;
|
||||
model->vertex.data[i].pos.y = m3d->vertex[i].y;
|
||||
model->vertex.data[i].pos.z = m3d->vertex[i].z;
|
||||
model->vertex.data[i].pos.w = m3d->vertex[i].w;
|
||||
|
||||
model->vertex.data[i].col.packed = m3d->vertex[i].color;
|
||||
if (last == UINT32_MAX)
|
||||
{
|
||||
model->meshes.data[current_index].mat_idx = m3d->face[i].materialid;
|
||||
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->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)
|
||||
{
|
||||
model->index.data[j] = m3d->face[i].vertex[0];
|
||||
model->index.data[j+1] = m3d->face[i].vertex[1];
|
||||
model->index.data[j+2] = m3d->face[i].vertex[2];
|
||||
}
|
||||
*/
|
||||
model->vertices.data[j+0].pos.x = m3d->vertex[m3d->face[i].vertex[0]].x;
|
||||
model->vertices.data[j+0].pos.y = m3d->vertex[m3d->face[i].vertex[0]].y;
|
||||
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;
|
||||
}
|
||||
|
||||
static void apFreeModel(Model *model)
|
||||
static void apFreeModel(apModel *model)
|
||||
{
|
||||
free(model->vertex.data);
|
||||
free(model->index.data);
|
||||
m3d_free(model->m3d);
|
||||
free(model->vertices.data);
|
||||
free(model->indices.data);
|
||||
free(model->meshes.data);
|
||||
free(model->materials.data);
|
||||
free(model);
|
||||
}
|
||||
|
||||
|
||||
93
src/assets.h
93
src/assets.h
@ -11,13 +11,14 @@
|
||||
|
||||
// ::Assets::Types::Header::
|
||||
|
||||
typedef struct Vertex
|
||||
typedef struct apVertex
|
||||
{
|
||||
f32 v_x, v_y, v_z;
|
||||
f32 n_x, n_y, n_z;
|
||||
f32 uv_x, uv_y;
|
||||
u32 color;
|
||||
} Vertex;
|
||||
Vec3 pos;
|
||||
Vec3 normal;
|
||||
Vec2 uv;
|
||||
} apVertex;
|
||||
|
||||
ArrayType(apVertex);
|
||||
|
||||
typedef struct Image
|
||||
{
|
||||
@ -27,45 +28,57 @@ typedef struct Image
|
||||
i32 ch;
|
||||
} Image;
|
||||
|
||||
typedef struct Material
|
||||
typedef struct apMatProps
|
||||
{
|
||||
Vec4 color;
|
||||
Vec4 albedo;
|
||||
Vec4 ambient;
|
||||
Vec4 specular;
|
||||
Vec4 emission;
|
||||
f32 shininess;
|
||||
} Material;
|
||||
} apMatProps;
|
||||
|
||||
typedef struct ModelIndex
|
||||
typedef struct apMatTextures
|
||||
{
|
||||
u32 material;
|
||||
u32 start;
|
||||
u32 count;
|
||||
} ModelIndex;
|
||||
u32 albedo;
|
||||
u32 ambient;
|
||||
u32 specular;
|
||||
} apMatTextures;
|
||||
|
||||
typedef struct Model
|
||||
typedef struct apMaterial
|
||||
{
|
||||
struct
|
||||
{
|
||||
Vertex *data;
|
||||
u64 count;
|
||||
} vertex;
|
||||
struct
|
||||
{
|
||||
u32 *data;
|
||||
u64 count;
|
||||
} index;
|
||||
struct
|
||||
{
|
||||
Material *data;
|
||||
u64 count;
|
||||
} material;
|
||||
struct
|
||||
{
|
||||
ModelIndex *data;
|
||||
u64 count;
|
||||
} offset;
|
||||
} Model;
|
||||
apMatProps props;
|
||||
apMatTextures tex;
|
||||
} apMaterial;
|
||||
|
||||
ArrayType(apMaterial);
|
||||
|
||||
typedef struct apMesh
|
||||
{
|
||||
u64 mat_idx;
|
||||
u64 start_idx;
|
||||
u64 length;
|
||||
} apMesh;
|
||||
|
||||
ArrayType(apMesh);
|
||||
|
||||
typedef struct apTexData
|
||||
{
|
||||
rawptr bytes;
|
||||
u32 w;
|
||||
u32 h;
|
||||
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
|
||||
{
|
||||
@ -99,7 +112,7 @@ typedef struct Asset
|
||||
{
|
||||
const char *cstr;
|
||||
u8 *bytes;
|
||||
Model *model;
|
||||
apModel *model;
|
||||
};
|
||||
union
|
||||
{
|
||||
@ -160,5 +173,5 @@ static void apFreeImage(Image *image);
|
||||
|
||||
// ::Assets::Models::Functions::Header::
|
||||
|
||||
static Model *apParseModel(u8 *data);
|
||||
static void apFreeModel(Model *model);
|
||||
static apModel *apParseModel(u8 *data);
|
||||
static void apFreeModel(apModel *model);
|
||||
|
||||
@ -43,6 +43,26 @@ typedef void * rawptr;
|
||||
typedef u32 usize;
|
||||
#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
|
||||
{
|
||||
c8 *value;
|
||||
@ -53,8 +73,23 @@ typedef union
|
||||
{
|
||||
struct { f32 x, y, z, w; };
|
||||
struct { f32 r, g, b, a; };
|
||||
f32 array[4];
|
||||
} 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
|
||||
{
|
||||
struct { u8 x, y, z, w; };
|
||||
|
||||
@ -259,7 +259,7 @@ TestAssetPack(Arena *arena)
|
||||
for (u32 i = 0; i < MODEL_ASSET_MAX; i++, current_asset++)
|
||||
{
|
||||
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::
|
||||
|
||||
MeshBuffer yoder;
|
||||
rIndexedBuffer yoder;
|
||||
|
||||
static b32
|
||||
Init(Renderer *renderer)
|
||||
@ -46,11 +46,26 @@ Init(Renderer *renderer)
|
||||
renderer->pipelines[i] = BuildPipeline(g_Pipeline_Create_Info + i);
|
||||
}
|
||||
|
||||
yoder = CreateMeshBuffer("models/yoda");
|
||||
yoder = rLoadModel("models/yoda");
|
||||
|
||||
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
|
||||
BuildPipeline(PipelineCreateInfo *create_info)
|
||||
@ -142,10 +157,10 @@ CreateShader(int type)
|
||||
return (ShaderHandle)glCreateShader(type);
|
||||
}
|
||||
|
||||
static MeshBuffer
|
||||
CreateMeshBuffer(char *asset)
|
||||
static rIndexedBuffer
|
||||
rLoadModel(char *asset)
|
||||
{
|
||||
MeshBuffer mesh = {0};
|
||||
rIndexedBuffer mesh = {0};
|
||||
|
||||
/*
|
||||
mesh.array = CreateVertexArray();
|
||||
@ -164,7 +179,7 @@ CreateMeshBuffer(char *asset)
|
||||
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
data.model->v_count * sizeof(Vertex),
|
||||
data.model->v_count * sizeof(apVertex),
|
||||
data.model->vertices,
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
@ -178,10 +193,10 @@ CreateMeshBuffer(char *asset)
|
||||
);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(apVertex), 0);
|
||||
|
||||
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);
|
||||
|
||||
@ -192,17 +207,86 @@ CreateMeshBuffer(char *asset)
|
||||
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::
|
||||
|
||||
|
||||
// ::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::
|
||||
|
||||
@ -255,12 +339,14 @@ RunCycle(Renderer *renderer)
|
||||
{
|
||||
while (RGFW_window_checkEvent(renderer->window));
|
||||
|
||||
Asset yoder = apLoad("models/yoda");
|
||||
|
||||
glUseProgram(renderer->pipelines[PIPELINE_PBR]);
|
||||
|
||||
glClearColor(0.1f, 0.8f, 0.4f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
DrawMeshBuffer(&yoder);
|
||||
//DrawMeshBuffer(&yoder);
|
||||
|
||||
RGFW_window_swapBuffers(renderer->window);
|
||||
|
||||
|
||||
@ -25,39 +25,60 @@ typedef unsigned int ShaderHandle;
|
||||
typedef unsigned int VertexArray;
|
||||
typedef unsigned int UBO;
|
||||
|
||||
typedef struct MeshBuffer
|
||||
typedef struct rIndexedBuffer
|
||||
{
|
||||
VertexArray array;
|
||||
VertexBuffer vertex;
|
||||
IndexBuffer index;
|
||||
u32 draw_count;
|
||||
} MeshBuffer;
|
||||
i64 icount, ioffset;
|
||||
u32 vao, buffer;
|
||||
} rIndexedBuffer;
|
||||
|
||||
typedef struct rMesh
|
||||
{
|
||||
rIndexedBuffer buffer;
|
||||
apMatProps material;
|
||||
u32 texture;
|
||||
} rMesh;
|
||||
|
||||
ArrayType(rMesh);
|
||||
|
||||
typedef struct rModel
|
||||
{
|
||||
rMeshArray meshes;
|
||||
} rModel;
|
||||
|
||||
typedef struct Renderer
|
||||
{
|
||||
RGFW_window *window;
|
||||
PipelineHandle pipelines[PIPELINE_MAX];
|
||||
MeshBuffer models[MODEL_ASSET_MAX];
|
||||
rIndexedBuffer models[MODEL_ASSET_MAX];
|
||||
} Renderer;
|
||||
|
||||
// ::Init::Decl::
|
||||
|
||||
static b32 Init(Renderer *renderer);
|
||||
static b32 InitModels(Renderer *renderer);
|
||||
static PipelineHandle CreatePipeline();
|
||||
static VertexBuffer CreateVertexBuffer();
|
||||
static IndexBuffer CreateIndexBuffer();
|
||||
static VertexArray CreateVertexArray();
|
||||
static ShaderHandle CreateShader(int type);
|
||||
static PipelineHandle BuildPipeline(PipelineCreateInfo *create_info);
|
||||
static MeshBuffer CreateMeshBuffer(char *asset);
|
||||
static UBO CreateUBO(rawptr data, u32 size);
|
||||
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::
|
||||
|
||||
static u32 CreateTexture(rawptr data, u32 width, u32 height);
|
||||
static u32 CreateTexture(rawptr data, u32 width, u32 height, u32 channels);
|
||||
|
||||
// ::Draw::Decl::
|
||||
|
||||
static void DrawMeshBuffer(MeshBuffer *mesh);
|
||||
static void DrawMeshBuffer(rIndexedBuffer *mesh);
|
||||
|
||||
|
||||
@ -1,9 +1,25 @@
|
||||
#version 460
|
||||
|
||||
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 = 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()
|
||||
{
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// ====== TODO: Research values here ========
|
||||
// ==========================================
|
||||
|
||||
struct Vertex {
|
||||
struct apVertex {
|
||||
vec4 pos;
|
||||
vec4 col;
|
||||
};
|
||||
@ -14,7 +14,7 @@ struct GUIVertex {
|
||||
};
|
||||
|
||||
layout (buffer_reference, std430) readonly buffer VertexBuffer {
|
||||
Vertex vertices[];
|
||||
apVertex vertices[];
|
||||
};
|
||||
|
||||
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 IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0)
|
||||
#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 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); \
|
||||
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::
|
||||
|
||||
static b32 String8Eq(String8 l, String8 r);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user