adding special port rotation for boot peers
[SauerbratenRemote.git] / SauerbratenRemote / src / engine / rendersky.cpp
blobf6793897446b674c25bef23368c62919f886d128
1 #include "pch.h"
2 #include "engine.h"
4 Texture *sky[6] = { 0, 0, 0, 0, 0, 0 }, *clouds[6] = { 0, 0, 0, 0, 0, 0 };
6 void loadsky(const char *basename, Texture *texs[6])
8 loopi(6)
10 const char *side = cubemapsides[i].name;
11 s_sprintfd(name)("packages/%s_%s.jpg", basename, side);
12 if((texs[i] = textureload(name, 3, true, false))==notexture)
14 strcpy(name+strlen(name)-3, "png");
15 if((texs[i] = textureload(name, 3, true, false))==notexture) conoutf(CON_ERROR, "could not load sky texture packages/%s_%s", basename, side);
20 Texture *cloudoverlay = NULL;
22 Texture *loadskyoverlay(const char *basename)
24 s_sprintfd(name)("packages/%s.jpg", basename);
25 Texture *t = textureload(name, 0, true, false);
26 if(t!=notexture) return t;
27 strcpy(name+strlen(name)-3, "png");
28 t = textureload(name, 0, true, false);
29 if(t==notexture) conoutf(CON_ERROR, "could not load sky overlay texture packages/%s", basename);
30 return t;
33 SVARFR(skybox, "", { if(skybox[0]) loadsky(skybox, sky); });
34 FVARR(spinsky, 0);
35 VARR(yawsky, 0, 0, 360);
36 SVARFR(cloudbox, "", { if(cloudbox[0]) loadsky(cloudbox, clouds); });
37 FVARR(spinclouds, 0);
38 VARR(yawclouds, 0, 0, 360);
39 FVARR(cloudclip, 0.5f);
40 SVARFR(cloudlayer, "", { if(cloudlayer[0]) cloudoverlay = loadskyoverlay(cloudlayer); });
41 FVARR(cloudscrollx, 0);
42 FVARR(cloudscrolly, 0);
43 FVARR(cloudscale, 1);
44 FVARR(spincloudlayer, 0);
45 FVARR(yawcloudlayer, 0);
46 FVARR(cloudheight, 0.2f);
47 FVARR(cloudfade, 0.2f);
48 VARR(cloudsubdiv, 4, 16, 64);
49 VARR(cloudcolour, 0, 0xFFFFFF, 0xFFFFFF);
51 void draw_envbox_face(float s0, float t0, int x0, int y0, int z0,
52 float s1, float t1, int x1, int y1, int z1,
53 float s2, float t2, int x2, int y2, int z2,
54 float s3, float t3, int x3, int y3, int z3,
55 GLuint texture)
57 glBindTexture(GL_TEXTURE_2D, texture);
58 glBegin(GL_QUADS);
59 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
60 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
61 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
62 glTexCoord2f(s0, t0); glVertex3f(x0, y0, z0);
63 glEnd();
64 xtraverts += 4;
67 void draw_envbox(int w, float zclip = 0.0f, int faces = 0x3F, Texture **sky = NULL)
69 float vclip = 1-zclip;
70 int z = int(ceil(2*w*(vclip-0.5f)));
72 if(faces&0x01)
73 draw_envbox_face(0.0f, 0.0f, -w, -w, -w,
74 1.0f, 0.0f, -w, w, -w,
75 1.0f, vclip, -w, w, z,
76 0.0f, vclip, -w, -w, z, sky[0] ? sky[0]->id : notexture->id);
78 if(faces&0x02)
79 draw_envbox_face(1.0f, vclip, +w, -w, z,
80 0.0f, vclip, +w, w, z,
81 0.0f, 0.0f, +w, w, -w,
82 1.0f, 0.0f, +w, -w, -w, sky[1] ? sky[1]->id : notexture->id);
84 if(faces&0x04)
85 draw_envbox_face(1.0f, vclip, -w, -w, z,
86 0.0f, vclip, w, -w, z,
87 0.0f, 0.0f, w, -w, -w,
88 1.0f, 0.0f, -w, -w, -w, sky[2] ? sky[2]->id : notexture->id);
90 if(faces&0x08)
91 draw_envbox_face(1.0f, vclip, +w, w, z,
92 0.0f, vclip, -w, w, z,
93 0.0f, 0.0f, -w, w, -w,
94 1.0f, 0.0f, +w, w, -w, sky[3] ? sky[3]->id : notexture->id);
96 if(!zclip && faces&0x10)
97 draw_envbox_face(0.0f, 1.0f, -w, w, w,
98 0.0f, 0.0f, +w, w, w,
99 1.0f, 0.0f, +w, -w, w,
100 1.0f, 1.0f, -w, -w, w, sky[4] ? sky[4]->id : notexture->id);
102 if(faces&0x20)
103 draw_envbox_face(0.0f, 1.0f, +w, w, -w,
104 0.0f, 0.0f, -w, w, -w,
105 1.0f, 0.0f, -w, -w, -w,
106 1.0f, 1.0f, +w, -w, -w, sky[5] ? sky[5]->id : notexture->id);
109 void draw_env_overlay(int w, Texture *overlay = NULL, float tx = 0, float ty = 0)
111 float z = -w*cloudheight, tsz = 0.5f*(1-cloudfade)/cloudscale, psz = w*(1-cloudfade);
112 glBindTexture(GL_TEXTURE_2D, overlay ? overlay->id : notexture->id);
113 float r = (cloudcolour>>16)/255.0f, g = ((cloudcolour>>8)&255)/255.0f, b = (cloudcolour&255)/255.0f;
114 glColor3f(r, g, b);
115 glBegin(GL_POLYGON);
116 loopi(cloudsubdiv)
118 vec p(1, 1, 0);
119 p.rotate_around_z((-2.0f*M_PI*i)/cloudsubdiv);
120 glTexCoord2f(tx + p.x*tsz, ty + p.y*tsz); glVertex3f(p.x*psz, p.y*psz, z);
122 glEnd();
123 float tsz2 = 0.5f/cloudscale;
124 glBegin(GL_QUAD_STRIP);
125 loopi(cloudsubdiv+1)
127 vec p(1, 1, 0);
128 p.rotate_around_z((-2.0f*M_PI*i)/cloudsubdiv);
129 glColor4f(r, g, b, 1);
130 glTexCoord2f(tx + p.x*tsz, ty + p.y*tsz); glVertex3f(p.x*psz, p.y*psz, z);
131 glColor4f(r, g, b, 0);
132 glTexCoord2f(tx + p.x*tsz2, ty + p.y*tsz2); glVertex3f(p.x*w, p.y*w, z);
134 glEnd();
137 VARP(sparklyfix, 0, 0, 1);
138 VAR(showsky, 0, 1, 1);
139 VAR(clipsky, 0, 1, 1);
141 bool drawskylimits(bool explicitonly)
143 nocolorshader->set();
145 glDisable(GL_TEXTURE_2D);
146 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
147 bool rendered = rendersky(explicitonly);
148 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
149 glEnable(GL_TEXTURE_2D);
151 return rendered;
154 void drawskyoutline()
156 notextureshader->set();
158 glDisable(GL_TEXTURE_2D);
159 glDepthMask(GL_FALSE);
160 extern int wireframe;
161 if(!wireframe)
163 enablepolygonoffset(GL_POLYGON_OFFSET_LINE);
164 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
166 glColor3f(0.5f, 0.0f, 0.5f);
167 rendersky(true);
168 if(!wireframe)
170 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
171 disablepolygonoffset(GL_POLYGON_OFFSET_LINE);
173 glDepthMask(GL_TRUE);
174 glEnable(GL_TEXTURE_2D);
176 if(!glaring) defaultshader->set();
179 VAR(clampsky, 0, 1, 1);
181 void drawskybox(int farplane, bool limited)
183 extern int renderedskyfaces, renderedskyclip; // , renderedsky, renderedexplicitsky;
184 bool alwaysrender = editmode || !insideworld(camera1->o) || reflecting,
185 explicitonly = false;
186 if(limited)
188 explicitonly = alwaysrender || !sparklyfix || refracting;
189 if(!drawskylimits(explicitonly) && !alwaysrender) return;
190 extern int ati_skybox_bug;
191 if(!alwaysrender && !renderedskyfaces && !ati_skybox_bug) explicitonly = false;
193 else if(!alwaysrender)
195 extern vtxarray *visibleva;
196 renderedskyfaces = 0;
197 renderedskyclip = INT_MAX;
198 for(vtxarray *va = visibleva; va; va = va->next)
200 if(va->occluded >= OCCLUDE_BB && va->skyfaces&0x80) continue;
201 renderedskyfaces |= va->skyfaces&0x3F;
202 if(!(va->skyfaces&0x1F) || camera1->o.z < va->skyclip) renderedskyclip = min(renderedskyclip, va->skyclip);
203 else renderedskyclip = 0;
205 if(!renderedskyfaces) return;
208 if(alwaysrender)
210 renderedskyfaces = 0x3F;
211 renderedskyclip = 0;
214 float skyclip = clipsky ? max(renderedskyclip-1, 0) : 0;
215 if(reflectz<hdr.worldsize && reflectz>skyclip) skyclip = reflectz;
217 if(glaring)
219 static Shader *skyboxglareshader = NULL;
220 if(!skyboxglareshader) skyboxglareshader = lookupshaderbyname("skyboxglare");
221 skyboxglareshader->set();
223 else defaultshader->set();
225 bool fog = glIsEnabled(GL_FOG)==GL_TRUE;
226 if(fog) glDisable(GL_FOG);
228 if(limited)
230 if(explicitonly) glDisable(GL_DEPTH_TEST);
231 else glDepthFunc(GL_GEQUAL);
233 else glDepthFunc(GL_LEQUAL);
235 glDepthMask(GL_FALSE);
237 if(clampsky) glDepthRange(1, 1);
239 glColor3f(1, 1, 1);
241 glPushMatrix();
242 glLoadIdentity();
243 glRotatef(camera1->roll, 0, 0, 1);
244 glRotatef(camera1->pitch, -1, 0, 0);
245 glRotatef(camera1->yaw+spinsky*lastmillis/1000.0f+yawsky, 0, 1, 0);
246 glRotatef(90, 1, 0, 0);
247 if(reflecting) glScalef(1, 1, -1);
248 draw_envbox(farplane/2, skyclip ? 0.5f + 0.5f*(skyclip-camera1->o.z)/float(hdr.worldsize) : 0, renderedskyfaces | ((spinsky || yawsky) && renderedskyfaces&0x0F ? 0x0F : 0), sky);
249 glPopMatrix();
251 if(!glaring && cloudbox[0])
253 if((spinclouds || yawclouds) && renderedskyfaces&0x0F) renderedskyfaces |= 0x0F;
255 if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
257 glEnable(GL_BLEND);
258 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
260 glPushMatrix();
261 glLoadIdentity();
262 glRotatef(camera1->roll, 0, 0, 1);
263 glRotatef(camera1->pitch, -1, 0, 0);
264 glRotatef(camera1->yaw+spinclouds*lastmillis/1000.0f+yawclouds, 0, 1, 0);
265 glRotatef(90, 1, 0, 0);
266 if(reflecting) glScalef(1, 1, -1);
267 draw_envbox(farplane/2, skyclip ? 0.5f + 0.5f*(skyclip-camera1->o.z)/float(hdr.worldsize) : cloudclip, renderedskyfaces | ((spinclouds || yawclouds) && renderedskyfaces&0x0F ? 0x0F : 0), clouds);
268 glPopMatrix();
270 glDisable(GL_BLEND);
273 if(!glaring && cloudlayer[0] && cloudheight && renderedskyfaces&(cloudheight < 0 ? 0x1F : 0x2F))
275 if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
277 glDisable(GL_CULL_FACE);
279 glEnable(GL_BLEND);
280 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
282 glPushMatrix();
283 glLoadIdentity();
284 glRotatef(camera1->roll, 0, 0, 1);
285 glRotatef(camera1->pitch, -1, 0, 0);
286 glRotatef(camera1->yaw+spincloudlayer*lastmillis/1000.0f+yawcloudlayer, 0, 1, 0);
287 glRotatef(90, 1, 0, 0);
288 if(reflecting) glScalef(1, 1, -1);
289 draw_env_overlay(farplane/2, cloudoverlay, cloudscrollx * lastmillis/1000.0f, cloudscrolly * lastmillis/1000.0f);
290 glPopMatrix();
292 glDisable(GL_BLEND);
294 glEnable(GL_CULL_FACE);
297 if(clampsky) glDepthRange(0, 1);
299 glDepthMask(GL_TRUE);
301 if(limited)
303 if(explicitonly) glEnable(GL_DEPTH_TEST);
304 else glDepthFunc(GL_LESS);
305 if(!reflecting && !refracting && !envmapping && editmode && showsky) drawskyoutline();
307 else glDepthFunc(GL_LESS);
309 if(fog) glEnable(GL_FOG);
312 VARNR(skytexture, useskytexture, 0, 1, 1);
314 int explicitsky = 0;
315 double skyarea = 0;
317 bool limitsky()
319 return (explicitsky && (useskytexture || editmode)) || (sparklyfix && skyarea / (double(hdr.worldsize)*double(hdr.worldsize)*6) < 0.9);