00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef LILITH3D_OPENGL_INCLUDED
00023 #define LILITH3D_OPENGL_INCLUDED
00024
00025 #include "glew.h"
00026
00027 #include "SDL.h"
00028 #include "../grinliz/glvector.h"
00029 #include "../grinliz/glcolor.h"
00030
00031
00032 #ifdef LILITH_GL_HERE
00033 #define LILITHEXTERN
00034 #else
00035 #define LILITHEXTERN extern
00036 #endif
00037
00038 namespace lilith3d
00039 {
00040
00041
00042 typedef SDL_Surface* (SDLCALL * PFN_IMG_LOAD) (const char *file);
00043 LILITHEXTERN PFN_IMG_LOAD libIMG_Load;
00044
00045
00046 bool InitLilith3D();
00047
00048 class Texture;
00049 struct Shader;
00050
00053 struct Vertex
00054 {
00055 grinliz::Vector3F pos;
00056 grinliz::Vector3F normal;
00057 grinliz::Vector2F tex;
00058
00059 U32 HashCode() const
00060 {
00061
00062
00063
00064 return grinliz::LRintf( pos.x ) + 10*grinliz::LRintf( pos.y ) + 100*grinliz::LRintf(pos.z)
00065 + 1000*grinliz::LRintf( tex.x ) + 10000*grinliz::LRintf( tex.y );
00066 }
00067
00068 inline int Compare( const Vertex& rhs, const float epsilon ) const {
00069 int c = pos.Compare( rhs.pos, epsilon );
00070 if ( c ) return c;
00071 c = normal.Compare( rhs.normal, epsilon );
00072 if ( c ) return c;
00073 return tex.Compare( rhs.tex, epsilon );
00074 }
00075 inline int CompareWONormal( const Vertex& rhs, const float epsilon ) const {
00076 int c = pos.Compare( rhs.pos, epsilon );
00077 if ( c ) return c;
00078 return tex.Compare( rhs.tex, epsilon );
00079 }
00080
00081
00082 static void SetPointers( const Vertex* v );
00083 };
00084
00085
00086 struct L3VertexState
00087 {
00088 L3VertexState()
00089 : color3Pointer( 0 ),
00090 color4Pointer( 0 ),
00091 color4BytePointer( 0 ),
00092 vPointer( 0 ),
00093 vertexPointer( 0 ),
00094 vertexPointerStride( 0 ),
00095 texturePointer( 0 ),
00096 texturePointerStride( 0 ),
00097 normalPointer( 0 ),
00098 normalPointerStride( 0 ),
00099 indexPointer( 0 )
00100 {}
00101
00102 const Vertex *vPointer;
00103 const grinliz::Vector3F *vertexPointer;
00104 unsigned vertexPointerStride;
00105 const grinliz::Vector2F *texturePointer;
00106 unsigned texturePointerStride;
00107 const grinliz::Vector3F *normalPointer;
00108 unsigned normalPointerStride;
00109 const int *indexPointer;
00110
00111 const grinliz::Color3F *color3Pointer;
00112 const grinliz::Color4F *color4Pointer;
00113 const grinliz::Color4U8 *color4BytePointer;
00114 };
00115
00123 struct L3State
00124 {
00125 L3State()
00126 : blend( false ),
00127 linear( false ),
00128 clamp( false ),
00129 depthWrite( true ),
00130 depthCheck( true ),
00131 lighting( true ),
00132 texture( 0 ),
00133 alphaTest( 0.0f ),
00134 shader( 0 )
00135 {}
00136
00137 bool blend;
00138 bool linear;
00139 bool clamp;
00140 bool depthWrite;
00141 bool depthCheck;
00142 bool lighting;
00143
00144 const Texture *texture;
00145
00146 float alphaTest;
00147 const Shader* shader;
00148 };
00149
00152 class StateManager
00153 {
00154 friend class LightingStack;
00155 friend class Texture2DStack;
00156 friend class AlphaTestStack;
00157
00158 public:
00160 static void Reset();
00161
00162 static void Enable( const L3State& state );
00163 static void Enable( const L3VertexState& state );
00164 static void Enable( const L3State& state, const L3VertexState& vState )
00165 {
00166 Enable( state );
00167 Enable( vState );
00168 }
00169
00170 static void ChangeTexture( const Texture* tex );
00171 static void SetLightProperties( const grinliz::Vector3F& vector,
00172 const grinliz::Color4F& ambient,
00173 const grinliz::Color4F& diffuse );
00174
00175 static void Texture2D( bool enable ) {
00176 if ( enable && !flags.IsSet( TEXTURE_2D ) ) {
00177 glEnable( GL_TEXTURE_2D );
00178 flags.Set( TEXTURE_2D );
00179 }
00180 else if ( !enable && flags.IsSet( TEXTURE_2D ) ) {
00181 glDisable( GL_TEXTURE_2D );
00182 flags.Clear( TEXTURE_2D );
00183 }
00184 }
00185
00186 static void AlphaTest( bool enable, float v ) {
00187 if ( enable && !flags.IsSet( ALPHA_TEST ) ) {
00188 glEnable( GL_ALPHA_TEST );
00189 flags.Set( ALPHA_TEST );
00190 glAlphaFunc ( GL_GREATER, v ) ;
00191 }
00192 else if ( !enable && flags.IsSet( ALPHA_TEST ) ) {
00193 glDisable( GL_ALPHA_TEST );
00194 flags.Clear( ALPHA_TEST );
00195 }
00196 }
00197
00198
00199 static void DepthWrite( bool enable ) {
00200 if ( enable && !flags.IsSet( DEPTHWRITE ) ) {
00201 glDepthMask( GL_TRUE );
00202 flags.Set( DEPTHWRITE );
00203 }
00204 else if ( !enable && flags.IsSet( DEPTHWRITE ) ) {
00205 glDepthMask( GL_FALSE );
00206 flags.Clear( DEPTHWRITE );
00207 }
00208 }
00209
00210 static void Blend( bool enable ) {
00211 if ( enable && !flags.IsSet( BLEND ) ) {
00212 glEnable( GL_BLEND );
00213 flags.Set( BLEND );
00214 }
00215 else if ( !enable && flags.IsSet( BLEND ) ) {
00216 glDisable( GL_BLEND );
00217 flags.Clear( BLEND );
00218 }
00219 }
00220
00221 static void ErrorCheck() {
00222 #ifdef DEBUG
00223 GLenum result = glGetError();
00224 if ( result != GL_NO_ERROR )
00225 GLOUTPUT(( "GL Error 0x%x\n", result ));
00226 GLASSERT( result == GL_NO_ERROR );
00227 #endif
00228 }
00229
00230 static U32 Flags() { return flags.ToU32(); }
00231
00232 enum {
00233
00234 VERTEX_ARRAY = 0x00001,
00235 TEXTURE_ARRAY = 0x00002,
00236 COLOR_ARRAY = 0x00004,
00237 NORMAL_ARRAY = 0x00020,
00238 INDEX_ARRAY = 0x00040,
00239
00240
00241 TEXTURE_2D = 0x00100,
00242
00243
00244 BLEND = 0x01000,
00245 DEPTHWRITE = 0x02000,
00246 DEPTH_TEST = 0x04000,
00247 ALPHA_TEST = 0x08000,
00248 LIGHTING = 0x10000,
00249
00250 };
00251
00252 private:
00253 static void Lighting( bool enable ) {
00254 GLASSERT( flags.IsSet( LIGHTING ) ? glIsEnabled( GL_LIGHTING ) : !glIsEnabled( GL_LIGHTING ) );
00255 if ( enable && !flags.IsSet( LIGHTING ) ) {
00256 glEnable( GL_LIGHTING );
00257 flags.Set( LIGHTING );
00258 }
00259 else if ( !enable && flags.IsSet( LIGHTING ) ) {
00260 glDisable( GL_LIGHTING );
00261 flags.Clear( LIGHTING );
00262 }
00263 }
00264
00265 static const Texture* texture;
00266
00267 static grinliz::Flag< U32 > flags;
00268 };
00269
00270
00271 class LightingStack
00272 {
00273 public:
00274 LightingStack( bool enable ) {
00275 wasEnabled = StateManager::flags.IsSet( StateManager::LIGHTING );
00276 StateManager::Lighting( enable );
00277 }
00278 ~LightingStack() {
00279 StateManager::Lighting( wasEnabled != 0 );
00280 }
00281
00282 private:
00283 U32 wasEnabled;
00284 };
00285
00286
00287 class AlphaTestStack
00288 {
00289 public:
00290 AlphaTestStack( bool enable, float v ) {
00291 wasEnabled = StateManager::flags.IsSet( StateManager::ALPHA_TEST );
00292 StateManager::AlphaTest( enable, v );
00293 }
00294 ~AlphaTestStack() {
00295 StateManager::AlphaTest( wasEnabled != 0, 0.5f );
00296 }
00297
00298 private:
00299 U32 wasEnabled;
00300 };
00301
00302
00303 class Texture2DStack
00304 {
00305 public:
00306 Texture2DStack( bool enable ) {
00307 wasEnabled = StateManager::flags.IsSet( StateManager::TEXTURE_2D );
00308 StateManager::Texture2D( enable );
00309 }
00310 ~Texture2DStack() {
00311 StateManager::Texture2D( wasEnabled != 0 );
00312 }
00313
00314 private:
00315 U32 wasEnabled;
00316 };
00317
00318
00319 class FogStack
00320 {
00321 public:
00322 FogStack( bool enable ) {
00323 wasEnabled = glIsEnabled( GL_FOG );
00324 if ( enable && !wasEnabled )
00325 glEnable( GL_FOG );
00326 else if ( !enable && wasEnabled )
00327 glDisable( GL_FOG );
00328 }
00329 ~FogStack() {
00330 if ( wasEnabled ) glEnable( GL_FOG );
00331 else glDisable( GL_FOG );
00332 }
00333
00334 private:
00335 GLboolean wasEnabled;
00336 };
00337
00338
00339 void L3glInitFrame();
00340 void L3glDestroy();
00341
00342
00343 Uint32 GetPixel(SDL_Surface *surface, int x, int y);
00344 void PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 void InvertGlSurface( SDL_Surface* surface );
00369 void SurfaceCopyAndInvert( SDL_Surface* target, SDL_Surface* source );
00370 void SurfaceCopyInvertAndReduce( SDL_Surface* target, SDL_Surface* source, int reduce );
00371
00372
00373
00374 struct VertexEqual
00375 {
00376 bool operator()(const Vertex& s1, const Vertex& s2) const
00377 {
00378 const float EPS = 0.000002f;
00379 return s1.Compare( s2, EPS ) == 0;
00380 }
00381 };
00382
00383 struct VertexEqualWONormal
00384 {
00385 bool operator()(const Vertex& s1, const Vertex& s2) const
00386 {
00387 const float EPS = 0.000002f;
00388 return s1.CompareWONormal( s2, EPS ) == 0;
00389 }
00390 };
00391
00392 };
00393
00394 #endif
00395