git-svn-id: https://scorched3d.svn.sourceforge.net/svnroot/scorched3d/trunk/scorched...
[scorched3d/parasti.git] / src / client / sky / Hemisphere.cpp
blob68d10985dec047d3a81e487756f31fd2bca1a696
1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
3 //
4 // This file is part of Scorched3D.
5 //
6 // Scorched3D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // Scorched3D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with Scorched3D; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ////////////////////////////////////////////////////////////////////////////////
21 #include <image/Image.h>
22 #include <GLEXT/GLState.h>
23 #include <common/Vector.h>
24 #include <sky/Hemisphere.h>
25 #include <common/Defines.h>
26 #include <vector>
27 #include <math.h>
29 void Hemisphere::draw(float radius, float radius2,
30 int heightSlices, int rotationSlices,
31 int startHeightSlice, int startRotationSlice,
32 int endHeightSlice, int endRotationSlice,
33 bool inverse, unsigned int flags)
35 glBegin(GL_QUAD_STRIP);
36 const float maxTexCoord = 1.0f;
37 for (int j=startHeightSlice; j<endHeightSlice; j++)
39 float theta1 = j * HALFPI / float(heightSlices);
40 float theta2 = (j + 1) * HALFPI / float(heightSlices);
42 for (int i=startRotationSlice;i<=endRotationSlice;i++)
44 float theta3 = i * TWOPI / float(rotationSlices);
45 float c = theta3 / TWOPI * maxTexCoord;
47 Vector e1, p1;
48 e1[0] = float(cos(theta1) * cos(theta3));
49 e1[2] = float(sin(theta1));
50 e1[1] = float(cos(theta1) * sin(theta3));
51 p1[0] = radius * e1[0];
52 p1[2] = radius2 * e1[2];
53 p1[1] = radius * e1[1];
55 Vector e2, p2;
56 e2[0] = float(cos(theta2) * cos(theta3));
57 e2[2] = float(sin(theta2));
58 e2[1] = float(cos(theta2) * sin(theta3));
59 p2[0] = radius * e2[0];
60 p2[2] = radius2 * e2[2];
61 p2[1] = radius * e2[1];
63 if (!inverse)
65 if (flags & eWidthTexture) glTexCoord2f((p1[0] + radius) / (2 * radius),
66 (p1[1] + radius) / (2 * radius));
67 else glTexCoord2f(c, float(j) / float(heightSlices));
68 glVertex3fv(p1);
69 if (flags & eWidthTexture) glTexCoord2f((p2[0] + radius) / (2 * radius),
70 (p2[1] + radius) / (2 * radius));
71 else glTexCoord2f(c, float(j+1) / float(heightSlices));
72 glVertex3fv(p2);
74 else
76 if (flags & eWidthTexture) glTexCoord2f((p2[0] + radius) / (2 * radius),
77 (p2[1] + radius) / (2 * radius));
78 else glTexCoord2f(c, float(j+1) / float(heightSlices));
79 glVertex3fv(p2);
80 if (flags & eWidthTexture) glTexCoord2f((p1[0] + radius) / (2 * radius),
81 (p1[1] + radius) / (2 * radius));
82 else glTexCoord2f(c, float(j) / float(heightSlices));
83 glVertex3fv(p1);
86 glEnd();
87 glBegin(GL_QUAD_STRIP);
89 glEnd();
92 void Hemisphere::drawColored(float radius, float radius2,
93 int heightSlices, int rotationSlices,
94 int startHeightSlice, int startRotationSlice,
95 int endHeightSlice, int endRotationSlice,
96 bool inverse, Image &colors, Vector &sunDir, int daytime,
97 bool horizonGlow)
99 GLubyte *bits = colors.getBits();
101 glBegin(GL_QUAD_STRIP);
102 const float maxTexCoord = 1.0f;
103 for (int j=startHeightSlice; j<endHeightSlice; j++)
105 float theta1 = j * HALFPI / float(heightSlices);
106 if (j<0) theta1 *= 0.75f;
107 float theta2 = (j + 1) * HALFPI / float(heightSlices);
109 int colorJ = MAX(j - 1, 0);
110 int colorIndexA = int(float(colorJ) / float(heightSlices) * 15.0f);
111 int colorIndexB = int(float(j) / float(heightSlices) * 15.0f);
112 int bitmapIndexA = daytime * 3 + (16 * 3) * colorIndexA;
113 int bitmapIndexB = daytime * 3 + (16 * 3) * colorIndexB;
115 DIALOG_ASSERT(bitmapIndexA >= 0);
116 DIALOG_ASSERT(bitmapIndexB + 2 <
117 colors.getWidth() * colors.getHeight() * colors.getComponents());
119 for (int i=startRotationSlice;i<=endRotationSlice;i++)
121 float theta3 = i * TWOPI / float(rotationSlices);
122 float c = theta3 / TWOPI * maxTexCoord;
124 Vector e1, p1, c1;
125 e1[0] = float(cos(theta1) * cos(theta3));
126 e1[2] = float(sin(theta1));
127 e1[1] = float(cos(theta1) * sin(theta3));
128 p1[0] = radius * e1[0];
129 p1[2] = radius2 * e1[2];
130 p1[1] = radius * e1[1];
133 float dotP = 0.0f;
134 if (horizonGlow)
136 dotP = e1.Normalize().dotP(sunDir);
137 dotP = (dotP + 1.0f) / 4.0f;
140 c1[0] = MIN(float(bits[bitmapIndexA]) / 255.0f + dotP, 1.0f);
141 c1[1] = MIN(float(bits[bitmapIndexA + 1]) / 255.0f + dotP, 1.0f);
142 c1[2] = MIN(float(bits[bitmapIndexA + 2]) / 255.0f + dotP, 1.0f);
145 Vector e2, p2, c2;
146 e2[0] = float(cos(theta2) * cos(theta3));
147 e2[2] = float(sin(theta2));
148 e2[1] = float(cos(theta2) * sin(theta3));
149 p2[0] = radius * e2[0];
150 p2[2] = radius2 * e2[2];
151 p2[1] = radius * e2[1];
154 float dotP = 0.0f;
155 if (horizonGlow)
157 dotP = e2.Normalize().dotP(sunDir);
158 dotP = (dotP + 1.0f) / 4.0f;
161 c2[0] = MIN(float(bits[bitmapIndexB]) / 255.0f + dotP, 1.0f);
162 c2[1] = MIN(float(bits[bitmapIndexB + 1]) / 255.0f + dotP, 1.0f);
163 c2[2] = MIN(float(bits[bitmapIndexB + 2]) / 255.0f + dotP, 1.0f);
166 if (!inverse)
168 glColor3fv(c1);
169 glVertex3fv(p1);
170 glColor3fv(c2);
171 glVertex3fv(p2);
173 else
175 glColor3fv(c2);
176 glVertex3fv(p2);
177 glColor3fv(c1);
178 glVertex3fv(p1);
181 glEnd();
182 glBegin(GL_QUAD_STRIP);
184 glEnd();