1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
4 // This file is part of Scorched3D.
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 ////////////////////////////////////////////////////////////////////////////////
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()
36 instance_
= new GLLenseFlare
;
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
,
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
);
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();
140 glDepthMask(GL_FALSE
);
141 GLState
currentState(GLState::BLEND_ON
);
142 glBlendFunc(GL_ONE
, GL_ONE
);
144 GLState
*afterThreeState
= 0;
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
;
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
);
169 flares_
[flare_
[i
].type
].draw();
171 position
= flarePos
+ (axis
* flare_
[i
].loc
);
174 if (i
==3) afterThreeState
= new GLState(GLState::DEPTH_OFF
);
180 tmp
= position
+ sx
+ sy
;
181 glTexCoord2f(0.0, 0.0);
184 tmp
= (position
- sx
) + sy
;
185 glTexCoord2f(1.0, 0.0);
188 tmp
= (position
- sx
) - sy
;
189 glTexCoord2f(1.0, 1.0);
192 tmp
= (position
+ sx
) - sy
;
193 glTexCoord2f(0.0, 1.0);
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))
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
++)
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
;
254 tmp
= position
+ sx
+ sy
;
255 glTexCoord2f(0.0, 0.0);
258 tmp
= (position
- sx
) + sy
;
259 glTexCoord2f(1.0, 0.0);
262 tmp
= (position
- sx
) - sy
;
263 glTexCoord2f(1.0, 1.0);
266 tmp
= (position
+ sx
) - sy
;
267 glTexCoord2f(0.0, 1.0);
272 glDepthMask(GL_TRUE
);
273 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);