1 #include "engine.h"
2
3 Texture *sky[6] = { 0, 0, 0, 0, 0, 0 }, *clouds[6] = { 0, 0, 0, 0, 0, 0 };
4
loadsky(const char * basename,Texture * texs[6])5 void loadsky(const char *basename, Texture *texs[6])
6 {
7 bool fail = false;
8 loopi(6)
9 {
10 const char *side = cubemapsides[i].name;
11 defformatstring(name)("%s_%s", basename, side);
12 if((texs[i] = textureload(name, 3, true, false)) == notexture)
13 {
14 conoutf("\frcould not load sky texture %s_%s", basename, side);
15 fail = true;
16 }
17 }
18 }
19
20 Texture *cloudoverlay = NULL;
21
loadskyoverlay(const char * basename)22 Texture *loadskyoverlay(const char *basename)
23 {
24 Texture *t = textureload(basename, 0, true, false);
25 if(t == notexture) conoutf("\frcould not load sky overlay texture %s", basename);
26 return t;
27 }
28
29 HVARW(skybgcolour, 0, 0x000000, 0xFFFFFF);
30 VARW(skybgglare, 0, 0, 1);
31
32 SVARFW(skybox, "", { if(skybox[0]) loadsky(skybox, sky); });
33 FVARW(skyblend, 0, 1.0f, 1);
34 VARW(skyglare, 0, 1, 1);
35 HVARW(skycolour, 0, 0xFFFFFF, 0xFFFFFF);
36 FVARW(spinsky, -720, 0, 720);
37 VARW(yawsky, 0, 0, 360);
38
39 SVARFW(cloudbox, "", { if(cloudbox[0]) loadsky(cloudbox, clouds); });
40 FVARW(cloudblend, 0, 1.0f, 1);
41 VARW(cloudglare, 0, 0, 1);
42 HVARW(cloudcolour, 0, 0xFFFFFF, 0xFFFFFF);
43 FVARW(spinclouds, -720, 0, 720);
44 VARW(yawclouds, 0, 0, 360);
45
46 SVARFW(cloudlayer, "", { if(cloudlayer[0]) cloudoverlay = loadskyoverlay(cloudlayer); });
47 FVARW(cloudlayerblend, 0, 1.0f, 1);
48 VARW(cloudlayerglare, 0, 0, 1);
49 HVARW(cloudlayercolour, 0, 0xFFFFFF, 0xFFFFFF);
50 FVARW(cloudscrollx, -16, 0, 16);
51 FVARW(cloudscrolly, -16, 0, 16);
52 FVARW(cloudscale, 0, 1, 64);
53 FVARW(spincloudlayer, -720, 0, 720);
54 VARW(yawcloudlayer, 0, 0, 360);
55 FVARW(cloudheight, -1, 0.2f, 1);
56 FVARW(cloudfade, 0, 0.2f, 1);
57 VARW(cloudsubdiv, 4, 16, 64);
58
59 FVARW(cloudclip, 0, 0.5f, 1);
60
draw_envbox_face(float s0,float t0,int x0,int y0,int z0,float s1,float t1,int x1,int y1,int z1,float s2,float t2,int x2,int y2,int z2,float s3,float t3,int x3,int y3,int z3,GLuint texture)61 void draw_envbox_face(float s0, float t0, int x0, int y0, int z0,
62 float s1, float t1, int x1, int y1, int z1,
63 float s2, float t2, int x2, int y2, int z2,
64 float s3, float t3, int x3, int y3, int z3,
65 GLuint texture)
66 {
67 glBindTexture(GL_TEXTURE_2D, texture);
68 glBegin(GL_QUADS);
69 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
70 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
71 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
72 glTexCoord2f(s0, t0); glVertex3f(x0, y0, z0);
73 glEnd();
74 xtraverts += 4;
75 }
76
draw_envbox_quad(int x0,int y0,int z0,int x1,int y1,int z1,int x2,int y2,int z2,int x3,int y3,int z3)77 void draw_envbox_quad(int x0, int y0, int z0,
78 int x1, int y1, int z1,
79 int x2, int y2, int z2,
80 int x3, int y3, int z3)
81 {
82 glBegin(GL_QUADS);
83 glVertex3f(x3, y3, z3);
84 glVertex3f(x2, y2, z2);
85 glVertex3f(x1, y1, z1);
86 glVertex3f(x0, y0, z0);
87 glEnd();
88 xtraverts += 4;
89 }
90
draw_envbox(int w,float zclip=0.0f,int faces=0x3F,Texture ** sky=NULL)91 void draw_envbox(int w, float zclip = 0.0f, int faces = 0x3F, Texture **sky = NULL)
92 {
93 float vclip = 1-zclip;
94 int z = int(ceil(2*w*(vclip-0.5f)));
95
96 if(faces&0x01)
97 draw_envbox_face(0.0f, 0.0f, -w, -w, -w,
98 1.0f, 0.0f, -w, w, -w,
99 1.0f, vclip, -w, w, z,
100 0.0f, vclip, -w, -w, z, sky && sky[0] ? sky[0]->id : notexture->id);
101
102 if(faces&0x02)
103 draw_envbox_face(1.0f, vclip, +w, -w, z,
104 0.0f, vclip, +w, w, z,
105 0.0f, 0.0f, +w, w, -w,
106 1.0f, 0.0f, +w, -w, -w, sky && sky[1] ? sky[1]->id : notexture->id);
107
108 if(faces&0x04)
109 draw_envbox_face(1.0f, vclip, -w, -w, z,
110 0.0f, vclip, w, -w, z,
111 0.0f, 0.0f, w, -w, -w,
112 1.0f, 0.0f, -w, -w, -w, sky && sky[2] ? sky[2]->id : notexture->id);
113
114 if(faces&0x08)
115 draw_envbox_face(1.0f, vclip, +w, w, z,
116 0.0f, vclip, -w, w, z,
117 0.0f, 0.0f, -w, w, -w,
118 1.0f, 0.0f, +w, w, -w, sky && sky[3] ? sky[3]->id : notexture->id);
119
120 if(!zclip && faces&0x10)
121 draw_envbox_face(0.0f, 1.0f, -w, w, w,
122 0.0f, 0.0f, +w, w, w,
123 1.0f, 0.0f, +w, -w, w,
124 1.0f, 1.0f, -w, -w, w, sky && sky[4] ? sky[4]->id : notexture->id);
125
126 if(faces&0x20)
127 draw_envbox_face(0.0f, 1.0f, +w, w, -w,
128 0.0f, 0.0f, -w, w, -w,
129 1.0f, 0.0f, -w, -w, -w,
130 1.0f, 1.0f, +w, -w, -w, sky && sky[5] ? sky[5]->id : notexture->id);
131 }
132
draw_envbox_bg(int w)133 void draw_envbox_bg(int w)
134 {
135 draw_envbox_quad(-w, -w, -w, -w, w, -w, -w, w, w, -w, -w, w);
136 draw_envbox_quad(+w, -w, w, +w, w, w, +w, w, -w, +w, -w, -w);
137 draw_envbox_quad(-w, -w, w, w, -w, w, w, -w, -w, -w, -w, -w);
138 draw_envbox_quad(+w, w, w, -w, w, w, -w, w, -w, +w, w, -w);
139 draw_envbox_quad(-w, w, w, +w, w, w, +w, -w, w, -w, -w, w);
140 draw_envbox_quad(+w, w, -w, -w, w, -w, -w, -w, -w, +w, -w, -w);
141 }
142
draw_env_overlay(int w,Texture * overlay=NULL,int colour=0xFFFFFF,float a=1.f,float tx=0,float ty=0)143 void draw_env_overlay(int w, Texture *overlay = NULL, int colour = 0xFFFFFF, float a = 1.f, float tx = 0, float ty = 0)
144 {
145 float z = -w*cloudheight, tsz = 0.5f*(1-cloudfade)/cloudscale, psz = w*(1-cloudfade);
146 glBindTexture(GL_TEXTURE_2D, overlay ? overlay->id : notexture->id);
147 float r = (colour>>16)/255.0f, g = ((colour>>8)&255)/255.0f, b = (colour&255)/255.0f;
148 glColor4f(r, g, b, a);
149 glBegin(GL_POLYGON);
150 loopi(cloudsubdiv)
151 {
152 vec p(1, 1, 0);
153 p.rotate_around_z((-2.0f*M_PI*i)/cloudsubdiv);
154 glTexCoord2f(tx + p.x*tsz, ty + p.y*tsz); glVertex3f(p.x*psz, p.y*psz, z);
155 }
156 glEnd();
157 float tsz2 = 0.5f/cloudscale;
158 glBegin(GL_QUAD_STRIP);
159 loopi(cloudsubdiv+1)
160 {
161 vec p(1, 1, 0);
162 p.rotate_around_z((-2.0f*M_PI*i)/cloudsubdiv);
163 glColor4f(r, g, b, a);
164 glTexCoord2f(tx + p.x*tsz, ty + p.y*tsz); glVertex3f(p.x*psz, p.y*psz, z);
165 glColor4f(r, g, b, 0);
166 glTexCoord2f(tx + p.x*tsz2, ty + p.y*tsz2); glVertex3f(p.x*w, p.y*w, z);
167 }
168 glEnd();
169 }
170
171 static struct domevert
172 {
173 vec pos;
174 uchar color[4];
175
domevertdomevert176 domevert() {}
domevertdomevert177 domevert(const vec &pos, float alpha) : pos(pos)
178 {
179 memcpy(color, fogcolor.v, 3);
180 color[3] = uchar(alpha*255);
181 }
domevertdomevert182 domevert(const domevert &v0, const domevert &v1) : pos(vec(v0.pos).add(v1.pos).normalize())
183 {
184 memcpy(color, v0.color, 4);
185 if(v0.pos.z != v1.pos.z) color[3] += uchar((v1.color[3] - v0.color[3]) * (pos.z - v0.pos.z) / (v1.pos.z - v0.pos.z));
186 }
187 } *domeverts = NULL;
188 static GLushort *domeindices = NULL;
189 static int domenumverts = 0, domenumindices = 0, domecapindices = 0;
190 static GLuint domevbuf = 0, domeebuf = 0;
191 static bvec domecolor(0, 0, 0);
192 static float domeminalpha = 0, domemaxalpha = 0, domecapsize = -1;
193
194 static void subdivide(int depth, int face);
195
genface(int depth,int i1,int i2,int i3)196 static void genface(int depth, int i1, int i2, int i3)
197 {
198 int face = domenumindices; domenumindices += 3;
199 domeindices[face] = i3;
200 domeindices[face+1] = i2;
201 domeindices[face+2] = i1;
202 subdivide(depth, face);
203 }
204
subdivide(int depth,int face)205 static void subdivide(int depth, int face)
206 {
207 if(depth-- <= 0) return;
208 int idx[6];
209 loopi(3) idx[i] = domeindices[face+2-i];
210 loopi(3)
211 {
212 int vert = domenumverts++;
213 domeverts[vert] = domevert(domeverts[idx[i]], domeverts[idx[(i+1)%3]]); //push on to unit sphere
214 idx[3+i] = vert;
215 domeindices[face+2-i] = vert;
216 }
217 subdivide(depth, face);
218 loopi(3) genface(depth, idx[i], idx[3+i], idx[3+(i+2)%3]);
219 }
220
sortdomecap(const GLushort * x,const GLushort * y)221 static int sortdomecap(const GLushort *x, const GLushort *y)
222 {
223 const vec &xv = domeverts[*x].pos, &yv = domeverts[*y].pos;
224 if(xv.y < 0)
225 {
226 if(yv.y >= 0 || xv.x < yv.x) return -1;
227 if(xv.x > yv.x) return 1;
228 }
229 else if(yv.y < 0 || xv.x < yv.x) return 1;
230 else if(xv.x > yv.x) return -1;
231 return 0;
232 }
233
initdome(float minalpha=0.0f,float maxalpha=1.0f,float capsize=-1,int hres=16,int depth=2)234 static void initdome(float minalpha = 0.0f, float maxalpha = 1.0f, float capsize = -1, int hres = 16, int depth = 2)
235 {
236 const int tris = hres << (2*depth);
237 domenumverts = domenumindices = domecapindices = 0;
238 DELETEA(domeverts);
239 DELETEA(domeindices);
240 domeverts = new domevert[tris+1 + (capsize >= 0 ? 1 : 0)];
241 domeindices = new GLushort[(tris + (capsize >= 0 ? hres<<depth : 0))*3];
242 domeverts[domenumverts++] = domevert(vec(0.0f, 0.0f, 1.0f), minalpha); //build initial 'hres' sided pyramid
243 loopi(hres)
244 {
245 float angle = 2*M_PI*float(i)/hres;
246 domeverts[domenumverts++] = domevert(vec(cosf(angle), sinf(angle), 0.0f), maxalpha);
247 }
248 loopi(hres) genface(depth, 0, i+1, 1+(i+1)%hres);
249
250 if(capsize >= 0)
251 {
252 GLushort *domecap = &domeindices[domenumindices];
253 int domecapverts = 0;
254 loopi(domenumverts) if(!domeverts[i].pos.z) domecap[domecapverts++] = i;
255 domeverts[domenumverts++] = domevert(vec(0.0f, 0.0f, -capsize), maxalpha);
256 quicksort(domecap, domecapverts, sortdomecap);
257 loopi(domecapverts)
258 {
259 int n = domecapverts-1-i;
260 domecap[n*3] = domecap[n];
261 domecap[n*3+1] = domecap[(n+1)%domecapverts];
262 domecap[n*3+2] = domenumverts-1;
263 domecapindices += 3;
264 }
265 }
266
267 if(hasVBO)
268 {
269 if(!domevbuf) glGenBuffers_(1, &domevbuf);
270 glBindBuffer_(GL_ARRAY_BUFFER_ARB, domevbuf);
271 glBufferData_(GL_ARRAY_BUFFER_ARB, domenumverts*sizeof(domevert), domeverts, GL_STATIC_DRAW_ARB);
272 DELETEA(domeverts);
273
274 if(!domeebuf) glGenBuffers_(1, &domeebuf);
275 glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER_ARB, domeebuf);
276 glBufferData_(GL_ELEMENT_ARRAY_BUFFER_ARB, (domenumindices + domecapindices)*sizeof(GLushort), domeindices, GL_STATIC_DRAW_ARB);
277 DELETEA(domeindices);
278 }
279 }
280
deletedome()281 static void deletedome()
282 {
283 domenumverts = domenumindices = 0;
284 if(domevbuf) { glDeleteBuffers_(1, &domevbuf); domevbuf = 0; }
285 if(domeebuf) { glDeleteBuffers_(1, &domeebuf); domeebuf = 0; }
286 DELETEA(domeverts);
287 DELETEA(domeindices);
288 }
289
290 FVARW(fogdomeheight, -1, -0.5f, 1);
291 FVARW(fogdomemin, 0, 0, 1);
292 FVARW(fogdomemax, 0, 0, 1);
293 VARW(fogdomecap, 0, 0, 1);
294
drawdome()295 static void drawdome()
296 {
297 float capsize = fogdomecap && fogdomeheight < 1 ? (1 + fogdomeheight) / (1 - fogdomeheight) : -1;
298 if(!domenumverts || domecolor != fogcolor || domeminalpha != fogdomemin || domemaxalpha != fogdomemax || domecapsize != capsize)
299 {
300 initdome(min(fogdomemin, fogdomemax), fogdomemax, capsize);
301 domecolor = fogcolor;
302 domeminalpha = fogdomemin;
303 domemaxalpha = fogdomemax;
304 domecapsize = capsize;
305 }
306
307 if(hasVBO)
308 {
309 glBindBuffer_(GL_ARRAY_BUFFER_ARB, domevbuf);
310 glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER_ARB, domeebuf);
311 }
312
313 glEnableClientState(GL_VERTEX_ARRAY);
314 glEnableClientState(GL_COLOR_ARRAY);
315 glVertexPointer(3, GL_FLOAT, sizeof(domevert), &domeverts->pos);
316 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(domevert), &domeverts->color);
317
318 if(hasDRE) glDrawRangeElements_(GL_TRIANGLES, 0, domenumverts-1, domenumindices + fogdomecap*domecapindices, GL_UNSIGNED_SHORT, domeindices);
319 else glDrawElements(GL_TRIANGLES, domenumindices + fogdomecap*domecapindices, GL_UNSIGNED_SHORT, domeindices);
320 xtraverts += domenumverts;
321 glde++;
322
323 glDisableClientState(GL_VERTEX_ARRAY);
324 glDisableClientState(GL_COLOR_ARRAY);
325
326 if(hasVBO)
327 {
328 glBindBuffer_(GL_ARRAY_BUFFER_ARB, 0);
329 glBindBuffer_(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
330 }
331 }
332
cleanupsky()333 void cleanupsky()
334 {
335 deletedome();
336 }
337
338 VARP(sparklyfix, 0, 0, 1);
339 VAR(showsky, 0, 1, 1);
340 VAR(clipsky, 0, 1, 1);
341
drawskylimits(bool explicitonly)342 bool drawskylimits(bool explicitonly)
343 {
344 nocolorshader->set();
345
346 glDisable(GL_TEXTURE_2D);
347 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
348 bool rendered = rendersky(explicitonly);
349 glColorMask(COLORMASK, GL_TRUE);
350 glEnable(GL_TEXTURE_2D);
351
352 return rendered;
353 }
354
drawskyoutline()355 void drawskyoutline()
356 {
357 notextureshader->set();
358
359 glDisable(GL_TEXTURE_2D);
360 glDepthMask(GL_FALSE);
361 extern int wireframe;
362 if(!wireframe)
363 {
364 enablepolygonoffset(GL_POLYGON_OFFSET_LINE);
365 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
366 }
367 glColor3f(0.5f, 0.0f, 0.5f);
368 rendersky(true);
369 if(!wireframe)
370 {
371 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
372 disablepolygonoffset(GL_POLYGON_OFFSET_LINE);
373 }
374 glDepthMask(GL_TRUE);
375 glEnable(GL_TEXTURE_2D);
376
377 if(!glaring) defaultshader->set();
378 }
379
380 VAR(clampsky, 0, 1, 1);
381
yawskyfaces(int faces,int yaw=0,float spin=0)382 static int yawskyfaces(int faces, int yaw = 0, float spin = 0)
383 {
384 if(spin || yaw%90) return faces&0x0F ? faces | 0x0F : faces;
385 static const int faceidxs[3][4] =
386 {
387 { 3, 2, 0, 1 },
388 { 1, 0, 3, 2 },
389 { 2, 3, 1, 0 }
390 };
391 yaw /= 90;
392 if(yaw < 1 || yaw > 3) return faces;
393 const int *idxs = faceidxs[yaw - 1];
394 return (faces & ~0x0F) | (((faces>>idxs[0])&1)<<0) | (((faces>>idxs[1])&1)<<1) | (((faces>>idxs[2])&1)<<2) | (((faces>>idxs[3])&1)<<3);
395 }
396
drawskybox(int farplane,bool limited)397 void drawskybox(int farplane, bool limited)
398 {
399 extern int renderedskyfaces, renderedskyclip; // , renderedsky, renderedexplicitsky;
400 bool alwaysrender = editmode || !insideworld(camera1->o) || reflecting,
401 explicitonly = false;
402 if(limited)
403 {
404 explicitonly = alwaysrender || !sparklyfix || refracting;
405 if(!drawskylimits(explicitonly) && !alwaysrender) return;
406 extern int ati_skybox_bug;
407 if(!alwaysrender && !renderedskyfaces && !ati_skybox_bug) explicitonly = false;
408 }
409 else if(!alwaysrender)
410 {
411 extern vtxarray *visibleva;
412 renderedskyfaces = 0;
413 renderedskyclip = INT_MAX;
414 for(vtxarray *va = visibleva; va; va = va->next)
415 {
416 if(va->occluded >= OCCLUDE_BB && va->skyfaces&0x80) continue;
417 renderedskyfaces |= va->skyfaces&0x3F;
418 if(!(va->skyfaces&0x1F) || camera1->o.z < va->skyclip) renderedskyclip = min(renderedskyclip, va->skyclip);
419 else renderedskyclip = 0;
420 }
421 if(!renderedskyfaces) return;
422 }
423
424 if(alwaysrender)
425 {
426 renderedskyfaces = 0x3F;
427 renderedskyclip = 0;
428 }
429
430 float skyclip = clipsky ? max(renderedskyclip-1, 0) : 0;
431 if(reflectz<hdr.worldsize && reflectz>skyclip) skyclip = reflectz;
432
433 if(renderpath!=R_FIXEDFUNCTION || !fogging) glDisable(GL_FOG);
434
435 if(limited)
436 {
437 if(explicitonly) glDisable(GL_DEPTH_TEST);
438 else glDepthFunc(GL_GEQUAL);
439 }
440 else glDepthFunc(GL_LEQUAL);
441
442 glDepthMask(GL_FALSE);
443
444 if(clampsky) glDepthRange(1, 1);
445
446 bool blendsky = !skybox[0] || !sky[0] || sky[0]->bpp >= 4;
447
448 if((!glaring || skybgglare) && blendsky)
449 {
450 glDisable(GL_TEXTURE_2D);
451 notextureshader->set();
452
453 glPushMatrix();
454 glLoadIdentity();
455 glRotatef(camera1->roll, 0, 0, 1);
456 glRotatef(camera1->pitch, -1, 0, 0);
457 glRotatef(camera1->yaw, 0, 1, 0);
458 glRotatef(90, 1, 0, 0);
459 if(reflecting) glScalef(1, 1, -1);
460 glColor3f((skybgcolour>>16)/255.0f, ((skybgcolour>>8)&255)/255.0f, (skybgcolour&255)/255.0f);
461 draw_envbox_bg(farplane/2);
462 glPopMatrix();
463
464 glEnable(GL_TEXTURE_2D);
465 }
466
467 if(glaring)
468 {
469 static Shader *skyboxglareshader = NULL;
470 if(!skyboxglareshader) skyboxglareshader = lookupshaderbyname("skyboxglare");
471 skyboxglareshader->set();
472 }
473 else defaultshader->set();
474
475 if((!glaring || skyglare) && skybox[0])
476 {
477 if(fading) glColorMask(COLORMASK, GL_FALSE);
478
479 if(blendsky)
480 {
481 glEnable(GL_BLEND);
482 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
483 }
484
485 glPushMatrix();
486 glLoadIdentity();
487 glRotatef(camera1->roll, 0, 0, 1);
488 glRotatef(camera1->pitch, -1, 0, 0);
489 glRotatef(camera1->yaw+spinsky*lastmillis/1000.0f+yawsky, 0, 1, 0);
490 glRotatef(90, 1, 0, 0);
491 if(reflecting) glScalef(1, 1, -1);
492 glColor4f((skycolour>>16)/255.0f, ((skycolour>>8)&255)/255.0f, (skycolour&255)/255.0f, skyblend);
493 draw_envbox(farplane/2, skyclip ? 0.5f + 0.5f*(skyclip-camera1->o.z)/float(hdr.worldsize) : 0, yawskyfaces(renderedskyfaces, yawsky, spinsky), sky);
494 glPopMatrix();
495
496 if(blendsky) glDisable(GL_BLEND);
497 }
498
499 if((!glaring || cloudglare) && cloudbox[0])
500 {
501 if(fading) glColorMask(COLORMASK, GL_FALSE);
502
503 glEnable(GL_BLEND);
504 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
505
506 glPushMatrix();
507 glLoadIdentity();
508 glRotatef(camera1->roll, 0, 0, 1);
509 glRotatef(camera1->pitch, -1, 0, 0);
510 glRotatef(camera1->yaw+spinclouds*lastmillis/1000.0f+yawclouds, 0, 1, 0);
511 glRotatef(90, 1, 0, 0);
512 if(reflecting) glScalef(1, 1, -1);
513 glColor4f((cloudcolour>>16)/255.0f, ((cloudcolour>>8)&255)/255.0f, (cloudcolour&255)/255.0f, cloudblend);
514 draw_envbox(farplane/2, skyclip ? 0.5f + 0.5f*(skyclip-camera1->o.z)/float(hdr.worldsize) : cloudclip, yawskyfaces(renderedskyfaces, yawclouds, spinclouds), clouds);
515 glPopMatrix();
516
517 glDisable(GL_BLEND);
518 }
519
520 if((!glaring || cloudlayerglare) && cloudlayer[0] && cloudheight && renderedskyfaces&(cloudheight < 0 ? 0x1F : 0x2F))
521 {
522 if(fading) glColorMask(COLORMASK, GL_FALSE);
523
524 glDisable(GL_CULL_FACE);
525
526 glEnable(GL_BLEND);
527 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
528
529 glPushMatrix();
530 glLoadIdentity();
531 glRotatef(camera1->roll, 0, 0, 1);
532 glRotatef(camera1->pitch, -1, 0, 0);
533 glRotatef(camera1->yaw+spincloudlayer*lastmillis/1000.0f+yawcloudlayer, 0, 1, 0);
534 glRotatef(90, 1, 0, 0);
535 if(reflecting) glScalef(1, 1, -1);
536 draw_env_overlay(farplane/2, cloudoverlay, cloudlayercolour, cloudlayerblend, cloudscrollx * lastmillis/1000.0f, cloudscrolly * lastmillis/1000.0f);
537 glPopMatrix();
538
539 glDisable(GL_BLEND);
540
541 glEnable(GL_CULL_FACE);
542 }
543
544 if(!glaring && fogdomemax)
545 {
546 if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
547
548 notextureshader->set();
549 glDisable(GL_TEXTURE_2D);
550
551 glEnable(GL_BLEND);
552 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
553
554 glPushMatrix();
555 glLoadIdentity();
556 glRotatef(camera1->roll, 0, 0, 1);
557 glRotatef(camera1->pitch, -1, 0, 0);
558 glRotatef(camera1->yaw, 0, 1, 0);
559 glRotatef(90, 1, 0, 0);
560 if(reflecting) glScalef(1, 1, -1);
561 glTranslatef(0, 0, -farplane*fogdomeheight*0.5f);
562 glScalef(farplane/2, farplane/2, -farplane*(0.5f - fogdomeheight*0.5f));
563 drawdome();
564 glPopMatrix();
565
566 glDisable(GL_BLEND);
567 glEnable(GL_TEXTURE_2D);
568 }
569
570 if(clampsky) glDepthRange(0, 1);
571
572 glDepthMask(GL_TRUE);
573
574 if(limited)
575 {
576 if(explicitonly) glEnable(GL_DEPTH_TEST);
577 else glDepthFunc(GL_LESS);
578 if(!reflecting && !refracting && !envmapping && editmode && showsky) drawskyoutline();
579 }
580 else glDepthFunc(GL_LESS);
581
582 if(renderpath!=R_FIXEDFUNCTION || !fogging) glEnable(GL_FOG);
583 }
584
585 VARNW(skytexture, useskytexture, 0, 1, 1);
586
587 int explicitsky = 0;
588 double skyarea = 0;
589
limitsky()590 bool limitsky()
591 {
592 return (explicitsky && (useskytexture || editmode)) || (sparklyfix && skyarea / (double(hdr.worldsize)*double(hdr.worldsize)*6) < 0.9);
593 }
594
595