Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions gfx/gl/texture_types.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
#pragma once

typedef enum {
GL_TEXTURE_TYPE_NORMAL = 0,
GL_TEXTURE_TYPE_CUBEMAP = 1,
GL_TEXTURE_TYPE_COUNT = 1,
GL_TEXTURE_TYPE_NORMAL = 0,
GL_TEXTURE_TYPE_DIFFUSE = 1,
GL_TEXTURE_TYPE_SPECULAR = 2,
GL_TEXTURE_TYPE_AMBIENT = 3,
GL_TEXTURE_TYPE_EMISSIVE = 4,
GL_TEXTURE_TYPE_HEIGHT = 5,
GL_TEXTURE_TYPE_NORMALS = 6,
GL_TEXTURE_TYPE_SHININESS = 7,
GL_TEXTURE_TYPE_OPACITY = 8,
GL_TEXTURE_TYPE_DISPLACEMENT = 9,
GL_TEXTURE_TYPE_LIGHTMAP = 10,
GL_TEXTURE_TYPE_REFLECTION = 11,
GL_TEXTURE_TYPE_BASE_COLOR = 12,
GL_TEXTURE_TYPE_NORMAL_CAMERA = 13,
GL_TEXTURE_TYPE_EMISSION_COLOR = 14,
GL_TEXTURE_TYPE_METALNESS = 15,
GL_TEXTURE_TYPE_DIFFUSE_ROUGHNESS = 16,
GL_TEXTURE_TYPE_AMBIENT_OCCLUSION = 17,
GL_TEXTURE_TYPE_CUBEMAP = 18,
GL_TEXTURE_TYPE_COUNT
} gltexturetype;
17 changes: 17 additions & 0 deletions gfx/glrenderer3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,23 @@ void glrenderer3d_draw(const glrendererconfig_t config)
switch(config.calls.call[call_idx].textures.items[txt_idx].type)
{
case GL_TEXTURE_TYPE_NORMAL:
case GL_TEXTURE_TYPE_DIFFUSE:
case GL_TEXTURE_TYPE_SPECULAR:
case GL_TEXTURE_TYPE_AMBIENT:
case GL_TEXTURE_TYPE_EMISSIVE:
case GL_TEXTURE_TYPE_HEIGHT:
case GL_TEXTURE_TYPE_NORMALS:
case GL_TEXTURE_TYPE_SHININESS:
case GL_TEXTURE_TYPE_OPACITY:
case GL_TEXTURE_TYPE_DISPLACEMENT:
case GL_TEXTURE_TYPE_LIGHTMAP:
case GL_TEXTURE_TYPE_REFLECTION:
case GL_TEXTURE_TYPE_BASE_COLOR:
case GL_TEXTURE_TYPE_NORMAL_CAMERA:
case GL_TEXTURE_TYPE_EMISSION_COLOR:
case GL_TEXTURE_TYPE_METALNESS:
case GL_TEXTURE_TYPE_DIFFUSE_ROUGHNESS:
case GL_TEXTURE_TYPE_AMBIENT_OCCLUSION:
gltexture2d_bind(
config.calls.call[call_idx].textures.items[txt_idx].source.normal_texture,
txt_idx
Expand Down
99 changes: 71 additions & 28 deletions gfx/model/assimp.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ boneinfo_t boneinfo(matrix4f_t offset) {

#define MAX_MESHES_PER_MODEL 10

typedef struct {
gltexture2d_t texture;
u8 assimp_type;
} model_texture_t;

typedef struct glmodel_t {

str_t directory_path;
Expand Down Expand Up @@ -93,6 +98,8 @@ void glmodel_destroy(glmodel_t *self);

#ifndef IGNORE_ASSIMP_IMPLEMENTATION

gltexture2d_t assimp__internal_load_texture_from_path(glmodel_t *self, const struct aiScene *scene, const char *path);

const struct {
enum aiTextureType type;
char *name;
Expand Down Expand Up @@ -142,6 +149,34 @@ void assimp__internal_glmesh_processMaterial(glmodel_t *self, const struct aiSce
}

//TODO: setup materials

for (i32 type = aiTextureType_DIFFUSE; type <= aiTextureType_AMBIENT_OCCLUSION; type++)
{
u32 count = aiGetMaterialTextureCount(material, (enum aiTextureType)type);
for (u32 i = 0; i < count; i++)
{
struct aiString path;
if (aiGetMaterialTexture(material, (enum aiTextureType)type, i, &path,
NULL, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS)
{
bool found = false;
list_iterator(&self->textures, iter) {
if (((model_texture_t *)iter)->assimp_type == type) {
found = true;
break;
}
}

if (!found) {
model_texture_t mt = {
.texture = assimp__internal_load_texture_from_path(self, scene, path.data),
.assimp_type = (u8)type
};
list_append(&self->textures, mt);
}
}
}
}
}

glmesh_t assimp__internal_glmesh_processMesh(const struct aiMesh *mesh) {
Expand Down Expand Up @@ -322,6 +357,9 @@ void assimp__internal_glmesh_processScene(glmodel_t *self, const struct aiScene
}

ASSERT(scene->mNumMeshes <= MAX_MESHES_PER_MODEL);

u64 processed_materials = 0;

for (u32 mesh_index = 0; mesh_index < scene->mNumMeshes; mesh_index++)
{
struct aiMesh *mesh = scene->mMeshes[mesh_index];
Expand All @@ -331,12 +369,18 @@ void assimp__internal_glmesh_processScene(glmodel_t *self, const struct aiScene
// Process mesh
const glmesh_t m = assimp__internal_glmesh_processMesh(mesh);

// Process materials
assimp__internal_glmesh_processMaterial(
self,
scene,
mesh->mMaterialIndex
);
// Process materials (once per unique material index).
// Multiple meshes may share the same material; a u64 bitmask
// tracks which material indices have already been processed to
// avoid redundant texture loading and duplicate list entries.
if (!(processed_materials & ((u64)1 << mesh->mMaterialIndex))) {
processed_materials |= (u64)1 << mesh->mMaterialIndex;
assimp__internal_glmesh_processMaterial(
self,
scene,
mesh->mMaterialIndex
);
}
Comment on lines +376 to +383

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

explain the bitmask logic and the reason to bring in a comment


if (mesh->mNumBones) {
assimp__internal_glmesh_process_bones(mesh, &m.vtx, self->bone_name_to_index, &self->bone_infos);
Expand All @@ -352,21 +396,19 @@ void assimp__internal_glmesh_processScene(glmodel_t *self, const struct aiScene
}
}

void assimp__internal_glmodel_load_alltextures(glmodel_t *self, const struct aiScene *scene)
{
for(u32 texture_index = 0; texture_index < scene->mNumTextures; texture_index++)
{
gltexture2d_t texture = {0};
struct aiTexture *aitexture = scene->mTextures[texture_index];

if (aitexture->mFilename.length == 0 && aitexture->mHeight == 0) {
texture = gltexture2d_embedded_init((u8 *)aitexture->pcData, aitexture->mWidth);
} else {
str_t absolute_texture_path = str_join(self->arena, &self->directory_path, aitexture->mFilename.data);
texture = gltexture2d_init(absolute_texture_path.data);
gltexture2d_t assimp__internal_load_texture_from_path(glmodel_t *self, const struct aiScene *scene, const char *path) {
bool is_embedded = (path[0] == '*');
if (is_embedded) {
i32 index = atoi(path + 1);
ASSERT(index >= 0 && (u32)index < scene->mNumTextures);
struct aiTexture *aitexture = scene->mTextures[index];
if (aitexture->mHeight == 0) {
return gltexture2d_embedded_init((u8 *)aitexture->pcData, aitexture->mWidth);
}
list_append(&self->textures, texture);
ASSERT(0 && "Raw pixel embedded texture not supported via material reference");
}
str_t absolute_path = str_join(self->arena, &self->directory_path, path);
return gltexture2d_init(absolute_path.data);
}


Expand All @@ -377,9 +419,9 @@ glmodel_t glmodel_init(const char *filepath)
memcpy(o.filepath, filepath, strlen(filepath));
o.directory_path = str_get_directory_path(filepath);
o.arena = calloc(1, sizeof(arena_t));
*o.arena = arena_init(NULL, 64 * MB);
*o.arena = arena_init(NULL, 200 * MB);
o.meshes = list_init(glmesh_t, o.arena);
o.textures = list_init(gltexture2d_t, o.arena);
o.textures = list_init(model_texture_t, o.arena);
o.colors = list_init(vec4f_t, o.arena);
o.bone_infos = list_init(boneinfo_t, o.arena);
o.animator = animator_init(o.arena);
Expand All @@ -401,13 +443,11 @@ glmodel_t glmodel_init(const char *filepath)
glms_mat4_transpose(*(matrix4f_t *)&scene->mRootNode->mTransformation)
);

assimp__internal_glmodel_load_alltextures(&o, scene);

//debug_assimp_vertex_bones(scene);
assimp__internal_glmesh_processScene(&o, scene);

//load all animations
animator_load_all_animations(&o.animator, scene, o.arena);
animator_load_all_animations(&o.animator, scene, o.arena, (animation_filter_t){0});


//NOTE: this to cache the root channel idx to get the root position of the model during an animation
Expand All @@ -434,6 +474,7 @@ glmodel_t glmodel_init(const char *filepath)
}
}

#if 0
// Strip root bone translation from all animations — engine controls root position
if (o.internal.root_channel_idx >= 0) {
list_iterator(&o.animator.animations, iter) {
Expand All @@ -446,6 +487,7 @@ glmodel_t glmodel_init(const char *filepath)
}
}
}
#endif

logging("Completed loading model %s ...", filepath);

Expand All @@ -455,7 +497,7 @@ glmodel_t glmodel_init(const char *filepath)
void glmodel_destroy(glmodel_t *const self)
{
list_iterator(&self->meshes, iter) glmesh_destroy((glmesh_t *)iter);
list_iterator(&self->textures, iter) gltexture2d_destroy(iter);
list_iterator(&self->textures, iter) gltexture2d_destroy(&((model_texture_t *)iter)->texture);

aiReleaseImport(self->scene);
arena_destroy(self->arena);
Expand Down Expand Up @@ -640,9 +682,10 @@ gltexturelist_t glmodel_get_texuturelist(const glmodel_t *self)
.items = {0}
};
list_iterator(&self->textures, iter) {
list.items[(u64)list_iterator_index] = (gltextureitem_t ){
.type = GL_TEXTURE_TYPE_NORMAL,
.source = iter
model_texture_t *mt = (model_texture_t *)iter;
list.items[(u64)list_iterator_index] = (gltextureitem_t){
.type = (gltexturetype)mt->assimp_type,
.source = { .normal_texture = &mt->texture }
};
}
return list;
Expand Down