Hemisphere.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 }

Generated on Mon Feb 16 15:14:47 2009 for Scorched3D by  doxygen 1.5.3