diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 4a5fc38c8a..ee77bf8582 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -44,7 +44,15 @@ using i16vec4_t = int16_t[4]; using u16vec4_t = uint16_t[4]; using i16vec2_t = int16_t[2]; using u16vec2_t = uint16_t[2]; -using f16vec4_t = int16_t[4]; // half float vector + +// The struct has the same memory layout as a half-float +struct f16_t +{ + uint16_t bits; +}; + +using f16vec2_t = f16_t[2]; // half float vector +using f16vec4_t = f16_t[4]; // half float vector // GL conversion helpers static inline float unorm8ToFloat(byte unorm8) { @@ -114,13 +122,13 @@ static inline void snorm16ToFloat( const i16vec4_t in, vec4_t out ) out[ 3 ] = snorm16ToFloat( in[ 3 ] ); } -static inline int16_t floatToHalf( float in ) { +static inline f16_t floatToHalf( float in ) { static float scale = powf(2.0f, 15 - 127); floatint_t fi; fi.f = in * scale; - return (int16_t)(((fi.ui & 0x80000000) >> 16) | ((fi.ui & 0x0fffe000) >> 13)); + return { uint16_t(((fi.ui & 0x80000000) >> 16) | ((fi.ui & 0x0fffe000) >> 13)) }; } static inline void floatToHalf( const vec4_t in, f16vec4_t out ) { @@ -129,11 +137,11 @@ static inline void floatToHalf( const vec4_t in, f16vec4_t out ) out[ 2 ] = floatToHalf( in[ 2 ] ); out[ 3 ] = floatToHalf( in[ 3 ] ); } -static inline float halfToFloat( int16_t in ) { +static inline float halfToFloat( f16_t in ) { static float scale = powf(2.0f, 127 - 15); floatint_t fi; - fi.ui = (((unsigned int)in & 0x8000) << 16) | (((unsigned int)in & 0x7fff) << 13); + fi.ui = (((unsigned int)in.bits & 0x8000) << 16) | (((unsigned int)in.bits & 0x7fff) << 13); return fi.f * scale; } static inline void halfToFloat( const f16vec4_t in, vec4_t out ) @@ -813,10 +821,10 @@ static inline void glFboSetExt() vec3_t *xyz; i16vec4_t *qtangent; u8vec4_t *color; - union { i16vec2_t *st; i16vec4_t *stpq; vec2_t *stf; }; + union { f16vec2_t *st; f16vec4_t *stpq; vec2_t *stf; }; int (*boneIndexes)[ 4 ]; vec4_t *boneWeights; - vec4_t *spriteOrientation; + f16vec4_t *spriteOrientation; int numFrames; int numVerts; @@ -2264,7 +2272,7 @@ static inline void glFboSetExt() vec4_t tangent; vec4_t binormal; vec4_t normal; - vec2_t texCoords; + vec2_t texCoordsF; uint32_t firstWeight; uint32_t numWeights; @@ -2394,10 +2402,10 @@ static inline void glFboSetExt() // vertex data float *positions; - int16_t *texcoords; float *normals; float *tangents; float *bitangents; + f16_t *texcoords; byte *blendIndexes; byte *blendWeights; byte *colors; @@ -3181,7 +3189,7 @@ inline bool checkGLErrors() void R_CalcTangents( vec3_t tangent, vec3_t binormal, const vec3_t v0, const vec3_t v1, const vec3_t v2, - const i16vec2_t t0, const i16vec2_t t1, const i16vec2_t t2 ); + const f16vec2_t t0, const f16vec2_t t1, const f16vec2_t t2 ); /* * QTangent representation of tangentspace: @@ -3398,7 +3406,7 @@ inline bool checkGLErrors() i16vec4_t qtangents; f16vec4_t spriteOrientation; }; - i16vec4_t texCoords; + f16vec4_t texCoords; }; #ifdef GL_ARB_sync diff --git a/src/engine/renderer/tr_main.cpp b/src/engine/renderer/tr_main.cpp index 6afcd5631e..8d466e1c9b 100644 --- a/src/engine/renderer/tr_main.cpp +++ b/src/engine/renderer/tr_main.cpp @@ -102,7 +102,7 @@ void R_CalcTangents( vec3_t tangent, vec3_t binormal, void R_CalcTangents( vec3_t tangent, vec3_t binormal, const vec3_t v0, const vec3_t v1, const vec3_t v2, - const i16vec2_t t0, const i16vec2_t t1, const i16vec2_t t2 ) + const f16vec2_t t0, const f16vec2_t t1, const f16vec2_t t2 ) { vec2_t t0f, t1f, t2f; diff --git a/src/engine/renderer/tr_model_iqm.cpp b/src/engine/renderer/tr_model_iqm.cpp index f2a461eb0c..b221dafcde 100644 --- a/src/engine/renderer/tr_model_iqm.cpp +++ b/src/engine/renderer/tr_model_iqm.cpp @@ -480,7 +480,7 @@ bool R_LoadIQModel( model_t *mod, void *buffer, int filesize, size += header->num_vertexes * 3 * sizeof(float); // normals size += header->num_vertexes * 3 * sizeof(float); // tangents size += header->num_vertexes * 3 * sizeof(float); // bitangents - size += header->num_vertexes * 2 * sizeof(int16_t); // texcoords + size += header->num_vertexes * 2 * sizeof(f16_t); // texcoords size += header->num_vertexes * 4 * sizeof(byte); // blendIndexes size += header->num_vertexes * 4 * sizeof(byte); // blendWeights size += header->num_vertexes * 4 * sizeof(byte); // colors @@ -540,7 +540,7 @@ bool R_LoadIQModel( model_t *mod, void *buffer, int filesize, IQModel->bitangents = (float *)ptr; ptr = IQModel->bitangents + 3 * header->num_vertexes; - IQModel->texcoords = (int16_t *)ptr; + IQModel->texcoords = (f16_t *)ptr; ptr = IQModel->texcoords + 2 * header->num_vertexes; IQModel->blendIndexes = (byte *)ptr; @@ -803,7 +803,7 @@ bool R_LoadIQModel( model_t *mod, void *buffer, int filesize, vboData.qtangent = qtangentbuf; vboData.numFrames = 0; vboData.color = (u8vec4_t *)IQModel->colors; - vboData.st = (i16vec2_t *)IQModel->texcoords; + vboData.st = (f16vec2_t *)IQModel->texcoords; vboData.noLightCoords = true; vboData.boneIndexes = (int (*)[4])indexbuf; vboData.boneWeights = (vec4_t *)weightbuf; diff --git a/src/engine/renderer/tr_model_md3.cpp b/src/engine/renderer/tr_model_md3.cpp index 56884b258b..c9dd4155f8 100644 --- a/src/engine/renderer/tr_model_md3.cpp +++ b/src/engine/renderer/tr_model_md3.cpp @@ -259,7 +259,7 @@ bool R_LoadMD3( model_t *mod, int lod, void *buffer, const char *modName ) data.xyz = ( vec3_t * ) ri.Hunk_AllocateTempMemory( sizeof( *data.xyz ) * mdvModel->numFrames * surf->numVerts ); data.qtangent = ( i16vec4_t * ) ri.Hunk_AllocateTempMemory( sizeof( i16vec4_t ) * mdvModel->numFrames * surf->numVerts ); data.numFrames = mdvModel->numFrames; - data.st = ( i16vec2_t * ) ri.Hunk_AllocateTempMemory( sizeof( i16vec2_t ) * surf->numVerts ); + data.st = ( f16vec2_t * ) ri.Hunk_AllocateTempMemory( sizeof( f16vec2_t ) * surf->numVerts ); data.noLightCoords = true; data.numVerts = surf->numVerts; diff --git a/src/engine/renderer/tr_model_md5.cpp b/src/engine/renderer/tr_model_md5.cpp index e59652fce2..bda5307585 100644 --- a/src/engine/renderer/tr_model_md5.cpp +++ b/src/engine/renderer/tr_model_md5.cpp @@ -325,7 +325,7 @@ bool R_LoadMD5( model_t *mod, void *buffer, const char *modName ) for (unsigned k = 0; k < 2; k++ ) { token = COM_ParseExt2( &buf_p, false ); - v->texCoords[ k ] = atof( token ); + v->texCoordsF[ k ] = atof( token ); } // skip ) @@ -518,9 +518,9 @@ bool R_LoadMD5( model_t *mod, void *buffer, const char *modName ) v1 = surf->verts[ tri->indexes[ 1 ] ].position; v2 = surf->verts[ tri->indexes[ 2 ] ].position; - t0 = surf->verts[ tri->indexes[ 0 ] ].texCoords; - t1 = surf->verts[ tri->indexes[ 1 ] ].texCoords; - t2 = surf->verts[ tri->indexes[ 2 ] ].texCoords; + t0 = surf->verts[ tri->indexes[ 0 ] ].texCoordsF; + t1 = surf->verts[ tri->indexes[ 1 ] ].texCoordsF; + t2 = surf->verts[ tri->indexes[ 2 ] ].texCoordsF; R_CalcFaceNormal( normal, v0, v1, v2 ); R_CalcTangents( tangent, binormal, v0, v1, v2, t0, t1, t2 ); diff --git a/src/engine/renderer/tr_model_skel.cpp b/src/engine/renderer/tr_model_skel.cpp index d1aa765470..beae801678 100644 --- a/src/engine/renderer/tr_model_skel.cpp +++ b/src/engine/renderer/tr_model_skel.cpp @@ -131,7 +131,7 @@ void AddSurfaceToVBOSurfacesList( growList_t *vboSurfaces, growList_t *vboTriang data.qtangent = ( i16vec4_t * ) ri.Hunk_AllocateTempMemory( sizeof( i16vec4_t ) * vertexesNum ); data.boneIndexes = ( int (*)[ 4 ] ) ri.Hunk_AllocateTempMemory( sizeof( *data.boneIndexes ) * vertexesNum ); data.boneWeights = ( vec4_t * ) ri.Hunk_AllocateTempMemory( sizeof( *data.boneWeights ) * vertexesNum ); - data.st = ( i16vec2_t * ) ri.Hunk_AllocateTempMemory( sizeof( i16vec2_t ) * vertexesNum ); + data.st = ( f16vec2_t * ) ri.Hunk_AllocateTempMemory( sizeof( f16vec2_t ) * vertexesNum ); data.noLightCoords = true; data.numVerts = vertexesNum; @@ -168,8 +168,8 @@ void AddSurfaceToVBOSurfacesList( growList_t *vboSurfaces, growList_t *vboTriang R_TBNtoQtangents( surf->verts[ j ].tangent, surf->verts[ j ].binormal, surf->verts[ j ].normal, data.qtangent[ j ] ); - data.st[ j ][ 0 ] = floatToHalf( surf->verts[ j ].texCoords[ 0 ] ); - data.st[ j ][ 1 ] = floatToHalf( surf->verts[ j ].texCoords[ 1 ] ); + data.st[ j ][ 0 ] = floatToHalf( surf->verts[ j ].texCoordsF[ 0 ] ); + data.st[ j ][ 1 ] = floatToHalf( surf->verts[ j ].texCoordsF[ 1 ] ); for (unsigned k = 0; k < MAX_WEIGHTS; k++ ) { diff --git a/src/engine/renderer/tr_shade_calc.cpp b/src/engine/renderer/tr_shade_calc.cpp index 8168489376..1ccc5959c1 100644 --- a/src/engine/renderer/tr_shade_calc.cpp +++ b/src/engine/renderer/tr_shade_calc.cpp @@ -543,7 +543,10 @@ static void AutospriteDeform( int firstVertex, int numVertexes, int numIndexes ) for ( j = 0; j < 4; j++ ) { VectorCopy( mid, v[ j ].xyz ); Vector4Set( v[ j ].spriteOrientation, - 0, 0, 0, floatToHalf( radius ) ); + floatToHalf( 0 ), + floatToHalf( 0 ), + floatToHalf( 0 ), + floatToHalf( radius ) ); } } } @@ -664,7 +667,8 @@ static void Autosprite2Deform( int firstVertex, int numVertexes, int numIndexes k = 1; VectorSubtract( v1->xyz, mid[ k ], minor ); - if ( ( DotProduct( cross, minor ) * v1->texCoords[ 3 ] ) < 0 ) { + // I guess this works, since the sign bit is the MSB for both floating point and integers + if ( ( DotProduct( cross, minor ) * static_cast(v1->texCoords[ 3 ].bits) ) < 0 ) { VectorNegate( major, orientation ); } else { VectorCopy( major, orientation ); diff --git a/src/engine/renderer/tr_surface.cpp b/src/engine/renderer/tr_surface.cpp index 81dba71140..21d10f70ba 100644 --- a/src/engine/renderer/tr_surface.cpp +++ b/src/engine/renderer/tr_surface.cpp @@ -1147,9 +1147,7 @@ static void Tess_SurfaceMD5( md5Surface_t *srf ) VectorCopy( position, tessVertex->xyz ); - Vector2Set( tessVertex->texCoords, - floatToHalf( surfaceVertex->texCoords[ 0 ] ), - floatToHalf( surfaceVertex->texCoords[ 1 ] ) ); + floatToHalf( surfaceVertex->texCoordsF, tessVertex->texCoords ); } } else @@ -1192,9 +1190,7 @@ static void Tess_SurfaceMD5( md5Surface_t *srf ) R_TBNtoQtangents( tangent, binormal, normal, tessVertex->qtangents ); - Vector2Set( tessVertex->texCoords, - floatToHalf( surfaceVertex->texCoords[ 0 ] ), - floatToHalf( surfaceVertex->texCoords[ 1 ] ) ); + floatToHalf( surfaceVertex->texCoordsF, tessVertex->texCoords ); } } @@ -1317,7 +1313,7 @@ void Tess_SurfaceIQM( srfIQModel_t *surf ) { float *modelNormal = model->normals + 3 * firstVertex; float *modelTangent = model->tangents + 3 * firstVertex; float *modelBitangent = model->bitangents + 3 * firstVertex; - int16_t *modelTexcoord = model->texcoords + 2 * firstVertex; + f16_t *modelTexcoord = model->texcoords + 2 * firstVertex; shaderVertex_t *tessVertex = tess.verts + tess.numVertexes; shaderVertex_t *lastVertex = tessVertex + surf->num_vertexes; diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index 1fafd6f2bd..b5c6c33b21 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -32,7 +32,7 @@ struct fmtVertexAnim1 { const GLsizei sizeVertexAnim1 = sizeof( struct fmtVertexAnim1 ); // interleaved texcoords and colour in part 2 struct fmtVertexAnim2 { - i16vec2_t texcoord; + f16vec2_t texcoord; Color::Color32Bit colour; }; const GLsizei sizeVertexAnim2 = sizeof( struct fmtVertexAnim2 ); @@ -40,7 +40,7 @@ const GLsizei sizeVertexAnim2 = sizeof( struct fmtVertexAnim2 ); // interleaved data: position, texcoord, colour, qtangent, bonefactors struct fmtSkeletal { i16vec4_t position; - i16vec2_t texcoord; + f16vec2_t texcoord; Color::Color32Bit colour; i16vec4_t qtangents; u16vec4_t boneFactors;