lilith3dgl.h

00001 /*--License:
00002         Lilith 3D Engine
00003         Copyright Lee Thomason (Grinning Lizard Software) 2002-2007
00004         www.grinninglizard.com/lilith
00005 
00006         This program is free software; you can redistribute it and/or
00007         modify it under the terms of the GNU General Public License
00008         as published by the Free Software Foundation; either version 2
00009         of the License, or (at your option) any later version.
00010 
00011         This program is distributed in the hope that it will be useful,
00012         but WITHOUT ANY WARRANTY; without even the implied warranty of
00013         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014         GNU General Public License for more details.
00015 
00016         You should have received a copy of the GNU General Public License
00017         along with this program; if not, write to the Free Software
00018         Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020         The full text of the license can be found in license.txt
00021 */
00022 #ifndef LILITH3D_OPENGL_INCLUDED
00023 #define LILITH3D_OPENGL_INCLUDED
00024 
00025 #include "glew.h"
00026 //#include <GL/glu.h>
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 // Access to SDL_image
00042 typedef SDL_Surface* (SDLCALL * PFN_IMG_LOAD) (const char *file);
00043 LILITHEXTERN PFN_IMG_LOAD libIMG_Load;
00044 
00045 // Initialize libraries.
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                 // Need a low res hash code due to rounding and bit differences from
00062                 // floating point compution. Also, the Compare has an epsilon.
00063                 // And the normal may not matter. Grr.
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         // set the OpenGL vertex, normal, and texture pointers.
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;                  // turn on blending (alpha)
00138         bool                    linear;                 // use linear texture hint (instead of mipmap)
00139         bool                    clamp;                  // clamp instead of repeat texture
00140         bool                    depthWrite;             // set to false to disable writing to the depth buffer
00141         bool                    depthCheck;             // check the depth buffer before writing a texel
00142         bool                    lighting;               // turn on opengl lights
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                 // Vertex array support
00234                 VERTEX_ARRAY                    = 0x00001,
00235                 TEXTURE_ARRAY                   = 0x00002,
00236                 COLOR_ARRAY                             = 0x00004,
00237                 NORMAL_ARRAY                    = 0x00020,
00238                 INDEX_ARRAY                             = 0x00040,
00239 
00240                 // Texture
00241                 TEXTURE_2D                              = 0x00100,
00242 
00243                 // General modes
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 // SDL pixel functions.
00343 Uint32 GetPixel(SDL_Surface *surface, int x, int y);
00344 void PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
00345 /*
00346 inline Uint32 GetPixel32( SDL_Surface *surface, int x, Uint8* row )
00347 {
00348         GLASSERT( surface->format->BytesPerPixel == 4 );
00349     Uint8 *p = row + (x<<2);
00350     return *(Uint32 *)p;
00351 }
00352 
00353 
00354 inline Uint32 GetPixel24(SDL_Surface *surface, int x, Uint8* row )
00355 {
00356         GLASSERT( surface->format->BytesPerPixel == 3 );
00357     Uint8 *p = row + x*3;
00358 
00359     #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
00360                 return p[0] << 16 | p[1] << 8 | p[2];
00361     #else
00362         return p[0] | p[1] << 8 | p[2] << 16;
00363         #endif
00364 }
00365 */
00366 
00367 // SDL OpenGL Surface functions.
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 

Generated on Fri Mar 23 19:36:22 2007 for Lilith3D by  doxygen 1.5.1-p1