00001 #include "glfuncs.h"
00002 #include <iostream>
00003 
00004 using namespace std;
00005 
00006 glfuncs* glfuncs::_instance = NULL;
00007 
00008 glfuncs::glfuncs()
00009 {
00010         init_glfuncs();
00011         base = buildFont();
00012 }
00013 
00014 glfuncs* glfuncs::instance()
00015 {
00016         if(!_instance)
00017                 _instance = new glfuncs();
00018         return _instance;
00019 }
00020 
00021 void* glfuncs::get_funcaddr(const char* p)
00022 {
00023         void* f=SDL_GL_GetProcAddress(p);
00024         if (f)
00025         {
00026                 return f;
00027         }
00028         else
00029         {
00030                 printf("Unable to get function pointer for %s\n",p);
00031                 exit(1);
00032         }
00033 }
00034 
00035 void glfuncs::init_glfuncs()
00036 {
00037         glBegin=(void(APIENTRY*)(GLenum))get_funcaddr("glBegin");
00038         glEnd=(void(APIENTRY*)())get_funcaddr("glEnd");
00039         glVertex3f=(void(APIENTRY*)(GLfloat, GLfloat, GLfloat))get_funcaddr("glVertex3f");
00040         glClearColor=(void(APIENTRY*)(GLfloat, GLfloat, GLfloat, GLfloat))get_funcaddr("glClearColor");
00041         glClear=(void(APIENTRY*)(GLbitfield))get_funcaddr("glClear");
00042         glDisable=(void(APIENTRY*)(GLenum))get_funcaddr("glDisable");
00043         glEnable=(void(APIENTRY*)(GLenum))get_funcaddr("glEnable");
00044         glColor4ub=(void(APIENTRY*)(GLubyte,GLubyte,GLubyte,GLubyte))get_funcaddr("glColor4ub");
00045         glPointSize=(void(APIENTRY*)(GLfloat))get_funcaddr("glPointSize");
00046         glHint=(void(APIENTRY*)(GLenum,GLenum))get_funcaddr("glHint");
00047         glBlendFunc=(void(APIENTRY*)(GLenum,GLenum))get_funcaddr("glBlendFunc");
00048         glMatrixMode=(void(APIENTRY*)(GLenum))get_funcaddr("glMatrixMode");
00049         glLoadIdentity=(void(APIENTRY*)())get_funcaddr("glLoadIdentity");
00050         glOrtho=(void(APIENTRY*)(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble))get_funcaddr("glOrtho");
00051         glRotatef=(void(APIENTRY*)(GLfloat,GLfloat,GLfloat,GLfloat))get_funcaddr("glRotatef");
00052         glViewport=(void(APIENTRY*)(GLint,GLint,GLsizei,GLsizei))get_funcaddr("glViewport");
00053         glFogf=(void(APIENTRY*)(GLenum,GLfloat))get_funcaddr("glFogf");
00054         glGenTextures=(void(APIENTRY*)(GLsizei,GLuint*))get_funcaddr("glGenTextures");
00055         glBindTexture=(void(APIENTRY*)(GLenum,GLuint))get_funcaddr("glBindTexture");
00056         glTexParameteri=(void(APIENTRY*)(GLenum,GLenum,GLint))get_funcaddr("glTexParameteri");
00057         glTexImage2D=(void(APIENTRY*)(GLenum,GLint,GLint,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid *))get_funcaddr("glTexImage2D");
00058         glColor3f=(void(APIENTRY*)(GLfloat,GLfloat,GLfloat))get_funcaddr("glColor3f");
00059         glVertex2f=(void(APIENTRY*)(GLfloat,GLfloat))get_funcaddr("glVertex2f");
00060         glTexCoord2f=(void(APIENTRY*)(GLfloat,GLfloat))get_funcaddr("glTexCoord2f");
00061         glTexEnvf=(void(APIENTRY*)(GLenum,GLenum,GLfloat))get_funcaddr("glTexEnvf");
00062         glColor4f=(void(APIENTRY*)(GLfloat,GLfloat,GLfloat,GLfloat))get_funcaddr("glColor4f");
00063         glDepthMask=(void(APIENTRY*)(GLboolean))get_funcaddr("glDepthMask");
00064         glClearDepth=(void(APIENTRY*)(GLclampd))get_funcaddr("glClearDepth");
00065         glDepthFunc=(void(APIENTRY*)(GLenum))get_funcaddr("glDepthFunc");
00066         glShadeModel=(void(APIENTRY*)(GLenum))get_funcaddr("glShadeModel");
00067         glFinish=(void(APIENTRY*)())get_funcaddr("glFinish");
00068 
00069         glGenLists=(GLuint(APIENTRY*)(GLsizei))get_funcaddr("glGenLists");
00070         glDeleteLists=(void(APIENTRY*)(GLuint,GLsizei))get_funcaddr("glDeleteLists");
00071         glPopAttrib=(void(APIENTRY*)())get_funcaddr("glPopAttrib");
00072         glCallLists=(void(APIENTRY*)(GLsizei,GLenum,const GLvoid*))get_funcaddr("glCallLists");
00073         glListBase=(void(APIENTRY*)(GLuint))get_funcaddr("glListBase");
00074         glPushAttrib=(void(APIENTRY*)(GLbitfield))get_funcaddr("glPushAttrib");
00075 
00076         glRasterPos2f=(void(APIENTRY*)(GLfloat,GLfloat))get_funcaddr("glRasterPos2f");
00077         glGetBooleanv=(void(APIENTRY*)(GLenum, GLboolean *))get_funcaddr("glGetBooleanv");
00078 
00079         wglUseFontBitmapsA=(void(APIENTRY*)(HDC,long,long,long))get_funcaddr("wglUseFontBitmapsA");
00080 }
00081 
00082 
00083 int glfuncs::power_of_two(int input)
00084 {
00085     int value = 1;
00086 
00087     while ( value < input ) {
00088         value <<= 1;
00089     }
00090     return value;
00091 }
00092 
00093 GLuint glfuncs::SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
00094 {
00095     GLuint texture;
00096     int w, h;
00097     SDL_Surface *image;
00098     SDL_Rect area;
00099     Uint32 saved_flags;
00100     Uint8  saved_alpha;
00101 
00102     
00103     w = power_of_two(surface->w);
00104     h = power_of_two(surface->h);
00105     texcoord[0] = 0.0f;         
00106     texcoord[1] = 0.0f;         
00107     texcoord[2] = (GLfloat)surface->w / w;  
00108     texcoord[3] = (GLfloat)surface->h / h;  
00109 
00110     image = SDL_CreateRGBSurface(
00111             SDL_SWSURFACE,
00112             w, h,
00113             32,
00114 #if SDL_BYTEORDER == SDL_LIL_ENDIAN 
00115             0x000000FF,
00116             0x0000FF00,
00117             0x00FF0000,
00118             0xFF000000
00119 #else
00120             0xFF000000,
00121             0x00FF0000,
00122             0x0000FF00,
00123             0x000000FF
00124 #endif
00125                );
00126     if ( image == NULL ) {
00127         return 0;
00128     }
00129 
00130     
00131     saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
00132     saved_alpha = surface->format->alpha;
00133     if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
00134         SDL_SetAlpha(surface, 0, 0);
00135     }
00136 
00137     
00138     area.x = 0;
00139     area.y = 0;
00140     area.w = surface->w;
00141     area.h = surface->h;
00142     SDL_BlitSurface(surface, &area, image, &area);
00143 
00144     
00145     if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
00146         SDL_SetAlpha(surface, saved_flags, saved_alpha);
00147     }
00148 
00149     
00150     glGenTextures(1, &texture);
00151     glBindTexture(GL_TEXTURE_2D, texture);
00152     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00153     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00154     glTexImage2D(GL_TEXTURE_2D,
00155              0,
00156              GL_RGBA,
00157              w, h,
00158              0,
00159              GL_RGBA,
00160              GL_UNSIGNED_BYTE,
00161              image->pixels);
00162     SDL_FreeSurface(image); 
00163 
00164     return texture;
00165 }
00166 
00167 SDL_Surface *glfuncs::load_image( std::string filename ) 
00168 { 
00169         
00170         SDL_Surface* loadedImage = NULL; 
00171         
00172         
00173         SDL_Surface* optimizedImage = NULL; 
00174         
00175         
00176         loadedImage = IMG_Load( filename.c_str() ); 
00177         
00178         
00179         if( loadedImage != NULL ) 
00180         { 
00181                 
00182                 optimizedImage = SDL_DisplayFormatAlpha( loadedImage ); 
00183                 
00184                 SDL_FreeSurface( loadedImage ); 
00185         } 
00186         
00187         
00188         return optimizedImage; 
00189 }
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 bool glfuncs::intersect(SDL_Rect &A, SDL_Rect &B, int* x , int* y)
00198 {
00199         return intersectX(A,B,x) && intersectY(A,B,y);
00200 }
00201 
00202 bool glfuncs::intersectX(SDL_Rect &A, SDL_Rect &B, int* x)
00203 {
00204         bool returnme;
00205         
00206     int leftA, leftB;
00207     int rightA, rightB;
00208         
00209         
00210     leftA = A.x;
00211     rightA = A.x + A.w;
00212 
00213         
00214     leftB = B.x;
00215     rightB = B.x + B.w;
00216 
00217         
00218     if( rightA <= leftB || leftA >= rightB )
00219                 returnme = false;
00220         else 
00221                 returnme = true;
00222 
00223         if(x != NULL)
00224         {
00225                 int centerAx = A.x + A.w/2;
00226                 int centerBx = B.x + B.w/2;
00227 
00228                 
00229                 
00230                 bool left;
00231 
00232                 if(returnme)
00233                         left = (centerAx >= centerBx);
00234                 else
00235                         left = (centerAx <= centerBx);
00236                 
00237                 
00238                 *x = min(abs(leftB-rightA),abs(leftA-rightB));
00239                 
00240                 
00241                 if(left)
00242                         *x = -(*x);
00243         }
00244         return returnme;
00245 
00246 }
00247 bool glfuncs::intersectY(SDL_Rect &A, SDL_Rect &B, int* y)
00248 {
00249         bool returnme;
00250         
00251         int topA, topB;
00252     int bottomA, bottomB;
00253 
00254         
00255         topA = A.y;
00256     bottomA = A.y + A.h;
00257         
00258     
00259     topB = B.y;
00260     bottomB = B.y + B.h;
00261 
00262 
00263         
00264     if( bottomA <= topB || topA >= bottomB )
00265                 returnme = false;
00266         else 
00267                 returnme = true;
00268 
00269         if(y != NULL)
00270         {
00271                 
00272                 int centerAy = A.y + A.h/2;
00273                 int centerBy = B.y + B.h/2;
00274 
00275                 
00276                 
00277                 bool up;
00278                 
00279                 if(returnme)
00280                         up = (centerAy >= centerBy);
00281                 else
00282                         up = (centerAy <= centerBy);
00283 
00284                 
00285                 *y = min(abs(bottomB-topA),abs(bottomA-topB));
00286                 
00287                 
00288                 if(up)
00289                         *y = -(*y);
00290 
00291                 
00292         }
00293 
00294         
00295 
00296         return returnme;
00297 }
00298 
00299 
00300 GLuint glfuncs::buildFont(GLvoid)                                                               
00301 {
00302         SDL_SysWMinfo info;
00303         SDL_VERSION(&info.version);
00304         SDL_GetWMInfo(&info);
00305 
00306         HWND hWnd = info.window;
00307 
00308         HDC hDC = GetDC(hWnd); 
00309 
00310         HFONT   font;                                                                           
00311         HFONT   oldfont;                                                                        
00312 
00313         GLuint base = glGenLists(96);                           
00314 
00315         font = CreateFont(      -24,                                                    
00316                                                 0,                                                              
00317                                                 0,                                                              
00318                                                 0,                                                              
00319                                                 FW_BOLD,                                                
00320                                                 FALSE,                                                  
00321                                                 FALSE,                                                  
00322                                                 FALSE,                                                  
00323                                                 ANSI_CHARSET,                                   
00324                                                 OUT_TT_PRECIS,                                  
00325                                                 CLIP_DEFAULT_PRECIS,                    
00326                                                 ANTIALIASED_QUALITY,                    
00327                                                 FF_DONTCARE|DEFAULT_PITCH,              
00328                                                 "Courier New");                                 
00329 
00330         oldfont = (HFONT)SelectObject(hDC, font);           
00331         wglUseFontBitmaps(hDC, 32, 96, base);                           
00332         SelectObject(hDC, oldfont);                                                     
00333         DeleteObject(font);                                                                     
00334 
00335         return base;
00336 }
00337 
00338 
00339 GLvoid glfuncs::killFont()                                                                      
00340 {
00341         glDeleteLists(base, 96);                                                        
00342 }
00343 
00344 
00345 GLvoid glfuncs::glPrint(std::string text)                                       
00346 {                                                       
00347 
00348         if (text == "")                                                                 
00349                 return;                                                                                 
00350 
00351         glPushAttrib(GL_LIST_BIT);                                                      
00352         glListBase(base - 32);                                                          
00353         glCallLists(strlen(text.c_str()), GL_UNSIGNED_BYTE, text.c_str());      
00354         glPopAttrib();                                                                          
00355 }
00356 
00357 
00358 int glfuncs::loadTexture(std::string filename, GLfloat coords[4], SDL_Rect & rect)
00359 {
00360         SDL_Surface *surface = load_image(filename);
00361         rect.x = 0;
00362     rect.y = 0;
00363     rect.w = surface->w;
00364     rect.h = surface->h;
00365         int texture = SDL_GL_LoadTexture(surface,coords);
00366         SDL_FreeSurface(surface);
00367         return texture;
00368 }