diff --git a/res/ft_shaders.farc b/res/ft_shaders.farc index 5db353a..6f00324 100644 Binary files a/res/ft_shaders.farc and b/res/ft_shaders.farc differ diff --git a/src/DivaGL/mdl/disp_manager.cpp b/src/DivaGL/mdl/disp_manager.cpp index e73bba7..5fb9947 100644 --- a/src/DivaGL/mdl/disp_manager.cpp +++ b/src/DivaGL/mdl/disp_manager.cpp @@ -323,6 +323,7 @@ namespace mdl { object_data_get_vertex_attrib_buffer_bindings(args, texcoord_array, vertex_attrib_buffer_binding); + uint32_t compression = mesh->attrib.m.compression; GLsizei size_vertex = (GLsizei)mesh->size_vertex; obj_vertex_format vertex_format = mesh->vertex_format; @@ -333,7 +334,7 @@ namespace mdl { && i.morph_vertex_buffer == morph_vertex_buffer && i.morph_vertex_buffer_offset == morph_vertex_buffer_offset && i.index_buffer == index_buffer && i.vertex_format == vertex_format - && i.size_vertex == size_vertex + && i.size_vertex == size_vertex && i.compression == compression && !memcmp(i.vertex_attrib_buffer_binding, vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)) && !memcmp(i.texcoord_array, texcoord_array, sizeof(texcoord_array))) @@ -388,6 +389,7 @@ namespace mdl { vertex_array->alive_time = 60; vertex_array->vertex_format = vertex_format; vertex_array->size_vertex = size_vertex; + vertex_array->compression = compression; memcpy(&vertex_array->texcoord_array, texcoord_array, sizeof(texcoord_array)); memcpy(&vertex_array->vertex_attrib_buffer_binding, vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)); @@ -419,9 +421,24 @@ namespace mdl { vertex_array->vertex_attrib_array[NORMAL_INDEX] = true; } - glVertexAttribPointer(NORMAL_INDEX, - 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 12; + switch (compression) { + case 0: + default: + glVertexAttribPointer(NORMAL_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 12; + break; + case 1: + glVertexAttribPointer(NORMAL_INDEX, + 3, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); + offset += 8; + break; + case 2: + glVertexAttribPointer(NORMAL_INDEX, + 4, GL_INT_2_10_10_10_REV, GL_TRUE, size_vertex, (void*)offset); + offset += 4; + break; + } } else if (vertex_array->vertex_attrib_array[NORMAL_INDEX]) { glDisableVertexAttribArray(NORMAL_INDEX); @@ -434,16 +451,31 @@ namespace mdl { vertex_array->vertex_attrib_array[TANGENT_INDEX] = true; } - glVertexAttribPointer(TANGENT_INDEX, - 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 16; + switch (compression) { + case 0: + default: + glVertexAttribPointer(TANGENT_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + break; + case 1: + glVertexAttribPointer(TANGENT_INDEX, + 4, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); + offset += 8; + break; + case 2: + glVertexAttribPointer(TANGENT_INDEX, + 4, GL_INT_2_10_10_10_REV, GL_TRUE, size_vertex, (void*)offset); + offset += 4; + break; + } } else if (vertex_array->vertex_attrib_array[TANGENT_INDEX]) { glDisableVertexAttribArray(TANGENT_INDEX); vertex_array->vertex_attrib_array[TANGENT_INDEX] = false; } - if (vertex_format & OBJ_VERTEX_BINORMAL) + if (!compression && (vertex_format & OBJ_VERTEX_BINORMAL)) offset += 12; for (int32_t i = 0; i < 2; i++) { @@ -462,19 +494,45 @@ namespace mdl { vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i] = true; } - glVertexAttribPointer(TEXCOORD0_INDEX + i, 2, GL_FLOAT, GL_FALSE, - size_vertex, (void*)(offset + 8ULL * texcoord_index)); + switch (compression) { + case 0: + default: + glVertexAttribPointer(TEXCOORD0_INDEX + i, 2, GL_FLOAT, GL_FALSE, + size_vertex, (void*)(offset + 8ULL * texcoord_index)); + break; + case 1: + case 2: + glVertexAttribPointer(TEXCOORD0_INDEX + i, 2, GL_HALF_FLOAT, GL_FALSE, + size_vertex, (void*)(offset + 4ULL * texcoord_index)); + break; + } } } - if (vertex_format & OBJ_VERTEX_TEXCOORD0) - offset += 8; - if (vertex_format & OBJ_VERTEX_TEXCOORD1) - offset += 8; - if (vertex_format & OBJ_VERTEX_TEXCOORD2) - offset += 8; - if (vertex_format & OBJ_VERTEX_TEXCOORD3) - offset += 8; + switch (compression) { + case 0: + default: + if (vertex_format & OBJ_VERTEX_TEXCOORD0) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD1) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD2) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD3) + offset += 8; + break; + case 1: + case 2: + if (vertex_format & OBJ_VERTEX_TEXCOORD0) + offset += 4; + if (vertex_format & OBJ_VERTEX_TEXCOORD1) + offset += 4; + if (vertex_format & OBJ_VERTEX_TEXCOORD2) + offset += 4; + if (vertex_format & OBJ_VERTEX_TEXCOORD3) + offset += 4; + break; + } if (vertex_format & OBJ_VERTEX_COLOR0) { if (!vertex_array->vertex_attrib_array[COLOR0_INDEX]) { @@ -482,16 +540,27 @@ namespace mdl { vertex_array->vertex_attrib_array[COLOR0_INDEX] = true; } - glVertexAttribPointer(COLOR0_INDEX, - 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 16; + switch (compression) { + case 0: + default: + glVertexAttribPointer(COLOR0_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + break; + case 1: + case 2: + glVertexAttribPointer(COLOR0_INDEX, + 4, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 8; + break; + } } else if (vertex_array->vertex_attrib_array[COLOR0_INDEX]) { glDisableVertexAttribArray(COLOR0_INDEX); vertex_array->vertex_attrib_array[COLOR0_INDEX] = false; } - if (vertex_format & OBJ_VERTEX_COLOR1) + if (!compression && (vertex_format & OBJ_VERTEX_COLOR1)) offset += 16; if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) { @@ -500,18 +569,44 @@ namespace mdl { vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX] = true; } - glVertexAttribPointer(BONE_WEIGHT_INDEX, - 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 16; + switch (compression) { + case 0: + default: + glVertexAttribPointer(BONE_WEIGHT_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + break; + case 1: + glVertexAttribPointer(BONE_WEIGHT_INDEX, + 4, GL_UNSIGNED_SHORT, GL_TRUE, size_vertex, (void*)offset); + offset += 8; + break; + case 2: + glVertexAttribPointer(BONE_WEIGHT_INDEX, + 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, size_vertex, (void*)offset); + offset += 4; + break; + } if (!vertex_array->vertex_attrib_array[BONE_INDEX_INDEX]) { glEnableVertexAttribArray(BONE_INDEX_INDEX); vertex_array->vertex_attrib_array[BONE_INDEX_INDEX] = true; } - glVertexAttribIPointer(BONE_INDEX_INDEX, - 4, GL_SHORT, size_vertex, (void*)offset); - offset += 8; + switch (compression) { + case 0: + case 1: + default: + glVertexAttribIPointer(BONE_INDEX_INDEX, + 4, GL_UNSIGNED_SHORT, size_vertex, (void*)offset); + offset += 8; + break; + case 2: + glVertexAttribIPointer(BONE_INDEX_INDEX, + 4, GL_UNSIGNED_BYTE, size_vertex, (void*)offset); + offset += 4; + break; + } } else { if (vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX]) { @@ -525,7 +620,7 @@ namespace mdl { } } - if (vertex_format & OBJ_VERTEX_UNKNOWN) { + if (!compression && (vertex_format & OBJ_VERTEX_UNKNOWN)) { if (!vertex_array->vertex_attrib_array[UNKNOWN_INDEX]) { glEnableVertexAttribArray(UNKNOWN_INDEX); vertex_array->vertex_attrib_array[UNKNOWN_INDEX] = true; @@ -565,9 +660,24 @@ namespace mdl { vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX] = true; } - glVertexAttribPointer(MORPH_NORMAL_INDEX, - 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 12; + switch (compression) { + case 0: + default: + glVertexAttribPointer(MORPH_NORMAL_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 12; + break; + case 1: + glVertexAttribPointer(MORPH_NORMAL_INDEX, + 3, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); + offset += 8; + break; + case 2: + glVertexAttribPointer(MORPH_NORMAL_INDEX, + 3, GL_INT_2_10_10_10_REV, GL_TRUE, size_vertex, (void*)offset); + offset += 4; + break; + } } else if (vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX]) { glDisableVertexAttribArray(MORPH_NORMAL_INDEX); @@ -580,9 +690,24 @@ namespace mdl { vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX] = true; } - glVertexAttribPointer(MORPH_TANGENT_INDEX, - 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 16; + switch (compression) { + case 0: + default: + glVertexAttribPointer(MORPH_TANGENT_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + break; + case 1: + glVertexAttribPointer(MORPH_TANGENT_INDEX, + 4, GL_SHORT, GL_TRUE, size_vertex, (void*)offset); + offset += 8; + break; + case 2: + glVertexAttribPointer(MORPH_TANGENT_INDEX, + 4, GL_INT_2_10_10_10_REV, GL_TRUE, size_vertex, (void*)offset); + offset += 4; + break; + } } else if (vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX]) { glDisableVertexAttribArray(MORPH_TANGENT_INDEX); @@ -598,9 +723,20 @@ namespace mdl { vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX] = true; } - glVertexAttribPointer(MORPH_TEXCOORD0_INDEX, - 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 8; + switch (compression) { + case 0: + default: + glVertexAttribPointer(MORPH_TEXCOORD0_INDEX, + 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 8; + break; + case 1: + case 2: + glVertexAttribPointer(MORPH_TEXCOORD0_INDEX, + 2, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 4; + break; + } } else if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX]) { glDisableVertexAttribArray(MORPH_TEXCOORD0_INDEX); @@ -613,19 +749,42 @@ namespace mdl { vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = true; } - glVertexAttribPointer(MORPH_TEXCOORD1_INDEX, - 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 8; + switch (compression) { + case 0: + default: + glVertexAttribPointer(MORPH_TEXCOORD1_INDEX, + 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 8; + break; + case 1: + case 2: + glVertexAttribPointer(MORPH_TEXCOORD1_INDEX, + 2, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 4; + break; + } } else if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX]) { glDisableVertexAttribArray(MORPH_TEXCOORD1_INDEX); vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = false; } - if (vertex_format & OBJ_VERTEX_TEXCOORD2) - offset += 8; - if (vertex_format & OBJ_VERTEX_TEXCOORD3) - offset += 8; + switch (compression) { + case 0: + default: + if (vertex_format & OBJ_VERTEX_TEXCOORD2) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD3) + offset += 8; + break; + case 1: + case 2: + if (vertex_format & OBJ_VERTEX_TEXCOORD2) + offset += 4; + if (vertex_format & OBJ_VERTEX_TEXCOORD3) + offset += 4; + break; + } if (vertex_format & OBJ_VERTEX_COLOR0) { uniform->arr[U_MORPH_COLOR] = 1; @@ -635,23 +794,47 @@ namespace mdl { vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX] = true; } - glVertexAttribPointer(MORPH_COLOR_INDEX, - 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); - offset += 16; + switch (compression) { + case 0: + default: + glVertexAttribPointer(MORPH_COLOR_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + break; + case 1: + case 2: + glVertexAttribPointer(MORPH_COLOR_INDEX, + 4, GL_HALF_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 8; + break; + } } else if (vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX]) { glDisableVertexAttribArray(MORPH_COLOR_INDEX); vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX] = false; } - if (vertex_format & OBJ_VERTEX_COLOR1) - offset += 16; + switch (compression) { + case 0: + default: + if (vertex_format & OBJ_VERTEX_COLOR1) + offset += 16; - if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) - offset += 32; + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) + offset += 24; - if (vertex_format & OBJ_VERTEX_UNKNOWN) - offset += 16; + if (vertex_format & OBJ_VERTEX_UNKNOWN) + offset += 16; + break; + case 1: + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) + offset += 16; + break; + case 2: + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) + offset += 8; + break; + } } else { if (vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX]) { @@ -2908,6 +3091,7 @@ static void object_data_get_vertex_attrib_buffer_bindings(const mdl::ObjSubMeshA GLuint vertex_buffer = args->vertex_buffer; GLuint morph_vertex_buffer = args->morph_vertex_buffer; + uint32_t compression = mesh->attrib.m.compression; GLsizei size_vertex = (GLsizei)mesh->size_vertex; obj_vertex_format vertex_format = mesh->vertex_format; @@ -2933,7 +3117,7 @@ static void object_data_get_vertex_attrib_buffer_bindings(const mdl::ObjSubMeshA vertex_attrib_buffer_binding[BONE_INDEX_INDEX] = vertex_buffer; } - if (vertex_format & OBJ_VERTEX_UNKNOWN) + if (!compression && (vertex_format & OBJ_VERTEX_UNKNOWN)) vertex_attrib_buffer_binding[UNKNOWN_INDEX] = vertex_buffer; if (args->morph_vertex_buffer) { diff --git a/src/DivaGL/mdl/disp_manager.hpp b/src/DivaGL/mdl/disp_manager.hpp index 9ecae66..945b00d 100644 --- a/src/DivaGL/mdl/disp_manager.hpp +++ b/src/DivaGL/mdl/disp_manager.hpp @@ -364,6 +364,7 @@ namespace mdl { bool vertex_attrib_array[16]; obj_vertex_format vertex_format; GLsizei size_vertex; + uint32_t compression; GLuint vertex_attrib_buffer_binding[16]; int32_t texcoord_array[2]; diff --git a/src/DivaGL/object.cpp b/src/DivaGL/object.cpp index b99526c..6ab6547 100644 --- a/src/DivaGL/object.cpp +++ b/src/DivaGL/object.cpp @@ -90,6 +90,8 @@ static void free_vertex_buffer(GLuint buffer); static void obj_vertex_add_bone_weight(vec4& bone_weight, vec4i16& bone_index, int16_t index, float_t weight); static void obj_vertex_validate_bone_data(vec4& bone_weight, vec4i16& bone_index); static uint32_t obj_vertex_format_get_vertex_size(obj_vertex_format format); +static uint32_t obj_vertex_format_get_vertex_size_comp1(obj_vertex_format format); +static uint32_t obj_vertex_format_get_vertex_size_comp2(obj_vertex_format format); obj_material_shader_lighting_type obj_material_shader_attrib::get_lighting_type() const { if (!m.is_lgt_diffuse && !m.is_lgt_specular) @@ -239,7 +241,20 @@ bool obj_mesh_vertex_buffer::load(obj_mesh* mesh, bool dynamic) { if (!mesh->num_vertex) return false; - uint32_t size_vertex = obj_vertex_format_get_vertex_size(mesh->vertex_format); + uint32_t size_vertex; + switch (mesh->attrib.m.compression) { + case 0: + default: + size_vertex = obj_vertex_format_get_vertex_size(mesh->vertex_format); + break; + case 1: + size_vertex = obj_vertex_format_get_vertex_size_comp1(mesh->vertex_format); + break; + case 2: + size_vertex = obj_vertex_format_get_vertex_size_comp2(mesh->vertex_format); + break; + } + mesh->size_vertex = size_vertex; void* vertex = force_malloc((size_t)size_vertex * mesh->num_vertex); @@ -284,141 +299,382 @@ void* obj_mesh_vertex_buffer::fill_data(void* data, obj_mesh* mesh) { uint32_t size_vertex = mesh->size_vertex; uint32_t num_vertex = mesh->num_vertex; size_t d = (size_t)data; - if (vertex_format & OBJ_VERTEX_POSITION) { - vec3* position = vtx.position; - for (uint32_t i = num_vertex; i; i--) { - *(vec3*)d = *position++; - d += size_vertex; + switch (mesh->attrib.m.compression) { + case 0: + default: + if (vertex_format & OBJ_VERTEX_POSITION) { + vec3* position = vtx.position; + for (uint32_t i = num_vertex; i; i--) { + *(vec3*)d = *position++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 12; } - d -= (size_t)size_vertex * num_vertex; - d += 12; - } - if (vertex_format & OBJ_VERTEX_NORMAL) { - vec3* normal = vtx.normal; - for (uint32_t i = num_vertex; i; i--) { - *(vec3*)d = *normal++; - d += size_vertex; + if (vertex_format & OBJ_VERTEX_NORMAL) { + vec3* normal = vtx.normal; + for (uint32_t i = num_vertex; i; i--) { + *(vec3*)d = *normal++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 12; } - d -= (size_t)size_vertex * num_vertex; - d += 12; - } - - if (vertex_format & OBJ_VERTEX_TANGENT) { - vec4* tangent = vtx.tangent; - for (uint32_t i = num_vertex; i; i--) { - *(vec4*)d = *tangent++; - d += size_vertex; - } - d -= (size_t)size_vertex * num_vertex; - d += 16; - } - if (vertex_format & OBJ_VERTEX_BINORMAL) { - vec3* binormal = vtx.binormal; - for (uint32_t i = num_vertex; i; i--) { - *(vec3*)d = *binormal++; - d += size_vertex; + if (vertex_format & OBJ_VERTEX_TANGENT) { + vec4* tangent = vtx.tangent; + for (uint32_t i = num_vertex; i; i--) { + *(vec4*)d = *tangent++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 16; } - d -= (size_t)size_vertex * num_vertex; - d += 12; - } - if (vertex_format & OBJ_VERTEX_TEXCOORD0) { - vec2* texcoord0 = vtx.texcoord0; - for (uint32_t i = num_vertex; i; i--) { - *(vec2*)d = *texcoord0++; - d += size_vertex; + if (vertex_format & OBJ_VERTEX_BINORMAL) { + vec3* binormal = vtx.binormal; + for (uint32_t i = num_vertex; i; i--) { + *(vec3*)d = *binormal++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 12; } - d -= (size_t)size_vertex * num_vertex; - d += 8; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD1) { - vec2* texcoord1 = vtx.texcoord1; - for (uint32_t i = num_vertex; i; i--) { - *(vec2*)d = *texcoord1++; - d += size_vertex; - } - d -= (size_t)size_vertex * num_vertex; - d += 8; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD2) { - vec2* texcoord2 = vtx.texcoord2; - for (uint32_t i = num_vertex; i; i--) { - *(vec2*)d = *texcoord2++; - d += size_vertex; - } - d -= (size_t)size_vertex * num_vertex; - d += 8; - } - - if (vertex_format & OBJ_VERTEX_TEXCOORD3) { - vec2* texcoord3 = vtx.texcoord3; - for (uint32_t i = num_vertex; i; i--) { - *(vec2*)d = *texcoord3++; - d += size_vertex; - } - d -= (size_t)size_vertex * num_vertex; - d += 8; - } - - if (vertex_format & OBJ_VERTEX_COLOR0) { - vec4* color0 = vtx.color0; - for (uint32_t i = num_vertex; i; i--) { - *(vec4*)d = *color0++; - d += size_vertex; - } - d -= (size_t)size_vertex * num_vertex; - d += 16; - } - - if (vertex_format & OBJ_VERTEX_COLOR1) { - vec4* color1 = vtx.color1; - for (uint32_t i = num_vertex; i; i--) { - *(vec4*)d = *color1++; - d += size_vertex; - } - d -= (size_t)size_vertex * num_vertex; - d += 16; - } - - if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) { - vec4* bone_weight = vtx.bone_weight; - vec4* bone_index = vtx.bone_index; - for (uint32_t i = num_vertex; i; i--) { - vec4 _bone_weight = *bone_weight++; - int32_t bone_index_x = (int32_t)bone_index->x; - int32_t bone_index_y = (int32_t)bone_index->y; - int32_t bone_index_z = (int32_t)bone_index->z; - int32_t bone_index_w = (int32_t)bone_index->w; - bone_index++; - - vec4i16 _bone_index; - _bone_index.x = (int16_t)(bone_index_x >= 0 ? bone_index_x / 3 : -1); - _bone_index.y = (int16_t)(bone_index_y >= 0 ? bone_index_y / 3 : -1); - _bone_index.z = (int16_t)(bone_index_z >= 0 ? bone_index_z / 3 : -1); - _bone_index.w = (int16_t)(bone_index_w >= 0 ? bone_index_w / 3 : -1); - obj_vertex_validate_bone_data(_bone_weight, _bone_index); - - *(vec4*)d = _bone_weight; - *(vec4i16*)(d + 16) = _bone_index; - d += size_vertex; + if (vertex_format & OBJ_VERTEX_TEXCOORD0) { + vec2* texcoord0 = vtx.texcoord0; + for (uint32_t i = num_vertex; i; i--) { + *(vec2*)d = *texcoord0++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; } - d -= (size_t)size_vertex * num_vertex; - d += 24; - } - if (vertex_format & OBJ_VERTEX_UNKNOWN) { - vec4* unknown = vtx.unknown; - for (uint32_t i = num_vertex; i; i--) { - *(vec4*)d = *unknown++; - d += size_vertex; + if (vertex_format & OBJ_VERTEX_TEXCOORD1) { + vec2* texcoord1 = vtx.texcoord1; + for (uint32_t i = num_vertex; i; i--) { + *(vec2*)d = *texcoord1++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; } - d -= (size_t)size_vertex * num_vertex; - d += 16; + + if (vertex_format & OBJ_VERTEX_TEXCOORD2) { + vec2* texcoord2 = vtx.texcoord2; + for (uint32_t i = num_vertex; i; i--) { + *(vec2*)d = *texcoord2++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD3) { + vec2* texcoord3 = vtx.texcoord3; + for (uint32_t i = num_vertex; i; i--) { + *(vec2*)d = *texcoord3++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_COLOR0) { + vec4* color0 = vtx.color0; + for (uint32_t i = num_vertex; i; i--) { + *(vec4*)d = *color0++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 16; + } + + if (vertex_format & OBJ_VERTEX_COLOR1) { + vec4* color1 = vtx.color1; + for (uint32_t i = num_vertex; i; i--) { + *(vec4*)d = *color1++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 16; + } + + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) { + vec4* bone_weight = vtx.bone_weight; + vec4* bone_index = vtx.bone_index; + for (uint32_t i = num_vertex; i; i--) { + vec4 _bone_weight = *bone_weight++; + + int32_t bone_index_x = (int32_t)bone_index->x; + int32_t bone_index_y = (int32_t)bone_index->y; + int32_t bone_index_z = (int32_t)bone_index->z; + int32_t bone_index_w = (int32_t)bone_index->w; + bone_index++; + + vec4i16 _bone_index; + _bone_index.x = (int16_t)(bone_index_x >= 0 ? bone_index_x / 3 : -1); + _bone_index.y = (int16_t)(bone_index_y >= 0 ? bone_index_y / 3 : -1); + _bone_index.z = (int16_t)(bone_index_z >= 0 ? bone_index_z / 3 : -1); + _bone_index.w = (int16_t)(bone_index_w >= 0 ? bone_index_w / 3 : -1); + obj_vertex_validate_bone_data(_bone_weight, _bone_index); + + *(vec4*)d = _bone_weight; + *(vec4i16*)(d + 16) = _bone_index; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 24; + } + + if (vertex_format & OBJ_VERTEX_UNKNOWN) { + vec4* unknown = vtx.unknown; + for (uint32_t i = num_vertex; i; i--) { + *(vec4*)d = *unknown++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 16; + } + break; + case 1: + if (vertex_format & OBJ_VERTEX_POSITION) { + vec3* position = vtx.position; + for (uint32_t i = num_vertex; i; i--) { + *(vec3*)d = *position++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 12; + } + + if (vertex_format & OBJ_VERTEX_NORMAL) { + vec3* normal = vtx.normal; + for (uint32_t i = num_vertex; i; i--) { + vec3_to_vec3i16(*normal++ * 32767.0f, *(vec3i16*)d); + *(int16_t*)(d + 6) = 0; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_TANGENT) { + vec4* tangent = vtx.tangent; + for (uint32_t i = num_vertex; i; i--) { + vec4_to_vec4i16(*tangent++ * 32767.0f, *(vec4i16*)d); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD0) { + vec2* texcoord0 = vtx.texcoord0; + for (uint32_t i = num_vertex; i; i--) { + vec2_to_vec2h(*texcoord0++, *(vec2h*)d); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 4; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD1) { + vec2* texcoord1 = vtx.texcoord1; + for (uint32_t i = num_vertex; i; i--) { + vec2_to_vec2h(*texcoord1++, *(vec2h*)d); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 4; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD2) { + vec2* texcoord2 = vtx.texcoord2; + for (uint32_t i = num_vertex; i; i--) { + vec2_to_vec2h(*texcoord2++, *(vec2h*)d); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 4; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD3) { + vec2* texcoord3 = vtx.texcoord3; + for (uint32_t i = num_vertex; i; i--) { + vec2_to_vec2h(*texcoord3++, *(vec2h*)d); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 4; + } + + if (vertex_format & OBJ_VERTEX_COLOR0) { + vec4* color0 = vtx.color0; + for (uint32_t i = num_vertex; i; i--) { + vec4_to_vec4h(*color0++, *(vec4h*)d); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; + } + + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) { + vec4* bone_weight = vtx.bone_weight; + vec4* bone_index = vtx.bone_index; + for (uint32_t i = num_vertex; i; i--) { + vec4 _bone_weight = *bone_weight++; + + int32_t bone_index_x = (int32_t)bone_index->x; + int32_t bone_index_y = (int32_t)bone_index->y; + int32_t bone_index_z = (int32_t)bone_index->z; + int32_t bone_index_w = (int32_t)bone_index->w; + bone_index++; + + vec4i16 _bone_index; + _bone_index.x = (int16_t)(bone_index_x >= 0 ? bone_index_x / 3 : -1); + _bone_index.y = (int16_t)(bone_index_y >= 0 ? bone_index_y / 3 : -1); + _bone_index.z = (int16_t)(bone_index_z >= 0 ? bone_index_z / 3 : -1); + _bone_index.w = (int16_t)(bone_index_w >= 0 ? bone_index_w / 3 : -1); + obj_vertex_validate_bone_data(_bone_weight, _bone_index); + + vec4_to_vec4u16(_bone_weight * 65535.0f, *(vec4u16*)d); + *(vec4i16*)(d + 16) = _bone_index; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 16; + } + break; + case 2: + if (vertex_format & OBJ_VERTEX_POSITION) { + vec3* position = vtx.position; + for (uint32_t i = num_vertex; i; i--) { + *(vec3*)d = *position++; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 12; + } + + if (vertex_format & OBJ_VERTEX_NORMAL) { + vec3* normal = vtx.normal; + for (uint32_t i = num_vertex; i; i--) { + vec3i16 normal_int; + vec3_to_vec3i16(*normal++ * 511.0f, normal_int); + *(uint32_t*)d = (((uint32_t)0 & 0x03) << 30) + | (((uint32_t)normal_int.z & 0x3FF) << 20) + | (((uint32_t)normal_int.y & 0x3FF) << 10) + | ((uint32_t)normal_int.x & 0x3FF); + *(int16_t*)(d + 6) = 0; + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 4; + } + + if (vertex_format & OBJ_VERTEX_TANGENT) { + vec4* tangent = vtx.tangent; + for (uint32_t i = num_vertex; i; i--) { + vec4i16 tangent_int; + vec4_to_vec4i16(*tangent++ * 511.0f, tangent_int); + *(uint32_t*)d = (((uint32_t)clamp_def(tangent_int.w, -1, 1) & 0x03) << 30) + | (((uint32_t)tangent_int.z & 0x3FF) << 20) + | (((uint32_t)tangent_int.y & 0x3FF) << 10) + | ((uint32_t)tangent_int.x & 0x3FF); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 4; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD0) { + vec2* texcoord0 = vtx.texcoord0; + for (uint32_t i = num_vertex; i; i--) { + vec2_to_vec2h(*texcoord0++, *(vec2h*)d); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 4; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD1) { + vec2* texcoord1 = vtx.texcoord1; + for (uint32_t i = num_vertex; i; i--) { + vec2_to_vec2h(*texcoord1++, *(vec2h*)d); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 4; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD2) { + vec2* texcoord2 = vtx.texcoord2; + for (uint32_t i = num_vertex; i; i--) { + vec2_to_vec2h(*texcoord2++, *(vec2h*)d); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 4; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD3) { + vec2* texcoord3 = vtx.texcoord3; + for (uint32_t i = num_vertex; i; i--) { + vec2_to_vec2h(*texcoord3++, *(vec2h*)d); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 4; + } + + if (vertex_format & OBJ_VERTEX_COLOR0) { + vec4* color0 = vtx.color0; + for (uint32_t i = num_vertex; i; i--) { + vec4_to_vec4h(*color0++, *(vec4h*)d); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; + } + + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) { + vec4* bone_weight = vtx.bone_weight; + vec4* bone_index = vtx.bone_index; + for (uint32_t i = num_vertex; i; i--) { + vec4 _bone_weight = *bone_weight++; + + int32_t bone_index_x = (int32_t)bone_index->x; + int32_t bone_index_y = (int32_t)bone_index->y; + int32_t bone_index_z = (int32_t)bone_index->z; + int32_t bone_index_w = (int32_t)bone_index->w; + bone_index++; + + vec4i16 _bone_index; + _bone_index.x = (int16_t)(bone_index_x >= 0 ? bone_index_x / 3 : -1); + _bone_index.y = (int16_t)(bone_index_y >= 0 ? bone_index_y / 3 : -1); + _bone_index.z = (int16_t)(bone_index_z >= 0 ? bone_index_z / 3 : -1); + _bone_index.w = (int16_t)(bone_index_w >= 0 ? bone_index_w / 3 : -1); + obj_vertex_validate_bone_data(_bone_weight, _bone_index); + + vec4i16 bone_weight_int; + vec4_to_vec4i16(_bone_weight * 1023.0f, bone_weight_int); + *(uint32_t*)d = (((uint32_t)0 & 0x03) << 30) + | (((uint32_t)bone_weight_int.z & 0x3FF) << 20) + | (((uint32_t)bone_weight_int.y & 0x3FF) << 10) + | ((uint32_t)bone_weight_int.x & 0x3FF); + + vec4i bone_index; + vec4i16_to_vec4i(_bone_index, bone_index); + vec4i_to_vec4u8(bone_index, *(vec4u8*)(d + 4)); + d += size_vertex; + } + d -= (size_t)size_vertex * num_vertex; + d += 8; + } + break; } return (void*)((size_t)data + (size_t)size_vertex * num_vertex); @@ -556,7 +812,21 @@ bool obj_vertex_buffer::load(obj* obj) { if (!mesh.num_vertex) continue; - uint32_t size_vertex = obj_vertex_format_get_vertex_size(mesh.vertex_format); + mesh.attrib.m.compression = 0; + + uint32_t size_vertex; + switch (mesh.attrib.m.compression) { + case 0: + default: + size_vertex = obj_vertex_format_get_vertex_size(mesh.vertex_format); + break; + case 1: + size_vertex = obj_vertex_format_get_vertex_size_comp1(mesh.vertex_format); + break; + case 2: + size_vertex = obj_vertex_format_get_vertex_size_comp2(mesh.vertex_format); + break; + } mesh.size_vertex = size_vertex; buffer_size += (size_t)size_vertex * mesh.num_vertex; @@ -977,3 +1247,49 @@ inline static uint32_t obj_vertex_format_get_vertex_size(obj_vertex_format forma size += 16; return size; } + +inline static uint32_t obj_vertex_format_get_vertex_size_comp1(obj_vertex_format format) { + uint32_t size = 0; + if (format & OBJ_VERTEX_POSITION) + size += 12; + if (format & OBJ_VERTEX_NORMAL) + size += 8; + if (format & OBJ_VERTEX_TANGENT) + size += 8; + if (format & OBJ_VERTEX_TEXCOORD0) + size += 4; + if (format & OBJ_VERTEX_TEXCOORD1) + size += 4; + if (format & OBJ_VERTEX_TEXCOORD2) + size += 4; + if (format & OBJ_VERTEX_TEXCOORD3) + size += 4; + if (format & OBJ_VERTEX_COLOR0) + size += 8; + if ((format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) + size += 16; + return size; +} + +inline static uint32_t obj_vertex_format_get_vertex_size_comp2(obj_vertex_format format) { + uint32_t size = 0; + if (format & OBJ_VERTEX_POSITION) + size += 12; + if (format & OBJ_VERTEX_NORMAL) + size += 4; + if (format & OBJ_VERTEX_TANGENT) + size += 4; + if (format & OBJ_VERTEX_TEXCOORD0) + size += 4; + if (format & OBJ_VERTEX_TEXCOORD1) + size += 4; + if (format & OBJ_VERTEX_TEXCOORD2) + size += 4; + if (format & OBJ_VERTEX_TEXCOORD3) + size += 4; + if (format & OBJ_VERTEX_COLOR0) + size += 8; + if ((format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) + size += 8; + return size; +} diff --git a/src/DivaGL/object.hpp b/src/DivaGL/object.hpp index a1c6ef6..e600ffd 100644 --- a/src/DivaGL/object.hpp +++ b/src/DivaGL/object.hpp @@ -325,7 +325,8 @@ struct obj_mesh_attrib_member { uint32_t billboard_y_axis : 1; uint32_t translucent_sort_by_radius : 1; uint32_t billboard : 1; - uint32_t dummy : 28; + uint32_t dummy : 26; // 28 + uint32_t compression : 2; // Own stuff }; union obj_mesh_attrib { diff --git a/src/DivaGL/rob/rob.cpp b/src/DivaGL/rob/rob.cpp index 4a8cf59..39d0509 100644 --- a/src/DivaGL/rob/rob.cpp +++ b/src/DivaGL/rob/rob.cpp @@ -787,36 +787,134 @@ HOOK(void, FASTCALL, RobCloth__UpdateVertexBuffer, 0x000000014021CF00, obj_mesh* if (double_sided) indices_count /= 2; - if (mesh->vertex_format & OBJ_VERTEX_TANGENT) - for (int32_t i = 2; i; i--, facing = -1.0f) { - for (int32_t j = indices_count; j; j--, indices++) { - CLOTHNode* node = &nodes[*indices]; + bool tangent = !!(mesh->vertex_format & OBJ_VERTEX_TANGENT); - *(vec3*)data = node->trans; - *(vec3*)(data + 0x0C) = node->normal * facing; - *(vec3*)(data + 0x18) = node->tangent; - *(float_t*)(data + 0x24) = node->tangent_sign; + switch (mesh->attrib.m.compression) { + case 0: + default: + if (tangent) + for (int32_t i = 2; i; i--, facing = -1.0f) { + for (int32_t j = indices_count; j; j--, indices++) { + CLOTHNode* node = &nodes[*indices]; - data += mesh->size_vertex; + *(vec3*)data = node->trans; + *(vec3*)(data + 0x0C) = node->normal * facing; + *(vec3*)(data + 0x18) = node->tangent; + *(float_t*)(data + 0x24) = node->tangent_sign; + + data += mesh->size_vertex; + } + + if (!double_sided) + break; } + else + for (int32_t i = 2; i; i--, facing = -1.0f) { + for (int32_t j = indices_count; j; j--, indices++) { + CLOTHNode* node = &nodes[*indices]; - if (!double_sided) - break; - } - else - for (int32_t i = 2; i; i--, facing = -1.0f) { - for (int32_t j = indices_count; j; j--, indices++) { - CLOTHNode* node = &nodes[*indices]; + *(vec3*)data = node->trans; + *(vec3*)(data + 0x0C) = node->normal * facing; - *(vec3*)data = node->trans; - *(vec3*)(data + 0x0C) = node->normal * facing; + data += mesh->size_vertex; + } - data += mesh->size_vertex; + if (!double_sided) + break; } + break; + case 1: + if (tangent) + for (int32_t i = 2; i; i--, facing = -1.0f) { + for (int32_t j = indices_count; j; j--, indices++) { + CLOTHNode* node = &nodes[*indices]; - if (!double_sided) - break; - } + *(vec3*)data = node->trans; + + vec3_to_vec3i16(node->normal * (32767.0f * facing), *(vec3i16*)(data + 0x0C)); + *(int16_t*)(data + 0x12) = 0; + + vec4 tangent; + *(vec3*)&tangent = node->tangent; + tangent.w = node->tangent_sign; + vec4_to_vec4i16(tangent * 32767.0f, *(vec4i16*)(data + 0x14)); + + data += mesh->size_vertex; + } + + if (!double_sided) + break; + } + else + for (int32_t i = 2; i; i--, facing = -1.0f) { + for (int32_t j = indices_count; j; j--, indices++) { + CLOTHNode* node = &nodes[*indices]; + + *(vec3*)data = node->trans; + + vec3_to_vec3i16(node->normal * (32767.0f * facing), *(vec3i16*)(data + 0x0C)); + *(int16_t*)(data + 0x12) = 0; + + data += mesh->size_vertex; + } + + if (!double_sided) + break; + } + case 2: + if (tangent) + for (int32_t i = 2; i; i--, facing = -1.0f) { + for (int32_t j = indices_count; j; j--, indices++) { + CLOTHNode* node = &nodes[*indices]; + + *(vec3*)data = node->trans; + + vec3i16 normal_int; + vec3_to_vec3i16(node->normal * 511.0f, normal_int); + *(uint32_t*)(data + 0x0C) = (((uint32_t)0 & 0x03) << 30) + | (((uint32_t)normal_int.z & 0x3FF) << 20) + | (((uint32_t)normal_int.y & 0x3FF) << 10) + | ((uint32_t)normal_int.x & 0x3FF); + + vec4 tangent; + *(vec3*)&tangent = node->tangent; + tangent.w = node->tangent_sign; + + vec4i16 tangent_int; + vec4_to_vec4i16(tangent * 511.0f, tangent_int); + *(uint32_t*)(data + 0x10) = (((uint32_t)clamp_def(tangent_int.w, -1, 1) & 0x03) << 30) + | (((uint32_t)tangent_int.z & 0x3FF) << 20) + | (((uint32_t)tangent_int.y & 0x3FF) << 10) + | ((uint32_t)tangent_int.x & 0x3FF); + + data += mesh->size_vertex; + } + + if (!double_sided) + break; + } + else + for (int32_t i = 2; i; i--, facing = -1.0f) { + for (int32_t j = indices_count; j; j--, indices++) { + CLOTHNode* node = &nodes[*indices]; + + *(vec3*)data = node->trans; + + vec3i16 normal_int; + vec3_to_vec3i16(node->normal * 511.0f, normal_int); + *(uint32_t*)(data + 0x0C) = (((uint32_t)0 & 0x03) << 30) + | (((uint32_t)normal_int.z & 0x3FF) << 20) + | (((uint32_t)normal_int.y & 0x3FF) << 10) + | ((uint32_t)normal_int.x & 0x3FF); + + data += mesh->size_vertex; + } + + if (!double_sided) + break; + } + break; + } buffer.UnmapMemory(); }