00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "r_local.h"
00026 #include "r_error.h"
00027 #include "r_sphere.h"
00028 #include "r_geoscape.h"
00029
00030 #include "r_mesh.h"
00031 #include "r_draw.h"
00032
00033 #define MARKER_SIZE 60.0
00034
00035 extern const float STANDARD_3D_ZOOM;
00036
00051 void R_DrawFlatGeoscape (int x, int y, int w, int h, float p, float cx, float cy, float iz, const char *map, qboolean overlayNation, qboolean overlayXVI, qboolean overlayRadar, image_t *r_dayandnightTexture, image_t *r_xviTexture, image_t *r_radarTexture)
00052 {
00053 image_t *gl;
00054 float geoscape_texcoords[4 * 2];
00055 short geoscape_verts[4 * 2];
00056
00057
00058 const float nx = x * viddef.rx;
00059 const float ny = y * viddef.ry;
00060 const float nw = w * viddef.rx;
00061 const float nh = h * viddef.ry;
00062
00063
00064 gl = R_FindImage(va("pics/geoscape/%s_day", map), it_wrappic);
00065 if (gl == r_noTexture)
00066 Com_Error(ERR_FATAL, "Could not load geoscape day image");
00067
00068
00069 glVertexPointer(2, GL_SHORT, 0, geoscape_verts);
00070 R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, geoscape_texcoords);
00071
00072 geoscape_texcoords[0] = cx - iz;
00073 geoscape_texcoords[1] = cy - iz;
00074 geoscape_texcoords[2] = cx + iz;
00075 geoscape_texcoords[3] = cy - iz;
00076 geoscape_texcoords[4] = cx + iz;
00077 geoscape_texcoords[5] = cy + iz;
00078 geoscape_texcoords[6] = cx - iz;
00079 geoscape_texcoords[7] = cy + iz;
00080
00081 geoscape_verts[0] = nx;
00082 geoscape_verts[1] = ny;
00083 geoscape_verts[2] = nx + nw;
00084 geoscape_verts[3] = ny;
00085 geoscape_verts[4] = nx + nw;
00086 geoscape_verts[5] = ny + nh;
00087 geoscape_verts[6] = nx;
00088 geoscape_verts[7] = ny + nh;
00089
00090
00091 R_BindTexture(gl->texnum);
00092 glDrawArrays(GL_QUADS, 0, 4);
00093
00094
00095 gl = R_FindImage(va("pics/geoscape/%s_night", map), it_wrappic);
00096
00097 if (gl != r_noTexture) {
00098 float geoscape_nighttexcoords[4 * 2];
00099
00100 R_BindTexture(gl->texnum);
00101 R_EnableTexture(&texunit_lightmap, qtrue);
00102 R_SelectTexture(&texunit_lightmap);
00103
00104 geoscape_nighttexcoords[0] = geoscape_texcoords[0] + p;
00105 geoscape_nighttexcoords[1] = geoscape_texcoords[1];
00106 geoscape_nighttexcoords[2] = geoscape_texcoords[2] + p;
00107 geoscape_nighttexcoords[3] = geoscape_texcoords[3];
00108 geoscape_nighttexcoords[4] = geoscape_texcoords[4] + p;
00109 geoscape_nighttexcoords[5] = geoscape_texcoords[5];
00110 geoscape_nighttexcoords[6] = geoscape_texcoords[6] + p;
00111 geoscape_nighttexcoords[7] = geoscape_texcoords[7];
00112
00113 R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, geoscape_nighttexcoords);
00114
00115 R_BindTexture(r_dayandnightTexture->texnum);
00116
00117 R_SelectTexture(&texunit_diffuse);
00118 glDrawArrays(GL_QUADS, 0, 4);
00119
00120 R_SelectTexture(&texunit_lightmap);
00121 R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, geoscape_texcoords);
00122
00123 R_EnableTexture(&texunit_lightmap, qfalse);
00124 }
00125
00126
00127 if (overlayNation) {
00128 gl = R_FindImage(va("pics/geoscape/%s_nations_overlay", map), it_wrappic);
00129 if (gl == r_noTexture)
00130 Com_Error(ERR_FATAL, "Could not load geoscape nation overlay image");
00131
00132
00133 R_BindTexture(gl->texnum);
00134 glDrawArrays(GL_QUADS, 0, 4);
00135 }
00136
00137
00138 if (overlayXVI) {
00139 gl = R_FindImage(va("pics/geoscape/%s_xvi_overlay", map), it_wrappic);
00140 if (gl == r_noTexture)
00141 Com_Error(ERR_FATAL, "Could not load xvi overlay image");
00142
00143 R_BindTexture(gl->texnum);
00144
00145 R_EnableTexture(&texunit_lightmap, qtrue);
00146 R_BindLightmapTexture(r_xviTexture->texnum);
00147
00148 glDrawArrays(GL_QUADS, 0, 4);
00149
00150 R_EnableTexture(&texunit_lightmap, qfalse);
00151 }
00152
00153
00154 if (overlayRadar) {
00155 R_BindTexture(r_radarTexture->texnum);
00156 glDrawArrays(GL_QUADS, 0, 4);
00157 }
00158
00159
00160 R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
00161 R_BindDefaultArray(GL_VERTEX_ARRAY);
00162 }
00163
00169 void R_Draw2DMapMarkers (const vec2_t screenPos, float direction, const char *model, int skin)
00170 {
00171 modelInfo_t mi;
00172 vec2_t size;
00173 vec3_t scale, center, position, angles;
00174 float zoom = 0.4f;
00175
00176 memset(&mi, 0, sizeof(mi));
00177 VectorCopy(vec3_origin, position);
00178 VectorCopy(vec3_origin, angles);
00179
00180 mi.model = R_RegisterModelShort(model);
00181 if (!mi.model) {
00182 Com_Printf("Could not find model '%s'\n", model);
00183 return;
00184 }
00185
00186 mi.name = model;
00187 mi.origin = position;
00188 mi.angles = angles;
00189 mi.skin = skin;
00190
00191 size[0] = size[1] = MARKER_SIZE * zoom;
00192 R_ModelAutoScale(size, &mi, scale, center);
00193
00194 mi.center = NULL;
00195
00196
00197 glPushMatrix();
00198
00199
00200
00201
00202
00203 glTranslatef(screenPos[0]* viddef.rx, screenPos[1]* viddef.ry, 0);
00204
00205 glScalef(viddef.rx, viddef.ry, 1.0f);
00206
00207 glRotatef(180.0f, 0, 1, 0);
00208 glRotatef(90.f - direction, 0, 0, 1);
00209
00210 R_DrawModelDirect(&mi, NULL, NULL);
00211
00212
00213 glPopMatrix();
00214 }
00215
00227 void R_Draw3DMapMarkers (int x, int y, int w, int h, const vec3_t rotate, const vec2_t pos, float direction, float earthRadius, const char *model, int skin)
00228 {
00229
00230 const float nx = x * viddef.rx;
00231 const float ny = y * viddef.ry;
00232 const float nw = w * viddef.rx;
00233 const float nh = h * viddef.ry;
00234
00235
00236
00237 const vec3_t earthPos = {nx + nw / 2.0, ny + nh / 2.0, 0.0};
00238
00239 modelInfo_t mi;
00240 vec2_t size;
00241 vec3_t scale, center, position, angles;
00242 float zoom = 0.4f;
00243
00244 memset(&mi, 0, sizeof(mi));
00245 VectorCopy(vec3_origin, position);
00246 VectorCopy(vec3_origin, angles);
00247
00248 mi.model = R_RegisterModelShort(model);
00249 if (!mi.model) {
00250 Com_Printf("Could not find model '%s'\n", model);
00251 return;
00252 }
00253
00254 mi.name = model;
00255 mi.origin = position;
00256 mi.angles = angles;
00257 mi.skin = skin;
00258
00259 size[0] = size[1] = MARKER_SIZE * zoom;
00260 R_ModelAutoScale(size, &mi, scale, center);
00261
00262 mi.center = NULL;
00263
00264
00265 glPushMatrix();
00266
00267
00268
00269
00270
00271
00272 glTranslatef(earthPos[0], earthPos[1], 10.0f);
00273
00274 glScalef(viddef.rx, viddef.ry, 1.0f);
00275
00276 glRotatef(-rotate[1], 1, 0, 0);
00277 glRotatef(rotate[2], 0, 1, 0);
00278 glRotatef(rotate[0] - pos[0], 0, 0, 1);
00279 glRotatef(90.0f - pos[1], 1, 0, 0);
00280 glTranslatef(0, 0, earthRadius);
00281 glRotatef(-90.0f + direction, 0, 0, 1);
00282
00283 R_DrawModelDirect(&mi, NULL, NULL);
00284
00285
00286 glPopMatrix();
00287 }
00288
00294 const float SKYBOX_DEPTH = -9999.0f;
00295
00303 #define SKYBOX_HALFSIZE 800.0f
00304
00305 static const float starFieldVerts[] = {
00306
00307 -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE,
00308 +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE,
00309 +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE,
00310 -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE,
00311
00312
00313 -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00314 +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00315 +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00316 -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00317
00318
00319 +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE,
00320 +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00321 +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00322 +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE,
00323
00324
00325 -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE,
00326 -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00327 -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00328 -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE,
00329
00330
00331 -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE,
00332 +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE,
00333 +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00334 -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00335
00336
00337 -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00338 +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, +SKYBOX_HALFSIZE,
00339 +SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE,
00340 -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE, -SKYBOX_HALFSIZE
00341 };
00342
00343 static const float starFieldTexCoords[] = {
00344 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
00345 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
00346 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
00347 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
00348 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
00349 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
00350 };
00351
00361 static void R_DrawStarfield (int texnum, const vec3_t pos, const vec3_t rotate, float p)
00362 {
00363 vec3_t angle;
00365
00366 glPushMatrix();
00367
00368
00369
00370 glTranslatef(pos[0], pos[1], -SKYBOX_DEPTH);
00371
00372
00373 VectorSet(angle, rotate[0] - p * todeg, rotate[1], rotate[2]);
00374 glRotatef(angle[YAW], 1, 0, 0);
00375 glRotatef(angle[ROLL], 0, 1, 0);
00376 glRotatef(angle[PITCH], 0, 0, 1);
00377
00378 R_BindTexture(texnum);
00379
00380
00381 glVertexPointer(3, GL_FLOAT, 0, starFieldVerts);
00382 glTexCoordPointer(2, GL_FLOAT, 0, starFieldTexCoords);
00383
00384
00385 glDrawArrays(GL_QUADS, 0, 24);
00386
00387
00388 glPopMatrix();
00389 }
00390
00399 static inline void RotateCelestialBody (const vec4_t v, vec4_t * r, const vec3_t rotate, const vec3_t earthPos, const float celestialDist)
00400 {
00401 vec4_t v1;
00402 vec4_t v2;
00403 vec3_t rotationAxis;
00404
00405 VectorSet(v2, v[1], v[0], v[2]);
00406 VectorSet(rotationAxis, 0, 0, 1);
00407 RotatePointAroundVector(v1, rotationAxis, v2, -rotate[PITCH]);
00408 VectorSet(rotationAxis, 0, 1, 0);
00409 RotatePointAroundVector(v2, rotationAxis, v1, -rotate[YAW]);
00410
00411 Vector4Set((*r), earthPos[0] + celestialDist * v2[1], earthPos[1] + celestialDist * v2[0], -celestialDist * v2[2], 0);
00412 }
00413
00414
00427 void R_Draw3DGlobe (int x, int y, int w, int h, int day, int second, const vec3_t rotate, float zoom, const char *map, qboolean disableSolarRender, float ambient, qboolean overlayNation, qboolean overlayXVI, qboolean overlayRadar, image_t *r_xviTexture, image_t *r_radarTexture)
00428 {
00429
00430 const float fullscale = zoom / STANDARD_3D_ZOOM;
00431
00432
00433 static const vec4_t diffuseLightColor = { 1.75f, 1.75f, 1.75f, 1.0f };
00434 static const vec4_t specularLightColor = { 2.0f, 1.9f, 1.7f, 1.0f };
00435 static const vec4_t darknessLightColor = { 0.0f, 0.0f, 0.0f, 1.0f };
00436 static const vec4_t brightDiffuseLightColor = { 5.0f, 5.0f, 5.0f, 1.0f };
00437 const vec4_t ambientLightColor = { ambient + 0.2f, ambient + 0.2f, ambient + 0.2f, ambient + 0.2f };
00438
00439 image_t *starfield;
00440 image_t *halo;
00441 image_t *sun;
00442 image_t *sunOverlay;
00443
00444
00445
00446
00447 static const float celestialDist = 1.37f * SKYBOX_HALFSIZE;
00448 static const float moonSize = 0.025f;
00449 vec4_t sunPos;
00450 vec4_t antiSunPos;
00451 vec4_t moonLoc;
00452 vec4_t sunLoc;
00453
00454
00455 const float nx = x * viddef.rx;
00456 const float ny = y * viddef.ry;
00457 const float nw = w * viddef.rx;
00458 const float nh = h * viddef.ry;
00459
00460
00461
00462 const vec3_t earthPos = { nx + nw / 2.0, ny + nh / 2.0, 0.0 };
00463
00464
00465
00466
00467 const float season = (float) (day % DAYS_PER_YEAR) / ((float) (DAYS_PER_YEAR) / (float) (SEASONS_PER_YEAR));
00468 const int currSeason = (int) floorf(season) % SEASONS_PER_YEAR;
00469 const int nextSeason = (int) ceilf(season) % SEASONS_PER_YEAR;
00470 const float seasonProgress = season - (float) currSeason;
00471
00472
00473 const float q = (day % DAYS_PER_YEAR * SECONDS_PER_DAY + second) * (2 * M_PI / (SECONDS_PER_DAY * DAYS_PER_YEAR));
00474 const float a = cos(q) * SIN_ALPHA;
00475 const float sqrta = sqrt(0.5f * (1 - a * a));
00476
00477
00478 const float p = (second - SECONDS_PER_DAY / 4) * (2.0 * M_PI / SECONDS_PER_DAY);
00479
00480 const float m = p + (((double)((10 * day % 249) / 10.0) + ((double)second / (double)SECONDS_PER_DAY)) / 24.9) * (2.0 * M_PI);
00481
00482 glPushMatrix();
00483 glMatrixMode(GL_TEXTURE);
00484 glLoadIdentity();
00485 glMatrixMode(GL_MODELVIEW);
00486 glDisable(GL_LIGHTING);
00487
00488 starfield = R_FindImage(va("pics/geoscape/%s_stars", map), it_wrappic);
00489 if (starfield != r_noTexture)
00490 R_DrawStarfield(starfield->texnum, earthPos, rotate, p);
00491
00492 glPopMatrix();
00493
00494
00495 Vector4Set(sunPos, cos(p) * sqrta, -sin(p) * sqrta, a, 0);
00496 Vector4Set(antiSunPos, -cos(p) * sqrta, sin(p) * sqrta, -a, 0);
00497
00498
00499 RotateCelestialBody(sunPos, &sunLoc, rotate, earthPos, 1.0);
00500
00501 sun = R_FindImage(va("pics/geoscape/%s_sun", map), it_wrappic);
00502 sunOverlay = R_FindImage(va("pics/geoscape/%s_sun_overlay", map), it_pic);
00503 if (sun != r_noTexture && sunOverlay != r_noTexture && sunLoc[2] > 0 && !disableSolarRender) {
00504 const int sunx = earthPos[0] + viddef.rx * (-128.0 + celestialDist * (sunLoc[0] - earthPos[0]));
00505 const int suny = earthPos[1] + viddef.ry * (-128.0 + celestialDist * (sunLoc[1] - earthPos[1]));
00506
00507 R_DrawTexture(sunOverlay->texnum, sunx, suny, 256.0 * viddef.rx, 256.0 * viddef.ry);
00508 R_DrawBuffers(2);
00509 R_DrawTexture(sun->texnum, sunx, suny, 256.0 * viddef.rx, 256.0 * viddef.ry);
00510 R_DrawBuffers(1);
00511 }
00512
00513
00514
00515
00516 VectorSet(moonLoc, cos(m) * sqrta, -sin(m) * sqrta, a);
00517 RotateCelestialBody(moonLoc, &moonLoc, rotate, earthPos, celestialDist);
00518
00519
00520 if (r_globeEarth.season != currSeason) {
00521 r_globeEarth.season = currSeason;
00522 R_FreeImage(r_globeEarth.texture);
00523 }
00524
00525
00526 r_globeEarth.texture = R_FindImage(va("pics/geoscape/%s/%s_season_%02d", r_config.lodDir, map, currSeason), it_wrappic);
00527 if (r_globeEarth.texture == r_noTexture)
00528 Com_Error(ERR_FATAL, "Could not find pics/geoscape/%s/%s_season_%02d\n", r_config.lodDir, map, currSeason);
00529
00530
00531 if (r_programs->integer) {
00532 r_globeEarth.glslProgram = r_state.geoscape_program;
00533
00534 r_globeEarth.blendTexture = R_FindImage(va("pics/geoscape/%s/%s_season_%02d", r_config.lodDir, map, nextSeason), it_wrappic);
00535 if (r_globeEarth.blendTexture == r_noTexture)
00536 Com_Error(ERR_FATAL, "Could not find pics/geoscape/%s/%s_season_%02d\n", r_config.lodDir, map, nextSeason);
00537
00538
00539 r_globeEarth.normalMap = R_FindImage(va("pics/geoscape/%s/%s_bump", r_config.lodDir, map), it_wrappic);
00540 if (r_globeEarth.normalMap == r_noTexture)
00541 r_globeEarth.normalMap = NULL;
00542
00543
00544 r_globeEarth.blendScale = seasonProgress;
00545
00546 VectorCopy(antiSunPos, r_globeEarth.nightLightPos);
00547 glLightfv(GL_LIGHT1, GL_AMBIENT, darknessLightColor);
00548 glLightfv(GL_LIGHT1, GL_DIFFUSE, brightDiffuseLightColor);
00549 glLightfv(GL_LIGHT1, GL_SPECULAR, darknessLightColor);
00550
00551 r_globeEarth.glowScale = 0.7;
00552 }
00553
00554
00555 r_globeMoon.texture = R_FindImage(va("pics/geoscape/%s_moon", map), it_wrappic);
00556
00557
00558 glMatrixMode(GL_TEXTURE);
00559 glLoadIdentity();
00560 glScalef(2, 1, 1);
00561 glMatrixMode(GL_MODELVIEW);
00562
00563
00564 glEnable(GL_LIGHTING);
00565 glEnable(GL_LIGHT0);
00566 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLightColor);
00567 glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLightColor);
00568 glLightfv(GL_LIGHT0, GL_SPECULAR, specularLightColor);
00569
00570
00571 if (r_globeMoon.texture != r_noTexture && moonLoc[2] > 0 && !disableSolarRender)
00572 R_SphereRender(&r_globeMoon, moonLoc, rotate, moonSize, sunPos);
00573
00574
00575 glEnable(GL_DEPTH_TEST);
00576
00577
00578 R_DrawBuffers(2);
00579 if (r_programs->integer == 0)
00580 glBlendFunc(GL_ONE, GL_ZERO);
00581
00582 R_SphereRender(&r_globeEarth, earthPos, rotate, fullscale, sunPos);
00583
00584 if (r_programs->integer == 0)
00585 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00586
00587 r_globeEarthAtmosphere.texture = R_FindImage(va("pics/geoscape/%s_atmosphere", map), it_wrappic);
00588
00589
00590 if (r_programs->integer && r_postprocess->integer) {
00591 r_globeEarthAtmosphere.normalMap = r_globeEarth.normalMap;
00592 r_globeEarthAtmosphere.glowScale = 1.0;
00593 r_globeEarthAtmosphere.blendScale = -1.0;
00594 r_globeEarthAtmosphere.glslProgram = r_state.atmosphere_program;
00595 R_SphereRender(&r_globeEarthAtmosphere, earthPos, rotate, fullscale, sunPos);
00596 } else {
00597 halo = R_FindImage("pics/geoscape/map_earth_halo", it_pic);
00598 if (halo != r_noTexture) {
00600 const float earthSizeX = fullscale * 20500.0 * viddef.rx;
00601 const float earthSizeY = fullscale * 20500.0 * viddef.ry;
00602 glMatrixMode(GL_TEXTURE);
00603 glPushMatrix();
00604 glLoadIdentity();
00605 glDisable(GL_LIGHTING);
00606
00607 R_DrawTexture(halo->texnum, earthPos[0] - earthSizeX * 0.5, earthPos[1] - earthSizeY * 0.5, earthSizeX, earthSizeY);
00608 glEnable(GL_LIGHTING);
00609 glPopMatrix();
00610 glMatrixMode(GL_MODELVIEW);
00611 }
00612 }
00613
00614 R_DrawBuffers(1);
00615 glDisable(GL_DEPTH_TEST);
00616
00617
00618 if (overlayNation) {
00619 r_globeEarth.overlay = R_FindImage(va("pics/geoscape/%s_nations_overlay", map), it_wrappic);
00620 if (r_globeEarth.overlay == r_noTexture)
00621 Com_Error(ERR_FATAL, "Could not load geoscape nation overlay image");
00622
00623 R_SphereRender(&r_globeEarth, earthPos, rotate, fullscale, sunPos);
00624
00625
00626 r_globeEarth.overlay = R_FindImage(va("pics/geoscape/%s_nations_overlay_glow", map), it_wrappic);
00627 if (r_globeEarth.overlay == r_noTexture)
00628 Com_Error(ERR_FATAL, "Could not load geoscape nation overlay glow image");
00629
00630 R_DrawBuffers(2);
00631 glDisable(GL_LIGHTING);
00632 R_SphereRender(&r_globeEarth, earthPos, rotate, fullscale, sunPos);
00633 glEnable(GL_LIGHTING);
00634 R_DrawBuffers(1);
00635
00636 r_globeEarth.overlay = NULL;
00637 }
00638
00639 if (overlayXVI) {
00640 r_globeEarth.overlay = R_FindImage(va("pics/geoscape/%s_xvi_overlay", map), it_wrappic);
00641 r_globeEarth.overlayAlphaMask = r_xviTexture;
00642 assert(r_globeEarth.overlayAlphaMask);
00643 R_SphereRender(&r_globeEarth, earthPos, rotate, fullscale, sunPos);
00644 r_globeEarth.overlayAlphaMask = NULL;
00645 r_globeEarth.overlay = NULL;
00646 }
00647
00648 if (overlayRadar) {
00649 r_globeEarth.overlay = r_radarTexture;
00650 assert(r_globeEarth.overlay);
00651 R_SphereRender(&r_globeEarth, earthPos, rotate, fullscale, sunPos);
00652 r_globeEarth.overlay = NULL;
00653 }
00654
00655
00656 glDisable(GL_LIGHTING);
00657
00658
00659 glMatrixMode(GL_TEXTURE);
00660 glLoadIdentity();
00661 glMatrixMode(GL_MODELVIEW);
00662 }
00663
00667 static inline void R_DrawQuad (void)
00668 {
00669 glBegin(GL_QUADS);
00670 glTexCoord2i(0, 1);
00671 glVertex2i(0, 0);
00672 glTexCoord2i(1, 1);
00673 glVertex2i(fbo_render->width, 0);
00674 glTexCoord2i(1, 0);
00675 glVertex2i(fbo_render->width, fbo_render->height);
00676 glTexCoord2i(0, 0);
00677 glVertex2i(0, fbo_render->height);
00678 glEnd();
00679 }
00680
00685 static void R_Blur (r_framebuffer_t * source, r_framebuffer_t * dest, int tex, int dir)
00686 {
00687 R_EnableBlur(r_state.convolve_program, qtrue, source, dest, dir);
00688
00689
00690 R_BindTextureForTexUnit(source->textures[tex], &texunit_0);
00691 R_UseViewport(source);
00692 R_DrawQuad();
00693
00694 R_EnableBlur(r_state.convolve_program, qfalse, NULL, NULL, 0);
00695 }
00696
00700 static void R_BlurStack (int levels, r_framebuffer_t ** sources, r_framebuffer_t ** dests)
00701 {
00702 int i;
00703
00704 for (i = 0; i < levels; i++) {
00705 const int l = levels - i - 1;
00706
00707 R_UseProgram(i == 0 ? default_program : r_state.combine2_program);
00708 R_UseFramebuffer(dests[l]);
00709 R_BindTextureForTexUnit(sources[l]->textures[0], &texunit_0);
00710 if (i != 0)
00711 R_BindTextureForTexUnit(dests[l + 1]->textures[0], &texunit_1);
00712
00713 R_UseViewport(sources[l]);
00714 R_DrawQuad();
00715
00716 R_Blur(dests[l], sources[l], 0, 1);
00717 R_Blur(sources[l], dests[l], 0, 0);
00718 }
00719 }
00720
00724 void R_DrawBloom (void)
00725 {
00726 int i;
00727 qboolean renderBufferState;
00728
00729 if (!r_config.frameBufferObject || !r_postprocess->integer || !r_programs->integer)
00730 return;
00731
00732
00733 renderBufferState = R_RenderbufferEnabled();
00734 glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT);
00735 glMatrixMode(GL_TEXTURE);
00736 glPushMatrix();
00737 glLoadIdentity();
00738 glMatrixMode(GL_MODELVIEW);
00739 glPushMatrix();
00740 glLoadIdentity();
00741 glMatrixMode(GL_PROJECTION);
00742 glPushMatrix();
00743 glLoadIdentity();
00744 glOrtho(0, viddef.width, viddef.height, 0, 9999.0f, SKYBOX_DEPTH);
00745
00746 glDisable(GL_LIGHTING);
00747 glDisable(GL_DEPTH_TEST);
00748
00749
00750 R_BindTexture(fbo_render->textures[1]);
00751 qglGenerateMipmapEXT(GL_TEXTURE_2D);
00752
00753 R_Blur(fbo_render, fbo_bloom0, 1, 0);
00754 R_Blur(fbo_bloom0, fbo_bloom1, 0, 1);
00755
00756 R_UseFramebuffer(r_state.buffers0[0]);
00757 R_BindTexture(fbo_bloom1->textures[0]);
00758 qglGenerateMipmapEXT(GL_TEXTURE_2D);
00759 R_UseViewport(r_state.buffers0[0]);
00760 R_DrawQuad();
00761
00762 for (i = 1; i < DOWNSAMPLE_PASSES; i++) {
00763 R_Blur(r_state.buffers0[i - 1], r_state.buffers1[i - 1], 0, 0);
00764 R_Blur(r_state.buffers1[i - 1], r_state.buffers2[i - 1], 0, 1);
00765 R_UseFramebuffer(r_state.buffers0[i]);
00766 R_BindTexture(r_state.buffers2[i - 1]->textures[0]);
00767 R_UseViewport(r_state.buffers0[i]);
00768 R_DrawQuad();
00769 }
00770
00771
00772 R_BlurStack(DOWNSAMPLE_PASSES, r_state.buffers0, r_state.buffers1);
00773
00774
00775 R_UseProgram(r_state.combine2_program);
00776 R_UseFramebuffer(fbo_bloom0);
00777 R_BindTextureForTexUnit(fbo_render->textures[1], &texunit_0);
00778 R_BindTextureForTexUnit(r_state.buffers1[0]->textures[0], &texunit_1);
00779
00780 R_UseViewport(fbo_screen);
00781 R_DrawQuad();
00782
00783
00784 R_UseFramebuffer(fbo_screen);
00785 R_UseProgram(r_state.combine2_program);
00786 R_BindTextureForTexUnit(fbo_render->textures[0], &texunit_0);
00787 R_BindTextureForTexUnit(fbo_bloom0->textures[0], &texunit_1);
00788
00789 R_DrawQuad();
00790
00791
00792 R_UseProgram(default_program);
00793
00794 R_CheckError();
00795
00796 glMatrixMode(GL_PROJECTION);
00797 glPopMatrix();
00798 glMatrixMode(GL_MODELVIEW);
00799 glPopMatrix();
00800 glMatrixMode(GL_TEXTURE);
00801 glPopMatrix();
00802 glPopAttrib();
00803 R_CheckError();
00804
00805
00806 R_EnableRenderbuffer(renderBufferState);
00807 }