2
===========================================================================
3
Copyright (C) 1999-2005 Id Software, Inc.
5
This file is part of Quake III Arena source code.
7
Quake III Arena source code is free software; you can redistribute it
8
and/or modify it under the terms of the GNU General Public License as
9
published by the Free Software Foundation; either version 2 of the License,
10
or (at your option) any later version.
12
Quake III Arena source code is distributed in the hope that it will be
13
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with Quake III Arena source code; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
===========================================================================
24
#if idppc_altivec && !defined(MACOS_X)
30
THIS ENTIRE FILE IS BACK END
32
backEnd.currentEntity will be valid.
34
Tess_Begin has already been called for the surface's shader.
36
The modelview matrix will be set.
38
It is safe to actually issue drawing commands here if you don't want to
39
use the shader system.
43
//============================================================================
51
void RB_CheckOverflow( int verts, int indexes ) {
52
if (tess.numVertexes + verts < SHADER_MAX_VERTEXES
53
&& tess.numIndexes + indexes < SHADER_MAX_INDEXES) {
59
if ( verts >= SHADER_MAX_VERTEXES ) {
60
ri.Error(ERR_DROP, "RB_CheckOverflow: verts > MAX (%d > %d)", verts, SHADER_MAX_VERTEXES );
62
if ( indexes >= SHADER_MAX_INDEXES ) {
63
ri.Error(ERR_DROP, "RB_CheckOverflow: indices > MAX (%d > %d)", indexes, SHADER_MAX_INDEXES );
66
RB_BeginSurface(tess.shader, tess.fogNum );
75
void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, byte *color, float s1, float t1, float s2, float t2 ) {
79
RB_CHECKOVERFLOW( 4, 6 );
81
ndx = tess.numVertexes;
83
// triangle indexes for a simple quad
84
tess.indexes[ tess.numIndexes ] = ndx;
85
tess.indexes[ tess.numIndexes + 1 ] = ndx + 1;
86
tess.indexes[ tess.numIndexes + 2 ] = ndx + 3;
88
tess.indexes[ tess.numIndexes + 3 ] = ndx + 3;
89
tess.indexes[ tess.numIndexes + 4 ] = ndx + 1;
90
tess.indexes[ tess.numIndexes + 5 ] = ndx + 2;
92
tess.xyz[ndx][0] = origin[0] + left[0] + up[0];
93
tess.xyz[ndx][1] = origin[1] + left[1] + up[1];
94
tess.xyz[ndx][2] = origin[2] + left[2] + up[2];
96
tess.xyz[ndx+1][0] = origin[0] - left[0] + up[0];
97
tess.xyz[ndx+1][1] = origin[1] - left[1] + up[1];
98
tess.xyz[ndx+1][2] = origin[2] - left[2] + up[2];
100
tess.xyz[ndx+2][0] = origin[0] - left[0] - up[0];
101
tess.xyz[ndx+2][1] = origin[1] - left[1] - up[1];
102
tess.xyz[ndx+2][2] = origin[2] - left[2] - up[2];
104
tess.xyz[ndx+3][0] = origin[0] + left[0] - up[0];
105
tess.xyz[ndx+3][1] = origin[1] + left[1] - up[1];
106
tess.xyz[ndx+3][2] = origin[2] + left[2] - up[2];
109
// constant normal all the way around
110
VectorSubtract( vec3_origin, backEnd.viewParms.or.axis[0], normal );
112
tess.normal[ndx][0] = tess.normal[ndx+1][0] = tess.normal[ndx+2][0] = tess.normal[ndx+3][0] = normal[0];
113
tess.normal[ndx][1] = tess.normal[ndx+1][1] = tess.normal[ndx+2][1] = tess.normal[ndx+3][1] = normal[1];
114
tess.normal[ndx][2] = tess.normal[ndx+1][2] = tess.normal[ndx+2][2] = tess.normal[ndx+3][2] = normal[2];
116
// standard square texture coordinates
117
tess.texCoords[ndx][0][0] = tess.texCoords[ndx][1][0] = s1;
118
tess.texCoords[ndx][0][1] = tess.texCoords[ndx][1][1] = t1;
120
tess.texCoords[ndx+1][0][0] = tess.texCoords[ndx+1][1][0] = s2;
121
tess.texCoords[ndx+1][0][1] = tess.texCoords[ndx+1][1][1] = t1;
123
tess.texCoords[ndx+2][0][0] = tess.texCoords[ndx+2][1][0] = s2;
124
tess.texCoords[ndx+2][0][1] = tess.texCoords[ndx+2][1][1] = t2;
126
tess.texCoords[ndx+3][0][0] = tess.texCoords[ndx+3][1][0] = s1;
127
tess.texCoords[ndx+3][0][1] = tess.texCoords[ndx+3][1][1] = t2;
129
// constant color all the way around
130
// should this be identity and let the shader specify from entity?
131
* ( unsigned int * ) &tess.vertexColors[ndx] =
132
* ( unsigned int * ) &tess.vertexColors[ndx+1] =
133
* ( unsigned int * ) &tess.vertexColors[ndx+2] =
134
* ( unsigned int * ) &tess.vertexColors[ndx+3] =
135
* ( unsigned int * )color;
138
tess.numVertexes += 4;
139
tess.numIndexes += 6;
147
void RB_AddQuadStamp( vec3_t origin, vec3_t left, vec3_t up, byte *color ) {
148
RB_AddQuadStampExt( origin, left, up, color, 0, 0, 1, 1 );
156
static void RB_SurfaceSprite( void ) {
160
// calculate the xyz locations for the four corners
161
radius = backEnd.currentEntity->e.radius;
162
if ( backEnd.currentEntity->e.rotation == 0 ) {
163
VectorScale( backEnd.viewParms.or.axis[1], radius, left );
164
VectorScale( backEnd.viewParms.or.axis[2], radius, up );
169
ang = M_PI * backEnd.currentEntity->e.rotation / 180;
173
VectorScale( backEnd.viewParms.or.axis[1], c * radius, left );
174
VectorMA( left, -s * radius, backEnd.viewParms.or.axis[2], left );
176
VectorScale( backEnd.viewParms.or.axis[2], c * radius, up );
177
VectorMA( up, s * radius, backEnd.viewParms.or.axis[1], up );
179
if ( backEnd.viewParms.isMirror ) {
180
VectorSubtract( vec3_origin, left, left );
183
RB_AddQuadStamp( backEnd.currentEntity->e.origin, left, up, backEnd.currentEntity->e.shaderRGBA );
192
void RB_SurfacePolychain( srfPoly_t *p ) {
196
RB_CHECKOVERFLOW( p->numVerts, 3*(p->numVerts - 2) );
198
// fan triangles into the tess array
199
numv = tess.numVertexes;
200
for ( i = 0; i < p->numVerts; i++ ) {
201
VectorCopy( p->verts[i].xyz, tess.xyz[numv] );
202
tess.texCoords[numv][0][0] = p->verts[i].st[0];
203
tess.texCoords[numv][0][1] = p->verts[i].st[1];
204
*(int *)&tess.vertexColors[numv] = *(int *)p->verts[ i ].modulate;
209
// generate fan indexes into the tess array
210
for ( i = 0; i < p->numVerts-2; i++ ) {
211
tess.indexes[tess.numIndexes + 0] = tess.numVertexes;
212
tess.indexes[tess.numIndexes + 1] = tess.numVertexes + i + 1;
213
tess.indexes[tess.numIndexes + 2] = tess.numVertexes + i + 2;
214
tess.numIndexes += 3;
217
tess.numVertexes = numv;
226
void RB_SurfaceTriangles( srfTriangles_t *srf ) {
229
float *xyz, *normal, *texCoords;
232
qboolean needsNormal;
234
dlightBits = srf->dlightBits[backEnd.smpFrame];
235
tess.dlightBits |= dlightBits;
237
RB_CHECKOVERFLOW( srf->numVerts, srf->numIndexes );
239
for ( i = 0 ; i < srf->numIndexes ; i += 3 ) {
240
tess.indexes[ tess.numIndexes + i + 0 ] = tess.numVertexes + srf->indexes[ i + 0 ];
241
tess.indexes[ tess.numIndexes + i + 1 ] = tess.numVertexes + srf->indexes[ i + 1 ];
242
tess.indexes[ tess.numIndexes + i + 2 ] = tess.numVertexes + srf->indexes[ i + 2 ];
244
tess.numIndexes += srf->numIndexes;
247
xyz = tess.xyz[ tess.numVertexes ];
248
normal = tess.normal[ tess.numVertexes ];
249
texCoords = tess.texCoords[ tess.numVertexes ][0];
250
color = tess.vertexColors[ tess.numVertexes ];
251
needsNormal = tess.shader->needsNormal;
253
for ( i = 0 ; i < srf->numVerts ; i++, dv++, xyz += 4, normal += 4, texCoords += 4, color += 4 ) {
259
normal[0] = dv->normal[0];
260
normal[1] = dv->normal[1];
261
normal[2] = dv->normal[2];
264
texCoords[0] = dv->st[0];
265
texCoords[1] = dv->st[1];
267
texCoords[2] = dv->lightmap[0];
268
texCoords[3] = dv->lightmap[1];
270
*(int *)color = *(int *)dv->color;
273
for ( i = 0 ; i < srf->numVerts ; i++ ) {
274
tess.vertexDlightBits[ tess.numVertexes + i] = dlightBits;
277
tess.numVertexes += srf->numVerts;
287
void RB_SurfaceBeam( void )
289
#define NUM_BEAM_SEGS 6
293
vec3_t direction, normalized_direction;
294
vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
295
vec3_t oldorigin, origin;
297
e = &backEnd.currentEntity->e;
299
oldorigin[0] = e->oldorigin[0];
300
oldorigin[1] = e->oldorigin[1];
301
oldorigin[2] = e->oldorigin[2];
303
origin[0] = e->origin[0];
304
origin[1] = e->origin[1];
305
origin[2] = e->origin[2];
307
normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
308
normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
309
normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
311
if ( VectorNormalize( normalized_direction ) == 0 )
314
PerpendicularVector( perpvec, normalized_direction );
316
VectorScale( perpvec, 4, perpvec );
318
for ( i = 0; i < NUM_BEAM_SEGS ; i++ )
320
RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
321
// VectorAdd( start_points[i], origin, start_points[i] );
322
VectorAdd( start_points[i], direction, end_points[i] );
325
GL_Bind( tr.whiteImage );
327
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
329
qglColor3f( 1, 0, 0 );
331
qglBegin( GL_TRIANGLE_STRIP );
332
for ( i = 0; i <= NUM_BEAM_SEGS; i++ ) {
333
qglVertex3fv( start_points[ i % NUM_BEAM_SEGS] );
334
qglVertex3fv( end_points[ i % NUM_BEAM_SEGS] );
339
//================================================================================
341
static void DoRailCore( const vec3_t start, const vec3_t end, const vec3_t up, float len, float spanWidth )
345
float t = len / 256.0f;
347
vbase = tess.numVertexes;
349
spanWidth2 = -spanWidth;
351
// FIXME: use quad stamp?
352
VectorMA( start, spanWidth, up, tess.xyz[tess.numVertexes] );
353
tess.texCoords[tess.numVertexes][0][0] = 0;
354
tess.texCoords[tess.numVertexes][0][1] = 0;
355
tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0] * 0.25;
356
tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1] * 0.25;
357
tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2] * 0.25;
360
VectorMA( start, spanWidth2, up, tess.xyz[tess.numVertexes] );
361
tess.texCoords[tess.numVertexes][0][0] = 0;
362
tess.texCoords[tess.numVertexes][0][1] = 1;
363
tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0];
364
tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1];
365
tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2];
368
VectorMA( end, spanWidth, up, tess.xyz[tess.numVertexes] );
370
tess.texCoords[tess.numVertexes][0][0] = t;
371
tess.texCoords[tess.numVertexes][0][1] = 0;
372
tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0];
373
tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1];
374
tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2];
377
VectorMA( end, spanWidth2, up, tess.xyz[tess.numVertexes] );
378
tess.texCoords[tess.numVertexes][0][0] = t;
379
tess.texCoords[tess.numVertexes][0][1] = 1;
380
tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0];
381
tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1];
382
tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2];
385
tess.indexes[tess.numIndexes++] = vbase;
386
tess.indexes[tess.numIndexes++] = vbase + 1;
387
tess.indexes[tess.numIndexes++] = vbase + 2;
389
tess.indexes[tess.numIndexes++] = vbase + 2;
390
tess.indexes[tess.numIndexes++] = vbase + 1;
391
tess.indexes[tess.numIndexes++] = vbase + 3;
394
static void DoRailDiscs( int numSegs, const vec3_t start, const vec3_t dir, const vec3_t right, const vec3_t up )
399
int spanWidth = r_railWidth->integer;
410
for ( i = 0; i < 4; i++ )
412
c = cos( DEG2RAD( 45 + i * 90 ) );
413
s = sin( DEG2RAD( 45 + i * 90 ) );
414
v[0] = ( right[0] * c + up[0] * s ) * scale * spanWidth;
415
v[1] = ( right[1] * c + up[1] * s ) * scale * spanWidth;
416
v[2] = ( right[2] * c + up[2] * s ) * scale * spanWidth;
417
VectorAdd( start, v, pos[i] );
421
// offset by 1 segment if we're doing a long distance shot
422
VectorAdd( pos[i], dir, pos[i] );
426
for ( i = 0; i < numSegs; i++ )
430
RB_CHECKOVERFLOW( 4, 6 );
432
for ( j = 0; j < 4; j++ )
434
VectorCopy( pos[j], tess.xyz[tess.numVertexes] );
435
tess.texCoords[tess.numVertexes][0][0] = ( j < 2 );
436
tess.texCoords[tess.numVertexes][0][1] = ( j && j != 3 );
437
tess.vertexColors[tess.numVertexes][0] = backEnd.currentEntity->e.shaderRGBA[0];
438
tess.vertexColors[tess.numVertexes][1] = backEnd.currentEntity->e.shaderRGBA[1];
439
tess.vertexColors[tess.numVertexes][2] = backEnd.currentEntity->e.shaderRGBA[2];
442
VectorAdd( pos[j], dir, pos[j] );
445
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 0;
446
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 1;
447
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 3;
448
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 3;
449
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 1;
450
tess.indexes[tess.numIndexes++] = tess.numVertexes - 4 + 2;
455
** RB_SurfaceRailRinges
457
void RB_SurfaceRailRings( void ) {
465
e = &backEnd.currentEntity->e;
467
VectorCopy( e->oldorigin, start );
468
VectorCopy( e->origin, end );
471
VectorSubtract( end, start, vec );
472
len = VectorNormalize( vec );
473
MakeNormalVectors( vec, right, up );
474
numSegs = ( len ) / r_railSegmentLength->value;
475
if ( numSegs <= 0 ) {
479
VectorScale( vec, r_railSegmentLength->value, vec );
481
DoRailDiscs( numSegs, start, vec, right, up );
485
** RB_SurfaceRailCore
487
void RB_SurfaceRailCore( void ) {
495
e = &backEnd.currentEntity->e;
497
VectorCopy( e->oldorigin, start );
498
VectorCopy( e->origin, end );
500
VectorSubtract( end, start, vec );
501
len = VectorNormalize( vec );
503
// compute side vector
504
VectorSubtract( start, backEnd.viewParms.or.origin, v1 );
505
VectorNormalize( v1 );
506
VectorSubtract( end, backEnd.viewParms.or.origin, v2 );
507
VectorNormalize( v2 );
508
CrossProduct( v1, v2, right );
509
VectorNormalize( right );
511
DoRailCore( start, end, right, len, r_railCoreWidth->integer );
515
** RB_SurfaceLightningBolt
517
void RB_SurfaceLightningBolt( void ) {
526
e = &backEnd.currentEntity->e;
528
VectorCopy( e->oldorigin, end );
529
VectorCopy( e->origin, start );
532
VectorSubtract( end, start, vec );
533
len = VectorNormalize( vec );
535
// compute side vector
536
VectorSubtract( start, backEnd.viewParms.or.origin, v1 );
537
VectorNormalize( v1 );
538
VectorSubtract( end, backEnd.viewParms.or.origin, v2 );
539
VectorNormalize( v2 );
540
CrossProduct( v1, v2, right );
541
VectorNormalize( right );
543
for ( i = 0 ; i < 4 ; i++ ) {
546
DoRailCore( start, end, right, len, 8 );
547
RotatePointAroundVector( temp, vec, right, 45 );
548
VectorCopy( temp, right );
553
** VectorArrayNormalize
555
* The inputs to this routing seem to always be close to length = 1.0 (about 0.6 to 2.0)
556
* This means that we don't have to worry about zero length or enormously long vectors.
558
static void VectorArrayNormalize(vec4_t *normals, unsigned int count)
564
register float half = 0.5;
565
register float one = 1.0;
566
float *components = (float *)normals;
568
// Vanilla PPC code, but since PPC has a reciprocal square root estimate instruction,
569
// runs *much* faster than calling sqrt(). We'll use a single Newton-Raphson
570
// refinement step to get a little more precision. This seems to yeild results
571
// that are correct to 3 decimal places and usually correct to at least 4 (sometimes 5).
572
// (That is, for the given input range of about 0.6 to 2.0).
584
asm("frsqrte %0,%1" : "=f" (y0) : "f" (B));
588
y1 = y0 + half*y0*(one - B*y0*y0);
598
#else // No assembly version for this architecture, or C_ONLY defined
599
// given the input, it's safe to call VectorNormalizeFast
601
VectorNormalizeFast(normals[0]);
614
static void LerpMeshVertexes_altivec(md3Surface_t *surf, float backlerp)
616
short *oldXyz, *newXyz, *oldNormals, *newNormals;
617
float *outXyz, *outNormal;
618
float oldXyzScale ALIGN(16);
619
float newXyzScale ALIGN(16);
620
float oldNormalScale ALIGN(16);
621
float newNormalScale ALIGN(16);
626
outXyz = tess.xyz[tess.numVertexes];
627
outNormal = tess.normal[tess.numVertexes];
629
newXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
630
+ (backEnd.currentEntity->e.frame * surf->numVerts * 4);
631
newNormals = newXyz + 3;
633
newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp);
634
newNormalScale = 1.0 - backlerp;
636
numVerts = surf->numVerts;
638
if ( backlerp == 0 ) {
639
vector signed short newNormalsVec0;
640
vector signed short newNormalsVec1;
641
vector signed int newNormalsIntVec;
642
vector float newNormalsFloatVec;
643
vector float newXyzScaleVec;
644
vector unsigned char newNormalsLoadPermute;
645
vector unsigned char newNormalsStorePermute;
648
newNormalsStorePermute = vec_lvsl(0,(float *)&newXyzScaleVec);
649
newXyzScaleVec = *(vector float *)&newXyzScale;
650
newXyzScaleVec = vec_perm(newXyzScaleVec,newXyzScaleVec,newNormalsStorePermute);
651
newXyzScaleVec = vec_splat(newXyzScaleVec,0);
652
newNormalsLoadPermute = vec_lvsl(0,newXyz);
653
newNormalsStorePermute = vec_lvsr(0,outXyz);
654
zero = (vector float)vec_splat_s8(0);
656
// just copy the vertexes
658
for (vertNum=0 ; vertNum < numVerts ; vertNum++,
659
newXyz += 4, newNormals += 4,
660
outXyz += 4, outNormal += 4)
662
newNormalsLoadPermute = vec_lvsl(0,newXyz);
663
newNormalsStorePermute = vec_lvsr(0,outXyz);
664
newNormalsVec0 = vec_ld(0,newXyz);
665
newNormalsVec1 = vec_ld(16,newXyz);
666
newNormalsVec0 = vec_perm(newNormalsVec0,newNormalsVec1,newNormalsLoadPermute);
667
newNormalsIntVec = vec_unpackh(newNormalsVec0);
668
newNormalsFloatVec = vec_ctf(newNormalsIntVec,0);
669
newNormalsFloatVec = vec_madd(newNormalsFloatVec,newXyzScaleVec,zero);
670
newNormalsFloatVec = vec_perm(newNormalsFloatVec,newNormalsFloatVec,newNormalsStorePermute);
671
//outXyz[0] = newXyz[0] * newXyzScale;
672
//outXyz[1] = newXyz[1] * newXyzScale;
673
//outXyz[2] = newXyz[2] * newXyzScale;
675
lat = ( newNormals[0] >> 8 ) & 0xff;
676
lng = ( newNormals[0] & 0xff );
677
lat *= (FUNCTABLE_SIZE/256);
678
lng *= (FUNCTABLE_SIZE/256);
680
// decode X as cos( lat ) * sin( long )
681
// decode Y as sin( lat ) * sin( long )
682
// decode Z as cos( long )
684
outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
685
outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
686
outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
688
vec_ste(newNormalsFloatVec,0,outXyz);
689
vec_ste(newNormalsFloatVec,4,outXyz);
690
vec_ste(newNormalsFloatVec,8,outXyz);
694
// interpolate and copy the vertex and normal
696
oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
697
+ (backEnd.currentEntity->e.oldframe * surf->numVerts * 4);
698
oldNormals = oldXyz + 3;
700
oldXyzScale = MD3_XYZ_SCALE * backlerp;
701
oldNormalScale = backlerp;
703
for (vertNum=0 ; vertNum < numVerts ; vertNum++,
704
oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4,
705
outXyz += 4, outNormal += 4)
707
vec3_t uncompressedOldNormal, uncompressedNewNormal;
709
// interpolate the xyz
710
outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale;
711
outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale;
712
outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale;
714
// FIXME: interpolate lat/long instead?
715
lat = ( newNormals[0] >> 8 ) & 0xff;
716
lng = ( newNormals[0] & 0xff );
719
uncompressedNewNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
720
uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
721
uncompressedNewNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
723
lat = ( oldNormals[0] >> 8 ) & 0xff;
724
lng = ( oldNormals[0] & 0xff );
728
uncompressedOldNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
729
uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
730
uncompressedOldNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
732
outNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale;
733
outNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale;
734
outNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale;
736
// VectorNormalize (outNormal);
738
VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts);
743
static void LerpMeshVertexes_scalar(md3Surface_t *surf, float backlerp)
745
short *oldXyz, *newXyz, *oldNormals, *newNormals;
746
float *outXyz, *outNormal;
747
float oldXyzScale, newXyzScale;
748
float oldNormalScale, newNormalScale;
753
outXyz = tess.xyz[tess.numVertexes];
754
outNormal = tess.normal[tess.numVertexes];
756
newXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
757
+ (backEnd.currentEntity->e.frame * surf->numVerts * 4);
758
newNormals = newXyz + 3;
760
newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp);
761
newNormalScale = 1.0 - backlerp;
763
numVerts = surf->numVerts;
765
if ( backlerp == 0 ) {
767
// just copy the vertexes
769
for (vertNum=0 ; vertNum < numVerts ; vertNum++,
770
newXyz += 4, newNormals += 4,
771
outXyz += 4, outNormal += 4)
774
outXyz[0] = newXyz[0] * newXyzScale;
775
outXyz[1] = newXyz[1] * newXyzScale;
776
outXyz[2] = newXyz[2] * newXyzScale;
778
lat = ( newNormals[0] >> 8 ) & 0xff;
779
lng = ( newNormals[0] & 0xff );
780
lat *= (FUNCTABLE_SIZE/256);
781
lng *= (FUNCTABLE_SIZE/256);
783
// decode X as cos( lat ) * sin( long )
784
// decode Y as sin( lat ) * sin( long )
785
// decode Z as cos( long )
787
outNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
788
outNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
789
outNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
793
// interpolate and copy the vertex and normal
795
oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals)
796
+ (backEnd.currentEntity->e.oldframe * surf->numVerts * 4);
797
oldNormals = oldXyz + 3;
799
oldXyzScale = MD3_XYZ_SCALE * backlerp;
800
oldNormalScale = backlerp;
802
for (vertNum=0 ; vertNum < numVerts ; vertNum++,
803
oldXyz += 4, newXyz += 4, oldNormals += 4, newNormals += 4,
804
outXyz += 4, outNormal += 4)
806
vec3_t uncompressedOldNormal, uncompressedNewNormal;
808
// interpolate the xyz
809
outXyz[0] = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale;
810
outXyz[1] = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale;
811
outXyz[2] = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale;
813
// FIXME: interpolate lat/long instead?
814
lat = ( newNormals[0] >> 8 ) & 0xff;
815
lng = ( newNormals[0] & 0xff );
818
uncompressedNewNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
819
uncompressedNewNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
820
uncompressedNewNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
822
lat = ( oldNormals[0] >> 8 ) & 0xff;
823
lng = ( oldNormals[0] & 0xff );
827
uncompressedOldNormal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
828
uncompressedOldNormal[1] = tr.sinTable[lat] * tr.sinTable[lng];
829
uncompressedOldNormal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
831
outNormal[0] = uncompressedOldNormal[0] * oldNormalScale + uncompressedNewNormal[0] * newNormalScale;
832
outNormal[1] = uncompressedOldNormal[1] * oldNormalScale + uncompressedNewNormal[1] * newNormalScale;
833
outNormal[2] = uncompressedOldNormal[2] * oldNormalScale + uncompressedNewNormal[2] * newNormalScale;
835
// VectorNormalize (outNormal);
837
VectorArrayNormalize((vec4_t *)tess.normal[tess.numVertexes], numVerts);
841
static void LerpMeshVertexes(md3Surface_t *surf, float backlerp)
844
if (com_altivec->integer) {
845
// must be in a seperate function or G3 systems will crash.
846
LerpMeshVertexes_altivec( surf, backlerp );
849
#endif // idppc_altivec
850
LerpMeshVertexes_scalar( surf, backlerp );
859
void RB_SurfaceMesh(md3Surface_t *surface) {
868
if ( backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame ) {
871
backlerp = backEnd.currentEntity->e.backlerp;
874
RB_CHECKOVERFLOW( surface->numVerts, surface->numTriangles*3 );
876
LerpMeshVertexes (surface, backlerp);
878
triangles = (int *) ((byte *)surface + surface->ofsTriangles);
879
indexes = surface->numTriangles * 3;
880
Bob = tess.numIndexes;
881
Doug = tess.numVertexes;
882
for (j = 0 ; j < indexes ; j++) {
883
tess.indexes[Bob + j] = Doug + triangles[j];
885
tess.numIndexes += indexes;
887
texCoords = (float *) ((byte *)surface + surface->ofsSt);
889
numVerts = surface->numVerts;
890
for ( j = 0; j < numVerts; j++ ) {
891
tess.texCoords[Doug + j][0][0] = texCoords[j*2+0];
892
tess.texCoords[Doug + j][0][1] = texCoords[j*2+1];
893
// FIXME: fill in lightmapST for completeness?
896
tess.numVertexes += surface->numVerts;
906
void RB_SurfaceFace( srfSurfaceFace_t *surf ) {
908
unsigned *indices, *tessIndexes;
916
RB_CHECKOVERFLOW( surf->numPoints, surf->numIndices );
918
dlightBits = surf->dlightBits[backEnd.smpFrame];
919
tess.dlightBits |= dlightBits;
921
indices = ( unsigned * ) ( ( ( char * ) surf ) + surf->ofsIndices );
923
Bob = tess.numVertexes;
924
tessIndexes = tess.indexes + tess.numIndexes;
925
for ( i = surf->numIndices-1 ; i >= 0 ; i-- ) {
926
tessIndexes[i] = indices[i] + Bob;
929
tess.numIndexes += surf->numIndices;
933
ndx = tess.numVertexes;
935
numPoints = surf->numPoints;
937
if ( tess.shader->needsNormal ) {
938
normal = surf->plane.normal;
939
for ( i = 0, ndx = tess.numVertexes; i < numPoints; i++, ndx++ ) {
940
VectorCopy( normal, tess.normal[ndx] );
944
for ( i = 0, v = surf->points[0], ndx = tess.numVertexes; i < numPoints; i++, v += VERTEXSIZE, ndx++ ) {
945
VectorCopy( v, tess.xyz[ndx]);
946
tess.texCoords[ndx][0][0] = v[3];
947
tess.texCoords[ndx][0][1] = v[4];
948
tess.texCoords[ndx][1][0] = v[5];
949
tess.texCoords[ndx][1][1] = v[6];
950
* ( unsigned int * ) &tess.vertexColors[ndx] = * ( unsigned int * ) &v[7];
951
tess.vertexDlightBits[ndx] = dlightBits;
955
tess.numVertexes += surf->numPoints;
959
static float LodErrorForVolume( vec3_t local, float radius ) {
963
// never let it go negative
964
if ( r_lodCurveError->value < 0 ) {
968
world[0] = local[0] * backEnd.or.axis[0][0] + local[1] * backEnd.or.axis[1][0] +
969
local[2] * backEnd.or.axis[2][0] + backEnd.or.origin[0];
970
world[1] = local[0] * backEnd.or.axis[0][1] + local[1] * backEnd.or.axis[1][1] +
971
local[2] * backEnd.or.axis[2][1] + backEnd.or.origin[1];
972
world[2] = local[0] * backEnd.or.axis[0][2] + local[1] * backEnd.or.axis[1][2] +
973
local[2] * backEnd.or.axis[2][2] + backEnd.or.origin[2];
975
VectorSubtract( world, backEnd.viewParms.or.origin, world );
976
d = DotProduct( world, backEnd.viewParms.or.axis[0] );
986
return r_lodCurveError->value / d;
993
Just copy the grid of points and triangulate
996
void RB_SurfaceGrid( srfGridMesh_t *cv ) {
1001
unsigned char *color;
1003
int rows, irows, vrows;
1005
int widthTable[MAX_GRID_SIZE];
1006
int heightTable[MAX_GRID_SIZE];
1008
int lodWidth, lodHeight;
1012
qboolean needsNormal;
1014
dlightBits = cv->dlightBits[backEnd.smpFrame];
1015
tess.dlightBits |= dlightBits;
1017
// determine the allowable discrepance
1018
lodError = LodErrorForVolume( cv->lodOrigin, cv->lodRadius );
1020
// determine which rows and columns of the subdivision
1021
// we are actually going to use
1024
for ( i = 1 ; i < cv->width-1 ; i++ ) {
1025
if ( cv->widthLodError[i] <= lodError ) {
1026
widthTable[lodWidth] = i;
1030
widthTable[lodWidth] = cv->width-1;
1035
for ( i = 1 ; i < cv->height-1 ; i++ ) {
1036
if ( cv->heightLodError[i] <= lodError ) {
1037
heightTable[lodHeight] = i;
1041
heightTable[lodHeight] = cv->height-1;
1045
// very large grids may have more points or indexes than can be fit
1046
// in the tess structure, so we may have to issue it in multiple passes
1050
while ( used < lodHeight - 1 ) {
1051
// see how many rows of both verts and indexes we can add without overflowing
1053
vrows = ( SHADER_MAX_VERTEXES - tess.numVertexes ) / lodWidth;
1054
irows = ( SHADER_MAX_INDEXES - tess.numIndexes ) / ( lodWidth * 6 );
1056
// if we don't have enough space for at least one strip, flush the buffer
1057
if ( vrows < 2 || irows < 1 ) {
1059
RB_BeginSurface(tess.shader, tess.fogNum );
1066
if ( vrows < irows + 1 ) {
1069
if ( used + rows > lodHeight ) {
1070
rows = lodHeight - used;
1073
numVertexes = tess.numVertexes;
1075
xyz = tess.xyz[numVertexes];
1076
normal = tess.normal[numVertexes];
1077
texCoords = tess.texCoords[numVertexes][0];
1078
color = ( unsigned char * ) &tess.vertexColors[numVertexes];
1079
vDlightBits = &tess.vertexDlightBits[numVertexes];
1080
needsNormal = tess.shader->needsNormal;
1082
for ( i = 0 ; i < rows ; i++ ) {
1083
for ( j = 0 ; j < lodWidth ; j++ ) {
1084
dv = cv->verts + heightTable[ used + i ] * cv->width
1087
xyz[0] = dv->xyz[0];
1088
xyz[1] = dv->xyz[1];
1089
xyz[2] = dv->xyz[2];
1090
texCoords[0] = dv->st[0];
1091
texCoords[1] = dv->st[1];
1092
texCoords[2] = dv->lightmap[0];
1093
texCoords[3] = dv->lightmap[1];
1094
if ( needsNormal ) {
1095
normal[0] = dv->normal[0];
1096
normal[1] = dv->normal[1];
1097
normal[2] = dv->normal[2];
1099
* ( unsigned int * ) color = * ( unsigned int * ) dv->color;
1100
*vDlightBits++ = dlightBits;
1116
numIndexes = tess.numIndexes;
1117
for (i = 0 ; i < h ; i++) {
1118
for (j = 0 ; j < w ; j++) {
1121
// vertex order to be reckognized as tristrips
1122
v1 = numVertexes + i*lodWidth + j + 1;
1127
tess.indexes[numIndexes] = v2;
1128
tess.indexes[numIndexes+1] = v3;
1129
tess.indexes[numIndexes+2] = v1;
1131
tess.indexes[numIndexes+3] = v1;
1132
tess.indexes[numIndexes+4] = v3;
1133
tess.indexes[numIndexes+5] = v4;
1138
tess.numIndexes = numIndexes;
1141
tess.numVertexes += rows * lodWidth;
1149
===========================================================================
1153
===========================================================================
1160
Draws x/y/z lines from the origin for orientation debugging
1163
void RB_SurfaceAxis( void ) {
1164
GL_Bind( tr.whiteImage );
1166
qglBegin( GL_LINES );
1167
qglColor3f( 1,0,0 );
1168
qglVertex3f( 0,0,0 );
1169
qglVertex3f( 16,0,0 );
1170
qglColor3f( 0,1,0 );
1171
qglVertex3f( 0,0,0 );
1172
qglVertex3f( 0,16,0 );
1173
qglColor3f( 0,0,1 );
1174
qglVertex3f( 0,0,0 );
1175
qglVertex3f( 0,0,16 );
1180
//===========================================================================
1183
====================
1186
Entities that have a single procedurally generated surface
1187
====================
1189
void RB_SurfaceEntity( surfaceType_t *surfType ) {
1190
switch( backEnd.currentEntity->e.reType ) {
1198
RB_SurfaceRailCore();
1201
RB_SurfaceRailRings();
1204
RB_SurfaceLightningBolt();
1213
void RB_SurfaceBad( surfaceType_t *surfType ) {
1214
ri.Printf( PRINT_ALL, "Bad surface tesselated.\n" );
1217
void RB_SurfaceFlare(srfFlare_t *surf)
1219
if (r_flares->integer)
1220
RB_AddFlare(surf, tess.fogNum, surf->origin, surf->color, surf->normal);
1223
void RB_SurfaceDisplayList( srfDisplayList_t *surf ) {
1224
// all apropriate state must be set in RB_BeginSurface
1225
// this isn't implemented yet...
1226
qglCallList( surf->listNum );
1229
void RB_SurfaceSkip( void *surf ) {
1233
void (*rb_surfaceTable[SF_NUM_SURFACE_TYPES])( void *) = {
1234
(void(*)(void*))RB_SurfaceBad, // SF_BAD,
1235
(void(*)(void*))RB_SurfaceSkip, // SF_SKIP,
1236
(void(*)(void*))RB_SurfaceFace, // SF_FACE,
1237
(void(*)(void*))RB_SurfaceGrid, // SF_GRID,
1238
(void(*)(void*))RB_SurfaceTriangles, // SF_TRIANGLES,
1239
(void(*)(void*))RB_SurfacePolychain, // SF_POLY,
1240
(void(*)(void*))RB_SurfaceMesh, // SF_MD3,
1241
(void(*)(void*))RB_SurfaceAnim, // SF_MD4,
1243
(void(*)(void*))RB_MDRSurfaceAnim, // SF_MDR,
1245
(void(*)(void*))RB_SurfaceFlare, // SF_FLARE,
1246
(void(*)(void*))RB_SurfaceEntity, // SF_ENTITY
1247
(void(*)(void*))RB_SurfaceDisplayList // SF_DISPLAY_LIST