diff --git a/src/DivaGL/mdl/disp_manager.cpp b/src/DivaGL/mdl/disp_manager.cpp index 2a1f7cb..d78c2f0 100644 --- a/src/DivaGL/mdl/disp_manager.cpp +++ b/src/DivaGL/mdl/disp_manager.cpp @@ -42,6 +42,17 @@ static const GLuint MORPH_TEXCOORD0_INDEX = 13; static const GLuint MORPH_TEXCOORD1_INDEX = 14; static const GLuint BONE_INDEX_INDEX = 15; +material_list_struct::material_list_struct() : blend_color(), +has_blend_color(), emission(), has_emission() { + hash = (uint32_t)-1; +} + +material_list_struct::material_list_struct(uint64_t hash, vec4& blend_color, + vec4u8& has_blend_color, vec4& emission, vec4u8& has_emission) : hash(hash), blend_color(blend_color), + has_blend_color(has_blend_color), emission(emission), has_emission(has_emission) { + +} + texture_pattern_struct::texture_pattern_struct() { src = (uint32_t)-1; dst = (uint32_t)-1; @@ -64,6 +75,9 @@ namespace mdl { prj::vector vertex_array_cache; prj::vector etc_vertex_array_cache; + int32_t material_list_count; + material_list_struct material_list_array[MATERIAL_LIST_COUNT]; + ObjSubMeshArgs::ObjSubMeshArgs() : sub_mesh(), mesh(), material(), textures(), mat_count(), mats(), vertex_buffer(), vertex_buffer_offset(), index_buffer(), set_blend_color(), chara_color(), self_shadow(), shadow(), morph_vertex_buffer(), morph_vertex_buffer_offset(), morph_weight(), texture_pattern_count(), @@ -189,7 +203,7 @@ namespace mdl { const obj_sub_mesh* sub_mesh, const obj_mesh* mesh, const obj_material_data* material, const prj::vector* textures, int32_t mat_count, const mat4* mats, GLuint vertex_buffer, size_t vertex_buffer_offset, GLuint index_buffer, - const vec4& blend_color, GLuint morph_vertex_buffer, + const vec4& blend_color, const vec4& emission, GLuint morph_vertex_buffer, size_t morph_vertex_buffer_offset, int32_t instances_count, mat4* instances_mat, void(FASTCALL* func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data) { kind = mdl::OBJ_KIND_NORMAL; @@ -230,6 +244,8 @@ namespace mdl { args->blend_color = 1.0f; } + args->emission = emission; + args->chara_color = disp_manager->chara_color; args->self_shadow = !!(disp_manager->obj_flags & (mdl::OBJ_8 | mdl::OBJ_4)); args->shadow = disp_manager->shadow_type; @@ -2044,12 +2060,79 @@ namespace mdl { if (!vertex_buffer || !index_buffer || obj_morph_vertex_buf && !morph_vertex_buffer) continue; + uint64_t material_hash = hash_utf8_fnv1a64m(material->material.name); + + material_list_struct* mat_list = 0; + for (int32_t k = 0; k < material_list_count; k++) + if (material_list_array[k].hash == material_hash) { + mat_list = &material_list_array[k]; + break; + } + vec4 _blend_color = 1.0f; - if (blend_color) - _blend_color = *blend_color; + vec4 _emission = 0.0f; + + if (mat_list) { + bool has_blend_color = false; + if (mat_list->has_blend_color.x) { + _blend_color.x = mat_list->blend_color.x; + has_blend_color = true; + } + + if (mat_list->has_blend_color.y) { + _blend_color.y = mat_list->blend_color.y; + has_blend_color = true; + } + + if (mat_list->has_blend_color.z) { + _blend_color.z = mat_list->blend_color.z; + has_blend_color = true; + } + + if (mat_list->has_blend_color.w) { + _blend_color.w = mat_list->blend_color.w; + has_blend_color = true; + } + + if (blend_color) { + if (!has_blend_color) + _blend_color = *blend_color; + else + _blend_color *= *blend_color; + } + + bool has_emission = false; + if (mat_list->has_emission.x) { + _emission.x = mat_list->emission.x; + has_emission = true; + } + + if (mat_list->has_emission.y) { + _emission.y = mat_list->emission.y; + has_emission = true; + } + + if (mat_list->has_emission.z) { + _emission.z = mat_list->emission.z; + has_emission = true; + } + + if (mat_list->has_emission.w) { + _emission.w = mat_list->emission.w; + has_emission = true; + } + + if (!has_emission) + _emission = material->material.color.emission; + } + else { + if (blend_color) + _blend_color = *blend_color; + _emission = material->material.color.emission; + } data->init_sub_mesh(mat, object->bounding_sphere.radius, sub_mesh, mesh, material, textures, - num_bone_index, mats, vertex_buffer, vertex_buffer_offset, index_buffer, _blend_color, + num_bone_index, mats, vertex_buffer, vertex_buffer_offset, index_buffer, _blend_color, _emission, morph_vertex_buffer, morph_vertex_buffer_offset, instances_count, instances_mat, func, func_data); if (obj_flags & mdl::OBJ_SHADOW_OBJECT) { @@ -2640,6 +2723,20 @@ namespace mdl { obj_flags = flags; } + void DispManager::set_material_list(int32_t count, const material_list_struct* value) { + if (count > MATERIAL_LIST_COUNT) + return; + + material_list_count = count; + + if (count) + for (int32_t i = 0; i < count; i++) + material_list_array[i] = value[i]; + else + for (int32_t i = 0; i < MATERIAL_LIST_COUNT; i++) + material_list_array[i] = {}; + } + void DispManager::set_morph(object_info object, float_t weight) { morph.weight = weight; morph.object = object; diff --git a/src/DivaGL/mdl/disp_manager.hpp b/src/DivaGL/mdl/disp_manager.hpp index d448249..ddb1714 100644 --- a/src/DivaGL/mdl/disp_manager.hpp +++ b/src/DivaGL/mdl/disp_manager.hpp @@ -14,6 +14,7 @@ #include "../object.hpp" #include "../shadow.hpp" +#define MATERIAL_LIST_COUNT 24 #define TEXTURE_PATTERN_COUNT 24 #define TEXTURE_TRANSFORM_COUNT 24 @@ -108,6 +109,18 @@ namespace mdl { }; } +struct material_list_struct { + uint64_t hash; + vec4 blend_color; + vec4u8 has_blend_color; + vec4 emission; + vec4u8 has_emission; + + material_list_struct(); + material_list_struct(uint64_t hash, vec4& blend_color, + vec4u8& has_blend_color, vec4& emission, vec4u8& has_emission); +}; + struct morph_struct { object_info object; float_t weight; @@ -159,6 +172,7 @@ namespace mdl { bool set_blend_color; bool chara_color; vec4 blend_color; + vec4 emission; bool self_shadow; shadow_type_enum shadow; GLuint morph_vertex_buffer; @@ -308,7 +322,7 @@ namespace mdl { const obj_sub_mesh* sub_mesh, const obj_mesh* mesh, const obj_material_data* material, const prj::vector* textures, int32_t mat_count, const mat4* mats, GLuint vertex_buffer, size_t vertex_buffer_offset, GLuint index_buffer, - const vec4& blend_color, GLuint morph_vertex_buffer, + const vec4& blend_color, const vec4& emission, GLuint morph_vertex_buffer, size_t morph_vertex_buffer_offset, int32_t instances_count, mat4* instances_mat, void(FASTCALL* func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data); void init_translucent(const mat4* mat, ObjTranslucentArgs* translucent); @@ -454,6 +468,7 @@ namespace mdl { void set_chara_color(bool value = false); void set_culling_finc(bool(FASTCALL* func)(obj_bounding_sphere*) = 0); void set_obj_flags(ObjFlags flags = (ObjFlags)0); + void set_material_list(int32_t count = 0, const material_list_struct* value = 0); void set_morph(object_info object = {}, float_t weight = 0.0f); void set_shadow_type(shadow_type_enum type = SHADOW_CHARA); void set_texture_color_coefficients(vec4& value); diff --git a/src/DivaGL/mdl/draw_object.cpp b/src/DivaGL/mdl/draw_object.cpp index e2757cb..bd14eba 100644 --- a/src/DivaGL/mdl/draw_object.cpp +++ b/src/DivaGL/mdl/draw_object.cpp @@ -400,7 +400,7 @@ namespace mdl { const obj_material_data* material = args->material; const prj::vector* textures = args->textures; if (draw_state->shader_index != -1) { - rctx->obj_batch.g_material_state_emission = material->material.color.emission; + rctx->obj_batch.g_material_state_emission = args->emission; draw_object_material_set_uniform(material, false); if (material->material.attrib.m.alpha_texture) uniform->arr[U_TEXTURE_COUNT] = 0; @@ -762,7 +762,7 @@ static void draw_object_material_set_default(const mdl::ObjSubMeshArgs* args, bo if (!sss_data_get()->enable) rctx->obj_batch.g_material_state_ambient.w = 1.0f; rctx->obj_batch.g_material_state_diffuse = material->material.color.diffuse; - rctx->obj_batch.g_material_state_emission = material->material.color.emission; + rctx->obj_batch.g_material_state_emission = args->emission; float_t line_light; if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_PHONG) { @@ -945,7 +945,7 @@ static void draw_object_material_set_reflect(const mdl::ObjSubMeshArgs* args) { else { ambient = material->material.color.ambient; diffuse = material->material.color.diffuse; - emission = material->material.color.emission; + emission = args->emission; specular = material->material.color.specular; }