00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <image/Image.h>
00022 #include <GLEXT/GLState.h>
00023 #include <common/Vector.h>
00024 #include <sky/Hemisphere.h>
00025 #include <common/Defines.h>
00026 #include <vector>
00027 #include <math.h>
00028
00029 void Hemisphere::draw(float radius, float radius2,
00030 int heightSlices, int rotationSlices,
00031 int startHeightSlice, int startRotationSlice,
00032 int endHeightSlice, int endRotationSlice,
00033 bool inverse, unsigned int flags)
00034 {
00035 glBegin(GL_QUAD_STRIP);
00036 const float maxTexCoord = 1.0f;
00037 for (int j=startHeightSlice; j<endHeightSlice; j++)
00038 {
00039 float theta1 = j * HALFPI / float(heightSlices);
00040 float theta2 = (j + 1) * HALFPI / float(heightSlices);
00041
00042 for (int i=startRotationSlice;i<=endRotationSlice;i++)
00043 {
00044 float theta3 = i * TWOPI / float(rotationSlices);
00045 float c = theta3 / TWOPI * maxTexCoord;
00046
00047 Vector e1, p1;
00048 e1[0] = float(cos(theta1) * cos(theta3));
00049 e1[2] = float(sin(theta1));
00050 e1[1] = float(cos(theta1) * sin(theta3));
00051 p1[0] = radius * e1[0];
00052 p1[2] = radius2 * e1[2];
00053 p1[1] = radius * e1[1];
00054
00055 Vector e2, p2;
00056 e2[0] = float(cos(theta2) * cos(theta3));
00057 e2[2] = float(sin(theta2));
00058 e2[1] = float(cos(theta2) * sin(theta3));
00059 p2[0] = radius * e2[0];
00060 p2[2] = radius2 * e2[2];
00061 p2[1] = radius * e2[1];
00062
00063 if (!inverse)
00064 {
00065 if (flags & eWidthTexture) glTexCoord2f((p1[0] + radius) / (2 * radius),
00066 (p1[1] + radius) / (2 * radius));
00067 else glTexCoord2f(c, float(j) / float(heightSlices));
00068 glVertex3fv(p1);
00069 if (flags & eWidthTexture) glTexCoord2f((p2[0] + radius) / (2 * radius),
00070 (p2[1] + radius) / (2 * radius));
00071 else glTexCoord2f(c, float(j+1) / float(heightSlices));
00072 glVertex3fv(p2);
00073 }
00074 else
00075 {
00076 if (flags & eWidthTexture) glTexCoord2f((p2[0] + radius) / (2 * radius),
00077 (p2[1] + radius) / (2 * radius));
00078 else glTexCoord2f(c, float(j+1) / float(heightSlices));
00079 glVertex3fv(p2);
00080 if (flags & eWidthTexture) glTexCoord2f((p1[0] + radius) / (2 * radius),
00081 (p1[1] + radius) / (2 * radius));
00082 else glTexCoord2f(c, float(j) / float(heightSlices));
00083 glVertex3fv(p1);
00084 }
00085 }
00086 glEnd();
00087 glBegin(GL_QUAD_STRIP);
00088 }
00089 glEnd();
00090 }
00091
00092 void Hemisphere::drawColored(float radius, float radius2,
00093 int heightSlices, int rotationSlices,
00094 int startHeightSlice, int startRotationSlice,
00095 int endHeightSlice, int endRotationSlice,
00096 bool inverse, Image &colors, Vector &sunDir, int daytime,
00097 bool horizonGlow)
00098 {
00099 GLubyte *bits = colors.getBits();
00100
00101 glBegin(GL_QUAD_STRIP);
00102 const float maxTexCoord = 1.0f;
00103 for (int j=startHeightSlice; j<endHeightSlice; j++)
00104 {
00105 float theta1 = j * HALFPI / float(heightSlices);
00106 if (j<0) theta1 *= 0.75f;
00107 float theta2 = (j + 1) * HALFPI / float(heightSlices);
00108
00109 int colorJ = MAX(j - 1, 0);
00110 int colorIndexA = int(float(colorJ) / float(heightSlices) * 15.0f);
00111 int colorIndexB = int(float(j) / float(heightSlices) * 15.0f);
00112 int bitmapIndexA = daytime * 3 + (16 * 3) * colorIndexA;
00113 int bitmapIndexB = daytime * 3 + (16 * 3) * colorIndexB;
00114
00115 DIALOG_ASSERT(bitmapIndexA >= 0);
00116 DIALOG_ASSERT(bitmapIndexB + 2 <
00117 colors.getWidth() * colors.getHeight() * colors.getComponents());
00118
00119 for (int i=startRotationSlice;i<=endRotationSlice;i++)
00120 {
00121 float theta3 = i * TWOPI / float(rotationSlices);
00122 float c = theta3 / TWOPI * maxTexCoord;
00123
00124 Vector e1, p1, c1;
00125 e1[0] = float(cos(theta1) * cos(theta3));
00126 e1[2] = float(sin(theta1));
00127 e1[1] = float(cos(theta1) * sin(theta3));
00128 p1[0] = radius * e1[0];
00129 p1[2] = radius2 * e1[2];
00130 p1[1] = radius * e1[1];
00131
00132 {
00133 float dotP = 0.0f;
00134 if (horizonGlow)
00135 {
00136 dotP = e1.Normalize().dotP(sunDir);
00137 dotP = (dotP + 1.0f) / 4.0f;
00138 }
00139
00140 c1[0] = MIN(float(bits[bitmapIndexA]) / 255.0f + dotP, 1.0f);
00141 c1[1] = MIN(float(bits[bitmapIndexA + 1]) / 255.0f + dotP, 1.0f);
00142 c1[2] = MIN(float(bits[bitmapIndexA + 2]) / 255.0f + dotP, 1.0f);
00143 }
00144
00145 Vector e2, p2, c2;
00146 e2[0] = float(cos(theta2) * cos(theta3));
00147 e2[2] = float(sin(theta2));
00148 e2[1] = float(cos(theta2) * sin(theta3));
00149 p2[0] = radius * e2[0];
00150 p2[2] = radius2 * e2[2];
00151 p2[1] = radius * e2[1];
00152
00153 {
00154 float dotP = 0.0f;
00155 if (horizonGlow)
00156 {
00157 dotP = e2.Normalize().dotP(sunDir);
00158 dotP = (dotP + 1.0f) / 4.0f;
00159 }
00160
00161 c2[0] = MIN(float(bits[bitmapIndexB]) / 255.0f + dotP, 1.0f);
00162 c2[1] = MIN(float(bits[bitmapIndexB + 1]) / 255.0f + dotP, 1.0f);
00163 c2[2] = MIN(float(bits[bitmapIndexB + 2]) / 255.0f + dotP, 1.0f);
00164 }
00165
00166 if (!inverse)
00167 {
00168 glColor3fv(c1);
00169 glVertex3fv(p1);
00170 glColor3fv(c2);
00171 glVertex3fv(p2);
00172 }
00173 else
00174 {
00175 glColor3fv(c2);
00176 glVertex3fv(p2);
00177 glColor3fv(c1);
00178 glVertex3fv(p1);
00179 }
00180 }
00181 glEnd();
00182 glBegin(GL_QUAD_STRIP);
00183 }
00184 glEnd();
00185 }