GLLenseFlare.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 <math.h>
00022 #include <GLEXT/GLState.h>
00023 #include <GLEXT/GLCamera.h>
00024 #include <image/ImageLuminance.h>
00025 #include <GLEXT/GLLenseFlare.h>
00026 #include <GLEXT/GLCameraFrustum.h>
00027 #include <common/Defines.h>
00028 #include <lang/LangResource.h>
00029 
00030 GLLenseFlare *GLLenseFlare::instance_ = 0;
00031 
00032 GLLenseFlare *GLLenseFlare::instance()
00033 {
00034         if (!instance_)
00035         {
00036                 instance_ = new GLLenseFlare;
00037         }
00038 
00039         return instance_;
00040 }
00041 
00042 GLLenseFlare::GLLenseFlare() : shineTic_(0)
00043 {
00044 
00045 }
00046 
00047 GLLenseFlare::~GLLenseFlare()
00048 {
00049 
00050 }
00051 
00052 void GLLenseFlare::setFlare(int index, int type, float scale, float loc, 
00053                                                         Vector &color1, Vector &color2, Vector &color3, Vector &color4,
00054                                                         float colorScale)
00055 {
00056         if (index > 2) loc *= 500;
00057 
00058         flare_[index].type = type;
00059         flare_[index].loc = loc;
00060         flare_[index].scale = scale;
00061         flare_[index].color1 = color1 * colorScale;
00062         flare_[index].color2 = color2 * colorScale;
00063         flare_[index].color3 = color3 * colorScale;
00064         flare_[index].color4 = color4 * colorScale;
00065 }
00066 
00067 void GLLenseFlare::init(ProgressCounter *counter)
00068 {
00069         if (counter) counter->setNewOp(LANG_RESOURCE("LENS_FLARES", "Lens Flares"));
00070 
00071         Vector red1(1.0f, 0.0f, 0.0f);
00072         Vector green1(0.0f, 1.0f, 0.0f);
00073         Vector blue1(0.0f, 0.0f, 1.0f);
00074 
00075         Vector red2(1.0f, 0.0f, 0.0f);
00076         Vector green2(0.5f, 1.0f, 0.0f);
00077         Vector blue2(0.5f, 0.0f, 1.0f);
00078 
00079         Vector red3(1.0f, 0.5f, 0.0f);
00080         Vector green3(0.0f, 1.0f, 0.0f);
00081         Vector blue3(0.0f, 0.5f, 1.0f);
00082 
00083         Vector red4(1.0f, 0.0f, 0.5f);
00084         Vector green4(0.0f, 1.0f, 0.5f);
00085         Vector blue4(0.0f, 0.0f, 1.0f);
00086 
00087         setFlare(0, -1, 1.0f, 0.3f, blue1, blue2, blue3, blue4, 1.0f);
00088         setFlare(1, -1, 1.0f, 0.2f, green1, green2, green3, green4, 1.f);
00089         setFlare(2, -1, 1.0f, 0.25f, red1, red2, red3, red4, 1.0f);
00090 
00091         /* Flares, ordered to eliminate redundant texture binds */
00092         setFlare(3, 1, 0.5f, 0.2f, red1, red2, red3, red4, 0.3f);
00093         setFlare(4, 2, 1.3f, 0.04f, red1, red2, red3, red4, 0.6f);
00094         setFlare(5, 3, 1.0f, 0.1f, red1, red2, red3, red4, 0.4f);
00095         setFlare(6, 3, 0.2f, 0.05f, red1, red2, red3, red4, 0.3f);
00096         setFlare(7, 0, 0.0f, 0.04f, red1, red2, red3, red4, 0.3f);
00097         setFlare(8, 5, -0.25f, 0.07f, red1, red2, red3, red4, 0.5f);
00098         setFlare(9, 5, -0.4f, 0.02f, red1, red2, red3, red4, 0.6f);
00099         setFlare(10, 5, -0.6f, 0.04f, red1, red2, red3, red4, 0.4f);
00100         setFlare(11, 5, -1.0f, 0.03f, red1, red2, red3, red4, 0.2f);
00101 
00102         int i;
00103         for (i = 0; i < 10; i++) 
00104         {
00105                 if (counter) counter->setNewPercentage(float (i) / 16.0f * 100.0f);
00106 
00107                 ImageLuminance bitmap(S3D::getDataFile(S3D::formatStringBuffer("data/textures/lensflare/shine%d.bw", i)));
00108                 shines_[i].create(bitmap);
00109         }
00110 
00111         for (i = 0; i < 6; i++) 
00112         {
00113                 if (counter) counter->setNewPercentage(float (i+10) / 16.0f * 100.0f);
00114 
00115                 ImageLuminance bitmap(S3D::getDataFile(S3D::formatStringBuffer("data/textures/lensflare/flare%d.bw", i)));
00116                 flares_[i].create(bitmap);
00117         }
00118 }
00119 
00120 void GLLenseFlare::draw(Vector &flarePos, 
00121         bool fullFlare, int colorNo, 
00122         float size, float alpha)
00123 {
00124         if (GLCameraFrustum::instance()->sphereInFrustum(flarePos, 5))
00125         {
00126                 Vector &cameraPos = GLCamera::getCurrentCamera()->getCurrentPos();
00127                 Vector &cameraAt = GLCamera::getCurrentCamera()->getLookAt();
00128 
00129                 Vector view_dir = flarePos - cameraPos;
00130                 Vector centre = cameraPos + view_dir.Normalize() * 20.0f;
00131                 Vector axis = (cameraAt - flarePos).Normalize();
00132 
00133                 Vector dx = axis.Normalize();
00134                 Vector dy = (dx * view_dir).Normalize();
00135                 dx = -(dy * view_dir).Normalize();
00136 
00137                 dx *= 2.0f * size;
00138                 dy *= 2.0f * size;
00139 
00140                 glDepthMask(GL_FALSE);
00141                 GLState currentState(GLState::BLEND_ON);
00142                 glBlendFunc(GL_ONE, GL_ONE);
00143 
00144                 GLState *afterThreeState = 0;
00145                 int endTexture = 12;
00146                 if (!fullFlare) endTexture = 3;
00147                 for (int i=0; i<endTexture; i++) 
00148                 {
00149                         Vector sx = dx * flare_[i].scale;
00150                         Vector sy = dy * flare_[i].scale;
00151                         static Vector position;
00152 
00153                         switch(colorNo)
00154                         {
00155                                 case 0: glColor4f(flare_[i].color1[0], flare_[i].color1[1], flare_[i].color1[2], alpha); break;
00156                                 case 1: glColor4f(flare_[i].color2[0], flare_[i].color2[1], flare_[i].color2[2], alpha); break;
00157                                 case 2: glColor4f(flare_[i].color3[0], flare_[i].color3[1], flare_[i].color3[2], alpha); break;
00158                                 case 3: glColor4f(flare_[i].color4[0], flare_[i].color4[1], flare_[i].color4[2], alpha); break;
00159                         }
00160                         if (flare_[i].type < 0) 
00161                         {
00162                                 shines_[shineTic_].draw();
00163                                 shineTic_ = (shineTic_ + 1) % 10;
00164 
00165                                 position = flarePos + (axis * flare_[i].loc);
00166                         } 
00167                         else 
00168                         {
00169                                 flares_[flare_[i].type].draw();
00170 
00171                                 position = flarePos + (axis * flare_[i].loc);
00172                         }
00173 
00174                         if (i==3) afterThreeState = new GLState(GLState::DEPTH_OFF);
00175 
00176                         glBegin(GL_QUADS);
00177 
00178                         static Vector tmp;
00179 
00180                         tmp = position + sx + sy;
00181                         glTexCoord2f(0.0, 0.0);
00182                         glVertex3fv(tmp);
00183 
00184                         tmp = (position - sx) + sy;
00185                         glTexCoord2f(1.0, 0.0);
00186                         glVertex3fv(tmp);
00187 
00188                         tmp = (position - sx) - sy;
00189                         glTexCoord2f(1.0, 1.0);
00190                         glVertex3fv(tmp);
00191 
00192                         tmp = (position + sx) - sy;
00193                         glTexCoord2f(0.0, 1.0);
00194                         glVertex3fv(tmp);
00195 
00196                         glEnd();
00197                 }
00198 
00199                 glDepthMask(GL_TRUE);
00200                 delete afterThreeState;
00201         }
00202         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00203 }
00204 
00205 void GLLenseFlare::draw(Vector &flarePos, Vector &flareDir, int colorNo)
00206 {
00207         if (!GLCameraFrustum::instance()->sphereInFrustum(flarePos, 5))
00208         {
00209                 return;
00210         }
00211 
00212         Vector &cameraPos = GLCamera::getCurrentCamera()->getCurrentPos();
00213         Vector &cameraAt = GLCamera::getCurrentCamera()->getLookAt();
00214 
00215         Vector flare_dir = flareDir;// .Normalize(); // Should already be normalized
00216         Vector view_dir = (flarePos - cameraPos).Normalize();
00217 
00218         float dotP = (float) flare_dir.dotP(view_dir);
00219         if (dotP <= 0.2f) return;
00220 
00221         Vector centre = cameraPos + view_dir * 20.0f;
00222         Vector axis = (cameraAt - flarePos).Normalize();
00223 
00224         Vector dx = axis.Normalize();
00225         Vector dy = (dx * view_dir).Normalize();
00226         dx = -(dy * view_dir).Normalize();
00227 
00228         dx *= 2.0f * (dotP - 0.2f);
00229         dy *= 2.0f * (dotP - 0.2f);
00230 
00231         glDepthMask(GL_FALSE);
00232         GLState currentState(GLState::BLEND_ON | GLState::TEXTURE_ON);
00233         glBlendFunc(GL_ONE, GL_ONE);
00234 
00235         for (int i=0; i<3; i++) 
00236         {
00237                 switch(colorNo)
00238                 {
00239                         case 0: glColor3fv(flare_[i].color1); break;
00240                         case 1: glColor3fv(flare_[i].color2); break;
00241                         case 2: glColor3fv(flare_[i].color3); break;
00242                         case 3: glColor3fv(flare_[i].color4); break;
00243                 }
00244         
00245                 shines_[shineTic_].draw();
00246                 shineTic_ = (shineTic_ + 1) % 10;
00247 
00248                 Vector position = flarePos + (axis * flare_[i].loc);
00249                 Vector sx = dx * flare_[i].scale;
00250                 Vector sy = dy * flare_[i].scale;
00251 
00252                 glBegin(GL_QUADS);
00253                         static Vector tmp;
00254                         tmp = position + sx + sy;
00255                         glTexCoord2f(0.0, 0.0);
00256                         glVertex3fv(tmp);
00257 
00258                         tmp = (position - sx) + sy;
00259                         glTexCoord2f(1.0, 0.0);
00260                         glVertex3fv(tmp);
00261 
00262                         tmp = (position - sx) - sy;
00263                         glTexCoord2f(1.0, 1.0);
00264                         glVertex3fv(tmp);
00265 
00266                         tmp = (position + sx) - sy;
00267                         glTexCoord2f(0.0, 1.0);
00268                         glVertex3fv(tmp);
00269 
00270                 glEnd();
00271         }
00272         glDepthMask(GL_TRUE);
00273         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00274 }

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