Compress some stuff to R10G10B10A2

This commit is contained in:
korenkonder
2024-04-21 19:28:11 +03:00
parent b49f8d7de5
commit aa900bfc68
6 changed files with 804 additions and 204 deletions
Binary file not shown.
+239 -55
View File
@@ -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) {
+1
View File
@@ -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];
+442 -126
View File
@@ -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;
}
+2 -1
View File
@@ -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 {
+120 -22
View File
@@ -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();
}