This is an automated email from the git hooks/post-receive script. smcv pushed a commit to annotated tag 1.5a in repository iortcw.
commit 5255f17a3a02bd825aabc9533de63c27eb409444 Author: MAN-AT-ARMS <m4n4t4...@gmail.com> Date: Sat Sep 10 10:10:03 2016 -0400 MP: Rend2: Store normals/tangents as int16_t[4] --- MP/code/rend2/tr_animation.c | 10 +- MP/code/rend2/tr_bsp.c | 208 +++++--------- MP/code/rend2/tr_curve.c | 6 +- MP/code/rend2/tr_extensions.c | 17 -- MP/code/rend2/tr_init.c | 2 - MP/code/rend2/tr_local.h | 36 +-- MP/code/rend2/tr_main.c | 360 ++---------------------- MP/code/rend2/tr_marks.c | 46 +++- MP/code/rend2/tr_model.c | 183 +++++++------ MP/code/rend2/tr_model_iqm.c | 15 +- MP/code/rend2/tr_shade_calc.c | 38 +-- MP/code/rend2/tr_surface.c | 620 ++++-------------------------------------- MP/code/rend2/tr_vbo.c | 147 +++------- 13 files changed, 367 insertions(+), 1321 deletions(-) diff --git a/MP/code/rend2/tr_animation.c b/MP/code/rend2/tr_animation.c index 5932f89..5e00202 100644 --- a/MP/code/rend2/tr_animation.c +++ b/MP/code/rend2/tr_animation.c @@ -68,7 +68,7 @@ static short *sh, *sh2; static float *pf; static vec3_t angles, tangles, torsoParentOffset, torsoAxis[3], tmpAxis[3]; static float *tempVert; -static uint32_t *tempNormal; +static int16_t *tempNormal; static vec3_t vec, v2, dir; static float diff, a1, a2; static int render_count; @@ -1166,7 +1166,7 @@ void RB_SurfaceAnim( mdsSurface_t *surface ) { numVerts = surface->numVerts; v = ( mdsVertex_t * )( (byte *)surface + surface->ofsVerts ); tempVert = ( float * )( tess.xyz + baseVertex ); - tempNormal = ( uint32_t * )( tess.normal + baseVertex ); + tempNormal = ( int16_t * )( tess.normal + baseVertex ); for ( j = 0; j < render_count; j++, tempVert += 4, tempNormal++ ) { mdsWeight_t *w; vec3_t newNormal; @@ -1181,7 +1181,7 @@ void RB_SurfaceAnim( mdsSurface_t *surface ) { LocalMatrixTransformVector( v->normal, bones[v->weights[0].boneIndex].matrix, newNormal ); - R_VaoPackNormal((byte *)tempNormal, newNormal); + R_VaoPackNormal(tempNormal, newNormal); tess.texCoords[baseVertex + j][0][0] = v->texCoords[0]; tess.texCoords[baseVertex + j][0][1] = v->texCoords[1]; @@ -1230,7 +1230,7 @@ void RB_SurfaceAnim( mdsSurface_t *surface ) { // show mesh edges tempVert = ( float * )( tess.xyz + baseVertex ); - tempNormal = ( uint32_t * )( tess.normal + baseVertex ); + tempNormal = ( int16_t * )( tess.normal + baseVertex ); GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); qglLineWidth( 1 ); @@ -1750,7 +1750,7 @@ void RB_MDRSurfaceAnim( mdrSurface_t *surface ) tess.xyz[baseVertex + j][1] = tempVert[1]; tess.xyz[baseVertex + j][2] = tempVert[2]; - R_VaoPackNormal((byte *)&tess.normal[baseVertex + j], tempNormal); + R_VaoPackNormal(tess.normal[baseVertex + j], tempNormal); tess.texCoords[baseVertex + j][0][0] = v->texCoords[0]; tess.texCoords[baseVertex + j][0][1] = v->texCoords[1]; diff --git a/MP/code/rend2/tr_bsp.c b/MP/code/rend2/tr_bsp.c index 2289bc2..3d1f0df 100644 --- a/MP/code/rend2/tr_bsp.c +++ b/MP/code/rend2/tr_bsp.c @@ -714,6 +714,66 @@ void *R_GetSurfMemory( int size ) { return (void *)retval; } +void LoadDrawVertToSrfVert(srfVert_t *s, drawVert_t *d, int realLightmapNum, float hdrVertColors[3], vec3_t *bounds) +{ + vec4_t v; + + s->xyz[0] = LittleFloat(d->xyz[0]); + s->xyz[1] = LittleFloat(d->xyz[1]); + s->xyz[2] = LittleFloat(d->xyz[2]); + + if (bounds) + AddPointToBounds(s->xyz, bounds[0], bounds[1]); + + s->st[0] = LittleFloat(d->st[0]); + s->st[1] = LittleFloat(d->st[1]); + + if (realLightmapNum >= 0) + { + s->lightmap[0] = FatPackU(LittleFloat(d->lightmap[0]), realLightmapNum); + s->lightmap[1] = FatPackV(LittleFloat(d->lightmap[1]), realLightmapNum); + } + else + { + s->lightmap[0] = LittleFloat(d->lightmap[0]); + s->lightmap[1] = LittleFloat(d->lightmap[1]); + } + + v[0] = LittleFloat(d->normal[0]); + v[1] = LittleFloat(d->normal[1]); + v[2] = LittleFloat(d->normal[2]); + + R_VaoPackNormal(s->normal, v); + + if (hdrVertColors) + { + v[0] = hdrVertColors[0]; + v[1] = hdrVertColors[1]; + v[2] = hdrVertColors[2]; + } + else + { + //hack: convert LDR vertex colors to HDR + if (r_hdr->integer) + { + v[0] = MAX(d->color[0], 0.499f); + v[1] = MAX(d->color[1], 0.499f); + v[2] = MAX(d->color[2], 0.499f); + } + else + { + v[0] = d->color[0]; + v[1] = d->color[1]; + v[2] = d->color[2]; + } + + } + v[3] = d->color[3] / 255.0f; + + R_ColorShiftLightingFloats(v, s->vertexColors, 1.0f / 255.0f); +} + + /* =============== ParseFace @@ -761,50 +821,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, ClearBounds(surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]); verts += LittleLong(ds->firstVert); for(i = 0; i < numVerts; i++) - { - vec4_t color; - - for(j = 0; j < 3; j++) - { - cv->verts[i].xyz[j] = LittleFloat(verts[i].xyz[j]); - cv->verts[i].normal[j] = LittleFloat(verts[i].normal[j]); - } - AddPointToBounds(cv->verts[i].xyz, surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]); - for(j = 0; j < 2; j++) - { - cv->verts[i].st[j] = LittleFloat(verts[i].st[j]); - //cv->verts[i].lightmap[j] = LittleFloat(verts[i].lightmap[j]); - } - cv->verts[i].lightmap[0] = FatPackU(LittleFloat(verts[i].lightmap[0]), realLightmapNum); - cv->verts[i].lightmap[1] = FatPackV(LittleFloat(verts[i].lightmap[1]), realLightmapNum); - - if (hdrVertColors) - { - color[0] = hdrVertColors[(ds->firstVert + i) * 3 ]; - color[1] = hdrVertColors[(ds->firstVert + i) * 3 + 1]; - color[2] = hdrVertColors[(ds->firstVert + i) * 3 + 2]; - } - else - { - //hack: convert LDR vertex colors to HDR - if (r_hdr->integer) - { - color[0] = MAX(verts[i].color[0], 0.499f); - color[1] = MAX(verts[i].color[1], 0.499f); - color[2] = MAX(verts[i].color[2], 0.499f); - } - else - { - color[0] = verts[i].color[0]; - color[1] = verts[i].color[1]; - color[2] = verts[i].color[2]; - } - - } - color[3] = verts[i].color[3] / 255.0f; - - R_ColorShiftLightingFloats( color, cv->verts[i].vertexColors, 1.0f / 255.0f ); - } + LoadDrawVertToSrfVert(&cv->verts[i], &verts[i], realLightmapNum, hdrVertColors ? hdrVertColors + (ds->firstVert + i) * 3 : NULL, surf->cullinfo.bounds); // copy triangles badTriangles = 0; @@ -870,7 +887,7 @@ ParseMesh */ static void ParseMesh ( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, msurface_t *surf ) { srfBspSurface_t *grid = (srfBspSurface_t *)surf->data; - int i, j; + int i; int width, height, numPoints; srfVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE]; vec3_t bounds[2]; @@ -905,49 +922,7 @@ static void ParseMesh ( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors, verts += LittleLong( ds->firstVert ); numPoints = width * height; for(i = 0; i < numPoints; i++) - { - vec4_t color; - - for(j = 0; j < 3; j++) - { - points[i].xyz[j] = LittleFloat(verts[i].xyz[j]); - points[i].normal[j] = LittleFloat(verts[i].normal[j]); - } - - for(j = 0; j < 2; j++) - { - points[i].st[j] = LittleFloat(verts[i].st[j]); - //points[i].lightmap[j] = LittleFloat(verts[i].lightmap[j]); - } - points[i].lightmap[0] = FatPackU(LittleFloat(verts[i].lightmap[0]), realLightmapNum); - points[i].lightmap[1] = FatPackV(LittleFloat(verts[i].lightmap[1]), realLightmapNum); - - if (hdrVertColors) - { - color[0] = hdrVertColors[(ds->firstVert + i) * 3 ]; - color[1] = hdrVertColors[(ds->firstVert + i) * 3 + 1]; - color[2] = hdrVertColors[(ds->firstVert + i) * 3 + 2]; - } - else - { - //hack: convert LDR vertex colors to HDR - if (r_hdr->integer) - { - color[0] = MAX(verts[i].color[0], 0.499f); - color[1] = MAX(verts[i].color[1], 0.499f); - color[2] = MAX(verts[i].color[2], 0.499f); - } - else - { - color[0] = verts[i].color[0]; - color[1] = verts[i].color[1]; - color[2] = verts[i].color[2]; - } - } - color[3] = verts[i].color[3] / 255.0f; - - R_ColorShiftLightingFloats( color, points[i].vertexColors, 1.0f / 255.0f ); - } + LoadDrawVertToSrfVert(&points[i], &verts[i], realLightmapNum, hdrVertColors ? hdrVertColors + (ds->firstVert + i) * 3 : NULL, NULL); // pre-tesseleate R_SubdividePatchToGrid( grid, width, height, points ); @@ -1011,49 +986,7 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColor ClearBounds(surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]); verts += LittleLong(ds->firstVert); for(i = 0; i < numVerts; i++) - { - vec4_t color; - - for(j = 0; j < 3; j++) - { - cv->verts[i].xyz[j] = LittleFloat(verts[i].xyz[j]); - cv->verts[i].normal[j] = LittleFloat(verts[i].normal[j]); - } - - AddPointToBounds( cv->verts[i].xyz, surf->cullinfo.bounds[0], surf->cullinfo.bounds[1] ); - - for(j = 0; j < 2; j++) - { - cv->verts[i].st[j] = LittleFloat(verts[i].st[j]); - cv->verts[i].lightmap[j] = LittleFloat(verts[i].lightmap[j]); - } - - if (hdrVertColors) - { - color[0] = hdrVertColors[(ds->firstVert + i) * 3 ]; - color[1] = hdrVertColors[(ds->firstVert + i) * 3 + 1]; - color[2] = hdrVertColors[(ds->firstVert + i) * 3 + 2]; - } - else - { - //hack: convert LDR vertex colors to HDR - if (r_hdr->integer) - { - color[0] = MAX(verts[i].color[0], 0.499f); - color[1] = MAX(verts[i].color[1], 0.499f); - color[2] = MAX(verts[i].color[2], 0.499f); - } - else - { - color[0] = verts[i].color[0]; - color[1] = verts[i].color[1]; - color[2] = verts[i].color[2]; - } - } - color[3] = verts[i].color[3] / 255.0f; - - R_ColorShiftLightingFloats( color, cv->verts[i].vertexColors, 1.0f / 255.0f ); - } + LoadDrawVertToSrfVert(&cv->verts[i], &verts[i], -1, hdrVertColors ? hdrVertColors + (ds->firstVert + i) * 3 : NULL, surf->cullinfo.bounds); // copy triangles badTriangles = 0; @@ -2081,8 +2014,8 @@ static void CopyVert(const srfVert_t * in, srfVert_t * out) #ifdef USE_VERT_TANGENT_SPACE VectorCopy4(in->tangent, out->tangent); #endif - VectorCopy(in->normal, out->normal); - VectorCopy(in->lightdir, out->lightdir); + VectorCopy4(in->normal, out->normal); + VectorCopy4(in->lightdir, out->lightdir); VectorCopy2(in->st, out->st); VectorCopy2(in->lightmap, out->lightmap); @@ -3545,7 +3478,14 @@ void R_CalcVertexLightDirs( void ) case SF_GRID: case SF_TRIANGLES: for(i = 0; i < bspSurf->numVerts; i++) - R_LightDirForPoint( bspSurf->verts[i].xyz, bspSurf->verts[i].lightdir, bspSurf->verts[i].normal, &s_worldData ); + { + vec3_t lightDir; + vec3_t normal; + + R_VaoUnpackNormal(normal, bspSurf->verts[i].normal); + R_LightDirForPoint( bspSurf->verts[i].xyz, lightDir, normal, &s_worldData ); + R_VaoPackNormal(bspSurf->verts[i].lightdir, lightDir); + } break; diff --git a/MP/code/rend2/tr_curve.c b/MP/code/rend2/tr_curve.c index 30547ce..bd7723d 100644 --- a/MP/code/rend2/tr_curve.c +++ b/MP/code/rend2/tr_curve.c @@ -214,7 +214,11 @@ static void MakeMeshNormals( int width, int height, srfVert_t ctrl[MAX_GRID_SIZE //if ( count == 0 ) { //printf("bad normal\n"); //} - VectorNormalize2( sum, dv->normal ); + { + vec3_t fNormal; + VectorNormalize2(sum, fNormal); + R_VaoPackNormal(dv->normal, fNormal); + } } } } diff --git a/MP/code/rend2/tr_extensions.c b/MP/code/rend2/tr_extensions.c index 602310b..6c0b8ca 100644 --- a/MP/code/rend2/tr_extensions.c +++ b/MP/code/rend2/tr_extensions.c @@ -295,23 +295,6 @@ void GLimp_InitExtraExtensions() ri.Printf(PRINT_ALL, result[2], extension); } - // GL_ARB_vertex_type_2_10_10_10_rev - extension = "GL_ARB_vertex_type_2_10_10_10_rev"; - glRefConfig.packedNormalDataType = GL_BYTE; - if( GLimp_HaveExtension( extension ) ) - { - qboolean useExt = !!r_arb_vertex_type_2_10_10_10_rev->integer; - - if (useExt) - glRefConfig.packedNormalDataType = GL_INT_2_10_10_10_REV; - - ri.Printf(PRINT_ALL, result[useExt], extension); - } - else - { - ri.Printf(PRINT_ALL, result[2], extension); - } - // use float lightmaps? glRefConfig.floatLightmap = (glRefConfig.textureFloat && glRefConfig.halfFloatPixel && r_floatLightmap->integer && r_hdr->integer); diff --git a/MP/code/rend2/tr_init.c b/MP/code/rend2/tr_init.c index fb8ac9f..0250ee7 100644 --- a/MP/code/rend2/tr_init.c +++ b/MP/code/rend2/tr_init.c @@ -125,7 +125,6 @@ cvar_t *r_arb_half_float_pixel; cvar_t *r_arb_half_float_vertex; cvar_t *r_ext_framebuffer_multisample; cvar_t *r_arb_seamless_cube_map; -cvar_t *r_arb_vertex_type_2_10_10_10_rev; cvar_t *r_arb_vertex_array_object; cvar_t *r_ext_direct_state_access; @@ -1293,7 +1292,6 @@ void R_Register( void ) { r_arb_half_float_vertex = ri.Cvar_Get( "r_arb_half_float_vertex", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_framebuffer_multisample = ri.Cvar_Get( "r_ext_framebuffer_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH); r_arb_seamless_cube_map = ri.Cvar_Get( "r_arb_seamless_cube_map", "0", CVAR_ARCHIVE | CVAR_LATCH); - r_arb_vertex_type_2_10_10_10_rev = ri.Cvar_Get( "r_arb_vertex_type_2_10_10_10_rev", "1", CVAR_ARCHIVE | CVAR_LATCH); r_arb_vertex_array_object = ri.Cvar_Get( "r_arb_vertex_array_object", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_direct_state_access = ri.Cvar_Get("r_ext_direct_state_access", "1", CVAR_ARCHIVE | CVAR_LATCH); diff --git a/MP/code/rend2/tr_local.h b/MP/code/rend2/tr_local.h index ee25e17..1ed5753 100644 --- a/MP/code/rend2/tr_local.h +++ b/MP/code/rend2/tr_local.h @@ -960,7 +960,6 @@ typedef enum { SF_TRIANGLES, SF_POLY, SF_MDV, - SF_MDC, SF_MDS, SF_MDR, SF_IQM, @@ -1008,11 +1007,11 @@ typedef struct vec3_t xyz; vec2_t st; vec2_t lightmap; - vec3_t normal; + int16_t normal[4]; #ifdef USE_VERT_TANGENT_SPACE - vec4_t tangent; + int16_t tangent[4]; #endif - vec3_t lightdir; + int16_t lightdir[4]; vec4_t vertexColors; #if DEBUG_OPTIMIZEVERTICES @@ -1021,9 +1020,9 @@ typedef struct } srfVert_t; #ifdef USE_VERT_TANGENT_SPACE -#define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0}, {0, 0, 0, 0}} +#define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}} #else -#define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0, 0}} +#define srfVert_t_cleared(x) srfVert_t (x) = {{0, 0, 0}, {0, 0}, {0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}} #endif // srfBspSurface_t covers SF_GRID, SF_TRIANGLES, SF_POLY, and SF_VAO_MESH @@ -1312,10 +1311,9 @@ typedef struct typedef struct { vec3_t xyz; - vec3_t normal; + int16_t normal[4]; #ifdef USE_VERT_TANGENT_SPACE - vec3_t tangent; - vec3_t bitangent; + int16_t tangent[4]; #endif } mdvVertex_t; @@ -1543,7 +1541,6 @@ typedef struct { qboolean depthClamp; qboolean seamlessCubeMap; - GLenum packedNormalDataType; GLenum packedTexcoordDataType; GLenum packedColorDataType; int packedTexcoordDataSize; @@ -1898,7 +1895,6 @@ extern cvar_t *r_arb_half_float_pixel; extern cvar_t *r_arb_half_float_vertex; extern cvar_t *r_ext_framebuffer_multisample; extern cvar_t *r_arb_seamless_cube_map; -extern cvar_t *r_arb_vertex_type_2_10_10_10_rev; extern cvar_t *r_arb_vertex_array_object; extern cvar_t *r_ext_direct_state_access; @@ -2074,7 +2070,7 @@ void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, void R_CalcTexDirs(vec3_t sdir, vec3_t tdir, const vec3_t v1, const vec3_t v2, const vec3_t v3, const vec2_t w1, const vec2_t w2, const vec2_t w3); -void R_CalcTbnFromNormalAndTexDirs(vec3_t tangent, vec3_t bitangent, vec3_t normal, vec3_t sdir, vec3_t tdir); +vec_t R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, const vec3_t normal, const vec3_t sdir, const vec3_t tdir); qboolean R_CalcTangentVectors(srfVert_t * dv[3]); #define CULL_IN 0 // completely unclipped @@ -2246,13 +2242,13 @@ typedef struct shaderCommands_s { glIndex_t indexes[SHADER_MAX_INDEXES] QALIGN(16); vec4_t xyz[SHADER_MAX_VERTEXES] QALIGN(16); - uint32_t normal[SHADER_MAX_VERTEXES] QALIGN(16); + int16_t normal[SHADER_MAX_VERTEXES][4] QALIGN(16); #ifdef USE_VERT_TANGENT_SPACE - uint32_t tangent[SHADER_MAX_VERTEXES] QALIGN(16); + int16_t tangent[SHADER_MAX_VERTEXES][4] QALIGN(16); #endif vec2_t texCoords[SHADER_MAX_VERTEXES][2] QALIGN(16); vec4_t vertexColors[SHADER_MAX_VERTEXES] QALIGN(16); - uint32_t lightdir[SHADER_MAX_VERTEXES] QALIGN(16); + int16_t lightdir[SHADER_MAX_VERTEXES][4] QALIGN(16); //int vertexDlightBits[SHADER_MAX_VERTEXES] QALIGN(16); void *attribPointers[ATTR_INDEX_COUNT]; @@ -2416,12 +2412,12 @@ VERTEX BUFFER OBJECTS ============================================================ */ -int R_VaoPackTangent(byte *out, vec4_t v); -int R_VaoPackNormal(byte *out, vec3_t v); +void R_VaoPackTangent(int16_t *out, vec4_t v); +void R_VaoPackNormal(int16_t *out, vec3_t v); int R_VaoPackTexCoord(byte *out, vec2_t st); int R_VaoPackColors(byte *out, vec4_t color); -void R_VaoUnpackTangent(vec4_t v, uint32_t b); -void R_VaoUnpackNormal(vec3_t v, uint32_t b); +void R_VaoUnpackTangent(vec4_t v, int16_t *pack); +void R_VaoUnpackNormal(vec3_t v, int16_t *pack); vao_t *R_CreateVao(const char *name, byte *vertexes, int vertexesSize, byte *indexes, int indexesSize, vaoUsage_t usage); vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int numIndexes, glIndex_t *inIndexes); @@ -2797,8 +2793,6 @@ void R_AddMDCSurfaces( trRefEntity_t *ent ); // done. //------------------------------------------------------------------------------ -void R_LatLongToNormal( vec3_t outNormal, short latLong ); - /* ============================================================ diff --git a/MP/code/rend2/tr_main.c b/MP/code/rend2/tr_main.c index edb2453..a304455 100644 --- a/MP/code/rend2/tr_main.c +++ b/MP/code/rend2/tr_main.c @@ -161,232 +161,14 @@ qboolean R_CompareVert(srfVert_t * v1, srfVert_t * v2, qboolean checkST) return qtrue; } -/* -============= -R_CalcNormalForTriangle -============= -*/ -void R_CalcNormalForTriangle(vec3_t normal, const vec3_t v0, const vec3_t v1, const vec3_t v2) -{ - vec3_t udir, vdir; - - // compute the face normal based on vertex points - VectorSubtract(v2, v0, udir); - VectorSubtract(v1, v0, vdir); - CrossProduct(udir, vdir, normal); - - VectorNormalize(normal); -} /* ============= -R_CalcTangentsForTriangle -http://members.rogers.com/deseric/tangentspace.htm -============= -*/ -void R_CalcTangentsForTriangle(vec3_t tangent, vec3_t bitangent, - const vec3_t v0, const vec3_t v1, const vec3_t v2, - const vec2_t t0, const vec2_t t1, const vec2_t t2) -{ - int i; - vec3_t planes[3]; - vec3_t u, v; - - for(i = 0; i < 3; i++) - { - VectorSet(u, v1[i] - v0[i], t1[0] - t0[0], t1[1] - t0[1]); - VectorSet(v, v2[i] - v0[i], t2[0] - t0[0], t2[1] - t0[1]); - - VectorNormalize(u); - VectorNormalize(v); - - CrossProduct(u, v, planes[i]); - } +R_CalcTexDirs - //So your tangent space will be defined by this : - //Normal = Normal of the triangle or Tangent X Bitangent (careful with the cross product, - // you have to make sure the normal points in the right direction) - //Tangent = ( dp(Fx(s,t)) / ds, dp(Fy(s,t)) / ds, dp(Fz(s,t)) / ds ) or ( -Bx/Ax, -By/Ay, - Bz/Az ) - //Bitangent = ( dp(Fx(s,t)) / dt, dp(Fy(s,t)) / dt, dp(Fz(s,t)) / dt ) or ( -Cx/Ax, -Cy/Ay, -Cz/Az ) - - // tangent... - tangent[0] = -planes[0][1] / planes[0][0]; - tangent[1] = -planes[1][1] / planes[1][0]; - tangent[2] = -planes[2][1] / planes[2][0]; - VectorNormalize(tangent); - - // bitangent... - bitangent[0] = -planes[0][2] / planes[0][0]; - bitangent[1] = -planes[1][2] / planes[1][0]; - bitangent[2] = -planes[2][2] / planes[2][0]; - VectorNormalize(bitangent); -} - - - - -/* -============= -R_CalcTangentSpace +Lengyel, Eric. Computing Tangent Space Basis Vectors for an Arbitrary Mesh. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html ============= */ -void R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, vec3_t normal, - const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2) -{ - vec3_t cp, u, v; - vec3_t faceNormal; - - VectorSet(u, v1[0] - v0[0], t1[0] - t0[0], t1[1] - t0[1]); - VectorSet(v, v2[0] - v0[0], t2[0] - t0[0], t2[1] - t0[1]); - - CrossProduct(u, v, cp); - if(fabs(cp[0]) > 10e-6) - { - tangent[0] = -cp[1] / cp[0]; - bitangent[0] = -cp[2] / cp[0]; - } - - u[0] = v1[1] - v0[1]; - v[0] = v2[1] - v0[1]; - - CrossProduct(u, v, cp); - if(fabs(cp[0]) > 10e-6) - { - tangent[1] = -cp[1] / cp[0]; - bitangent[1] = -cp[2] / cp[0]; - } - - u[0] = v1[2] - v0[2]; - v[0] = v2[2] - v0[2]; - - CrossProduct(u, v, cp); - if(fabs(cp[0]) > 10e-6) - { - tangent[2] = -cp[1] / cp[0]; - bitangent[2] = -cp[2] / cp[0]; - } - - VectorNormalize(tangent); - VectorNormalize(bitangent); - - // compute the face normal based on vertex points - if ( normal[0] == 0.0f && normal[1] == 0.0f && normal[2] == 0.0f ) - { - VectorSubtract(v2, v0, u); - VectorSubtract(v1, v0, v); - CrossProduct(u, v, faceNormal); - } - else - { - VectorCopy(normal, faceNormal); - } - - VectorNormalize(faceNormal); - -#if 1 - // Gram-Schmidt orthogonalize - //tangent[a] = (t - n * Dot(n, t)).Normalize(); - VectorMA(tangent, -DotProduct(faceNormal, tangent), faceNormal, tangent); - VectorNormalize(tangent); - - // compute the cross product B=NxT - //CrossProduct(normal, tangent, bitangent); -#else - // normal, compute the cross product N=TxB - CrossProduct(tangent, bitangent, normal); - VectorNormalize(normal); - - if(DotProduct(normal, faceNormal) < 0) - { - //VectorInverse(normal); - //VectorInverse(tangent); - //VectorInverse(bitangent); - - // compute the cross product T=BxN - CrossProduct(bitangent, faceNormal, tangent); - - // compute the cross product B=NxT - //CrossProduct(normal, tangent, bitangent); - } -#endif - - VectorCopy(faceNormal, normal); -} - -void R_CalcTangentSpaceFast(vec3_t tangent, vec3_t bitangent, vec3_t normal, - const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2) -{ - vec3_t cp, u, v; - vec3_t faceNormal; - - VectorSet(u, v1[0] - v0[0], t1[0] - t0[0], t1[1] - t0[1]); - VectorSet(v, v2[0] - v0[0], t2[0] - t0[0], t2[1] - t0[1]); - - CrossProduct(u, v, cp); - if(fabs(cp[0]) > 10e-6) - { - tangent[0] = -cp[1] / cp[0]; - bitangent[0] = -cp[2] / cp[0]; - } - - u[0] = v1[1] - v0[1]; - v[0] = v2[1] - v0[1]; - - CrossProduct(u, v, cp); - if(fabs(cp[0]) > 10e-6) - { - tangent[1] = -cp[1] / cp[0]; - bitangent[1] = -cp[2] / cp[0]; - } - - u[0] = v1[2] - v0[2]; - v[0] = v2[2] - v0[2]; - - CrossProduct(u, v, cp); - if(fabs(cp[0]) > 10e-6) - { - tangent[2] = -cp[1] / cp[0]; - bitangent[2] = -cp[2] / cp[0]; - } - - VectorNormalizeFast(tangent); - VectorNormalizeFast(bitangent); - - // compute the face normal based on vertex points - VectorSubtract(v2, v0, u); - VectorSubtract(v1, v0, v); - CrossProduct(u, v, faceNormal); - - VectorNormalizeFast(faceNormal); - -#if 0 - // normal, compute the cross product N=TxB - CrossProduct(tangent, bitangent, normal); - VectorNormalizeFast(normal); - - if(DotProduct(normal, faceNormal) < 0) - { - VectorInverse(normal); - //VectorInverse(tangent); - //VectorInverse(bitangent); - - CrossProduct(normal, tangent, bitangent); - } - - VectorCopy(faceNormal, normal); -#else - // Gram-Schmidt orthogonalize - //tangent[a] = (t - n * Dot(n, t)).Normalize(); - VectorMA(tangent, -DotProduct(faceNormal, tangent), faceNormal, tangent); - VectorNormalizeFast(tangent); -#endif - - VectorCopy(faceNormal, normal); -} - -/* -http://www.terathon.com/code/tangent.html -*/ void R_CalcTexDirs(vec3_t sdir, vec3_t tdir, const vec3_t v1, const vec3_t v2, const vec3_t v3, const vec2_t w1, const vec2_t w2, const vec2_t w3) { @@ -405,14 +187,21 @@ void R_CalcTexDirs(vec3_t sdir, vec3_t tdir, const vec3_t v1, const vec3_t v2, t1 = w2[1] - w1[1]; t2 = w3[1] - w1[1]; - r = 1.0f / (s1 * t2 - s2 * t1); + r = s1 * t2 - s2 * t1; + if (r) r = 1.0f / r; VectorSet(sdir, (t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); VectorSet(tdir, (s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); } +/* +============= +R_CalcTangentSpace -void R_CalcTbnFromNormalAndTexDirs(vec3_t tangent, vec3_t bitangent, vec3_t normal, vec3_t sdir, vec3_t tdir) +Lengyel, Eric. Computing Tangent Space Basis Vectors for an Arbitrary Mesh. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html +============= +*/ +vec_t R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, const vec3_t normal, const vec3_t sdir, const vec3_t tdir) { vec3_t n_cross_t; vec_t n_dot_t, handedness; @@ -426,110 +215,11 @@ void R_CalcTbnFromNormalAndTexDirs(vec3_t tangent, vec3_t bitangent, vec3_t norm CrossProduct(normal, sdir, n_cross_t); handedness = (DotProduct(n_cross_t, tdir) < 0.0f) ? -1.0f : 1.0f; - // Calculate bitangent - CrossProduct(normal, tangent, bitangent); - VectorScale(bitangent, handedness, bitangent); -} - -void R_CalcTBN2(vec3_t tangent, vec3_t bitangent, vec3_t normal, - const vec3_t v1, const vec3_t v2, const vec3_t v3, const vec2_t t1, const vec2_t t2, const vec2_t t3) -{ - vec3_t v2v1; - vec3_t v3v1; - - float c2c1_T; - float c2c1_B; - - float c3c1_T; - float c3c1_B; - - float denominator; - float scale1, scale2; - - vec3_t T, B, N, C; - - - // Calculate the tangent basis for each vertex of the triangle - // UPDATE: In the 3rd edition of the accompanying article, the for-loop located here has - // been removed as it was redundant (the entire TBN matrix was calculated three times - // instead of just one). - // - // Please note, that this function relies on the fact that the input geometry are triangles - // and the tangent basis for each vertex thus is identical! - // - - // Calculate the vectors from the current vertex to the two other vertices in the triangle - VectorSubtract(v2, v1, v2v1); - VectorSubtract(v3, v1, v3v1); - - // The equation presented in the article states that: - // c2c1_T = V2.texcoord.x - V1.texcoord.x - // c2c1_B = V2.texcoord.y - V1.texcoord.y - // c3c1_T = V3.texcoord.x - V1.texcoord.x - // c3c1_B = V3.texcoord.y - V1.texcoord.y - - // Calculate c2c1_T and c2c1_B - c2c1_T = t2[0] - t1[0]; - c2c1_B = t2[1] - t2[1]; - - // Calculate c3c1_T and c3c1_B - c3c1_T = t3[0] - t1[0]; - c3c1_B = t3[1] - t1[1]; - - denominator = c2c1_T * c3c1_B - c3c1_T * c2c1_B; - //if(ROUNDOFF(fDenominator) == 0.0f) - if(denominator == 0.0f) - { - // We won't risk a divide by zero, so set the tangent matrix to the identity matrix - VectorSet(tangent, 1, 0, 0); - VectorSet(bitangent, 0, 1, 0); - VectorSet(normal, 0, 0, 1); - } - else - { - // Calculate the reciprocal value once and for all (to achieve speed) - scale1 = 1.0f / denominator; - - // T and B are calculated just as the equation in the article states - VectorSet(T, (c3c1_B * v2v1[0] - c2c1_B * v3v1[0]) * scale1, - (c3c1_B * v2v1[1] - c2c1_B * v3v1[1]) * scale1, - (c3c1_B * v2v1[2] - c2c1_B * v3v1[2]) * scale1); - - VectorSet(B, (-c3c1_T * v2v1[0] + c2c1_T * v3v1[0]) * scale1, - (-c3c1_T * v2v1[1] + c2c1_T * v3v1[1]) * scale1, - (-c3c1_T * v2v1[2] + c2c1_T * v3v1[2]) * scale1); - - // The normal N is calculated as the cross product between T and B - CrossProduct(T, B, N); - -#if 0 - VectorCopy(T, tangent); - VectorCopy(B, bitangent); - VectorCopy(N, normal); -#else - // Calculate the reciprocal value once and for all (to achieve speed) - scale2 = 1.0f / ((T[0] * B[1] * N[2] - T[2] * B[1] * N[0]) + - (B[0] * N[1] * T[2] - B[2] * N[1] * T[0]) + - (N[0] * T[1] * B[2] - N[2] * T[1] * B[0])); - - // Calculate the inverse if the TBN matrix using the formula described in the article. - // We store the basis vectors directly in the provided TBN matrix: pvTBNMatrix - CrossProduct(B, N, C); tangent[0] = C[0] * scale2; - CrossProduct(N, T, C); tangent[1] = -C[0] * scale2; - CrossProduct(T, B, C); tangent[2] = C[0] * scale2; - VectorNormalize(tangent); - - CrossProduct(B, N, C); bitangent[0] = -C[1] * scale2; - CrossProduct(N, T, C); bitangent[1] = C[1] * scale2; - CrossProduct(T, B, C); bitangent[2] = -C[1] * scale2; - VectorNormalize(bitangent); + // Calculate orthogonal bitangent, if necessary + if (bitangent) + CrossProduct(normal, tangent, bitangent); - CrossProduct(B, N, C); normal[0] = C[2] * scale2; - CrossProduct(N, T, C); normal[1] = -C[2] * scale2; - CrossProduct(T, B, C); normal[2] = C[2] * scale2; - VectorNormalize(normal); -#endif - } + return handedness; } @@ -549,7 +239,8 @@ qboolean R_CalcTangentVectors(srfVert_t * dv[3]) /* do each vertex */ for(i = 0; i < 3; i++) { - vec3_t bitangent, nxt; + vec4_t tangent; + vec3_t normal, bitangent, nxt; // calculate s tangent vector s = dv[i]->st[0] + 10.0f; @@ -558,12 +249,12 @@ qboolean R_CalcTangentVectors(srfVert_t * dv[3]) bary[1] = ((dv[2]->st[0] - s) * (dv[0]->st[1] - t) - (dv[0]->st[0] - s) * (dv[2]->st[1] - t)) / bb; bary[2] = ((dv[0]->st[0] - s) * (dv[1]->st[1] - t) - (dv[1]->st[0] - s) * (dv[0]->st[1] - t)) / bb; - dv[i]->tangent[0] = bary[0] * dv[0]->xyz[0] + bary[1] * dv[1]->xyz[0] + bary[2] * dv[2]->xyz[0]; - dv[i]->tangent[1] = bary[0] * dv[0]->xyz[1] + bary[1] * dv[1]->xyz[1] + bary[2] * dv[2]->xyz[1]; - dv[i]->tangent[2] = bary[0] * dv[0]->xyz[2] + bary[1] * dv[1]->xyz[2] + bary[2] * dv[2]->xyz[2]; + tangent[0] = bary[0] * dv[0]->xyz[0] + bary[1] * dv[1]->xyz[0] + bary[2] * dv[2]->xyz[0]; + tangent[1] = bary[0] * dv[0]->xyz[1] + bary[1] * dv[1]->xyz[1] + bary[2] * dv[2]->xyz[1]; + tangent[2] = bary[0] * dv[0]->xyz[2] + bary[1] * dv[1]->xyz[2] + bary[2] * dv[2]->xyz[2]; - VectorSubtract(dv[i]->tangent, dv[i]->xyz, dv[i]->tangent); - VectorNormalize(dv[i]->tangent); + VectorSubtract(tangent, dv[i]->xyz, tangent); + VectorNormalize(tangent); // calculate t tangent vector s = dv[i]->st[0]; @@ -580,8 +271,11 @@ qboolean R_CalcTangentVectors(srfVert_t * dv[3]) VectorNormalize(bitangent); // store bitangent handedness - CrossProduct(dv[i]->normal, dv[i]->tangent, nxt); - dv[i]->tangent[3] = (DotProduct(nxt, bitangent) < 0.0f) ? -1.0f : 1.0f; + R_VaoUnpackNormal(normal, dv[i]->normal); + CrossProduct(normal, tangent, nxt); + tangent[3] = (DotProduct(nxt, bitangent) < 0.0f) ? -1.0f : 1.0f; + + R_VaoPackTangent(dv[i]->tangent, tangent); // debug code //% Sys_FPrintf( SYS_VRB, "%d S: (%f %f %f) T: (%f %f %f)\n", i, diff --git a/MP/code/rend2/tr_marks.c b/MP/code/rend2/tr_marks.c index 111d429..2cdece7 100644 --- a/MP/code/rend2/tr_marks.c +++ b/MP/code/rend2/tr_marks.c @@ -373,17 +373,21 @@ int R_OldMarkFragments( int numPoints, const vec3_t *points, const vec3_t projec // The offset is added in the vertex normal vector direction // so all triangles will still fit together. // The 2 unit offset should avoid pretty much all LOD problems. + vec3_t fNormal; numClipPoints = 3; dv = cv->verts + m * cv->width + n; VectorCopy( dv[0].xyz, clipPoints[0][0] ); - VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[0].normal, clipPoints[0][0] ); + R_VaoUnpackNormal(fNormal, dv[0].normal); + VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]); VectorCopy( dv[cv->width].xyz, clipPoints[0][1] ); - VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] ); + R_VaoUnpackNormal(fNormal, dv[cv->width].normal); + VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]); VectorCopy( dv[1].xyz, clipPoints[0][2] ); - VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[1].normal, clipPoints[0][2] ); + R_VaoUnpackNormal(fNormal, dv[1].normal); + VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]); // check the normal of this triangle VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 ); VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 ); @@ -403,11 +407,14 @@ int R_OldMarkFragments( int numPoints, const vec3_t *points, const vec3_t projec } VectorCopy( dv[1].xyz, clipPoints[0][0] ); - VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[1].normal, clipPoints[0][0] ); + R_VaoUnpackNormal(fNormal, dv[1].normal); + VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]); VectorCopy( dv[cv->width].xyz, clipPoints[0][1] ); - VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] ); + R_VaoUnpackNormal(fNormal, dv[cv->width].normal); + VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]); VectorCopy( dv[cv->width + 1].xyz, clipPoints[0][2] ); - VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[cv->width + 1].normal, clipPoints[0][2] ); + R_VaoUnpackNormal(fNormal, dv[cv->width + 1].normal); + VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]); // check the normal of this triangle VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 ); VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 ); @@ -463,8 +470,10 @@ int R_OldMarkFragments( int numPoints, const vec3_t *points, const vec3_t projec { for(j = 0; j < 3; j++) { + vec3_t fNormal; v = surf->verts[tri[j]].xyz; - VectorMA(v, MARKER_OFFSET, surf->verts[tri[j]].normal, clipPoints[0][j]); + R_VaoUnpackNormal(fNormal, surf->verts[tri[j]].normal); + VectorMA(v, MARKER_OFFSET, fNormal, clipPoints[0][j]); } // add the fragments of this face @@ -633,17 +642,21 @@ Com_Printf("bestnormal: %1.1f %1.1f %1.1f \n", bestnormal[0], bestnormal[1], bes // The offset is added in the vertex normal vector direction // so all triangles will still fit together. // The 2 unit offset should avoid pretty much all LOD problems. + vec3_t fNormal; numClipPoints = 3; dv = cv->verts + m * cv->width + n; VectorCopy( dv[0].xyz, clipPoints[0][0] ); - VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[0].normal, clipPoints[0][0] ); + R_VaoUnpackNormal(fNormal, dv[0].normal); + VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]); VectorCopy( dv[cv->width].xyz, clipPoints[0][1] ); - VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] ); + R_VaoUnpackNormal(fNormal, dv[cv->width].normal); + VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]); VectorCopy( dv[1].xyz, clipPoints[0][2] ); - VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[1].normal, clipPoints[0][2] ); + R_VaoUnpackNormal(fNormal, dv[1].normal); + VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]); // check the normal of this triangle VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 ); VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 ); @@ -663,11 +676,14 @@ Com_Printf("bestnormal: %1.1f %1.1f %1.1f \n", bestnormal[0], bestnormal[1], bes } VectorCopy( dv[1].xyz, clipPoints[0][0] ); - VectorMA( clipPoints[0][0], MARKER_OFFSET, dv[1].normal, clipPoints[0][0] ); + R_VaoUnpackNormal(fNormal, dv[1].normal); + VectorMA(clipPoints[0][0], MARKER_OFFSET, fNormal, clipPoints[0][0]); VectorCopy( dv[cv->width].xyz, clipPoints[0][1] ); - VectorMA( clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1] ); + R_VaoUnpackNormal(fNormal, dv[cv->width].normal); + VectorMA(clipPoints[0][1], MARKER_OFFSET, fNormal, clipPoints[0][1]); VectorCopy( dv[cv->width + 1].xyz, clipPoints[0][2] ); - VectorMA( clipPoints[0][2], MARKER_OFFSET, dv[cv->width + 1].normal, clipPoints[0][2] ); + R_VaoUnpackNormal(fNormal, dv[cv->width + 1].normal); + VectorMA(clipPoints[0][2], MARKER_OFFSET, fNormal, clipPoints[0][2]); // check the normal of this triangle VectorSubtract( clipPoints[0][0], clipPoints[0][1], v1 ); VectorSubtract( clipPoints[0][2], clipPoints[0][1], v2 ); @@ -831,8 +847,10 @@ Com_Printf("bestnormal: %1.1f %1.1f %1.1f \n", bestnormal[0], bestnormal[1], bes { for(j = 0; j < 3; j++) { + vec3_t fNormal; v = surf->verts[tri[j]].xyz; - VectorMA(v, MARKER_OFFSET, surf->verts[tri[j]].normal, clipPoints[0][j]); + R_VaoUnpackNormal(fNormal, surf->verts[tri[j]].normal); + VectorMA(v, MARKER_OFFSET, fNormal, clipPoints[0][j]); } // add the fragments of this face diff --git a/MP/code/rend2/tr_model.c b/MP/code/rend2/tr_model.c index 876a487..179ff89 100644 --- a/MP/code/rend2/tr_model.c +++ b/MP/code/rend2/tr_model.c @@ -822,6 +822,7 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void *buffer, const char *modN { unsigned lat, lng; unsigned short normal; + vec3_t fNormal; v->xyz[0] = md3xyz->xyz[0] * MD3_XYZ_SCALE; v->xyz[1] = md3xyz->xyz[1] * MD3_XYZ_SCALE; @@ -834,9 +835,15 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void *buffer, const char *modN lat *= (FUNCTABLE_SIZE/256); lng *= (FUNCTABLE_SIZE/256); - v->normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; - v->normal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - v->normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; + // decode X as cos( lat ) * sin( long ) + // decode Y as sin( lat ) * sin( long ) + // decode Z as cos( long ) + + fNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; + fNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; + fNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; + + R_VaoPackNormal(v->normal, fNormal); } } @@ -865,10 +872,13 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void *buffer, const char *modN #ifdef USE_VERT_TANGENT_SPACE // calc tangent spaces { + vec3_t *sdirs = ri.Z_Malloc(sizeof(*sdirs) * surf->numVerts * mdvModel->numFrames); + vec3_t *tdirs = ri.Z_Malloc(sizeof(*tdirs) * surf->numVerts * mdvModel->numFrames); + for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++) { - VectorClear(v->tangent); - VectorClear(v->bitangent); + VectorClear(sdirs[j]); + VectorClear(tdirs[j]); } for(f = 0; f < mdvModel->numFrames; f++) @@ -893,27 +903,32 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void *buffer, const char *modN R_CalcTexDirs(sdir, tdir, v0, v1, v2, t0, t1, t2); - VectorAdd(sdir, surf->verts[index0].tangent, surf->verts[index0].tangent); - VectorAdd(sdir, surf->verts[index1].tangent, surf->verts[index1].tangent); - VectorAdd(sdir, surf->verts[index2].tangent, surf->verts[index2].tangent); - VectorAdd(tdir, surf->verts[index0].bitangent, surf->verts[index0].bitangent); - VectorAdd(tdir, surf->verts[index1].bitangent, surf->verts[index1].bitangent); - VectorAdd(tdir, surf->verts[index2].bitangent, surf->verts[index2].bitangent); + VectorAdd(sdir, sdirs[index0], sdirs[index0]); + VectorAdd(sdir, sdirs[index1], sdirs[index1]); + VectorAdd(sdir, sdirs[index2], sdirs[index2]); + VectorAdd(tdir, tdirs[index0], tdirs[index0]); + VectorAdd(tdir, tdirs[index1], tdirs[index1]); + VectorAdd(tdir, tdirs[index2], tdirs[index2]); } } for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++) { - vec3_t sdir, tdir; + vec3_t normal; + vec4_t tangent; - VectorCopy(v->tangent, sdir); - VectorCopy(v->bitangent, tdir); + VectorNormalize(sdirs[j]); + VectorNormalize(tdirs[j]); - VectorNormalize(sdir); - VectorNormalize(tdir); + R_VaoUnpackNormal(normal, v->normal); - R_CalcTbnFromNormalAndTexDirs(v->tangent, v->bitangent, v->normal, sdir, tdir); + tangent[3] = R_CalcTangentSpace(tangent, NULL, normal, sdirs[j], tdirs[j]); + + R_VaoPackTangent(v->tangent, tangent); } + + ri.Free(sdirs); + ri.Free(tdirs); } #endif @@ -943,11 +958,11 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void *buffer, const char *modN offset_st = 0; offset_xyz = surf->numVerts * glRefConfig.packedTexcoordDataSize; offset_normal = offset_xyz + sizeof(vec3_t); - offset_tangent = offset_normal + sizeof(uint32_t); + offset_tangent = offset_normal + sizeof(int16_t) * 4; stride_st = glRefConfig.packedTexcoordDataSize; - stride_xyz = sizeof(vec3_t) + sizeof(uint32_t); + stride_xyz = sizeof(vec3_t) + sizeof(int16_t) * 4; #ifdef USE_VERT_TANGENT_SPACE - stride_xyz += sizeof(uint32_t); + stride_xyz += sizeof(int16_t) * 4; #endif stride_normal = stride_tangent = stride_xyz; @@ -959,11 +974,11 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void *buffer, const char *modN offset_xyz = 0; offset_st = offset_xyz + sizeof(vec3_t); offset_normal = offset_st + glRefConfig.packedTexcoordDataSize; - offset_tangent = offset_normal + sizeof(uint32_t); + offset_tangent = offset_normal + sizeof(int16_t) * 4; #ifdef USE_VERT_TANGENT_SPACE - stride_xyz = offset_tangent + sizeof(uint32_t); + stride_xyz = offset_tangent + sizeof(int16_t) * 4; #else - stride_xyz = offset_normal + sizeof(uint32_t); + stride_xyz = offset_normal + sizeof(int16_t) * 4; #endif stride_st = stride_normal = stride_tangent = stride_xyz; @@ -984,24 +999,19 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void *buffer, const char *modN v = surf->verts; for ( j = 0; j < surf->numVerts * mdvModel->numFrames ; j++, v++ ) { -#ifdef USE_VERT_TANGENT_SPACE - vec3_t nxt; - vec4_t tangent; -#endif // xyz memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t)); dataOfs += sizeof(vec3_t); // normal - dataOfs += R_VaoPackNormal(data + dataOfs, v->normal); + memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4); + dataOfs += sizeof(int16_t) * 4; #ifdef USE_VERT_TANGENT_SPACE - CrossProduct(v->normal, v->tangent, nxt); - VectorCopy(v->tangent, tangent); - tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f; // tangent - dataOfs += R_VaoPackTangent(data + dataOfs, tangent); + memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4); + dataOfs += sizeof(int16_t) * 4; #endif } } @@ -1011,10 +1021,6 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void *buffer, const char *modN st = surf->st; for ( j = 0; j < surf->numVerts; j++, v++, st++ ) { -#ifdef USE_VERT_TANGENT_SPACE - vec3_t nxt; - vec4_t tangent; -#endif // xyz memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t)); dataOfs += sizeof(v->xyz); @@ -1023,15 +1029,14 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void *buffer, const char *modN dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st); // normal - dataOfs += R_VaoPackNormal(data + dataOfs, v->normal); + memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4); + dataOfs += sizeof(int16_t) * 4; #ifdef USE_VERT_TANGENT_SPACE - CrossProduct(v->normal, v->tangent, nxt); - VectorCopy(v->tangent, tangent); - tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f; // tangent - dataOfs += R_VaoPackTangent(data + dataOfs, tangent); + memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4); + dataOfs += sizeof(int16_t) * 4; #endif } } @@ -1060,8 +1065,8 @@ static qboolean R_LoadMDC( model_t *mod, int lod, void *buffer, const char *modN vaoSurf->vao->attribs[ATTR_INDEX_POSITION].type = GL_FLOAT; vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = glRefConfig.packedTexcoordDataType; - vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType; - vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType; + vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT; + vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT; vaoSurf->vao->attribs[ATTR_INDEX_POSITION].normalized = GL_FALSE; vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].normalized = GL_FALSE; @@ -1327,6 +1332,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, const char *modN { unsigned lat, lng; unsigned short normal; + vec3_t fNormal; v->xyz[0] = LittleShort(md3xyz->xyz[0]) * MD3_XYZ_SCALE; v->xyz[1] = LittleShort(md3xyz->xyz[1]) * MD3_XYZ_SCALE; @@ -1339,11 +1345,15 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, const char *modN lat *= (FUNCTABLE_SIZE/256); lng *= (FUNCTABLE_SIZE/256); + // decode X as cos( lat ) * sin( long ) + // decode Y as sin( lat ) * sin( long ) + // decode Z as cos( long ) + fNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; + fNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; + fNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; - v->normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; - v->normal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - v->normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; + R_VaoPackNormal(v->normal, fNormal); } // swap all the ST @@ -1359,10 +1369,13 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, const char *modN #ifdef USE_VERT_TANGENT_SPACE // calc tangent spaces { + vec3_t *sdirs = ri.Z_Malloc(sizeof(*sdirs) * surf->numVerts * mdvModel->numFrames); + vec3_t *tdirs = ri.Z_Malloc(sizeof(*tdirs) * surf->numVerts * mdvModel->numFrames); + for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++) { - VectorClear(v->tangent); - VectorClear(v->bitangent); + VectorClear(sdirs[j]); + VectorClear(tdirs[j]); } for(f = 0; f < mdvModel->numFrames; f++) @@ -1387,27 +1400,32 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, const char *modN R_CalcTexDirs(sdir, tdir, v0, v1, v2, t0, t1, t2); - VectorAdd(sdir, surf->verts[index0].tangent, surf->verts[index0].tangent); - VectorAdd(sdir, surf->verts[index1].tangent, surf->verts[index1].tangent); - VectorAdd(sdir, surf->verts[index2].tangent, surf->verts[index2].tangent); - VectorAdd(tdir, surf->verts[index0].bitangent, surf->verts[index0].bitangent); - VectorAdd(tdir, surf->verts[index1].bitangent, surf->verts[index1].bitangent); - VectorAdd(tdir, surf->verts[index2].bitangent, surf->verts[index2].bitangent); + VectorAdd(sdir, sdirs[index0], sdirs[index0]); + VectorAdd(sdir, sdirs[index1], sdirs[index1]); + VectorAdd(sdir, sdirs[index2], sdirs[index2]); + VectorAdd(tdir, tdirs[index0], tdirs[index0]); + VectorAdd(tdir, tdirs[index1], tdirs[index1]); + VectorAdd(tdir, tdirs[index2], tdirs[index2]); } } for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++) { - vec3_t sdir, tdir; + vec3_t normal; + vec4_t tangent; + + VectorNormalize(sdirs[j]); + VectorNormalize(tdirs[j]); - VectorCopy(v->tangent, sdir); - VectorCopy(v->bitangent, tdir); + R_VaoUnpackNormal(normal, v->normal); - VectorNormalize(sdir); - VectorNormalize(tdir); + tangent[3] = R_CalcTangentSpace(tangent, NULL, normal, sdirs[j], tdirs[j]); - R_CalcTbnFromNormalAndTexDirs(v->tangent, v->bitangent, v->normal, sdir, tdir); + R_VaoPackTangent(v->tangent, tangent); } + + ri.Free(sdirs); + ri.Free(tdirs); } #endif @@ -1437,11 +1455,11 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, const char *modN offset_st = 0; offset_xyz = surf->numVerts * glRefConfig.packedTexcoordDataSize; offset_normal = offset_xyz + sizeof(vec3_t); - offset_tangent = offset_normal + sizeof(uint32_t); + offset_tangent = offset_normal + sizeof(int16_t) * 4; stride_st = glRefConfig.packedTexcoordDataSize; - stride_xyz = sizeof(vec3_t) + sizeof(uint32_t); + stride_xyz = sizeof(vec3_t) + sizeof(int16_t) * 4; #ifdef USE_VERT_TANGENT_SPACE - stride_xyz += sizeof(uint32_t); + stride_xyz += sizeof(int16_t) * 4; #endif stride_normal = stride_tangent = stride_xyz; @@ -1453,11 +1471,11 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, const char *modN offset_xyz = 0; offset_st = offset_xyz + sizeof(vec3_t); offset_normal = offset_st + glRefConfig.packedTexcoordDataSize; - offset_tangent = offset_normal + sizeof(uint32_t); + offset_tangent = offset_normal + sizeof(int16_t) * 4; #ifdef USE_VERT_TANGENT_SPACE - stride_xyz = offset_tangent + sizeof(uint32_t); + stride_xyz = offset_tangent + sizeof(int16_t) * 4; #else - stride_xyz = offset_normal + sizeof(uint32_t); + stride_xyz = offset_normal + sizeof(int16_t) * 4; #endif stride_st = stride_normal = stride_tangent = stride_xyz; @@ -1478,24 +1496,19 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, const char *modN v = surf->verts; for ( j = 0; j < surf->numVerts * mdvModel->numFrames ; j++, v++ ) { -#ifdef USE_VERT_TANGENT_SPACE - vec3_t nxt; - vec4_t tangent; -#endif // xyz memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t)); dataOfs += sizeof(vec3_t); // normal - dataOfs += R_VaoPackNormal(data + dataOfs, v->normal); + memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4); + dataOfs += sizeof(int16_t) * 4; #ifdef USE_VERT_TANGENT_SPACE - CrossProduct(v->normal, v->tangent, nxt); - VectorCopy(v->tangent, tangent); - tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f; // tangent - dataOfs += R_VaoPackTangent(data + dataOfs, tangent); + memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4); + dataOfs += sizeof(int16_t) * 4; #endif } } @@ -1505,10 +1518,6 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, const char *modN st = surf->st; for ( j = 0; j < surf->numVerts; j++, v++, st++ ) { -#ifdef USE_VERT_TANGENT_SPACE - vec3_t nxt; - vec4_t tangent; -#endif // xyz memcpy(data + dataOfs, &v->xyz, sizeof(vec3_t)); dataOfs += sizeof(v->xyz); @@ -1517,15 +1526,14 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, const char *modN dataOfs += R_VaoPackTexCoord(data + dataOfs, st->st); // normal - dataOfs += R_VaoPackNormal(data + dataOfs, v->normal); + memcpy(data + dataOfs, &v->normal, sizeof(int16_t) * 4); + dataOfs += sizeof(int16_t) * 4; #ifdef USE_VERT_TANGENT_SPACE - CrossProduct(v->normal, v->tangent, nxt); - VectorCopy(v->tangent, tangent); - tangent[3] = (DotProduct(nxt, v->bitangent) < 0.0f) ? -1.0f : 1.0f; // tangent - dataOfs += R_VaoPackTangent(data + dataOfs, tangent); + memcpy(data + dataOfs, &v->tangent, sizeof(int16_t) * 4); + dataOfs += sizeof(int16_t) * 4; #endif } } @@ -1554,8 +1562,8 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, const char *modN vaoSurf->vao->attribs[ATTR_INDEX_POSITION].type = GL_FLOAT; vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].type = glRefConfig.packedTexcoordDataType; - vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType; - vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType; + vaoSurf->vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT; + vaoSurf->vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT; vaoSurf->vao->attribs[ATTR_INDEX_POSITION].normalized = GL_FALSE; vaoSurf->vao->attribs[ATTR_INDEX_TEXCOORD].normalized = GL_FALSE; @@ -2036,6 +2044,9 @@ static qboolean R_LoadMDS( model_t *mod, void *buffer, const char *mod_name ) { LL( surf->ofsBoneReferences ); LL( surf->ofsEnd ); + // change to surface identifier + surf->ident = SF_MDS; + if ( surf->numVerts >= SHADER_MAX_VERTEXES ) { ri.Printf(PRINT_WARNING, "R_LoadMDS: %s has more than %i verts on %s (%i).\n", mod_name, SHADER_MAX_VERTEXES - 1, surf->name[0] ? surf->name : "a surface", diff --git a/MP/code/rend2/tr_model_iqm.c b/MP/code/rend2/tr_model_iqm.c index 6095a39..338433a 100644 --- a/MP/code/rend2/tr_model_iqm.c +++ b/MP/code/rend2/tr_model_iqm.c @@ -1024,9 +1024,9 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { int i; vec4_t *outXYZ; - uint32_t *outNormal; + int16_t *outNormal; #ifdef USE_VERT_TANGENT_SPACE - uint32_t *outTangent; + int16_t *outTangent; #endif vec2_t (*outTexCoord)[2]; vec4_t *outColor; @@ -1042,9 +1042,9 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { RB_CHECKOVERFLOW( surf->num_vertexes, surf->num_triangles * 3 ); outXYZ = &tess.xyz[tess.numVertexes]; - outNormal = &tess.normal[tess.numVertexes]; + outNormal = tess.normal[tess.numVertexes]; #ifdef USE_VERT_TANGENT_SPACE - outTangent = &tess.tangent[tess.numVertexes]; + outTangent = tess.tangent[tess.numVertexes]; #endif outTexCoord = &tess.texCoords[tess.numVertexes]; outColor = &tess.vertexColors[tess.numVertexes]; @@ -1056,7 +1056,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { // transform vertexes and fill other data for( i = 0; i < surf->num_vertexes; - i++, outXYZ++, outNormal++, outTexCoord++, outColor++ ) { + i++, outXYZ++, outNormal+=4, outTexCoord++, outColor++ ) { int j, k; float vtxMat[12]; float nrmMat[9]; @@ -1130,7 +1130,7 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { normal[1] = DotProduct(&nrmMat[3], &data->normals[3*vtx]); normal[2] = DotProduct(&nrmMat[6], &data->normals[3*vtx]); - R_VaoPackNormal((byte *)outNormal, normal); + R_VaoPackNormal(outNormal, normal); #ifdef USE_VERT_TANGENT_SPACE tangent[0] = DotProduct(&nrmMat[0], &data->tangents[4*vtx]); @@ -1138,7 +1138,8 @@ void RB_IQMSurfaceAnim( surfaceType_t *surface ) { tangent[2] = DotProduct(&nrmMat[6], &data->tangents[4*vtx]); tangent[3] = data->tangents[4*vtx+3]; - R_VaoPackTangent((byte *)outTangent++, tangent); + R_VaoPackTangent(outTangent, tangent); + outTangent+=4; #endif } diff --git a/MP/code/rend2/tr_shade_calc.c b/MP/code/rend2/tr_shade_calc.c index 7d6ab09..20b1ead 100644 --- a/MP/code/rend2/tr_shade_calc.c +++ b/MP/code/rend2/tr_shade_calc.c @@ -117,7 +117,7 @@ void RB_CalcDeformVertexes( deformStage_t *ds ) { vec3_t offset; float scale; float *xyz = ( float * ) tess.xyz; - uint32_t *normal = tess.normal; + int16_t *normal = tess.normal[0]; float *table; // Ridah @@ -147,13 +147,13 @@ void RB_CalcDeformVertexes( deformStage_t *ds ) { table = TableForFunc( ds->deformationWave.func ); - for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ ) + for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) { float off = ( xyz[0] + xyz[1] + xyz[2] ) * ds->deformationSpread; float dot; vec3_t fNormal; - R_VaoUnpackNormal(fNormal, *normal); + R_VaoUnpackNormal(fNormal, normal); scale = WAVEVALUE( table, ds->deformationWave.base, ds->deformationWave.amplitude, @@ -179,19 +179,19 @@ void RB_CalcDeformVertexes( deformStage_t *ds ) { else if ( ds->deformationWave.frequency == 0 ) { scale = EvalWaveForm( &ds->deformationWave ); - for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ ) + for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) { - R_VaoUnpackNormal(offset, *normal); + R_VaoUnpackNormal(offset, normal); xyz[0] += offset[0] * scale; xyz[1] += offset[1] * scale; xyz[2] += offset[2] * scale; } - } else - { + } + else { table = TableForFunc( ds->deformationWave.func ); - for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ ) + for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) { float off = ( xyz[0] + xyz[1] + xyz[2] ) * ds->deformationSpread; @@ -200,7 +200,7 @@ void RB_CalcDeformVertexes( deformStage_t *ds ) { ds->deformationWave.phase + off, ds->deformationWave.frequency ); - R_VaoUnpackNormal(offset, *normal); + R_VaoUnpackNormal(offset, normal); xyz[0] += offset[0] * scale; xyz[1] += offset[1] * scale; @@ -220,12 +220,12 @@ void RB_CalcDeformNormals( deformStage_t *ds ) { int i; float scale; float *xyz = ( float * ) tess.xyz; - uint32_t *normal = tess.normal; + int16_t *normal = tess.normal[0]; - for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal++ ) { + for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) { vec3_t fNormal; - R_VaoUnpackNormal(fNormal, *normal); + R_VaoUnpackNormal(fNormal, normal); scale = 0.98f; scale = R_NoiseGet4f( xyz[0] * scale, xyz[1] * scale, xyz[2] * scale, @@ -244,7 +244,7 @@ void RB_CalcDeformNormals( deformStage_t *ds ) { VectorNormalizeFast( fNormal ); - R_VaoPackNormal((byte *)normal, fNormal); + R_VaoPackNormal(normal, fNormal); } } @@ -258,17 +258,17 @@ void RB_CalcBulgeVertexes( deformStage_t *ds ) { int i; const float *st = ( const float * ) tess.texCoords[0]; float *xyz = ( float * ) tess.xyz; - uint32_t *normal = tess.normal; + int16_t *normal = tess.normal[0]; float now; now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f; - for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal++ ) { + for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) { int off; float scale; vec3_t fNormal; - R_VaoUnpackNormal(fNormal, *normal); + R_VaoUnpackNormal(fNormal, normal); off = (float)( FUNCTABLE_SIZE / ( M_PI * 2 ) ) * ( st[0] * ds->bulgeWidth + now ); @@ -810,18 +810,18 @@ void RB_CalcFogTexCoords( float *st ) { void RB_CalcFireRiseEnvTexCoords( float *st ) { int i; float *v; - uint32_t *normal = tess.normal; + int16_t *normal = tess.normal[0]; vec3_t fNormal, viewer, reflected; float d; v = tess.xyz[0]; VectorNegate( backEnd.currentEntity->e.fireRiseDir, viewer ); - for ( i = 0 ; i < tess.numVertexes ; i++, v += 4, normal++, st += 2 ) + for ( i = 0 ; i < tess.numVertexes ; i++, v += 4, normal += 4, st += 2 ) { VectorNormalizeFast( viewer ); - R_VaoUnpackNormal(fNormal, *normal); + R_VaoUnpackNormal(fNormal, normal); d = DotProduct( fNormal, viewer ); diff --git a/MP/code/rend2/tr_surface.c b/MP/code/rend2/tr_surface.c index 864ace5..459a04d 100644 --- a/MP/code/rend2/tr_surface.c +++ b/MP/code/rend2/tr_surface.c @@ -94,7 +94,7 @@ RB_AddQuadStampExt */ void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], float s1, float t1, float s2, float t2 ) { vec3_t normal; - uint32_t pNormal; + int16_t iNormal[4]; int ndx; RB_CheckVao(tess.vao); @@ -132,11 +132,12 @@ void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, float color[4], // constant normal all the way around VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal ); - R_VaoPackNormal((byte *)&pNormal, normal); - tess.normal[ndx] = - tess.normal[ndx+1] = - tess.normal[ndx+2] = - tess.normal[ndx+3] = pNormal; + R_VaoPackNormal(iNormal, normal); + + VectorCopy4(tess.normal[ndx], iNormal); + VectorCopy4(tess.normal[ndx+1], iNormal); + VectorCopy4(tess.normal[ndx+2], iNormal); + VectorCopy4(tess.normal[ndx+3], iNormal); // standard square texture coordinates VectorSet2(tess.texCoords[ndx ][0], s1, t1); @@ -348,10 +349,10 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIn glIndex_t *inIndex; srfVert_t *dv; float *xyz, *texCoords, *lightCoords; - uint32_t *lightdir; - uint32_t *normal; + int16_t *lightdir; + int16_t *normal; #ifdef USE_VERT_TANGENT_SPACE - uint32_t *tangent; + int16_t *tangent; #endif glIndex_t *outIndex; float *color; @@ -378,18 +379,18 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIn if ( tess.shader->vertexAttribs & ATTR_NORMAL ) { dv = verts; - normal = &tess.normal[ tess.numVertexes ]; - for ( i = 0 ; i < numVerts ; i++, dv++, normal++ ) - R_VaoPackNormal((byte *)normal, dv->normal); + normal = tess.normal[ tess.numVertexes ]; + for ( i = 0 ; i < numVerts ; i++, dv++, normal+=4 ) + VectorCopy4(dv->normal, normal); } #ifdef USE_VERT_TANGENT_SPACE if ( tess.shader->vertexAttribs & ATTR_TANGENT ) { dv = verts; - tangent = &tess.tangent[ tess.numVertexes ]; - for ( i = 0 ; i < numVerts ; i++, dv++, tangent++ ) - R_VaoPackTangent((byte *)tangent, dv->tangent); + tangent = tess.tangent[ tess.numVertexes ]; + for ( i = 0 ; i < numVerts ; i++, dv++, tangent+=4 ) + VectorCopy4(dv->tangent, tangent); } #endif @@ -420,9 +421,9 @@ static void RB_SurfaceVertsAndIndexes( int numVerts, srfVert_t *verts, int numIn if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION ) { dv = verts; - lightdir = &tess.lightdir[ tess.numVertexes ]; - for ( i = 0 ; i < numVerts ; i++, dv++, lightdir++ ) - R_VaoPackNormal((byte *)lightdir, dv->lightdir); + lightdir = tess.lightdir[ tess.numVertexes ]; + for ( i = 0 ; i < numVerts ; i++, dv++, lightdir+=4 ) + VectorCopy4(dv->lightdir, lightdir); } #if 0 // nothing even uses vertex dlightbits @@ -868,306 +869,18 @@ static void RB_SurfaceLightningBolt( void ) { } } -/* -** VectorArrayNormalize -* -* The inputs to this routing seem to always be close to length = 1.0 (about 0.6 to 2.0) -* This means that we don't have to worry about zero length or enormously long vectors. -*/ -#if 0 // Unused in rend2 -static void VectorArrayNormalize( vec4_t *normals, unsigned int count ) { -// assert(count); - -#if idppc - { - register float half = 0.5; - register float one = 1.0; - float *components = (float *)normals; - - // Vanilla PPC code, but since PPC has a reciprocal square root estimate instruction, - // runs *much* faster than calling sqrt(). We'll use a single Newton-Raphson - // refinement step to get a little more precision. This seems to yeild results - // that are correct to 3 decimal places and usually correct to at least 4 (sometimes 5). - // (That is, for the given input range of about 0.6 to 2.0). - do { - float x, y, z; - float B, y0, y1; - - x = components[0]; - y = components[1]; - z = components[2]; - components += 4; - B = x * x + y * y + z * z; - -#ifdef __GNUC__ - asm ( "frsqrte %0,%1" : "=f" ( y0 ) : "f" ( B ) ); -#else - y0 = __frsqrte( B ); -#endif - y1 = y0 + half * y0 * ( one - B * y0 * y0 ); - - x = x * y1; - y = y * y1; - components[-4] = x; - z = z * y1; - components[-3] = y; - components[-2] = z; - } while ( count-- ); - } -#else // No assembly version for this architecture, or C_ONLY defined - // given the input, it's safe to call VectorNormalizeFast - while ( count-- ) { - VectorNormalizeFast( normals[0] ); - normals++; - } -#endif -} -#endif - - - -/* -** LerpMeshVertexes -*/ -#if 0 // Unused -#if idppc_altivec -static void LerpMeshVertexes_altivec(md3Surface_t *surf, float backlerp) -{ - short *oldXyz, *newXyz, *oldNormals, *newNormals; - float *outXyz, *outNormal; - float oldXyzScale QALIGN(16); - float newXyzScale QALIGN(16); - float oldNormalScale QALIGN(16); - float newNormalScale QALIGN(16); - int vertNum; - unsigned lat, lng; - int numVerts; - - outXyz = tess.xyz[tess.numVertexes]; - outNormal = tess.normal[tess.numVertexes]; - - newXyz = (short *)((byte *)surf + surf->ofsXyzNormals) - + (backEnd.currentEntity->e.frame * surf->numVerts * 4); - newNormals = newXyz + 3; - - newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp); - newNormalScale = 1.0 - backlerp; - - numVerts = surf->numVerts; - - if ( backlerp == 0 ) { - vector signed short newNormalsVec0; - vector signed short newNormalsVec1; - vector signed int newNormalsIntVec; - vector float newNormalsFloatVec; - vector float newXyzScaleVec; - vector unsigned char newNormalsLoadPermute; - vector unsigned char newNormalsStorePermute; - vector float zero; - - newNormalsStorePermute = vec_lvsl(0,(float *)&newXyzScaleVec); - newXyzScaleVec = *(vector float *)&newXyzScale; - newXyzScaleVec = vec_perm(newXyzScaleVec,newXyzScaleVec,newNormalsStorePermute); - newXyzScaleVec = vec_splat(newXyzScaleVec,0); - newNormalsLoadPermute = vec_lvsl(0,newXyz); - newNormalsStorePermute = vec_lvsr(0,outXyz); - zero = (vector float)vec_splat_s8(0); - // - // just copy the vertexes - // - for (vertNum=0 ; vertNum < numVerts ; vertNum++, - newXyz += 4, newNormals += 4, - outXyz += 4, outNormal += 4) - { - newNormalsLoadPermute = vec_lvsl(0,newXyz); - newNormalsStorePermute = vec_lvsr(0,outXyz); - newNormalsVec0 = vec_ld(0,newXyz); - newNormalsVec1 = vec_ld(16,newXyz); - newNormalsVec0 = vec_perm(newNormalsVec0,newNormalsVec1,newNormalsLoadPermute); - newNormalsIntVec = vec_unpackh(newNormalsVec0); - newNormalsFloatVec = vec_ctf(newNormalsIntVec,0); - newNormalsFloatVec = vec_madd(newNormalsFloatVec,newXyzScaleVec,zero); - newNormalsFloatVec = vec_perm(newNormalsFloatVec,newNormalsFloatVec,newNormalsStorePermute); - //outXyz[0] = newXyz[0] * newXyzScale; - //outXyz[1] = newXyz[1] * newXyzScale; - //outXyz[2] = newXyz[2] * newXyzScale; - - lat = ( newNormals[0] >> 8 ) & 0xff; - lng = ( newNormals[0] & 0xff ); - lat *= (FUNCTABLE_SIZE/256); - lng *= (FUNCTABLE_SIZE/256); - - // decode X as cos( lat ) * sin( long ) - // decode Y as sin( lat ) * sin( long ) - // decode Z as cos( long ) - - outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; - outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; - - vec_ste(newNormalsFloatVec,0,outXyz); - vec_ste(newNormalsFloatVec,4,outXyz); - vec_ste(newNormalsFloatVec,8,outXyz); - } - } else { - // - // interpolate and copy the vertex and normal - // - oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals) - + (backEnd.currentEntity->e.oldframe * surf->numVerts * 4); - oldNormals = oldXyz + 3; - - oldXyzScale = MD3_XYZ_SCALE * backlerp; - oldNormalScale = backlerp; - - for (vertNum=0 ; vertNum < numVerts ; vertNum++, - oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4, - outXyz += 4, outNormal += 4) - { - vec3_t uncompressedOldNormal, uncompressedNewNormal; - - // interpolate the xyz - outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale; - outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale; - outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale; - - // FIXME: interpolate lat/long instead? - lat = ( newNormals[0] >> 8 ) & 0xff; - lng = ( newNormals[0] & 0xff ); - lat *= 4; - lng *= 4; - uncompressedNewNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; - uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - uncompressedNewNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; - - lat = ( oldNormals[0] >> 8 ) & 0xff; - lng = ( oldNormals[0] & 0xff ); - lat *= 4; - lng *= 4; - - uncompressedOldNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; - uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - uncompressedOldNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; - - outNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale; - outNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale; - outNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale; - -// VectorNormalize (outNormal); - } - VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts); - } -} -#endif -#endif - -static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp) +static void LerpMeshVertexes(mdvSurface_t *surf, float backlerp) { -#if 0 - short *oldXyz, *newXyz, *oldNormals, *newNormals; - float *outXyz, *outNormal; - float oldXyzScale, newXyzScale; - float oldNormalScale, newNormalScale; - int vertNum; - unsigned lat, lng; - int numVerts; - - outXyz = tess.xyz[tess.numVertexes]; - outNormal = tess.normal[tess.numVertexes]; - - newXyz = (short *)((byte *)surf + surf->ofsXyzNormals) - + (backEnd.currentEntity->e.frame * surf->numVerts * 4); - newNormals = newXyz + 3; - - newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp); - newNormalScale = 1.0 - backlerp; - - numVerts = surf->numVerts; - - if ( backlerp == 0 ) { - // - // just copy the vertexes - // - for (vertNum=0 ; vertNum < numVerts ; vertNum++, - newXyz += 4, newNormals += 4, - outXyz += 4, outNormal += 4) - { - - outXyz[0] = newXyz[0] * newXyzScale; - outXyz[1] = newXyz[1] * newXyzScale; - outXyz[2] = newXyz[2] * newXyzScale; - - lat = ( newNormals[0] >> 8 ) & 0xff; - lng = ( newNormals[0] & 0xff ); - lat *= (FUNCTABLE_SIZE/256); - lng *= (FUNCTABLE_SIZE/256); - - // decode X as cos( lat ) * sin( long ) - // decode Y as sin( lat ) * sin( long ) - // decode Z as cos( long ) - - outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; - outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; - } - } else { - // - // interpolate and copy the vertex and normal - // - oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals) - + (backEnd.currentEntity->e.oldframe * surf->numVerts * 4); - oldNormals = oldXyz + 3; - - oldXyzScale = MD3_XYZ_SCALE * backlerp; - oldNormalScale = backlerp; - - for (vertNum=0 ; vertNum < numVerts ; vertNum++, - oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4, - outXyz += 4, outNormal += 4) - { - vec3_t uncompressedOldNormal, uncompressedNewNormal; - - // interpolate the xyz - outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale; - outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale; - outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale; - - // FIXME: interpolate lat/long instead? - lat = ( newNormals[0] >> 8 ) & 0xff; - lng = ( newNormals[0] & 0xff ); - lat *= 4; - lng *= 4; - uncompressedNewNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; - uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - uncompressedNewNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; - - lat = ( oldNormals[0] >> 8 ) & 0xff; - lng = ( oldNormals[0] & 0xff ); - lat *= 4; - lng *= 4; - - uncompressedOldNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; - uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - uncompressedOldNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; - - outNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale; - outNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale; - outNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale; - -// VectorNormalize (outNormal); - } - VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts); - } -#endif float *outXyz; - uint32_t *outNormal; + int16_t *outNormal, *outTangent; mdvVertex_t *newVerts; int vertNum; newVerts = surf->verts + backEnd.currentEntity->e.frame * surf->numVerts; - outXyz = tess.xyz[tess.numVertexes]; - outNormal = &tess.normal[tess.numVertexes]; + outXyz = tess.xyz[tess.numVertexes]; + outNormal = tess.normal[tess.numVertexes]; + outTangent = tess.tangent[tess.numVertexes]; if (backlerp == 0) { @@ -1177,16 +890,15 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp) for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++) { - vec3_t normal; - VectorCopy(newVerts->xyz, outXyz); - VectorCopy(newVerts->normal, normal); - R_VaoPackNormal((byte *)outNormal, normal); + VectorCopy4(newVerts->normal, outNormal); + VectorCopy4(newVerts->tangent, outTangent); newVerts++; outXyz += 4; - outNormal++; + outNormal += 4; + outTangent += 4; } } else @@ -1201,36 +913,27 @@ static void LerpMeshVertexes_scalar(mdvSurface_t *surf, float backlerp) for (vertNum=0 ; vertNum < surf->numVerts ; vertNum++) { - vec3_t normal; - VectorLerp(newVerts->xyz, oldVerts->xyz, backlerp, outXyz); - VectorLerp(newVerts->normal, oldVerts->normal, backlerp, normal); - VectorNormalize(normal); - R_VaoPackNormal((byte *)outNormal, normal); + outNormal[0] = (int16_t)(newVerts->normal[0] * (1.0f - backlerp) + oldVerts->normal[0] * backlerp); + outNormal[1] = (int16_t)(newVerts->normal[1] * (1.0f - backlerp) + oldVerts->normal[1] * backlerp); + outNormal[2] = (int16_t)(newVerts->normal[2] * (1.0f - backlerp) + oldVerts->normal[2] * backlerp); + outNormal[3] = 0; + + outTangent[0] = (int16_t)(newVerts->tangent[0] * (1.0f - backlerp) + oldVerts->tangent[0] * backlerp); + outTangent[1] = (int16_t)(newVerts->tangent[1] * (1.0f - backlerp) + oldVerts->tangent[1] * backlerp); + outTangent[2] = (int16_t)(newVerts->tangent[2] * (1.0f - backlerp) + oldVerts->tangent[2] * backlerp); + outTangent[3] = newVerts->tangent[3]; newVerts++; oldVerts++; outXyz += 4; - outNormal++; + outNormal += 4; + outTangent += 4; } } } -static void LerpMeshVertexes(mdvSurface_t *surf, float backlerp) -{ -#if 0 -#if idppc_altivec - if (com_altivec->integer) { - // must be in a seperate function or G3 systems will crash. - LerpMeshVertexes_altivec( surf, backlerp ); - return; - } -#endif // idppc_altivec -#endif - LerpMeshVertexes_scalar( surf, backlerp ); -} - /* ============= @@ -1283,229 +986,6 @@ static void RB_SurfaceMesh(mdvSurface_t *surface) { } -/* -** R_LatLongToNormal -*/ -void R_LatLongToNormal( vec3_t outNormal, short latLong ) { - unsigned lat, lng; - - lat = ( latLong >> 8 ) & 0xff; - lng = ( latLong & 0xff ); - lat *= ( FUNCTABLE_SIZE / 256 ); - lng *= ( FUNCTABLE_SIZE / 256 ); - - // decode X as cos( lat ) * sin( long ) - // decode Y as sin( lat ) * sin( long ) - // decode Z as cos( long ) - - outNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng]; - outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - outNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK]; -} - -// Ridah -/* -** LerpCMeshVertexes -*/ -static void LerpCMeshVertexes( mdcSurface_t *surf, float backlerp ) { - short *oldXyz, *newXyz, *oldNormals, *newNormals; - float *outXyz; - uint32_t *outNormal; - vec3_t fNormal; - float oldXyzScale, newXyzScale; - float oldNormalScale, newNormalScale; - int vertNum; - unsigned lat, lng; - int numVerts; - - int oldBase, newBase; - short *oldComp = NULL, *newComp = NULL; // TTimo: init - mdcXyzCompressed_t *oldXyzComp = NULL, *newXyzComp = NULL; // TTimo: init - vec3_t oldOfsVec, newOfsVec; - - qboolean hasComp; - - outXyz = tess.xyz[tess.numVertexes]; - outNormal = &tess.normal[tess.numVertexes]; - - newBase = (int)*( ( short * )( (byte *)surf + surf->ofsFrameBaseFrames ) + backEnd.currentEntity->e.frame ); - newXyz = ( short * )( (byte *)surf + surf->ofsXyzNormals ) - + ( newBase * surf->numVerts * 4 ); - newNormals = newXyz + 3; - - hasComp = ( surf->numCompFrames > 0 ); - if ( hasComp ) { - newComp = ( ( short * )( (byte *)surf + surf->ofsFrameCompFrames ) + backEnd.currentEntity->e.frame ); - if ( *newComp >= 0 ) { - newXyzComp = ( mdcXyzCompressed_t * )( (byte *)surf + surf->ofsXyzCompressed ) - + ( *newComp * surf->numVerts ); - } - } - - newXyzScale = MD3_XYZ_SCALE * ( 1.0 - backlerp ); - newNormalScale = 1.0 - backlerp; - - numVerts = surf->numVerts; - - if ( backlerp == 0 ) { - // - // just copy the vertexes - // - for ( vertNum = 0 ; vertNum < numVerts ; vertNum++, - newXyz += 4, newNormals += 4, - outXyz += 4, outNormal++ ) - { - - outXyz[0] = newXyz[0] * newXyzScale; - outXyz[1] = newXyz[1] * newXyzScale; - outXyz[2] = newXyz[2] * newXyzScale; - - // add the compressed ofsVec - if ( hasComp && *newComp >= 0 ) { - R_MDC_DecodeXyzCompressed( newXyzComp->ofsVec, newOfsVec, fNormal ); - newXyzComp++; - VectorAdd( outXyz, newOfsVec, outXyz ); - } else { - lat = ( newNormals[0] >> 8 ) & 0xff; - lng = ( newNormals[0] & 0xff ); - lat *= 4; - lng *= 4; - - fNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng]; - fNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - fNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK]; - } - - R_VaoPackNormal((byte *)outNormal, fNormal); - } - } else { - // - // interpolate and copy the vertex and normal - // - oldBase = (int)*( ( short * )( (byte *)surf + surf->ofsFrameBaseFrames ) + backEnd.currentEntity->e.oldframe ); - oldXyz = ( short * )( (byte *)surf + surf->ofsXyzNormals ) - + ( oldBase * surf->numVerts * 4 ); - oldNormals = oldXyz + 3; - - if ( hasComp ) { - oldComp = ( ( short * )( (byte *)surf + surf->ofsFrameCompFrames ) + backEnd.currentEntity->e.oldframe ); - if ( *oldComp >= 0 ) { - oldXyzComp = ( mdcXyzCompressed_t * )( (byte *)surf + surf->ofsXyzCompressed ) - + ( *oldComp * surf->numVerts ); - } - } - - oldXyzScale = MD3_XYZ_SCALE * backlerp; - oldNormalScale = backlerp; - - for ( vertNum = 0 ; vertNum < numVerts ; vertNum++, - oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4, - outXyz += 4, outNormal++ ) - { - vec3_t uncompressedOldNormal, uncompressedNewNormal; - - // interpolate the xyz - outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale; - outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale; - outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale; - - // add the compressed ofsVec - if ( hasComp && *newComp >= 0 ) { - R_MDC_DecodeXyzCompressed( newXyzComp->ofsVec, newOfsVec, uncompressedNewNormal ); - newXyzComp++; - VectorMA( outXyz, 1.0 - backlerp, newOfsVec, outXyz ); - } else { - lat = ( newNormals[0] >> 8 ) & 0xff; - lng = ( newNormals[0] & 0xff ); - lat *= 4; - lng *= 4; - - uncompressedNewNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng]; - uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - uncompressedNewNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK]; - } - - if ( hasComp && *oldComp >= 0 ) { - R_MDC_DecodeXyzCompressed( oldXyzComp->ofsVec, oldOfsVec, uncompressedOldNormal ); - oldXyzComp++; - VectorMA( outXyz, backlerp, oldOfsVec, outXyz ); - } else { - lat = ( oldNormals[0] >> 8 ) & 0xff; - lng = ( oldNormals[0] & 0xff ); - lat *= 4; - lng *= 4; - - uncompressedOldNormal[0] = tr.sinTable[( lat + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK] * tr.sinTable[lng]; - uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng]; - uncompressedOldNormal[2] = tr.sinTable[( lng + ( FUNCTABLE_SIZE / 4 ) ) & FUNCTABLE_MASK]; - } - - fNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale; - fNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale; - fNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale; - - VectorNormalize( fNormal ); - - R_VaoPackNormal((byte *)outNormal, fNormal); - } - } -} - -/* -============= -RB_SurfaceCMesh -============= -*/ -void RB_SurfaceCMesh( mdcSurface_t *surface ) { - int j; - float backlerp; - int *triangles; - float *texCoords; - int indexes; - int Bob, Doug; - int numVerts; - - // RF, check for REFLAG_HANDONLY - if ( backEnd.currentEntity->e.reFlags & REFLAG_ONLYHAND ) { - if ( !strstr( surface->name, "hand" ) ) { - return; - } - } - - if ( backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame ) { - backlerp = 0; - } else { - backlerp = backEnd.currentEntity->e.backlerp; - } - - RB_CheckVao(tess.vao); - - RB_CHECKOVERFLOW( surface->numVerts, surface->numTriangles * 3 ); - - LerpCMeshVertexes( surface, backlerp ); - - triangles = ( int * )( (byte *)surface + surface->ofsTriangles ); - indexes = surface->numTriangles * 3; - Bob = tess.numIndexes; - Doug = tess.numVertexes; - for ( j = 0 ; j < indexes ; j++ ) { - tess.indexes[Bob + j] = Doug + triangles[j]; - } - tess.numIndexes += indexes; - - texCoords = ( float * )( (byte *)surface + surface->ofsSt ); - - numVerts = surface->numVerts; - for ( j = 0; j < numVerts; j++ ) { - tess.texCoords[Doug + j][0][0] = texCoords[j * 2 + 0]; - tess.texCoords[Doug + j][0][1] = texCoords[j * 2 + 1]; - // FIXME: fill in lightmapST for completeness? - } - - tess.numVertexes += surface->numVerts; - -} -// done. /* ============== @@ -1565,12 +1045,12 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { int i, j; float *xyz; float *texCoords, *lightCoords; - uint32_t *normal; + int16_t *normal; #ifdef USE_VERT_TANGENT_SPACE - uint32_t *tangent; + int16_t *tangent; #endif float *color; - uint32_t *lightdir; + int16_t *lightdir; srfVert_t *dv; int rows, irows, vrows; int used; @@ -1655,14 +1135,14 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { numVertexes = tess.numVertexes; xyz = tess.xyz[numVertexes]; - normal = &tess.normal[numVertexes]; + normal = tess.normal[numVertexes]; #ifdef USE_VERT_TANGENT_SPACE - tangent = &tess.tangent[numVertexes]; + tangent = tess.tangent[numVertexes]; #endif texCoords = tess.texCoords[numVertexes][0]; lightCoords = tess.texCoords[numVertexes][1]; color = tess.vertexColors[numVertexes]; - lightdir = &tess.lightdir[numVertexes]; + lightdir = tess.lightdir[numVertexes]; //vDlightBits = &tess.vertexDlightBits[numVertexes]; for ( i = 0 ; i < rows ; i++ ) { @@ -1678,13 +1158,15 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { if ( tess.shader->vertexAttribs & ATTR_NORMAL ) { - R_VaoPackNormal((byte *)normal++, dv->normal); + VectorCopy4(normal, dv->normal); + normal += 4; } #ifdef USE_VERT_TANGENT_SPACE if ( tess.shader->vertexAttribs & ATTR_TANGENT ) { - R_VaoPackTangent((byte *)tangent++, dv->tangent); + VectorCopy4(tangent, dv->tangent); + tangent += 4; } #endif @@ -1708,7 +1190,8 @@ static void RB_SurfaceGrid( srfBspSurface_t *srf ) { if ( tess.shader->vertexAttribs & ATTR_LIGHTDIRECTION ) { - R_VaoPackNormal((byte *)lightdir++, dv->lightdir); + VectorCopy4(lightdir, dv->lightdir); + lightdir += 4; } //*vDlightBits++ = dlightBits; @@ -1938,7 +1421,6 @@ void( *rb_surfaceTable[SF_NUM_SURFACE_TYPES] ) ( void * ) = { ( void( * ) ( void* ) )RB_SurfaceTriangles, // SF_TRIANGLES, ( void( * ) ( void* ) )RB_SurfacePolychain, // SF_POLY, ( void( * ) ( void* ) )RB_SurfaceMesh, // SF_MDV, - ( void( * ) ( void* ) )RB_SurfaceCMesh, // SF_MDC, ( void( * ) ( void* ) )RB_SurfaceAnim, // SF_MDS, ( void( * ) ( void* ) )RB_MDRSurfaceAnim, // SF_MDR, ( void( * ) ( void* ) )RB_IQMSurfaceAnim, // SF_IQM, diff --git a/MP/code/rend2/tr_vbo.c b/MP/code/rend2/tr_vbo.c index b1ff3d6..db3d8eb 100644 --- a/MP/code/rend2/tr_vbo.c +++ b/MP/code/rend2/tr_vbo.c @@ -23,73 +23,20 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_local.h" -union pack10_u { - struct { - signed int x:10; - signed int y:10; - signed int z:10; - signed int w:2; - } pack; - uint32_t i; -}; - -union pack8_u { - struct { - signed int x:8; - signed int y:8; - signed int z:8; - signed int w:8; - } pack; - uint32_t i; -}; - - -int R_VaoPackTangent(byte *out, vec4_t v) +void R_VaoPackTangent(int16_t *out, vec4_t v) { - if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV) - { - union pack10_u *num = (union pack10_u *)out; - - num->pack.x = v[0] * 511.0f; - num->pack.y = v[1] * 511.0f; - num->pack.z = v[2] * 511.0f; - num->pack.w = v[3]; - } - else - { - union pack8_u *num = (union pack8_u *)out; - - num->pack.x = v[0] * 127.0f; - num->pack.y = v[1] * 127.0f; - num->pack.z = v[2] * 127.0f; - num->pack.w = v[3] * 127.0f; - } - - return 4; + out[0] = v[0] * 32767.0f + (v[0] > 0.0f ? 0.5f : -0.5f); + out[1] = v[1] * 32767.0f + (v[1] > 0.0f ? 0.5f : -0.5f); + out[2] = v[2] * 32767.0f + (v[2] > 0.0f ? 0.5f : -0.5f); + out[3] = v[3] * 32767.0f + (v[3] > 0.0f ? 0.5f : -0.5f); } -int R_VaoPackNormal(byte *out, vec3_t v) +void R_VaoPackNormal(int16_t *out, vec3_t v) { - if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV) - { - union pack10_u *num = (union pack10_u *)out; - - num->pack.x = v[0] * 511.0f; - num->pack.y = v[1] * 511.0f; - num->pack.z = v[2] * 511.0f; - num->pack.w = 0; - } - else - { - union pack8_u *num = (union pack8_u *)out; - - num->pack.x = v[0] * 127.0f; - num->pack.y = v[1] * 127.0f; - num->pack.z = v[2] * 127.0f; - num->pack.w = 0; - } - - return 4; + out[0] = v[0] * 32767.0f + (v[0] > 0.0f ? 0.5f : -0.5f); + out[1] = v[1] * 32767.0f + (v[1] > 0.0f ? 0.5f : -0.5f); + out[2] = v[2] * 32767.0f + (v[2] > 0.0f ? 0.5f : -0.5f); + out[3] = 0; } int R_VaoPackTexCoord(byte *out, vec2_t st) @@ -140,50 +87,21 @@ int R_VaoPackColors(byte *out, vec4_t color) } } - -void R_VaoUnpackTangent(vec4_t v, uint32_t b) +void R_VaoUnpackTangent(vec4_t v, int16_t *pack) { - if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV) - { - union pack10_u *num = (union pack10_u *)&b; - - v[0] = num->pack.x / 511.0f; - v[1] = num->pack.y / 511.0f; - v[2] = num->pack.z / 511.0f; - v[3] = num->pack.w; - } - else - { - union pack8_u *num = (union pack8_u *)&b; - - v[0] = num->pack.x / 127.0f; - v[1] = num->pack.y / 127.0f; - v[2] = num->pack.z / 127.0f; - v[3] = num->pack.w / 127.0f; - } + v[0] = pack[0] / 32767.0f; + v[1] = pack[1] / 32767.0f; + v[2] = pack[2] / 32767.0f; + v[3] = pack[3] / 32767.0f; } -void R_VaoUnpackNormal(vec3_t v, uint32_t b) +void R_VaoUnpackNormal(vec3_t v, int16_t *pack) { - if (glRefConfig.packedNormalDataType == GL_INT_2_10_10_10_REV) - { - union pack10_u *num = (union pack10_u *)&b; - - v[0] = num->pack.x / 511.0f; - v[1] = num->pack.y / 511.0f; - v[2] = num->pack.z / 511.0f; - } - else - { - union pack8_u *num = (union pack8_u *)&b; - - v[0] = num->pack.x / 127.0f; - v[1] = num->pack.y / 127.0f; - v[2] = num->pack.z / 127.0f; - } + v[0] = pack[0] / 32767.0f; + v[1] = pack[1] / 32767.0f; + v[2] = pack[2] / 32767.0f; } - void Vao_SetVertexPointers(vao_t *vao) { int attribIndex; @@ -347,12 +265,12 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int num vao->attribs[ATTR_INDEX_LIGHTDIRECTION].count = 4; vao->attribs[ATTR_INDEX_POSITION ].type = GL_FLOAT; - vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType; - vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType; + vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT; + vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT; vao->attribs[ATTR_INDEX_TEXCOORD ].type = glRefConfig.packedTexcoordDataType; vao->attribs[ATTR_INDEX_LIGHTCOORD ].type = glRefConfig.packedTexcoordDataType; vao->attribs[ATTR_INDEX_COLOR ].type = glRefConfig.packedColorDataType; - vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = glRefConfig.packedNormalDataType; + vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = GL_SHORT; vao->attribs[ATTR_INDEX_POSITION ].normalized = GL_FALSE; vao->attribs[ATTR_INDEX_NORMAL ].normalized = GL_TRUE; @@ -363,14 +281,14 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int num vao->attribs[ATTR_INDEX_LIGHTDIRECTION].normalized = GL_TRUE; vao->attribs[ATTR_INDEX_POSITION ].offset = 0; dataSize = sizeof(verts[0].xyz); - vao->attribs[ATTR_INDEX_NORMAL ].offset = dataSize; dataSize += sizeof(uint32_t); + vao->attribs[ATTR_INDEX_NORMAL ].offset = dataSize; dataSize += sizeof(verts[0].normal); #ifdef USE_VERT_TANGENT_SPACE - vao->attribs[ATTR_INDEX_TANGENT ].offset = dataSize; dataSize += sizeof(uint32_t); + vao->attribs[ATTR_INDEX_TANGENT ].offset = dataSize; dataSize += sizeof(verts[0].tangent); #endif vao->attribs[ATTR_INDEX_TEXCOORD ].offset = dataSize; dataSize += glRefConfig.packedTexcoordDataSize; vao->attribs[ATTR_INDEX_LIGHTCOORD ].offset = dataSize; dataSize += glRefConfig.packedTexcoordDataSize; vao->attribs[ATTR_INDEX_COLOR ].offset = dataSize; dataSize += glRefConfig.packedColorDataSize; - vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = dataSize; dataSize += sizeof(uint32_t); + vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = dataSize; dataSize += sizeof(verts[0].lightdir); vao->attribs[ATTR_INDEX_POSITION ].stride = dataSize; vao->attribs[ATTR_INDEX_NORMAL ].stride = dataSize; @@ -400,11 +318,13 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int num dataOfs += sizeof(verts[i].xyz); // normal - dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].normal); + memcpy(data + dataOfs, &verts[i].normal, sizeof(verts[i].normal)); + dataOfs += sizeof(verts[i].normal); #ifdef USE_VERT_TANGENT_SPACE // tangent - dataOfs += R_VaoPackTangent(data + dataOfs, verts[i].tangent); + memcpy(data + dataOfs, &verts[i].tangent, sizeof(verts[i].tangent)); + dataOfs += sizeof(verts[i].tangent); #endif // texcoords @@ -417,7 +337,8 @@ vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int num dataOfs += R_VaoPackColors(data + dataOfs, verts[i].vertexColors); // light directions - dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].lightdir); + memcpy(data + dataOfs, &verts[i].lightdir, sizeof(verts[i].lightdir)); + dataOfs += sizeof(verts[i].lightdir); } vao->vertexesSize = dataSize; @@ -581,12 +502,12 @@ void R_InitVaos(void) tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].count = 4; tess.vao->attribs[ATTR_INDEX_POSITION ].type = GL_FLOAT; - tess.vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType; - tess.vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType; + tess.vao->attribs[ATTR_INDEX_NORMAL ].type = GL_SHORT; + tess.vao->attribs[ATTR_INDEX_TANGENT ].type = GL_SHORT; tess.vao->attribs[ATTR_INDEX_TEXCOORD ].type = GL_FLOAT; tess.vao->attribs[ATTR_INDEX_LIGHTCOORD ].type = GL_FLOAT; tess.vao->attribs[ATTR_INDEX_COLOR ].type = GL_FLOAT; - tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = glRefConfig.packedNormalDataType; + tess.vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = GL_SHORT; tess.vao->attribs[ATTR_INDEX_POSITION ].normalized = GL_FALSE; tess.vao->attribs[ATTR_INDEX_NORMAL ].normalized = GL_TRUE; -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/iortcw.git _______________________________________________ Pkg-games-commits mailing list Pkg-games-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits