git-svn-id: https://scorched3d.svn.sourceforge.net/svnroot/scorched3d/trunk/scorched...
[scorched3d/parasti.git] / src / client / GLEXT / GLLenseFlare.cpp
blob3004189ba55da81f692daec159083df46a492e5b
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 <math.h>
22 #include <GLEXT/GLState.h>
23 #include <GLEXT/GLCamera.h>
24 #include <image/ImageLuminance.h>
25 #include <GLEXT/GLLenseFlare.h>
26 #include <GLEXT/GLCameraFrustum.h>
27 #include <common/Defines.h>
28 #include <lang/LangResource.h>
30 GLLenseFlare *GLLenseFlare::instance_ = 0;
32 GLLenseFlare *GLLenseFlare::instance()
34 if (!instance_)
36 instance_ = new GLLenseFlare;
39 return instance_;
42 GLLenseFlare::GLLenseFlare() : shineTic_(0)
47 GLLenseFlare::~GLLenseFlare()
52 void GLLenseFlare::setFlare(int index, int type, float scale, float loc,
53 Vector &color1, Vector &color2, Vector &color3, Vector &color4,
54 float colorScale)
56 if (index > 2) loc *= 500;
58 flare_[index].type = type;
59 flare_[index].loc = loc;
60 flare_[index].scale = scale;
61 flare_[index].color1 = color1 * colorScale;
62 flare_[index].color2 = color2 * colorScale;
63 flare_[index].color3 = color3 * colorScale;
64 flare_[index].color4 = color4 * colorScale;
67 void GLLenseFlare::init(ProgressCounter *counter)
69 if (counter) counter->setNewOp(LANG_RESOURCE("LENS_FLARES", "Lens Flares"));
71 Vector red1(1.0f, 0.0f, 0.0f);
72 Vector green1(0.0f, 1.0f, 0.0f);
73 Vector blue1(0.0f, 0.0f, 1.0f);
75 Vector red2(1.0f, 0.0f, 0.0f);
76 Vector green2(0.5f, 1.0f, 0.0f);
77 Vector blue2(0.5f, 0.0f, 1.0f);
79 Vector red3(1.0f, 0.5f, 0.0f);
80 Vector green3(0.0f, 1.0f, 0.0f);
81 Vector blue3(0.0f, 0.5f, 1.0f);
83 Vector red4(1.0f, 0.0f, 0.5f);
84 Vector green4(0.0f, 1.0f, 0.5f);
85 Vector blue4(0.0f, 0.0f, 1.0f);
87 setFlare(0, -1, 1.0f, 0.3f, blue1, blue2, blue3, blue4, 1.0f);
88 setFlare(1, -1, 1.0f, 0.2f, green1, green2, green3, green4, 1.f);
89 setFlare(2, -1, 1.0f, 0.25f, red1, red2, red3, red4, 1.0f);
91 /* Flares, ordered to eliminate redundant texture binds */
92 setFlare(3, 1, 0.5f, 0.2f, red1, red2, red3, red4, 0.3f);
93 setFlare(4, 2, 1.3f, 0.04f, red1, red2, red3, red4, 0.6f);
94 setFlare(5, 3, 1.0f, 0.1f, red1, red2, red3, red4, 0.4f);
95 setFlare(6, 3, 0.2f, 0.05f, red1, red2, red3, red4, 0.3f);
96 setFlare(7, 0, 0.0f, 0.04f, red1, red2, red3, red4, 0.3f);
97 setFlare(8, 5, -0.25f, 0.07f, red1, red2, red3, red4, 0.5f);
98 setFlare(9, 5, -0.4f, 0.02f, red1, red2, red3, red4, 0.6f);
99 setFlare(10, 5, -0.6f, 0.04f, red1, red2, red3, red4, 0.4f);
100 setFlare(11, 5, -1.0f, 0.03f, red1, red2, red3, red4, 0.2f);
102 int i;
103 for (i = 0; i < 10; i++)
105 if (counter) counter->setNewPercentage(float (i) / 16.0f * 100.0f);
107 ImageLuminance bitmap(S3D::getDataFile(S3D::formatStringBuffer("data/textures/lensflare/shine%d.bw", i)));
108 shines_[i].create(bitmap);
111 for (i = 0; i < 6; i++)
113 if (counter) counter->setNewPercentage(float (i+10) / 16.0f * 100.0f);
115 ImageLuminance bitmap(S3D::getDataFile(S3D::formatStringBuffer("data/textures/lensflare/flare%d.bw", i)));
116 flares_[i].create(bitmap);
120 void GLLenseFlare::draw(Vector &flarePos,
121 bool fullFlare, int colorNo,
122 float size, float alpha)
124 if (GLCameraFrustum::instance()->sphereInFrustum(flarePos, 5))
126 Vector &cameraPos = GLCamera::getCurrentCamera()->getCurrentPos();
127 Vector &cameraAt = GLCamera::getCurrentCamera()->getLookAt();
129 Vector view_dir = flarePos - cameraPos;
130 Vector centre = cameraPos + view_dir.Normalize() * 20.0f;
131 Vector axis = (cameraAt - flarePos).Normalize();
133 Vector dx = axis.Normalize();
134 Vector dy = (dx * view_dir).Normalize();
135 dx = -(dy * view_dir).Normalize();
137 dx *= 2.0f * size;
138 dy *= 2.0f * size;
140 glDepthMask(GL_FALSE);
141 GLState currentState(GLState::BLEND_ON);
142 glBlendFunc(GL_ONE, GL_ONE);
144 GLState *afterThreeState = 0;
145 int endTexture = 12;
146 if (!fullFlare) endTexture = 3;
147 for (int i=0; i<endTexture; i++)
149 Vector sx = dx * flare_[i].scale;
150 Vector sy = dy * flare_[i].scale;
151 static Vector position;
153 switch(colorNo)
155 case 0: glColor4f(flare_[i].color1[0], flare_[i].color1[1], flare_[i].color1[2], alpha); break;
156 case 1: glColor4f(flare_[i].color2[0], flare_[i].color2[1], flare_[i].color2[2], alpha); break;
157 case 2: glColor4f(flare_[i].color3[0], flare_[i].color3[1], flare_[i].color3[2], alpha); break;
158 case 3: glColor4f(flare_[i].color4[0], flare_[i].color4[1], flare_[i].color4[2], alpha); break;
160 if (flare_[i].type < 0)
162 shines_[shineTic_].draw();
163 shineTic_ = (shineTic_ + 1) % 10;
165 position = flarePos + (axis * flare_[i].loc);
167 else
169 flares_[flare_[i].type].draw();
171 position = flarePos + (axis * flare_[i].loc);
174 if (i==3) afterThreeState = new GLState(GLState::DEPTH_OFF);
176 glBegin(GL_QUADS);
178 static Vector tmp;
180 tmp = position + sx + sy;
181 glTexCoord2f(0.0, 0.0);
182 glVertex3fv(tmp);
184 tmp = (position - sx) + sy;
185 glTexCoord2f(1.0, 0.0);
186 glVertex3fv(tmp);
188 tmp = (position - sx) - sy;
189 glTexCoord2f(1.0, 1.0);
190 glVertex3fv(tmp);
192 tmp = (position + sx) - sy;
193 glTexCoord2f(0.0, 1.0);
194 glVertex3fv(tmp);
196 glEnd();
199 glDepthMask(GL_TRUE);
200 delete afterThreeState;
202 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
205 void GLLenseFlare::draw(Vector &flarePos, Vector &flareDir, int colorNo)
207 if (!GLCameraFrustum::instance()->sphereInFrustum(flarePos, 5))
209 return;
212 Vector &cameraPos = GLCamera::getCurrentCamera()->getCurrentPos();
213 Vector &cameraAt = GLCamera::getCurrentCamera()->getLookAt();
215 Vector flare_dir = flareDir;// .Normalize(); // Should already be normalized
216 Vector view_dir = (flarePos - cameraPos).Normalize();
218 float dotP = (float) flare_dir.dotP(view_dir);
219 if (dotP <= 0.2f) return;
221 Vector centre = cameraPos + view_dir * 20.0f;
222 Vector axis = (cameraAt - flarePos).Normalize();
224 Vector dx = axis.Normalize();
225 Vector dy = (dx * view_dir).Normalize();
226 dx = -(dy * view_dir).Normalize();
228 dx *= 2.0f * (dotP - 0.2f);
229 dy *= 2.0f * (dotP - 0.2f);
231 glDepthMask(GL_FALSE);
232 GLState currentState(GLState::BLEND_ON | GLState::TEXTURE_ON);
233 glBlendFunc(GL_ONE, GL_ONE);
235 for (int i=0; i<3; i++)
237 switch(colorNo)
239 case 0: glColor3fv(flare_[i].color1); break;
240 case 1: glColor3fv(flare_[i].color2); break;
241 case 2: glColor3fv(flare_[i].color3); break;
242 case 3: glColor3fv(flare_[i].color4); break;
245 shines_[shineTic_].draw();
246 shineTic_ = (shineTic_ + 1) % 10;
248 Vector position = flarePos + (axis * flare_[i].loc);
249 Vector sx = dx * flare_[i].scale;
250 Vector sy = dy * flare_[i].scale;
252 glBegin(GL_QUADS);
253 static Vector tmp;
254 tmp = position + sx + sy;
255 glTexCoord2f(0.0, 0.0);
256 glVertex3fv(tmp);
258 tmp = (position - sx) + sy;
259 glTexCoord2f(1.0, 0.0);
260 glVertex3fv(tmp);
262 tmp = (position - sx) - sy;
263 glTexCoord2f(1.0, 1.0);
264 glVertex3fv(tmp);
266 tmp = (position + sx) - sy;
267 glTexCoord2f(0.0, 1.0);
268 glVertex3fv(tmp);
270 glEnd();
272 glDepthMask(GL_TRUE);
273 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);