00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "tr_local.h"
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 void RB_CheckOverflow( int verts, int indexes ) {
00049 if (tess.numVertexes + verts < SHADER_MAX_VERTEXES
00050 && tess.numIndexes + indexes < SHADER_MAX_INDEXES) {
00051 return;
00052 }
00053
00054 RB_EndSurface();
00055
00056 if ( verts >= SHADER_MAX_VERTEXES ) {
00057 ri.Error(ERR_DROP, "RB_CheckOverflow: verts > MAX (%d > %d)", verts, SHADER_MAX_VERTEXES );
00058 }
00059 if ( indexes >= SHADER_MAX_INDEXES ) {
00060 ri.Error(ERR_DROP, "RB_CheckOverflow: indices > MAX (%d > %d)", indexes, SHADER_MAX_INDEXES );
00061 }
00062
00063 RB_BeginSurface(tess.shader, tess.fogNum );
00064 }
00065
00066
00067
00068
00069
00070
00071
00072 void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, byte *color, float s1, float t1, float s2, float t2 ) {
00073 vec3_t normal;
00074 int ndx;
00075
00076 RB_CHECKOVERFLOW( 4, 6 );
00077
00078 ndx = tess.numVertexes;
00079
00080
00081 tess.indexes[ tess.numIndexes ] = ndx;
00082 tess.indexes[ tess.numIndexes + 1 ] = ndx + 1;
00083 tess.indexes[ tess.numIndexes + 2 ] = ndx + 3;
00084
00085 tess.indexes[ tess.numIndexes + 3 ] = ndx + 3;
00086 tess.indexes[ tess.numIndexes + 4 ] = ndx + 1;
00087 tess.indexes[ tess.numIndexes + 5 ] = ndx + 2;
00088
00089 tess.xyz[ndx][0] = origin[0] + left[0] + up[0];
00090 tess.xyz[ndx][1] = origin[1] + left[1] + up[1];
00091 tess.xyz[ndx][2] = origin[2] + left[2] + up[2];
00092
00093 tess.xyz[ndx+1][0] = origin[0] - left[0] + up[0];
00094 tess.xyz[ndx+1][1] = origin[1] - left[1] + up[1];
00095 tess.xyz[ndx+1][2] = origin[2] - left[2] + up[2];
00096
00097 tess.xyz[ndx+2][0] = origin[0] - left[0] - up[0];
00098 tess.xyz[ndx+2][1] = origin[1] - left[1] - up[1];
00099 tess.xyz[ndx+2][2] = origin[2] - left[2] - up[2];
00100
00101 tess.xyz[ndx+3][0] = origin[0] + left[0] - up[0];
00102 tess.xyz[ndx+3][1] = origin[1] + left[1] - up[1];
00103 tess.xyz[ndx+3][2] = origin[2] + left[2] - up[2];
00104
00105
00106
00107 VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal );
00108
00109 tess.normal[ndx][0] = tess.normal[ndx+1][0] = tess.normal[ndx+2][0] = tess.normal[ndx+3][0] = normal[0];
00110 tess.normal[ndx][1] = tess.normal[ndx+1][1] = tess.normal[ndx+2][1] = tess.normal[ndx+3][1] = normal[1];
00111 tess.normal[ndx][2] = tess.normal[ndx+1][2] = tess.normal[ndx+2][2] = tess.normal[ndx+3][2] = normal[2];
00112
00113
00114 tess.texCoords[ndx][0][0] = tess.texCoords[ndx][1][0] = s1;
00115 tess.texCoords[ndx][0][1] = tess.texCoords[ndx][1][1] = t1;
00116
00117 tess.texCoords[ndx+1][0][0] = tess.texCoords[ndx+1][1][0] = s2;
00118 tess.texCoords[ndx+1][0][1] = tess.texCoords[ndx+1][1][1] = t1;
00119
00120 tess.texCoords[ndx+2][0][0] = tess.texCoords[ndx+2][1][0] = s2;
00121 tess.texCoords[ndx+2][0][1] = tess.texCoords[ndx+2][1][1] = t2;
00122
00123 tess.texCoords[ndx+3][0][0] = tess.texCoords[ndx+3][1][0] = s1;
00124 tess.texCoords[ndx+3][0][1] = tess.texCoords[ndx+3][1][1] = t2;
00125
00126
00127
00128 * ( unsigned int * ) &tess.vertexColors[ndx] =
00129 * ( unsigned int * ) &tess.vertexColors[ndx+1] =
00130 * ( unsigned int * ) &tess.vertexColors[ndx+2] =
00131 * ( unsigned int * ) &tess.vertexColors[ndx+3] =
00132 * ( unsigned int * )color;
00133
00134
00135 tess.numVertexes += 4;
00136 tess.numIndexes += 6;
00137 }
00138
00139
00140
00141
00142
00143
00144 void RB_AddQuadStamp( vec3_t origin, vec3_t left, vec3_t up, byte *color ) {
00145 RB_AddQuadStampExt( origin, left, up, color, 0, 0, 1, 1 );
00146 }
00147
00148
00149
00150
00151
00152
00153 static void RB_SurfaceSprite( void ) {
00154 vec3_t left, up;
00155 float radius;
00156
00157
00158 radius = backEnd.currentEntity->e.radius;
00159 if ( backEnd.currentEntity->e.rotation == 0 ) {
00160 VectorScale( backEnd.viewParms.or.axis[1], radius, left );
00161 VectorScale( backEnd.viewParms.or.axis[2], radius, up );
00162 } else {
00163 float s, c;
00164 float ang;
00165
00166 ang = M_PI * backEnd.currentEntity->e.rotation / 180;
00167 s = sin( ang );
00168 c = cos( ang );
00169
00170 VectorScale( backEnd.viewParms.or.axis[1], c * radius, left );
00171 VectorMA( left, -s * radius, backEnd.viewParms.or.axis[2], left );
00172
00173 VectorScale( backEnd.viewParms.or.axis[2], c * radius, up );
00174 VectorMA( up, s * radius, backEnd.viewParms.or.axis[1], up );
00175 }
00176 if ( backEnd.viewParms.isMirror ) {
00177 VectorSubtract( vec3_origin, left, left );
00178 }
00179
00180 RB_AddQuadStamp( backEnd.currentEntity->e.origin, left, up, backEnd.currentEntity->e.shaderRGBA );
00181 }
00182
00183
00184
00185
00186
00187
00188
00189 void RB_SurfacePolychain( srfPoly_t *p ) {
00190 int i;
00191 int numv;
00192
00193 RB_CHECKOVERFLOW( p->numVerts, 3*(p->numVerts - 2) );
00194
00195
00196 numv = tess.numVertexes;
00197 for ( i = 0; i < p->numVerts; i++ ) {
00198 VectorCopy( p->verts[i].xyz, tess.xyz[numv] );
00199 tess.texCoords[numv][0][0] = p->verts[i].st[0];
00200 tess.texCoords[numv][0][1] = p->verts[i].st[1];
00201 *(int *)&tess.vertexColors[numv] = *(int *)p->verts[ i ].modulate;
00202
00203 numv++;
00204 }
00205
00206
00207 for ( i = 0; i < p->numVerts-2; i++ ) {
00208 tess.indexes[tess.numIndexes + 0] = tess.numVertexes;
00209 tess.indexes[tess.numIndexes + 1] = tess.numVertexes + i + 1;
00210 tess.indexes[tess.numIndexes + 2] = tess.numVertexes + i + 2;
00211 tess.numIndexes += 3;
00212 }
00213
00214 tess.numVertexes = numv;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223 void RB_SurfaceTriangles( srfTriangles_t *srf ) {
00224 int i;
00225 drawVert_t *dv;
00226 float *xyz, *normal, *texCoords;
00227 byte *color;
00228 int dlightBits;
00229 qboolean needsNormal;
00230
00231 dlightBits = srf->dlightBits[backEnd.smpFrame];
00232 tess.dlightBits |= dlightBits;
00233
00234 RB_CHECKOVERFLOW( srf->numVerts, srf->numIndexes );
00235
00236 for ( i = 0 ; i < srf->numIndexes ; i += 3 ) {
00237 tess.indexes[ tess.numIndexes + i + 0 ] = tess.numVertexes + srf->indexes[ i + 0 ];
00238 tess.indexes[ tess.numIndexes + i + 1 ] = tess.numVertexes + srf->indexes[ i + 1 ];
00239 tess.indexes[ tess.numIndexes + i + 2 ] = tess.numVertexes + srf->indexes[ i + 2 ];
00240 }
00241 tess.numIndexes += srf->numIndexes;
00242
00243 dv = srf->verts;
00244 xyz = tess.xyz[ tess.numVertexes ];
00245 normal = tess.normal[ tess.numVertexes ];
00246 texCoords = tess.texCoords[ tess.numVertexes ][0];
00247 color = tess.vertexColors[ tess.numVertexes ];
00248 needsNormal = tess.shader->needsNormal;
00249
00250 for ( i = 0 ; i < srf->numVerts ; i++, dv++, xyz += 4, normal += 4, texCoords += 4, color += 4 ) {
00251 xyz[0] = dv->xyz[0];
00252 xyz[1] = dv->xyz[1];
00253 xyz[2] = dv->xyz[2];
00254
00255 if ( needsNormal ) {
00256 normal[0] = dv->normal[0];
00257 normal[1] = dv->normal[1];
00258 normal[2] = dv->normal[2];
00259 }
00260
00261 texCoords[0] = dv->st[0];
00262 texCoords[1] = dv->st[1];
00263
00264 texCoords[2] = dv->lightmap[0];
00265 texCoords[3] = dv->lightmap[1];
00266
00267 *(int *)color = *(int *)dv->color;
00268 }
00269
00270 for ( i = 0 ; i < srf->numVerts ; i++ ) {
00271 tess.vertexDlightBits[ tess.numVertexes + i] = dlightBits;
00272 }
00273
00274 tess.numVertexes += srf->numVerts;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284 void RB_SurfaceBeam( void )
00285 {
00286 #define NUM_BEAM_SEGS 6
00287 refEntity_t *e;
00288 int i;
00289 vec3_t perpvec;
00290 vec3_t direction, normalized_direction;
00291 vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
00292 vec3_t oldorigin, origin;
00293
00294 e = &backEnd.currentEntity->e;
00295
00296 oldorigin[0] = e->oldorigin[0];
00297 oldorigin[1] = e->oldorigin[1];
00298 oldorigin[2] = e->oldorigin[2];
00299
00300 origin[0] = e->origin[0];
00301 origin[1] = e->origin[1];
00302 origin[2] = e->origin[2];
00303
00304 normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
00305 normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
00306 normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
00307
00308 if ( VectorNormalize( normalized_direction ) == 0 )
00309 return;
00310
00311 PerpendicularVector( perpvec, normalized_direction );
00312
00313 VectorScale( perpvec, 4, perpvec );
00314
00315 for ( i = 0; i < NUM_BEAM_SEGS ; i++ )
00316 {
00317 RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
00318
00319 VectorAdd( start_points[i], direction, end_points[i] );
00320 }
00321
00322 GL_Bind( tr.whiteImage );
00323
00324 GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
00325
00326 qglColor3f( 1, 0, 0 );
00327
00328 qglBegin( GL_TRIANGLE_STRIP );
00329 for ( i = 0; i <= NUM_BEAM_SEGS; i++ ) {
00330 qglVertex3fv( start_points[ i % NUM_BEAM_SEGS] );
00331 qglVertex3fv( end_points[ i % NUM_BEAM_SEGS] );
00332 }
00333 qglEnd();
00334 }
00335
00336
00337
00338 static void DoRailCore( const vec3_t start, const vec3_t end, const vec3_t up, float len, float spanWidth )
00339 {
00340 float spanWidth2;
00341 int vbase;
00342 float t = len / 256.0f;
00343
00344 vbase = tess.numVertexes;
00345
00346 spanWidth2 = -spanWidth;
00347
00348
00349 VectorMA( start, spanWidth, up, tess.xyz[tess.numVertexes] );
00350 tess.texCoords[tess.numVertexes][0][0] = 0;
00351 tess.texCoords[tess.numVertexes][0][1] = 0;
00352 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 0.25;
00353 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 0.25;
00354 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 0.25;
00355 tess.numVertexes++;
00356
00357 VectorMA( start, spanWidth2, up, tess.xyz[tess.numVertexes] );
00358 tess.texCoords[tess.numVertexes][0][0] = 0;
00359 tess.texCoords[tess.numVertexes][0][1] = 1;
00360 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0];
00361 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1];
00362 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2];
00363 tess.numVertexes++;
00364
00365 VectorMA( end, spanWidth, up, tess.xyz[tess.numVertexes] );
00366
00367 tess.texCoords[tess.numVertexes][0][0] = t;
00368 tess.texCoords[tess.numVertexes][0][1] = 0;
00369 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0];
00370 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1];
00371 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2];
00372 tess.numVertexes++;
00373
00374 VectorMA( end, spanWidth2, up, tess.xyz[tess.numVertexes] );
00375 tess.texCoords[tess.numVertexes][0][0] = t;
00376 tess.texCoords[tess.numVertexes][0][1] = 1;
00377 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0];
00378 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1];
00379 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2];
00380 tess.numVertexes++;
00381
00382 tess.indexes[tess.numIndexes++] = vbase;
00383 tess.indexes[tess.numIndexes++] = vbase + 1;
00384 tess.indexes[tess.numIndexes++] = vbase + 2;
00385
00386 tess.indexes[tess.numIndexes++] = vbase + 2;
00387 tess.indexes[tess.numIndexes++] = vbase + 1;
00388 tess.indexes[tess.numIndexes++] = vbase + 3;
00389 }
00390
00391 static void DoRailDiscs( int numSegs, const vec3_t start, const vec3_t dir, const vec3_t right, const vec3_t up )
00392 {
00393 int i;
00394 vec3_t pos[4];
00395 vec3_t v;
00396 int spanWidth = r_railWidth->integer;
00397 float c, s;
00398 float scale;
00399
00400 if ( numSegs > 1 )
00401 numSegs--;
00402 if ( !numSegs )
00403 return;
00404
00405 scale = 0.25;
00406
00407 for ( i = 0; i < 4; i++ )
00408 {
00409 c = cos( DEG2RAD( 45 + i * 90 ) );
00410 s = sin( DEG2RAD( 45 + i * 90 ) );
00411 v[0] = ( right[0] * c + up[0] * s ) * scale * spanWidth;
00412 v[1] = ( right[1] * c + up[1] * s ) * scale * spanWidth;
00413 v[2] = ( right[2] * c + up[2] * s ) * scale * spanWidth;
00414 VectorAdd( start, v, pos[i] );
00415
00416 if ( numSegs > 1 )
00417 {
00418
00419 VectorAdd( pos[i], dir, pos[i] );
00420 }
00421 }
00422
00423 for ( i = 0; i < numSegs; i++ )
00424 {
00425 int j;
00426
00427 RB_CHECKOVERFLOW( 4, 6 );
00428
00429 for ( j = 0; j < 4; j++ )
00430 {
00431 VectorCopy( pos[j], tess.xyz[tess.numVertexes] );
00432 tess.texCoords[tess.numVertexes][0][0] = ( j < 2 );
00433 tess.texCoords[tess.numVertexes][0][1] = ( j && j != 3 );
00434 tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0];
00435 tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1];
00436 tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2];
00437 tess.numVertexes++;
00438
00439 VectorAdd( pos[j], dir, pos[j] );
00440 }
00441
00442 tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 0;
00443 tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 1;
00444 tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 3;
00445 tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 3;
00446 tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 1;
00447 tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 2;
00448 }
00449 }
00450
00451
00452
00453
00454 void RB_SurfaceRailRings( void ) {
00455 refEntity_t *e;
00456 int numSegs;
00457 int len;
00458 vec3_t vec;
00459 vec3_t right, up;
00460 vec3_t start, end;
00461
00462 e = &backEnd.currentEntity->e;
00463
00464 VectorCopy( e->oldorigin, start );
00465 VectorCopy( e->origin, end );
00466
00467
00468 VectorSubtract( end, start, vec );
00469 len = VectorNormalize( vec );
00470 MakeNormalVectors( vec, right, up );
00471 numSegs = ( len ) / r_railSegmentLength->value;
00472 if ( numSegs <= 0 ) {
00473 numSegs = 1;
00474 }
00475
00476 VectorScale( vec, r_railSegmentLength->value, vec );
00477
00478 DoRailDiscs( numSegs, start, vec, right, up );
00479 }
00480
00481
00482
00483
00484 void RB_SurfaceRailCore( void ) {
00485 refEntity_t *e;
00486 int len;
00487 vec3_t right;
00488 vec3_t vec;
00489 vec3_t start, end;
00490 vec3_t v1, v2;
00491
00492 e = &backEnd.currentEntity->e;
00493
00494 VectorCopy( e->oldorigin, start );
00495 VectorCopy( e->origin, end );
00496
00497 VectorSubtract( end, start, vec );
00498 len = VectorNormalize( vec );
00499
00500
00501 VectorSubtract( start, backEnd.viewParms.or.origin, v1 );
00502 VectorNormalize( v1 );
00503 VectorSubtract( end, backEnd.viewParms.or.origin, v2 );
00504 VectorNormalize( v2 );
00505 CrossProduct( v1, v2, right );
00506 VectorNormalize( right );
00507
00508 DoRailCore( start, end, right, len, r_railCoreWidth->integer );
00509 }
00510
00511
00512
00513
00514 void RB_SurfaceLightningBolt( void ) {
00515 refEntity_t *e;
00516 int len;
00517 vec3_t right;
00518 vec3_t vec;
00519 vec3_t start, end;
00520 vec3_t v1, v2;
00521 int i;
00522
00523 e = &backEnd.currentEntity->e;
00524
00525 VectorCopy( e->oldorigin, end );
00526 VectorCopy( e->origin, start );
00527
00528
00529 VectorSubtract( end, start, vec );
00530 len = VectorNormalize( vec );
00531
00532
00533 VectorSubtract( start, backEnd.viewParms.or.origin, v1 );
00534 VectorNormalize( v1 );
00535 VectorSubtract( end, backEnd.viewParms.or.origin, v2 );
00536 VectorNormalize( v2 );
00537 CrossProduct( v1, v2, right );
00538 VectorNormalize( right );
00539
00540 for ( i = 0 ; i < 4 ; i++ ) {
00541 vec3_t temp;
00542
00543 DoRailCore( start, end, right, len, 8 );
00544 RotatePointAroundVector( temp, vec, right, 45 );
00545 VectorCopy( temp, right );
00546 }
00547 }
00548
00549
00550
00551
00552
00553
00554
00555 static void VectorArrayNormalize(vec4_t *normals, unsigned int count)
00556 {
00557
00558
00559 #if idppc
00560 {
00561 register float half = 0.5;
00562 register float one = 1.0;
00563 float *components = (float *)normals;
00564
00565
00566
00567
00568
00569
00570 do {
00571 float x, y, z;
00572 float B, y0, y1;
00573
00574 x = components[0];
00575 y = components[1];
00576 z = components[2];
00577 components += 4;
00578 B = x*x + y*y + z*z;
00579
00580 #ifdef __GNUC__
00581 asm("frsqrte %0,%1" : "=f" (y0) : "f" (B));
00582 #else
00583 y0 = __frsqrte(B);
00584 #endif
00585 y1 = y0 + half*y0*(one - B*y0*y0);
00586
00587 x = x * y1;
00588 y = y * y1;
00589 components[-4] = x;
00590 z = z * y1;
00591 components[-3] = y;
00592 components[-2] = z;
00593 } while(count--);
00594 }
00595 #else // No assembly version for this architecture, or C_ONLY defined
00596
00597 while (count--) {
00598 VectorNormalizeFast(normals[0]);
00599 normals++;
00600 }
00601 #endif
00602
00603 }
00604
00605
00606
00607
00608
00609
00610 static void LerpMeshVertexes (md3Surface_t *surf, float backlerp)
00611 {
00612 short *oldXyz, *newXyz, *oldNormals, *newNormals;
00613 float *outXyz, *outNormal;
00614 float oldXyzScale, newXyzScale;
00615 float oldNormalScale, newNormalScale;
00616 int vertNum;
00617 unsigned lat, lng;
00618 int numVerts;
00619
00620 outXyz = tess.xyz[tess.numVertexes];
00621 outNormal = tess.normal[tess.numVertexes];
00622
00623 newXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
00624 + (backEnd.currentEntity->e.frame * surf->numVerts * 4);
00625 newNormals = newXyz + 3;
00626
00627 newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp);
00628 newNormalScale = 1.0 - backlerp;
00629
00630 numVerts = surf->numVerts;
00631
00632 if ( backlerp == 0 ) {
00633 #if idppc_altivec
00634 vector signed short newNormalsVec0;
00635 vector signed short newNormalsVec1;
00636 vector signed int newNormalsIntVec;
00637 vector float newNormalsFloatVec;
00638 vector float newXyzScaleVec;
00639 vector unsigned char newNormalsLoadPermute;
00640 vector unsigned char newNormalsStorePermute;
00641 vector float zero;
00642
00643 newNormalsStorePermute = vec_lvsl(0,(float *)&newXyzScaleVec);
00644 newXyzScaleVec = *(vector float *)&newXyzScale;
00645 newXyzScaleVec = vec_perm(newXyzScaleVec,newXyzScaleVec,newNormalsStorePermute);
00646 newXyzScaleVec = vec_splat(newXyzScaleVec,0);
00647 newNormalsLoadPermute = vec_lvsl(0,newXyz);
00648 newNormalsStorePermute = vec_lvsr(0,outXyz);
00649 zero = (vector float)vec_splat_s8(0);
00650
00651
00652
00653 for (vertNum=0 ; vertNum < numVerts ; vertNum++,
00654 newXyz += 4, newNormals += 4,
00655 outXyz += 4, outNormal += 4)
00656 {
00657 newNormalsLoadPermute = vec_lvsl(0,newXyz);
00658 newNormalsStorePermute = vec_lvsr(0,outXyz);
00659 newNormalsVec0 = vec_ld(0,newXyz);
00660 newNormalsVec1 = vec_ld(16,newXyz);
00661 newNormalsVec0 = vec_perm(newNormalsVec0,newNormalsVec1,newNormalsLoadPermute);
00662 newNormalsIntVec = vec_unpackh(newNormalsVec0);
00663 newNormalsFloatVec = vec_ctf(newNormalsIntVec,0);
00664 newNormalsFloatVec = vec_madd(newNormalsFloatVec,newXyzScaleVec,zero);
00665 newNormalsFloatVec = vec_perm(newNormalsFloatVec,newNormalsFloatVec,newNormalsStorePermute);
00666
00667
00668
00669
00670 lat = ( newNormals[0] >> 8 ) & 0xff;
00671 lng = ( newNormals[0] & 0xff );
00672 lat *= (FUNCTABLE_SIZE/256);
00673 lng *= (FUNCTABLE_SIZE/256);
00674
00675
00676
00677
00678
00679 outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
00680 outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
00681 outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
00682
00683 vec_ste(newNormalsFloatVec,0,outXyz);
00684 vec_ste(newNormalsFloatVec,4,outXyz);
00685 vec_ste(newNormalsFloatVec,8,outXyz);
00686 }
00687
00688 #else
00689
00690
00691
00692 for (vertNum=0 ; vertNum < numVerts ; vertNum++,
00693 newXyz += 4, newNormals += 4,
00694 outXyz += 4, outNormal += 4)
00695 {
00696
00697 outXyz[0] = newXyz[0] * newXyzScale;
00698 outXyz[1] = newXyz[1] * newXyzScale;
00699 outXyz[2] = newXyz[2] * newXyzScale;
00700
00701 lat = ( newNormals[0] >> 8 ) & 0xff;
00702 lng = ( newNormals[0] & 0xff );
00703 lat *= (FUNCTABLE_SIZE/256);
00704 lng *= (FUNCTABLE_SIZE/256);
00705
00706
00707
00708
00709
00710 outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
00711 outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
00712 outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
00713 }
00714 #endif
00715 } else {
00716
00717
00718
00719 oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
00720 + (backEnd.currentEntity->e.oldframe * surf->numVerts * 4);
00721 oldNormals = oldXyz + 3;
00722
00723 oldXyzScale = MD3_XYZ_SCALE * backlerp;
00724 oldNormalScale = backlerp;
00725
00726 for (vertNum=0 ; vertNum < numVerts ; vertNum++,
00727 oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4,
00728 outXyz += 4, outNormal += 4)
00729 {
00730 vec3_t uncompressedOldNormal, uncompressedNewNormal;
00731
00732
00733 outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale;
00734 outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale;
00735 outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale;
00736
00737
00738 lat = ( newNormals[0] >> 8 ) & 0xff;
00739 lng = ( newNormals[0] & 0xff );
00740 lat *= 4;
00741 lng *= 4;
00742 uncompressedNewNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
00743 uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
00744 uncompressedNewNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
00745
00746 lat = ( oldNormals[0] >> 8 ) & 0xff;
00747 lng = ( oldNormals[0] & 0xff );
00748 lat *= 4;
00749 lng *= 4;
00750
00751 uncompressedOldNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
00752 uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
00753 uncompressedOldNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
00754
00755 outNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale;
00756 outNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale;
00757 outNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale;
00758
00759
00760 }
00761 VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts);
00762 }
00763 }
00764
00765
00766
00767
00768
00769
00770 void RB_SurfaceMesh(md3Surface_t *surface) {
00771 int j;
00772 float backlerp;
00773 int *triangles;
00774 float *texCoords;
00775 int indexes;
00776 int Bob, Doug;
00777 int numVerts;
00778
00779 if ( backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame ) {
00780 backlerp = 0;
00781 } else {
00782 backlerp = backEnd.currentEntity->e.backlerp;
00783 }
00784
00785 RB_CHECKOVERFLOW( surface->numVerts, surface->numTriangles*3 );
00786
00787 LerpMeshVertexes (surface, backlerp);
00788
00789 triangles = (int *) ((byte *)surface + surface->ofsTriangles);
00790 indexes = surface->numTriangles * 3;
00791 Bob = tess.numIndexes;
00792 Doug = tess.numVertexes;
00793 for (j = 0 ; j < indexes ; j++) {
00794 tess.indexes[Bob + j] = Doug + triangles[j];
00795 }
00796 tess.numIndexes += indexes;
00797
00798 texCoords = (float *) ((byte *)surface + surface->ofsSt);
00799
00800 numVerts = surface->numVerts;
00801 for ( j = 0; j < numVerts; j++ ) {
00802 tess.texCoords[Doug + j][0][0] = texCoords[j*2+0];
00803 tess.texCoords[Doug + j][0][1] = texCoords[j*2+1];
00804
00805 }
00806
00807 tess.numVertexes += surface->numVerts;
00808
00809 }
00810
00811
00812
00813
00814
00815
00816
00817 void RB_SurfaceFace( srfSurfaceFace_t *surf ) {
00818 int i;
00819 unsigned *indices, *tessIndexes;
00820 float *v;
00821 float *normal;
00822 int ndx;
00823 int Bob;
00824 int numPoints;
00825 int dlightBits;
00826
00827 RB_CHECKOVERFLOW( surf->numPoints, surf->numIndices );
00828
00829 dlightBits = surf->dlightBits[backEnd.smpFrame];
00830 tess.dlightBits |= dlightBits;
00831
00832 indices = ( unsigned * ) ( ( ( char * ) surf ) + surf->ofsIndices );
00833
00834 Bob = tess.numVertexes;
00835 tessIndexes = tess.indexes + tess.numIndexes;
00836 for ( i = surf->numIndices-1 ; i >= 0 ; i-- ) {
00837 tessIndexes[i] = indices[i] + Bob;
00838 }
00839
00840 tess.numIndexes += surf->numIndices;
00841
00842 v = surf->points[0];
00843
00844 ndx = tess.numVertexes;
00845
00846 numPoints = surf->numPoints;
00847
00848 if ( tess.shader->needsNormal ) {
00849 normal = surf->plane.normal;
00850 for ( i = 0, ndx = tess.numVertexes; i < numPoints; i++, ndx++ ) {
00851 VectorCopy( normal, tess.normal[ndx] );
00852 }
00853 }
00854
00855 for ( i = 0, v = surf->points[0], ndx = tess.numVertexes; i < numPoints; i++, v += VERTEXSIZE, ndx++ ) {
00856 VectorCopy( v, tess.xyz[ndx]);
00857 tess.texCoords[ndx][0][0] = v[3];
00858 tess.texCoords[ndx][0][1] = v[4];
00859 tess.texCoords[ndx][1][0] = v[5];
00860 tess.texCoords[ndx][1][1] = v[6];
00861 * ( unsigned int * ) &tess.vertexColors[ndx] = * ( unsigned int * ) &v[7];
00862 tess.vertexDlightBits[ndx] = dlightBits;
00863 }
00864
00865
00866 tess.numVertexes += surf->numPoints;
00867 }
00868
00869
00870 static float LodErrorForVolume( vec3_t local, float radius ) {
00871 vec3_t world;
00872 float d;
00873
00874
00875 if ( r_lodCurveError->value < 0 ) {
00876 return 0;
00877 }
00878
00879 world[0] = local[0] * backEnd.or.axis[0][0] + local[1] * backEnd.or.axis[1][0] +
00880 local[2] * backEnd.or.axis[2][0] + backEnd.or.origin[0];
00881 world[1] = local[0] * backEnd.or.axis[0][1] + local[1] * backEnd.or.axis[1][1] +
00882 local[2] * backEnd.or.axis[2][1] + backEnd.or.origin[1];
00883 world[2] = local[0] * backEnd.or.axis[0][2] + local[1] * backEnd.or.axis[1][2] +
00884 local[2] * backEnd.or.axis[2][2] + backEnd.or.origin[2];
00885
00886 VectorSubtract( world, backEnd.viewParms.or.origin, world );
00887 d = DotProduct( world, backEnd.viewParms.or.axis[0] );
00888
00889 if ( d < 0 ) {
00890 d = -d;
00891 }
00892 d -= radius;
00893 if ( d < 1 ) {
00894 d = 1;
00895 }
00896
00897 return r_lodCurveError->value / d;
00898 }
00899
00900
00901
00902
00903
00904
00905
00906
00907 void RB_SurfaceGrid( srfGridMesh_t *cv ) {
00908 int i, j;
00909 float *xyz;
00910 float *texCoords;
00911 float *normal;
00912 unsigned char *color;
00913 drawVert_t *dv;
00914 int rows, irows, vrows;
00915 int used;
00916 int widthTable[MAX_GRID_SIZE];
00917 int heightTable[MAX_GRID_SIZE];
00918 float lodError;
00919 int lodWidth, lodHeight;
00920 int numVertexes;
00921 int dlightBits;
00922 int *vDlightBits;
00923 qboolean needsNormal;
00924
00925 dlightBits = cv->dlightBits[backEnd.smpFrame];
00926 tess.dlightBits |= dlightBits;
00927
00928
00929 lodError = LodErrorForVolume( cv->lodOrigin, cv->lodRadius );
00930
00931
00932
00933 widthTable[0] = 0;
00934 lodWidth = 1;
00935 for ( i = 1 ; i < cv->width-1 ; i++ ) {
00936 if ( cv->widthLodError[i] <= lodError ) {
00937 widthTable[lodWidth] = i;
00938 lodWidth++;
00939 }
00940 }
00941 widthTable[lodWidth] = cv->width-1;
00942 lodWidth++;
00943
00944 heightTable[0] = 0;
00945 lodHeight = 1;
00946 for ( i = 1 ; i < cv->height-1 ; i++ ) {
00947 if ( cv->heightLodError[i] <= lodError ) {
00948 heightTable[lodHeight] = i;
00949 lodHeight++;
00950 }
00951 }
00952 heightTable[lodHeight] = cv->height-1;
00953 lodHeight++;
00954
00955
00956
00957
00958
00959 used = 0;
00960 rows = 0;
00961 while ( used < lodHeight - 1 ) {
00962
00963 do {
00964 vrows = ( SHADER_MAX_VERTEXES - tess.numVertexes ) / lodWidth;
00965 irows = ( SHADER_MAX_INDEXES - tess.numIndexes ) / ( lodWidth * 6 );
00966
00967
00968 if ( vrows < 2 || irows < 1 ) {
00969 RB_EndSurface();
00970 RB_BeginSurface(tess.shader, tess.fogNum );
00971 } else {
00972 break;
00973 }
00974 } while ( 1 );
00975
00976 rows = irows;
00977 if ( vrows < irows + 1 ) {
00978 rows = vrows - 1;
00979 }
00980 if ( used + rows > lodHeight ) {
00981 rows = lodHeight - used;
00982 }
00983
00984 numVertexes = tess.numVertexes;
00985
00986 xyz = tess.xyz[numVertexes];
00987 normal = tess.normal[numVertexes];
00988 texCoords = tess.texCoords[numVertexes][0];
00989 color = ( unsigned char * ) &tess.vertexColors[numVertexes];
00990 vDlightBits = &tess.vertexDlightBits[numVertexes];
00991 needsNormal = tess.shader->needsNormal;
00992
00993 for ( i = 0 ; i < rows ; i++ ) {
00994 for ( j = 0 ; j < lodWidth ; j++ ) {
00995 dv = cv->verts + heightTable[ used + i ] * cv->width
00996 + widthTable[ j ];
00997
00998 xyz[0] = dv->xyz[0];
00999 xyz[1] = dv->xyz[1];
01000 xyz[2] = dv->xyz[2];
01001 texCoords[0] = dv->st[0];
01002 texCoords[1] = dv->st[1];
01003 texCoords[2] = dv->lightmap[0];
01004 texCoords[3] = dv->lightmap[1];
01005 if ( needsNormal ) {
01006 normal[0] = dv->normal[0];
01007 normal[1] = dv->normal[1];
01008 normal[2] = dv->normal[2];
01009 }
01010 * ( unsigned int * ) color = * ( unsigned int * ) dv->color;
01011 *vDlightBits++ = dlightBits;
01012 xyz += 4;
01013 normal += 4;
01014 texCoords += 4;
01015 color += 4;
01016 }
01017 }
01018
01019
01020
01021 {
01022 int numIndexes;
01023 int w, h;
01024
01025 h = rows - 1;
01026 w = lodWidth - 1;
01027 numIndexes = tess.numIndexes;
01028 for (i = 0 ; i < h ; i++) {
01029 for (j = 0 ; j < w ; j++) {
01030 int v1, v2, v3, v4;
01031
01032
01033 v1 = numVertexes + i*lodWidth + j + 1;
01034 v2 = v1 - 1;
01035 v3 = v2 + lodWidth;
01036 v4 = v3 + 1;
01037
01038 tess.indexes[numIndexes] = v2;
01039 tess.indexes[numIndexes+1] = v3;
01040 tess.indexes[numIndexes+2] = v1;
01041
01042 tess.indexes[numIndexes+3] = v1;
01043 tess.indexes[numIndexes+4] = v3;
01044 tess.indexes[numIndexes+5] = v4;
01045 numIndexes += 6;
01046 }
01047 }
01048
01049 tess.numIndexes = numIndexes;
01050 }
01051
01052 tess.numVertexes += rows * lodWidth;
01053
01054 used += rows - 1;
01055 }
01056 }
01057
01058
01059
01060