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 #define SKY_SUBDIVISIONS 8
00026 #define HALF_SKY_SUBDIVISIONS (SKY_SUBDIVISIONS/2)
00027
00028 static float s_cloudTexCoords[6][SKY_SUBDIVISIONS+1][SKY_SUBDIVISIONS+1][2];
00029 static float s_cloudTexP[6][SKY_SUBDIVISIONS+1][SKY_SUBDIVISIONS+1];
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 static vec3_t sky_clip[6] =
00040 {
00041 {1,1,0},
00042 {1,-1,0},
00043 {0,-1,1},
00044 {0,1,1},
00045 {1,0,1},
00046 {-1,0,1}
00047 };
00048
00049 static float sky_mins[2][6], sky_maxs[2][6];
00050 static float sky_min, sky_max;
00051
00052
00053
00054
00055
00056
00057 static void AddSkyPolygon (int nump, vec3_t vecs)
00058 {
00059 int i,j;
00060 vec3_t v, av;
00061 float s, t, dv;
00062 int axis;
00063 float *vp;
00064
00065 static int vec_to_st[6][3] =
00066 {
00067 {-2,3,1},
00068 {2,3,-1},
00069
00070 {1,3,2},
00071 {-1,3,-2},
00072
00073 {-2,-1,3},
00074 {-2,1,-3}
00075
00076
00077
00078 };
00079
00080
00081 VectorCopy (vec3_origin, v);
00082 for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
00083 {
00084 VectorAdd (vp, v, v);
00085 }
00086 av[0] = fabs(v[0]);
00087 av[1] = fabs(v[1]);
00088 av[2] = fabs(v[2]);
00089 if (av[0] > av[1] && av[0] > av[2])
00090 {
00091 if (v[0] < 0)
00092 axis = 1;
00093 else
00094 axis = 0;
00095 }
00096 else if (av[1] > av[2] && av[1] > av[0])
00097 {
00098 if (v[1] < 0)
00099 axis = 3;
00100 else
00101 axis = 2;
00102 }
00103 else
00104 {
00105 if (v[2] < 0)
00106 axis = 5;
00107 else
00108 axis = 4;
00109 }
00110
00111
00112 for (i=0 ; i<nump ; i++, vecs+=3)
00113 {
00114 j = vec_to_st[axis][2];
00115 if (j > 0)
00116 dv = vecs[j - 1];
00117 else
00118 dv = -vecs[-j - 1];
00119 if (dv < 0.001)
00120 continue;
00121 j = vec_to_st[axis][0];
00122 if (j < 0)
00123 s = -vecs[-j -1] / dv;
00124 else
00125 s = vecs[j-1] / dv;
00126 j = vec_to_st[axis][1];
00127 if (j < 0)
00128 t = -vecs[-j -1] / dv;
00129 else
00130 t = vecs[j-1] / dv;
00131
00132 if (s < sky_mins[0][axis])
00133 sky_mins[0][axis] = s;
00134 if (t < sky_mins[1][axis])
00135 sky_mins[1][axis] = t;
00136 if (s > sky_maxs[0][axis])
00137 sky_maxs[0][axis] = s;
00138 if (t > sky_maxs[1][axis])
00139 sky_maxs[1][axis] = t;
00140 }
00141 }
00142
00143 #define ON_EPSILON 0.1f // point on plane side epsilon
00144 #define MAX_CLIP_VERTS 64
00145
00146
00147
00148
00149
00150 static void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
00151 {
00152 float *norm;
00153 float *v;
00154 qboolean front, back;
00155 float d, e;
00156 float dists[MAX_CLIP_VERTS];
00157 int sides[MAX_CLIP_VERTS];
00158 vec3_t newv[2][MAX_CLIP_VERTS];
00159 int newc[2];
00160 int i, j;
00161
00162 if (nump > MAX_CLIP_VERTS-2)
00163 ri.Error (ERR_DROP, "ClipSkyPolygon: MAX_CLIP_VERTS");
00164 if (stage == 6)
00165 {
00166 AddSkyPolygon (nump, vecs);
00167 return;
00168 }
00169
00170 front = back = qfalse;
00171 norm = sky_clip[stage];
00172 for (i=0, v = vecs ; i<nump ; i++, v+=3)
00173 {
00174 d = DotProduct (v, norm);
00175 if (d > ON_EPSILON)
00176 {
00177 front = qtrue;
00178 sides[i] = SIDE_FRONT;
00179 }
00180 else if (d < -ON_EPSILON)
00181 {
00182 back = qtrue;
00183 sides[i] = SIDE_BACK;
00184 }
00185 else
00186 sides[i] = SIDE_ON;
00187 dists[i] = d;
00188 }
00189
00190 if (!front || !back)
00191 {
00192 ClipSkyPolygon (nump, vecs, stage+1);
00193 return;
00194 }
00195
00196
00197 sides[i] = sides[0];
00198 dists[i] = dists[0];
00199 VectorCopy (vecs, (vecs+(i*3)) );
00200 newc[0] = newc[1] = 0;
00201
00202 for (i=0, v = vecs ; i<nump ; i++, v+=3)
00203 {
00204 switch (sides[i])
00205 {
00206 case SIDE_FRONT:
00207 VectorCopy (v, newv[0][newc[0]]);
00208 newc[0]++;
00209 break;
00210 case SIDE_BACK:
00211 VectorCopy (v, newv[1][newc[1]]);
00212 newc[1]++;
00213 break;
00214 case SIDE_ON:
00215 VectorCopy (v, newv[0][newc[0]]);
00216 newc[0]++;
00217 VectorCopy (v, newv[1][newc[1]]);
00218 newc[1]++;
00219 break;
00220 }
00221
00222 if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
00223 continue;
00224
00225 d = dists[i] / (dists[i] - dists[i+1]);
00226 for (j=0 ; j<3 ; j++)
00227 {
00228 e = v[j] + d*(v[j+3] - v[j]);
00229 newv[0][newc[0]][j] = e;
00230 newv[1][newc[1]][j] = e;
00231 }
00232 newc[0]++;
00233 newc[1]++;
00234 }
00235
00236
00237 ClipSkyPolygon (newc[0], newv[0][0], stage+1);
00238 ClipSkyPolygon (newc[1], newv[1][0], stage+1);
00239 }
00240
00241
00242
00243
00244
00245
00246 static void ClearSkyBox (void) {
00247 int i;
00248
00249 for (i=0 ; i<6 ; i++) {
00250 sky_mins[0][i] = sky_mins[1][i] = 9999;
00251 sky_maxs[0][i] = sky_maxs[1][i] = -9999;
00252 }
00253 }
00254
00255
00256
00257
00258
00259
00260 void RB_ClipSkyPolygons( shaderCommands_t *input )
00261 {
00262 vec3_t p[5];
00263 int i, j;
00264
00265 ClearSkyBox();
00266
00267 for ( i = 0; i < input->numIndexes; i += 3 )
00268 {
00269 for (j = 0 ; j < 3 ; j++)
00270 {
00271 VectorSubtract( input->xyz[input->indexes[i+j]],
00272 backEnd.viewParms.or.origin,
00273 p[j] );
00274 }
00275 ClipSkyPolygon( 3, p[0], 0 );
00276 }
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 static void MakeSkyVec( float s, float t, int axis, float outSt[2], vec3_t outXYZ )
00293 {
00294
00295 static int st_to_vec[6][3] =
00296 {
00297 {3,-1,2},
00298 {-3,1,2},
00299
00300 {1,3,2},
00301 {-1,-3,2},
00302
00303 {-2,-1,3},
00304 {2,-1,-3}
00305 };
00306
00307 vec3_t b;
00308 int j, k;
00309 float boxSize;
00310
00311 boxSize = backEnd.viewParms.zFar / 1.75;
00312 b[0] = s*boxSize;
00313 b[1] = t*boxSize;
00314 b[2] = boxSize;
00315
00316 for (j=0 ; j<3 ; j++)
00317 {
00318 k = st_to_vec[axis][j];
00319 if (k < 0)
00320 {
00321 outXYZ[j] = -b[-k - 1];
00322 }
00323 else
00324 {
00325 outXYZ[j] = b[k - 1];
00326 }
00327 }
00328
00329
00330 s = (s+1)*0.5;
00331 t = (t+1)*0.5;
00332 if (s < sky_min)
00333 {
00334 s = sky_min;
00335 }
00336 else if (s > sky_max)
00337 {
00338 s = sky_max;
00339 }
00340
00341 if (t < sky_min)
00342 {
00343 t = sky_min;
00344 }
00345 else if (t > sky_max)
00346 {
00347 t = sky_max;
00348 }
00349
00350 t = 1.0 - t;
00351
00352
00353 if ( outSt )
00354 {
00355 outSt[0] = s;
00356 outSt[1] = t;
00357 }
00358 }
00359
00360 static int sky_texorder[6] = {0,2,1,3,4,5};
00361 static vec3_t s_skyPoints[SKY_SUBDIVISIONS+1][SKY_SUBDIVISIONS+1];
00362 static float s_skyTexCoords[SKY_SUBDIVISIONS+1][SKY_SUBDIVISIONS+1][2];
00363
00364 static void DrawSkySide( struct image_s *image, const int mins[2], const int maxs[2] )
00365 {
00366 int s, t;
00367
00368 GL_Bind( image );
00369
00370 for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t < maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
00371 {
00372 qglBegin( GL_TRIANGLE_STRIP );
00373
00374 for ( s = mins[0]+HALF_SKY_SUBDIVISIONS; s <= maxs[0]+HALF_SKY_SUBDIVISIONS; s++ )
00375 {
00376 qglTexCoord2fv( s_skyTexCoords[t][s] );
00377 qglVertex3fv( s_skyPoints[t][s] );
00378
00379 qglTexCoord2fv( s_skyTexCoords[t+1][s] );
00380 qglVertex3fv( s_skyPoints[t+1][s] );
00381 }
00382
00383 qglEnd();
00384 }
00385 }
00386
00387 static void DrawSkyBox( shader_t *shader )
00388 {
00389 int i;
00390
00391 sky_min = 0;
00392 sky_max = 1;
00393
00394 Com_Memset( s_skyTexCoords, 0, sizeof( s_skyTexCoords ) );
00395
00396 for (i=0 ; i<6 ; i++)
00397 {
00398 int sky_mins_subd[2], sky_maxs_subd[2];
00399 int s, t;
00400
00401 sky_mins[0][i] = floor( sky_mins[0][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
00402 sky_mins[1][i] = floor( sky_mins[1][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
00403 sky_maxs[0][i] = ceil( sky_maxs[0][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
00404 sky_maxs[1][i] = ceil( sky_maxs[1][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
00405
00406 if ( ( sky_mins[0][i] >= sky_maxs[0][i] ) ||
00407 ( sky_mins[1][i] >= sky_maxs[1][i] ) )
00408 {
00409 continue;
00410 }
00411
00412 sky_mins_subd[0] = sky_mins[0][i] * HALF_SKY_SUBDIVISIONS;
00413 sky_mins_subd[1] = sky_mins[1][i] * HALF_SKY_SUBDIVISIONS;
00414 sky_maxs_subd[0] = sky_maxs[0][i] * HALF_SKY_SUBDIVISIONS;
00415 sky_maxs_subd[1] = sky_maxs[1][i] * HALF_SKY_SUBDIVISIONS;
00416
00417 if ( sky_mins_subd[0] < -HALF_SKY_SUBDIVISIONS )
00418 sky_mins_subd[0] = -HALF_SKY_SUBDIVISIONS;
00419 else if ( sky_mins_subd[0] > HALF_SKY_SUBDIVISIONS )
00420 sky_mins_subd[0] = HALF_SKY_SUBDIVISIONS;
00421 if ( sky_mins_subd[1] < -HALF_SKY_SUBDIVISIONS )
00422 sky_mins_subd[1] = -HALF_SKY_SUBDIVISIONS;
00423 else if ( sky_mins_subd[1] > HALF_SKY_SUBDIVISIONS )
00424 sky_mins_subd[1] = HALF_SKY_SUBDIVISIONS;
00425
00426 if ( sky_maxs_subd[0] < -HALF_SKY_SUBDIVISIONS )
00427 sky_maxs_subd[0] = -HALF_SKY_SUBDIVISIONS;
00428 else if ( sky_maxs_subd[0] > HALF_SKY_SUBDIVISIONS )
00429 sky_maxs_subd[0] = HALF_SKY_SUBDIVISIONS;
00430 if ( sky_maxs_subd[1] < -HALF_SKY_SUBDIVISIONS )
00431 sky_maxs_subd[1] = -HALF_SKY_SUBDIVISIONS;
00432 else if ( sky_maxs_subd[1] > HALF_SKY_SUBDIVISIONS )
00433 sky_maxs_subd[1] = HALF_SKY_SUBDIVISIONS;
00434
00435
00436
00437
00438 for ( t = sky_mins_subd[1]+HALF_SKY_SUBDIVISIONS; t <= sky_maxs_subd[1]+HALF_SKY_SUBDIVISIONS; t++ )
00439 {
00440 for ( s = sky_mins_subd[0]+HALF_SKY_SUBDIVISIONS; s <= sky_maxs_subd[0]+HALF_SKY_SUBDIVISIONS; s++ )
00441 {
00442 MakeSkyVec( ( s - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
00443 ( t - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
00444 i,
00445 s_skyTexCoords[t][s],
00446 s_skyPoints[t][s] );
00447 }
00448 }
00449
00450 DrawSkySide( shader->sky.outerbox[sky_texorder[i]],
00451 sky_mins_subd,
00452 sky_maxs_subd );
00453 }
00454
00455 }
00456
00457 static void FillCloudySkySide( const int mins[2], const int maxs[2], qboolean addIndexes )
00458 {
00459 int s, t;
00460 int vertexStart = tess.numVertexes;
00461 int tHeight, sWidth;
00462
00463 tHeight = maxs[1] - mins[1] + 1;
00464 sWidth = maxs[0] - mins[0] + 1;
00465
00466 for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
00467 {
00468 for ( s = mins[0]+HALF_SKY_SUBDIVISIONS; s <= maxs[0]+HALF_SKY_SUBDIVISIONS; s++ )
00469 {
00470 VectorAdd( s_skyPoints[t][s], backEnd.viewParms.or.origin, tess.xyz[tess.numVertexes] );
00471 tess.texCoords[tess.numVertexes][0][0] = s_skyTexCoords[t][s][0];
00472 tess.texCoords[tess.numVertexes][0][1] = s_skyTexCoords[t][s][1];
00473
00474 tess.numVertexes++;
00475
00476 if ( tess.numVertexes >= SHADER_MAX_VERTEXES )
00477 {
00478 ri.Error( ERR_DROP, "SHADER_MAX_VERTEXES hit in FillCloudySkySide()\n" );
00479 }
00480 }
00481 }
00482
00483
00484 if ( addIndexes ) {
00485 for ( t = 0; t < tHeight-1; t++ )
00486 {
00487 for ( s = 0; s < sWidth-1; s++ )
00488 {
00489 tess.indexes[tess.numIndexes] = vertexStart + s + t * ( sWidth );
00490 tess.numIndexes++;
00491 tess.indexes[tess.numIndexes] = vertexStart + s + ( t + 1 ) * ( sWidth );
00492 tess.numIndexes++;
00493 tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * ( sWidth );
00494 tess.numIndexes++;
00495
00496 tess.indexes[tess.numIndexes] = vertexStart + s + ( t + 1 ) * ( sWidth );
00497 tess.numIndexes++;
00498 tess.indexes[tess.numIndexes] = vertexStart + s + 1 + ( t + 1 ) * ( sWidth );
00499 tess.numIndexes++;
00500 tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * ( sWidth );
00501 tess.numIndexes++;
00502 }
00503 }
00504 }
00505 }
00506
00507 static void FillCloudBox( const shader_t *shader, int stage )
00508 {
00509 int i;
00510
00511 for ( i =0; i < 6; i++ )
00512 {
00513 int sky_mins_subd[2], sky_maxs_subd[2];
00514 int s, t;
00515 float MIN_T;
00516
00517 if ( 1 )
00518 {
00519 MIN_T = -HALF_SKY_SUBDIVISIONS;
00520
00521
00522 if ( i == 5 )
00523 continue;
00524 }
00525 else
00526 {
00527 switch( i )
00528 {
00529 case 0:
00530 case 1:
00531 case 2:
00532 case 3:
00533 MIN_T = -1;
00534 break;
00535 case 5:
00536
00537 continue;
00538 case 4:
00539 default:
00540 MIN_T = -HALF_SKY_SUBDIVISIONS;
00541 break;
00542 }
00543 }
00544
00545 sky_mins[0][i] = floor( sky_mins[0][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
00546 sky_mins[1][i] = floor( sky_mins[1][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
00547 sky_maxs[0][i] = ceil( sky_maxs[0][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
00548 sky_maxs[1][i] = ceil( sky_maxs[1][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
00549
00550 if ( ( sky_mins[0][i] >= sky_maxs[0][i] ) ||
00551 ( sky_mins[1][i] >= sky_maxs[1][i] ) )
00552 {
00553 continue;
00554 }
00555
00556 sky_mins_subd[0] = myftol( sky_mins[0][i] * HALF_SKY_SUBDIVISIONS );
00557 sky_mins_subd[1] = myftol( sky_mins[1][i] * HALF_SKY_SUBDIVISIONS );
00558 sky_maxs_subd[0] = myftol( sky_maxs[0][i] * HALF_SKY_SUBDIVISIONS );
00559 sky_maxs_subd[1] = myftol( sky_maxs[1][i] * HALF_SKY_SUBDIVISIONS );
00560
00561 if ( sky_mins_subd[0] < -HALF_SKY_SUBDIVISIONS )
00562 sky_mins_subd[0] = -HALF_SKY_SUBDIVISIONS;
00563 else if ( sky_mins_subd[0] > HALF_SKY_SUBDIVISIONS )
00564 sky_mins_subd[0] = HALF_SKY_SUBDIVISIONS;
00565 if ( sky_mins_subd[1] < MIN_T )
00566 sky_mins_subd[1] = MIN_T;
00567 else if ( sky_mins_subd[1] > HALF_SKY_SUBDIVISIONS )
00568 sky_mins_subd[1] = HALF_SKY_SUBDIVISIONS;
00569
00570 if ( sky_maxs_subd[0] < -HALF_SKY_SUBDIVISIONS )
00571 sky_maxs_subd[0] = -HALF_SKY_SUBDIVISIONS;
00572 else if ( sky_maxs_subd[0] > HALF_SKY_SUBDIVISIONS )
00573 sky_maxs_subd[0] = HALF_SKY_SUBDIVISIONS;
00574 if ( sky_maxs_subd[1] < MIN_T )
00575 sky_maxs_subd[1] = MIN_T;
00576 else if ( sky_maxs_subd[1] > HALF_SKY_SUBDIVISIONS )
00577 sky_maxs_subd[1] = HALF_SKY_SUBDIVISIONS;
00578
00579
00580
00581
00582 for ( t = sky_mins_subd[1]+HALF_SKY_SUBDIVISIONS; t <= sky_maxs_subd[1]+HALF_SKY_SUBDIVISIONS; t++ )
00583 {
00584 for ( s = sky_mins_subd[0]+HALF_SKY_SUBDIVISIONS; s <= sky_maxs_subd[0]+HALF_SKY_SUBDIVISIONS; s++ )
00585 {
00586 MakeSkyVec( ( s - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
00587 ( t - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
00588 i,
00589 NULL,
00590 s_skyPoints[t][s] );
00591
00592 s_skyTexCoords[t][s][0] = s_cloudTexCoords[i][t][s][0];
00593 s_skyTexCoords[t][s][1] = s_cloudTexCoords[i][t][s][1];
00594 }
00595 }
00596
00597
00598 FillCloudySkySide( sky_mins_subd, sky_maxs_subd, ( stage == 0 ) );
00599 }
00600 }
00601
00602
00603
00604
00605 void R_BuildCloudData( shaderCommands_t *input )
00606 {
00607 int i;
00608 shader_t *shader;
00609
00610 shader = input->shader;
00611
00612 assert( shader->isSky );
00613
00614 sky_min = 1.0 / 256.0f;
00615 sky_max = 255.0 / 256.0f;
00616
00617
00618 tess.numIndexes = 0;
00619 tess.numVertexes = 0;
00620
00621 if ( input->shader->sky.cloudHeight )
00622 {
00623 for ( i = 0; i < MAX_SHADER_STAGES; i++ )
00624 {
00625 if ( !tess.xstages[i] ) {
00626 break;
00627 }
00628 FillCloudBox( input->shader, i );
00629 }
00630 }
00631 }
00632
00633
00634
00635
00636
00637 #define SQR( a ) ((a)*(a))
00638 void R_InitSkyTexCoords( float heightCloud )
00639 {
00640 int i, s, t;
00641 float radiusWorld = 4096;
00642 float p;
00643 float sRad, tRad;
00644 vec3_t skyVec;
00645 vec3_t v;
00646
00647
00648
00649 backEnd.viewParms.zFar = 1024;
00650
00651 for ( i = 0; i < 6; i++ )
00652 {
00653 for ( t = 0; t <= SKY_SUBDIVISIONS; t++ )
00654 {
00655 for ( s = 0; s <= SKY_SUBDIVISIONS; s++ )
00656 {
00657
00658 MakeSkyVec( ( s - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
00659 ( t - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
00660 i,
00661 NULL,
00662 skyVec );
00663
00664
00665 p = ( 1.0f / ( 2 * DotProduct( skyVec, skyVec ) ) ) *
00666 ( -2 * skyVec[2] * radiusWorld +
00667 2 * sqrt( SQR( skyVec[2] ) * SQR( radiusWorld ) +
00668 2 * SQR( skyVec[0] ) * radiusWorld * heightCloud +
00669 SQR( skyVec[0] ) * SQR( heightCloud ) +
00670 2 * SQR( skyVec[1] ) * radiusWorld * heightCloud +
00671 SQR( skyVec[1] ) * SQR( heightCloud ) +
00672 2 * SQR( skyVec[2] ) * radiusWorld * heightCloud +
00673 SQR( skyVec[2] ) * SQR( heightCloud ) ) );
00674
00675 s_cloudTexP[i][t][s] = p;
00676
00677
00678 VectorScale( skyVec, p, v );
00679 v[2] += radiusWorld;
00680
00681
00682 VectorNormalize( v );
00683
00684 sRad = Q_acos( v[0] );
00685 tRad = Q_acos( v[1] );
00686
00687 s_cloudTexCoords[i][t][s][0] = sRad;
00688 s_cloudTexCoords[i][t][s][1] = tRad;
00689 }
00690 }
00691 }
00692 }
00693
00694
00695
00696
00697
00698
00699 void RB_DrawSun( void ) {
00700 float size;
00701 float dist;
00702 vec3_t origin, vec1, vec2;
00703 vec3_t temp;
00704
00705 if ( !backEnd.skyRenderedThisView ) {
00706 return;
00707 }
00708 if ( !r_drawSun->integer ) {
00709 return;
00710 }
00711 qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
00712 qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]);
00713
00714 dist = backEnd.viewParms.zFar / 1.75;
00715 size = dist * 0.4;
00716
00717 VectorScale( tr.sunDirection, dist, origin );
00718 PerpendicularVector( vec1, tr.sunDirection );
00719 CrossProduct( tr.sunDirection, vec1, vec2 );
00720
00721 VectorScale( vec1, size, vec1 );
00722 VectorScale( vec2, size, vec2 );
00723
00724
00725 qglDepthRange( 1.0, 1.0 );
00726
00727
00728 RB_BeginSurface( tr.sunShader, tess.fogNum );
00729 VectorCopy( origin, temp );
00730 VectorSubtract( temp, vec1, temp );
00731 VectorSubtract( temp, vec2, temp );
00732 VectorCopy( temp, tess.xyz[tess.numVertexes] );
00733 tess.texCoords[tess.numVertexes][0][0] = 0;
00734 tess.texCoords[tess.numVertexes][0][1] = 0;
00735 tess.vertexColors[tess.numVertexes][0] = 255;
00736 tess.vertexColors[tess.numVertexes][1] = 255;
00737 tess.vertexColors[tess.numVertexes][2] = 255;
00738 tess.numVertexes++;
00739
00740 VectorCopy( origin, temp );
00741 VectorAdd( temp, vec1, temp );
00742 VectorSubtract( temp, vec2, temp );
00743 VectorCopy( temp, tess.xyz[tess.numVertexes] );
00744 tess.texCoords[tess.numVertexes][0][0] = 0;
00745 tess.texCoords[tess.numVertexes][0][1] = 1;
00746 tess.vertexColors[tess.numVertexes][0] = 255;
00747 tess.vertexColors[tess.numVertexes][1] = 255;
00748 tess.vertexColors[tess.numVertexes][2] = 255;
00749 tess.numVertexes++;
00750
00751 VectorCopy( origin, temp );
00752 VectorAdd( temp, vec1, temp );
00753 VectorAdd( temp, vec2, temp );
00754 VectorCopy( temp, tess.xyz[tess.numVertexes] );
00755 tess.texCoords[tess.numVertexes][0][0] = 1;
00756 tess.texCoords[tess.numVertexes][0][1] = 1;
00757 tess.vertexColors[tess.numVertexes][0] = 255;
00758 tess.vertexColors[tess.numVertexes][1] = 255;
00759 tess.vertexColors[tess.numVertexes][2] = 255;
00760 tess.numVertexes++;
00761
00762 VectorCopy( origin, temp );
00763 VectorSubtract( temp, vec1, temp );
00764 VectorAdd( temp, vec2, temp );
00765 VectorCopy( temp, tess.xyz[tess.numVertexes] );
00766 tess.texCoords[tess.numVertexes][0][0] = 1;
00767 tess.texCoords[tess.numVertexes][0][1] = 0;
00768 tess.vertexColors[tess.numVertexes][0] = 255;
00769 tess.vertexColors[tess.numVertexes][1] = 255;
00770 tess.vertexColors[tess.numVertexes][2] = 255;
00771 tess.numVertexes++;
00772
00773 tess.indexes[tess.numIndexes++] = 0;
00774 tess.indexes[tess.numIndexes++] = 1;
00775 tess.indexes[tess.numIndexes++] = 2;
00776 tess.indexes[tess.numIndexes++] = 0;
00777 tess.indexes[tess.numIndexes++] = 2;
00778 tess.indexes[tess.numIndexes++] = 3;
00779
00780 RB_EndSurface();
00781
00782
00783 qglDepthRange( 0.0, 1.0 );
00784 }
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798 void RB_StageIteratorSky( void ) {
00799 if ( r_fastsky->integer ) {
00800 return;
00801 }
00802
00803
00804
00805
00806 RB_ClipSkyPolygons( &tess );
00807
00808
00809
00810
00811 if ( r_showsky->integer ) {
00812 qglDepthRange( 0.0, 0.0 );
00813 } else {
00814 qglDepthRange( 1.0, 1.0 );
00815 }
00816
00817
00818 if ( tess.shader->sky.outerbox[0] && tess.shader->sky.outerbox[0] != tr.defaultImage ) {
00819 qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight );
00820
00821 qglPushMatrix ();
00822 GL_State( 0 );
00823 qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]);
00824
00825 DrawSkyBox( tess.shader );
00826
00827 qglPopMatrix();
00828 }
00829
00830
00831
00832 R_BuildCloudData( &tess );
00833
00834 RB_StageIteratorGeneric();
00835
00836
00837
00838
00839
00840 qglDepthRange( 0.0, 1.0 );
00841
00842
00843 backEnd.skyRenderedThisView = qtrue;
00844 }
00845