pack tfrag normals into 10 bits (#2625)

Saves 16 bits and lets us align the `color_index` field properly.

This shouldn't improve or decrease performance by any noticeable amount
except maybe in really low end systems.
This commit is contained in:
ManDude
2023-05-06 02:08:33 +01:00
committed by GitHub
parent acae62c919
commit 40b2e93be7
6 changed files with 30 additions and 27 deletions
+16 -14
View File
@@ -173,23 +173,30 @@ std::array<math::Vector3f, 3> tie_normal_transform_v2(const std::array<math::Vec
// sqc2 vf12, -80(t8)
}
u32 pack_to_gl_normal(s16 nx, s16 ny, s16 nz) {
ASSERT(nx >= -512 && nx <= 511);
ASSERT(ny >= -512 && ny <= 511);
ASSERT(nz >= -512 && nz <= 511);
return (nx & 0x3ff) | ((ny & 0x3ff) << 10) | ((nz & 0x3ff) << 20);
}
/*!
* Unpack tie normal by transforming and converting to s16 for OpenGL.
*/
math::Vector<s16, 3> unpack_tie_normal(const std::array<math::Vector3f, 3>& mat,
s8 nx,
s8 ny,
s8 nz) {
u32 unpack_tie_normal(const std::array<math::Vector3f, 3>& mat, s8 nx, s8 ny, s8 nz) {
// rotate the normal
math::Vector3f nrm = math::Vector3f::zero();
nrm += mat[0] * nx;
nrm += mat[1] * ny;
nrm += mat[2] * nz;
// convert to s16 for OpenGL renderer
nrm *= 0.0078125; // number from EE asm
nrm *= 256.f * 128.f; // for normalize s16 -> float conversion by OpenGL.
// nrm /= 0x100; // number from EE asm
// nrm *= 0x200; // for normalized s10 -> float conversion by OpenGL.
nrm *= 2; // for normalized s10 -> float conversion by OpenGL.
return nrm.cast<s16>();
auto as_int = nrm.cast<s16>();
return pack_to_gl_normal(as_int.x(), as_int.y(), as_int.z());
}
void TieTree::unpack() {
@@ -206,9 +213,7 @@ void TieTree::unpack() {
vtx.z = proto_vtx.z;
vtx.s = proto_vtx.s;
vtx.t = proto_vtx.t;
vtx.nx = proto_vtx.nx << 8;
vtx.ny = proto_vtx.ny << 8;
vtx.nz = proto_vtx.nz << 8;
vtx.nor = pack_to_gl_normal(proto_vtx.nx << 1, proto_vtx.ny << 1, proto_vtx.nz << 1);
vtx.r = proto_vtx.r;
vtx.g = proto_vtx.g;
vtx.b = proto_vtx.b;
@@ -229,10 +234,7 @@ void TieTree::unpack() {
vtx.z = temp.z();
vtx.s = proto_vtx.s;
vtx.t = proto_vtx.t;
auto nrm = unpack_tie_normal(nmat, proto_vtx.nx, proto_vtx.ny, proto_vtx.nz);
vtx.nx = nrm.x();
vtx.ny = nrm.y();
vtx.nz = nrm.z();
vtx.nor = unpack_tie_normal(nmat, proto_vtx.nx, proto_vtx.ny, proto_vtx.nz);
vtx.r = proto_vtx.r;
vtx.g = proto_vtx.g;
vtx.b = proto_vtx.b;
+6 -5
View File
@@ -73,23 +73,24 @@ struct MemoryUsageTracker {
void add(MemoryUsageCategory category, u32 size_bytes) { data[category] += size_bytes; }
};
constexpr int TFRAG3_VERSION = 34;
constexpr int TFRAG3_VERSION = 35;
// These vertices should be uploaded to the GPU at load time and don't change
struct PreloadedVertex {
// the vertex position
float x = 0, y = 0, z = 0;
// envmap tint color, not used in == or hash.
u8 r = 0, g = 0, b = 0, a = 0;
// texture coordinates
float s = 0, t = 0;
u8 r = 0, g = 0, b = 0, a = 0; // envmap tint color, not used in == or hash.
// not used in == or hash!!
// note that this is a 10-bit 3-element field packed into 32-bits.
u32 nor = 0;
// color table index
u16 color_index = 0;
// not used in == or hash!!
s16 nx = 0, ny = 0, nz = 0;
struct hash {
std::size_t operator()(const PreloadedVertex& x) const;
};
@@ -111,7 +111,7 @@ void Tfrag3::update_load(const std::vector<tfrag3::TFragmentTreeKind>& tree_kind
);
glVertexAttribIPointer(2, // location 2 in the shader
1, // 1 values per vert
2, // 1 values per vert
GL_UNSIGNED_SHORT, // u16
sizeof(tfrag3::PreloadedVertex), // stride
(void*)offsetof(tfrag3::PreloadedVertex, color_index) // offset (0)
@@ -136,18 +136,18 @@ void Tie3::load_from_fr3_data(const LevelData* loader_data) {
);
glVertexAttribIPointer(2, // location 2 in the shader
1, // 1 values per vert
2, // 1 values per vert
GL_UNSIGNED_SHORT, // u16
sizeof(tfrag3::PreloadedVertex), // stride
(void*)offsetof(tfrag3::PreloadedVertex, color_index) // offset (0)
);
glVertexAttribPointer(3, // location 1 in the shader
3, // 3 values per vert
GL_SHORT, // floats
4, // 3 values per vert
GL_INT_2_10_10_10_REV, // floats
GL_TRUE, // normalized
sizeof(tfrag3::PreloadedVertex), // stride
(void*)offsetof(tfrag3::PreloadedVertex, nx) // offset (0)
(void*)offsetof(tfrag3::PreloadedVertex, nor) // offset (0)
);
glVertexAttribPointer(4, // location 1 in the shader
+2 -2
View File
@@ -251,11 +251,11 @@ void* RPC_PLAY([[maybe_unused]] unsigned int fno, void* _cmd, int size) {
list_node.prio = iVar5;
pRVar2 = FindThisVagStream(cmd_iter->names[s].chars, cmd_iter->id[s]);
if ((pRVar2 == 0x0) || (pRVar2->byte4 == '\0')) {
printf(" didn't exist, looks like it needs to be added!\n");
// printf(" didn't exist, looks like it needs to be added!\n");
WaitSema(EEPlayList.sema);
iVar3 = (VagStrListNode*)FindVagStreamInList(&list_node, &EEPlayList);
if (iVar3 == (VagStrListNode*)0x0) {
printf("node also doesn't exist, adding it!\n");
// printf("node also doesn't exist, adding it!\n");
iVar4 = (VagStrListNode*)InsertVagStreamInList(&list_node, &EEPlayList);
iVar4->id = list_node.id;
+1 -1
View File
@@ -377,7 +377,7 @@ void TerminateVAG(VagCmd* cmd, int param_2) {
lfo_node.plugin_id = cmd->plugin_id;
RemoveLfoStreamFromList(&lfo_node, &LfoList);
}
printf("termina removing %s (2)\n", vag_node.name);
// printf("termina removing %s (2)\n", vag_node.name);
RemoveVagStreamFromList(&vag_node, &EEPlayList);
if (param_2 == 1) {