00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <GL/gl.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <memory.h>
00026 #include <math.h>
00027 #include <string.h>
00028 #include <time.h>
00029
00030 #include "flare.h"
00031 #include "texture.h"
00032 #include "vector.h"
00033 #include "camera.h"
00034
00035 extern float SunPosition[3];
00036 extern TEXTURE* texture;
00037 extern CAMERA* camera;
00038 extern int currentCamera;
00039 extern HWND hWnd;
00040 extern RECT screen;
00041 extern PAINTSTRUCT ps;
00042
00043
00044
00045
00046
00047
00048 #define HEIGHTFROMWIDTH(w) ((w)*SCREENheight/SCREENwidth)
00049
00050 #define isqrt(x) (int)((double)(x))
00051
00052
00053
00054
00055
00056 typedef struct TEXTURE_DEF
00057 {
00058 char* filename;
00059 TEXTURE* FlareTexture;
00060 }
00061 TEXTURE_DEF;
00062
00063
00064 enum
00065 {
00066 TEX_CRCL,
00067 TEX_HXGN,
00068 TEX_RING,
00069 TEX_FLAR,
00070 NPIECETEXTURES,
00071 TEX_SUN = NPIECETEXTURES,
00072 TEX_BACK,
00073 NTEXTURES
00074 };
00075
00076
00077
00078 TEXTURE_DEF gTextures[ NTEXTURES ] =
00079 {
00080 { "crcl.tga" },
00081 { "hxgn.tga" },
00082 { "ring.tga" },
00083 { "flar.tga" },
00084 { "sun.tga" },
00085 { "back.tga" }
00086 };
00087 TEXTURE_DEF *TM_getNthTexture( int n );
00088 TEXTURE_DEF *TM_getNamedTexture( char *name );
00089 void TM_loadTextures( void );
00090 void TM_setTexture( TEXTURE_DEF *tex );
00091
00092
00093
00094
00095
00096 void drawQuad( int x, int y, int width, int height, TEXTURE_DEF *tex, unsigned int colour );
00097
00098
00099
00100
00101
00102 int SCREENwidth = screen.right;
00103 int SCREENheight = screen.bottom;
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 void FLARE_randomize(FLARE_DEF *flare,
00116 int nTextures,
00117 int nPieces,
00118 float fMaxSize,
00119 unsigned int minColour,
00120 unsigned int maxColour)
00121 {
00122 int i;
00123 float fFracDist;
00124 float fEnvelopeSize;
00125 FLARE_ELEMENT_DEF *element;
00126
00127 srand((unsigned)time(NULL));
00128
00129
00130
00131 flare->nPieces = nPieces;
00132 flare->fScale = fMaxSize;
00133 flare->fMaxSize = fMaxSize;
00134 fFracDist = 1.0f/(float)(flare->nPieces - 1);
00135
00136 for (i = 0; i < flare->nPieces; ++i)
00137 {
00138 element = &flare->element[i];
00139 element->fDistance = (fFracDist*i) + FLARE_FRANGE(0,fFracDist);
00140
00141
00142
00143 fEnvelopeSize = (float)fabs(1.0f - 2*element->fDistance);
00144
00145 element->fSize = FLARE_FRANGE(0.6f, 1.0f) * fEnvelopeSize;
00146 element->argb = FLARE_RANGE(minColour & 0xff000000, maxColour & 0xff000000) |
00147 FLARE_RANGE(minColour & 0x00ff0000, maxColour & 0x00ff0000) |
00148 FLARE_RANGE(minColour & 0x0000ff00, maxColour & 0x0000ff00) |
00149 FLARE_RANGE(minColour & 0x000000ff, maxColour & 0x000000ff);
00150 element->texture = TM_getNthTexture( FLARE_RANGE(0, nTextures - 1) );
00151 }
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 void FLARE_render(FLARE_DEF *flare, int lx, int ly, int cx, int cy)
00167 {
00168 int dx, dy;
00169 int px, py;
00170 int maxflaredist, flaredist, flaremaxsize, flarescale;
00171 int width, height, alpha;
00172 int i;
00173 FLARE_ELEMENT_DEF *element;
00174
00175
00176 maxflaredist = isqrt(cx*cx + cy*cy);
00177 flaredist = isqrt((lx - cx)*(lx - cx)+
00178 (ly - cy)*(ly - cy));
00179 flaredist = (maxflaredist - flaredist);
00180 flaremaxsize = (int)(SCREENwidth * flare->fMaxSize);
00181 flarescale = (int)(SCREENwidth * flare->fScale);
00182
00183
00184 dx = cx + (cx - lx);
00185 dy = cy + (cy - ly);
00186
00187
00188 for (i = 0; i < flare->nPieces; ++i)
00189 {
00190 element = &flare->element[i];
00191
00192
00193 px = (int)((1.0f - element->fDistance)*lx + element->fDistance*dx);
00194 py = (int)((1.0f - element->fDistance)*ly + element->fDistance*dy);
00195
00196
00197
00198 width = (int)((flaredist*flarescale*element->fSize)/maxflaredist);
00199
00200
00201
00202
00203 if (width > flaremaxsize)
00204 {
00205 width = flaremaxsize;
00206 }
00207
00208
00209
00210 height = HEIGHTFROMWIDTH(width);
00211 alpha = (flaredist*(element->argb >> 24))/maxflaredist;
00212
00213 if ( width > 1 )
00214 {
00215 unsigned int argb = (alpha << 24 ) | (element->argb & 0x00ffffff);
00216
00217 drawQuad( px - width/2, py - height/2, width, height, element->texture, argb );
00218 }
00219 }
00220 }
00221
00222
00223
00224
00225
00226
00227
00228 void drawQuad( int x, int y, int width, int height, TEXTURE_DEF *tex, unsigned int colour )
00229 {
00230 glBindTexture(GL_TEXTURE_2D, tex->FlareTexture->TexID);
00231
00232 glBegin(GL_QUADS);
00233
00234 glColor4ub( (GLbyte)(colour >> 16 & 0xff),
00235 (GLbyte)(colour >> 8 & 0xff),
00236 (GLbyte)(colour >> 0 & 0xff),
00237 (GLbyte)(colour >> 24 & 0xff) );
00238
00239 glTexCoord2f( 0.0f, 0.0f );
00240 glVertex3f( x, y, 1.0);
00241 glTexCoord2f( 1.0f, 0.0f );
00242 glVertex3f( x + width, y, 1.0);
00243 glTexCoord2f( 1.0f, 1.0f );
00244 glVertex3f( x + width, y + height, 1.0);
00245 glTexCoord2f( 0.0f, 1.0f );
00246 glVertex3f( x, y + height, 1.0);
00247
00248 glEnd();
00249 }
00250
00251
00252
00253
00254 TEXTURE_DEF *TM_getNthTexture( int n )
00255 {
00256 if ( ( n < 0 ) || ( n >= NTEXTURES ) )
00257 return NULL;
00258
00259 return &gTextures[n];
00260 }
00261
00262 TEXTURE_DEF *TM_getNamedTexture( char *name )
00263 {
00264 int i;
00265
00266 for ( i = 0; i < NTEXTURES; ++i )
00267 {
00268 if ( strncmp( name, gTextures[i].FlareTexture->TexName, strlen( name ) ) == 0 )
00269 return &gTextures[i];
00270 }
00271
00272 return NULL;
00273 }
00274
00275 void TM_loadTextures( void )
00276 {
00277 int i;
00278
00279 TEXTURE_DEF *tex = &gTextures[0];
00280
00281 for ( i = 0; i < NTEXTURES; ++i, ++tex )
00282 {
00283 tex->FlareTexture->LoadTGA();
00284 }
00285 }
00286
00287 #define FLARE_MINCOLOUR MAKEID(60, 255, 200, 0)
00288 #define FLARE_MAXCOLOUR MAKEID(220, 235, 235, 64)
00289 #define FLARE_MINELEMENTSPERFLARE 8
00290 #define FLARE_MAXSIZE 0.2f
00291
00292 FLARE_DEF renderFlare;
00293
00294 void loadFlareFile( FLARE_DEF *flare, char *filename )
00295 {
00296 int n = 0;
00297 FILE *f;
00298 char buf[256];
00299
00300 memset( flare, 0, sizeof( FLARE_DEF ) );
00301
00302 f = fopen( filename, "r" );
00303 if ( f )
00304 {
00305 fgets( buf, sizeof( buf ), f );
00306 sscanf( buf, "%f %f", &flare->fScale, &flare->fMaxSize );
00307
00308 while ( !feof(f) )
00309 {
00310 char name[8] = { '\0', };
00311 double dDist = 0.0, dSize = 0.0;
00312 unsigned int a = 0, r = 0, g = 0, b = 0;
00313
00314 fgets( buf, sizeof( buf ), f );
00315 if ( sscanf( buf, "%s %lf %lf ( %d %d %d %d )",
00316 name, &dDist, &dSize, &a, &r, &g, &b ) )
00317 {
00318 flare->element[ n ].texture = TM_getNamedTexture( name );
00319 flare->element[ n ].fDistance = (float)dDist;
00320 flare->element[ n ].fSize = (float)dSize;
00321 flare->element[ n ].argb = ( a << 24 ) | ( r << 16 ) | ( g << 8 ) | ( b << 0 );
00322
00323 ++n;
00324 }
00325 }
00326
00327 flare->nPieces = n;
00328
00329 fclose( f );
00330 }
00331 }
00332
00333 void newFlare( int bFromFile )
00334 {
00335 if ( bFromFile )
00336 loadFlareFile( &renderFlare, "flare.txt" );
00337 else
00338 FLARE_randomize(&renderFlare, NPIECETEXTURES, FLARE_RANGE(FLARE_MINELEMENTSPERFLARE, FLARE_MAXELEMENTSPERFLARE), FLARE_MAXSIZE, FLARE_MINCOLOUR, FLARE_MAXCOLOUR);
00339 }
00340
00341 void DrawLensFlare()
00342 {
00343 VECTOR suns_position(25.0 + camera[currentCamera].Position.x, 20.0 + camera[currentCamera].Position.y, -35.0 + camera[currentCamera].Position.z);
00344
00345 SunPosition[1] = -1.0;
00346 SunPosition[2] = -1.0;
00347
00348 glRenderMode(GL_FEEDBACK);
00349 glBegin(GL_POINTS);
00350 glVertex3fv(&suns_position.x);
00351 glEnd();
00352 glRenderMode(GL_RENDER);
00353
00354 SunPosition[2] = screen.bottom - SunPosition[2];
00355
00356
00357 glPushMatrix();
00358 glMatrixMode(GL_PROJECTION);
00359 glPushMatrix();
00360 gluOrtho2D(0, SCREENwidth, SCREENheight, 0);
00361 glMatrixMode(GL_MODELVIEW);
00362 glLoadIdentity();
00363
00364 glDisable(GL_DEPTH_TEST);
00365 glDisable(GL_LIGHTING);
00366 glDisable(GL_CULL_FACE);
00367 glEnable(GL_BLEND);
00368 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00369
00370 if ((SunPosition[1] != -1.0))
00371 {
00372
00373 int position[2];
00374 position[1] = abs((int)SunPosition[1] - 400);
00375 position[2] = abs((int)SunPosition[2] - 300);
00376 float glare_distance = sqrt(position[1] * position[1] + position[2] * position[2]);
00377 float alpha = 1.0 - glare_distance / 500.0;
00378
00379
00380 glBindTexture(GL_TEXTURE_2D, texture[6].TexID);
00381
00382 glBegin(GL_QUADS);
00383
00384 glColor4f(1.0, 1.0, 1.0, alpha - 0.3);
00385
00386 glTexCoord2f( 0.0f, 0.0f );
00387 glVertex3f(0, 0, 1.0);
00388 glTexCoord2f( 1.0f, 0.0f );
00389 glVertex3f(800, 0, 1.0);
00390 glTexCoord2f( 1.0f, 1.0f );
00391 glVertex3f(800, 600, 1.0);
00392 glTexCoord2f( 0.0f, 1.0f );
00393 glVertex3f(0, 600, 1.0);
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 glEnd();
00405
00406 FLARE_render(&renderFlare, (int)SunPosition[1], (int)SunPosition[2], SCREENwidth/2, SCREENheight/2);
00407 }
00408
00409 glMatrixMode(GL_PROJECTION);
00410 glPopMatrix();
00411 glMatrixMode(GL_MODELVIEW);
00412 glPopMatrix();
00413
00414 glEnable(GL_DEPTH_TEST);
00415 glEnable(GL_LIGHTING);
00416 glEnable(GL_CULL_FACE);
00417 glDisable(GL_BLEND);
00418 }
00419
00420 void InitializeLensFlare()
00421 {
00422 SCREENwidth = screen.right;
00423 SCREENheight = screen.bottom;
00424
00425 for (int loop = 0; loop < NTEXTURES; loop++)
00426 {
00427 gTextures[loop].FlareTexture = new TEXTURE;
00428 sprintf(gTextures[loop].FlareTexture->TexName, "%s", gTextures[loop].filename);
00429 }
00430 TM_loadTextures();
00431 newFlare( 0 );
00432
00433 glFeedbackBuffer(3, GL_2D, SunPosition);
00434 }
00435
00436 void ResetLensFlare()
00437 {
00438 FLARE_randomize(&renderFlare, NPIECETEXTURES, FLARE_RANGE(FLARE_MINELEMENTSPERFLARE, FLARE_MAXELEMENTSPERFLARE), FLARE_MAXSIZE, FLARE_MINCOLOUR, FLARE_MAXCOLOUR);
00439 }
00440
00441 void CleanupLensFlare()
00442 {
00443 for (int loop = 0; loop < NTEXTURES; loop++)
00444 {
00445 delete gTextures[loop].FlareTexture;
00446 }
00447 }