00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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;
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 }