C:/Documents and Settings/jegan/Desktop/projectX/glfuncs.cpp

Go to the documentation of this file.
00001 #include "glfuncs.h"
00002 #include "Screen.h"
00003 
00004 
00005 #include <iostream>
00006 
00007 using namespace std;
00008 
00009 glfuncs* glfuncs::_instance = NULL;
00010 
00011 glfuncs::glfuncs()
00012 {
00013         init_glfuncs();
00014 
00015         GLfloat coords[4];
00016         SDL_Rect rect;
00017         _bigFont = loadTexture("fonts/bigFont.png",coords,rect);
00018         _smallFont = loadTexture("fonts/smallFont.png",coords,rect);
00019 
00020         _bigBase = buildFont(1,16,32,_bigFont);
00021         _smallBase = buildFont(1,8,16,_smallFont);
00022         //_base = buildFont(24);
00023         //_small = buildFont(12);
00024 }
00025 
00026 glfuncs* glfuncs::instance()
00027 {
00028         if(!_instance)
00029                 _instance = new glfuncs();
00030         return _instance;
00031 }
00032 
00033 void* glfuncs::get_funcaddr(const char* p)
00034 {
00035         void* f=SDL_GL_GetProcAddress(p);
00036         if (f)
00037         {
00038                 return f;
00039         }
00040         else
00041         {
00042                 printf("Unable to get function pointer for %s\n",p);
00043                 exit(1);
00044         }
00045 }
00046 
00047 void glfuncs::init_glfuncs()
00048 {
00049         glBegin=(void(APIENTRY*)(GLenum))get_funcaddr("glBegin");
00050         glEnd=(void(APIENTRY*)())get_funcaddr("glEnd");
00051         glVertex3f=(void(APIENTRY*)(GLfloat, GLfloat, GLfloat))get_funcaddr("glVertex3f");
00052         glClearColor=(void(APIENTRY*)(GLfloat, GLfloat, GLfloat, GLfloat))get_funcaddr("glClearColor");
00053         glClear=(void(APIENTRY*)(GLbitfield))get_funcaddr("glClear");
00054         glDisable=(void(APIENTRY*)(GLenum))get_funcaddr("glDisable");
00055         glEnable=(void(APIENTRY*)(GLenum))get_funcaddr("glEnable");
00056         glColor4ub=(void(APIENTRY*)(GLubyte,GLubyte,GLubyte,GLubyte))get_funcaddr("glColor4ub");
00057         glPointSize=(void(APIENTRY*)(GLfloat))get_funcaddr("glPointSize");
00058         glHint=(void(APIENTRY*)(GLenum,GLenum))get_funcaddr("glHint");
00059         glBlendFunc=(void(APIENTRY*)(GLenum,GLenum))get_funcaddr("glBlendFunc");
00060         glMatrixMode=(void(APIENTRY*)(GLenum))get_funcaddr("glMatrixMode");
00061         glLoadIdentity=(void(APIENTRY*)())get_funcaddr("glLoadIdentity");
00062         glOrtho=(void(APIENTRY*)(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble))get_funcaddr("glOrtho");
00063         glRotatef=(void(APIENTRY*)(GLfloat,GLfloat,GLfloat,GLfloat))get_funcaddr("glRotatef");
00064         glViewport=(void(APIENTRY*)(GLint,GLint,GLsizei,GLsizei))get_funcaddr("glViewport");
00065         glFogf=(void(APIENTRY*)(GLenum,GLfloat))get_funcaddr("glFogf");
00066         glGenTextures=(void(APIENTRY*)(GLsizei,GLuint*))get_funcaddr("glGenTextures");
00067         glBindTexture=(void(APIENTRY*)(GLenum,GLuint))get_funcaddr("glBindTexture");
00068         glTexParameteri=(void(APIENTRY*)(GLenum,GLenum,GLint))get_funcaddr("glTexParameteri");
00069         glTexImage2D=(void(APIENTRY*)(GLenum,GLint,GLint,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid *))get_funcaddr("glTexImage2D");
00070         glColor3f=(void(APIENTRY*)(GLfloat,GLfloat,GLfloat))get_funcaddr("glColor3f");
00071         glVertex2f=(void(APIENTRY*)(GLfloat,GLfloat))get_funcaddr("glVertex2f");
00072         glTexCoord2f=(void(APIENTRY*)(GLfloat,GLfloat))get_funcaddr("glTexCoord2f");
00073         glTexEnvf=(void(APIENTRY*)(GLenum,GLenum,GLfloat))get_funcaddr("glTexEnvf");
00074         glColor4f=(void(APIENTRY*)(GLfloat,GLfloat,GLfloat,GLfloat))get_funcaddr("glColor4f");
00075         glDepthMask=(void(APIENTRY*)(GLboolean))get_funcaddr("glDepthMask");
00076         glClearDepth=(void(APIENTRY*)(GLclampd))get_funcaddr("glClearDepth");
00077         glDepthFunc=(void(APIENTRY*)(GLenum))get_funcaddr("glDepthFunc");
00078         glShadeModel=(void(APIENTRY*)(GLenum))get_funcaddr("glShadeModel");
00079         glFinish=(void(APIENTRY*)())get_funcaddr("glFinish");
00080 
00081         glGenLists=(GLuint(APIENTRY*)(GLsizei))get_funcaddr("glGenLists");
00082         glDeleteLists=(void(APIENTRY*)(GLuint,GLsizei))get_funcaddr("glDeleteLists");
00083         glPopAttrib=(void(APIENTRY*)())get_funcaddr("glPopAttrib");
00084         glCallLists=(void(APIENTRY*)(GLsizei,GLenum,const GLvoid*))get_funcaddr("glCallLists");
00085         glListBase=(void(APIENTRY*)(GLuint))get_funcaddr("glListBase");
00086         glPushAttrib=(void(APIENTRY*)(GLbitfield))get_funcaddr("glPushAttrib");
00087 
00088         glRasterPos2f=(void(APIENTRY*)(GLfloat,GLfloat))get_funcaddr("glRasterPos2f");
00089         glGetBooleanv=(void(APIENTRY*)(GLenum, GLboolean *))get_funcaddr("glGetBooleanv");
00090 
00091         glEndList=(void(APIENTRY*)())get_funcaddr("glEndList");
00092         glTranslated=(void(APIENTRY*)(GLdouble,GLdouble,GLdouble))get_funcaddr("glTranslated");
00093         glNewList=(void(APIENTRY*)(GLuint,GLenum))get_funcaddr("glNewList");
00094         glVertex2i=(void(APIENTRY*)(GLint,GLint))get_funcaddr("glVertex2i");
00095         glPushMatrix=(void(APIENTRY*)())get_funcaddr("glPushMatrix");
00096         glPopMatrix=(void(APIENTRY*)())get_funcaddr("glPopMatrix");
00097         
00098         glDeleteTextures=(void(APIENTRY*)(GLsizei, const GLuint *))get_funcaddr("glDeleteTextures");
00099 
00100         wglUseFontBitmapsA=(void(APIENTRY*)(HDC,long,long,long))get_funcaddr("wglUseFontBitmapsA");
00101 }
00102 
00103 /* Quick utility function for texture creation */
00104 int glfuncs::power_of_two(int input)
00105 {
00106     int value = 1;
00107 
00108     while ( value < input ) {
00109         value <<= 1;
00110     }
00111     return value;
00112 }
00113 
00114 GLuint glfuncs::SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
00115 {
00116     GLuint texture;
00117     int w, h;
00118     SDL_Surface *image;
00119     SDL_Rect area;
00120     Uint32 saved_flags;
00121     Uint8  saved_alpha;
00122 
00123     /* Use the surface width and height expanded to powers of 2 */
00124     w = power_of_two(surface->w);
00125     h = power_of_two(surface->h);
00126     texcoord[0] = 0.0f;         /* Min X */
00127     texcoord[1] = 0.0f;         /* Min Y */
00128     texcoord[2] = (GLfloat)surface->w / w;  /* Max X */
00129     texcoord[3] = (GLfloat)surface->h / h;  /* Max Y */
00130 
00131     image = SDL_CreateRGBSurface(
00132             SDL_SWSURFACE,
00133             w, h,
00134             32,
00135 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
00136             0x000000FF,
00137             0x0000FF00,
00138             0x00FF0000,
00139             0xFF000000
00140 #else
00141             0xFF000000,
00142             0x00FF0000,
00143             0x0000FF00,
00144             0x000000FF
00145 #endif
00146                );
00147     if ( image == NULL ) {
00148         return 0;
00149     }
00150 
00151     /* Save the alpha blending attributes */
00152     saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
00153     saved_alpha = surface->format->alpha;
00154     if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
00155         SDL_SetAlpha(surface, 0, 0);
00156     }
00157 
00158     /* Copy the surface into the GL texture image */
00159     area.x = 0;
00160     area.y = 0;
00161     area.w = surface->w;
00162     area.h = surface->h;
00163     SDL_BlitSurface(surface, &area, image, &area);
00164 
00165     /* Restore the alpha blending attributes */
00166     if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
00167         SDL_SetAlpha(surface, saved_flags, saved_alpha);
00168     }
00169 
00170     /* Create an OpenGL texture for the image */
00171     glGenTextures(1, &texture);
00172     glBindTexture(GL_TEXTURE_2D, texture);
00173     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00174     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00175     glTexImage2D(GL_TEXTURE_2D,
00176              0,
00177              GL_RGBA,
00178              w, h,
00179              0,
00180              GL_RGBA,
00181              GL_UNSIGNED_BYTE,
00182              image->pixels);
00183     SDL_FreeSurface(image); /* No longer needed */
00184 
00185     return texture;
00186 }
00187 
00188 SDL_Surface *glfuncs::load_image( std::string filename ) 
00189 { 
00190         //The image that's loaded 
00191         SDL_Surface* loadedImage = NULL; 
00192         
00193         //The optimized image that will be used 
00194         SDL_Surface* optimizedImage = NULL; 
00195         
00196         //Load the image using SDL_image 
00197         loadedImage = IMG_Load( filename.c_str() ); 
00198         
00199         //If the image loaded 
00200         if( loadedImage != NULL ) 
00201         { 
00202                 //Create an optimized image 
00203                 optimizedImage = SDL_DisplayFormatAlpha( loadedImage ); 
00204                 //Free the old image 
00205                 SDL_FreeSurface( loadedImage ); 
00206         } 
00207         
00208         //Return the optimized image 
00209         return optimizedImage; 
00210 }
00211 
00212 /* Taken from SDL Tutorial Lesson 13
00213  * http://lazyfooproductions.com/SDL_tutorials/lesson13/index.php
00214  * 
00215  * Highly modified
00216  */
00217 
00218 bool glfuncs::intersect(SDL_Rect &A, SDL_Rect &B, int* x , int* y)
00219 {
00220         return intersectX(A,B,x) && intersectY(A,B,y);
00221 }
00222 
00223 bool glfuncs::intersectX(SDL_Rect &A, SDL_Rect &B, int* x)
00224 {
00225         bool returnme;
00226         //The sides of the rectangles
00227     int leftA, leftB;
00228     int rightA, rightB;
00229         
00230         //Calculate the sides of rect A
00231     leftA = A.x;
00232     rightA = A.x + A.w;
00233 
00234         //Calculate the sides of rect B
00235     leftB = B.x;
00236     rightB = B.x + B.w;
00237 
00238         //If any of the sides from A are outside of B
00239     if( rightA <= leftB || leftA >= rightB )
00240                 returnme = false;
00241         else 
00242                 returnme = true;
00243 
00244         if(x != NULL)
00245         {
00246                 int centerAx = A.x + A.w/2;
00247                 int centerBx = B.x + B.w/2;
00248 
00249                 // this corresponds to the direction 
00250                 // b must be moved
00251                 bool left;
00252 
00253                 if(returnme)
00254                         left = (centerAx >= centerBx);
00255                 else
00256                         left = (centerAx <= centerBx);
00257                 
00258                 //this is the amount b needs to be moved
00259                 *x = min(abs(leftB-rightA),abs(leftA-rightB));
00260                 
00261                 // make sure the sign is right
00262                 if(left)
00263                         *x = -(*x);
00264         }
00265         return returnme;
00266 
00267 }
00268 bool glfuncs::intersectY(SDL_Rect &A, SDL_Rect &B, int* y)
00269 {
00270         bool returnme;
00271         //The sides of the rectangles
00272         int topA, topB;
00273     int bottomA, bottomB;
00274 
00275         //Calculate the sides of rect A
00276         topA = A.y;
00277     bottomA = A.y + A.h;
00278         
00279     //Calculate the sides of rect B
00280     topB = B.y;
00281     bottomB = B.y + B.h;
00282 
00283 
00284         //If any of the sides from A are outside of B
00285     if( bottomA <= topB || topA >= bottomB )
00286                 returnme = false;
00287         else 
00288                 returnme = true;
00289 
00290         if(y != NULL)
00291         {
00292                 
00293                 int centerAy = A.y + A.h/2;
00294                 int centerBy = B.y + B.h/2;
00295 
00296                 // this corresponds to the direction
00297                 // b must be moved
00298                 bool up;
00299                 
00300                 if(returnme)
00301                         up = (centerAy >= centerBy);
00302                 else
00303                         up = (centerAy <= centerBy);
00304 
00305                 //this is the amount b needs to be moved
00306                 *y = min(abs(bottomB-topA),abs(bottomA-topB));
00307                 
00308                 // make sure the sign is right
00309                 if(up)
00310                         *y = -(*y);
00311 
00312                 
00313         }
00314 
00315         
00316 
00317         return returnme;
00318 }
00319 
00320 /* Taken from http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=17 */
00321 GLuint glfuncs::buildFont(double scale, double width, double height, int fontTexture)                   // Build Our Bitmap Font
00322 {
00323         GLuint base;
00324 
00325         double  cx;                                                                                     // Holds Our X Character Coord
00326         double  cy;                                                                                     // Holds Our Y Character Coord
00327 
00328         base=glGenLists(96);                                                            // Creating 256 Display Lists
00329         glBindTexture(GL_TEXTURE_2D, fontTexture);                      // Select Our Font Texture
00330 
00331         double invW = 0.0625;
00332         double invH = 0.125;
00333 
00334         for (int loop=0; loop<96; loop++)                                               // Loop Through All 256 Lists
00335         {
00336                 cx=(loop%16)*invW;                                              // X Position Of Current Character
00337                 cy=(loop/16)*invH;                                              // Y Position Of Current Character
00338 
00339                 glNewList(base+loop,GL_COMPILE);                                // Start Building A List
00340                         glBegin(GL_QUADS);                                                      // Use A Quad For Each Character
00341                                 glTexCoord2f(cx,cy+invH);                       // Texture Coord (Bottom Left)
00342                                 glVertex2i(0,height*scale);                                             // Vertex Coord (Bottom Left)
00343                                 glTexCoord2f(cx+invW,cy+invH);  // Texture Coord (Bottom Right)
00344                                 glVertex2i(width*scale,height*scale);                                           // Vertex Coord (Bottom Right)
00345                                 glTexCoord2f(cx+invW,cy);                       // Texture Coord (Top Right)
00346                                 glVertex2i(width*scale,0);                                              // Vertex Coord (Top Right)
00347                                 glTexCoord2f(cx,cy);                                    // Texture Coord (Top Left)
00348                                 glVertex2i(0,0);                                                // Vertex Coord (Top Left)
00349                         glEnd();                                                                        // Done Building Our Quad (Character)
00350                         glTranslated(width*scale-1,0,0);                                                // Move To The Right Of The Character
00351                 glEndList();                                                                    // Done Building The Display List
00352         }                                                                                                       // Loop Until All 256 Are Built
00353 
00354         return base;
00355 
00356         /*
00357         SDL_SysWMinfo info;
00358         SDL_VERSION(&info.version);
00359         SDL_GetWMInfo(&info);
00360 
00361         HWND hWnd = info.window;
00362 
00363         HDC hDC = GetDC(hWnd); 
00364 
00365         HFONT   font;                                                                           // Windows Font ID
00366         HFONT   oldfont;                                                                        // Used For Good House Keeping
00367 
00368         GLuint base = glGenLists(96);                           // Storage For 96 Characters
00369 
00370         font = CreateFont(      -1*height,                                              // Height Of Font
00371                                                 0,                                                              // Width Of Font
00372                                                 0,                                                              // Angle Of Escapement
00373                                                 0,                                                              // Orientation Angle
00374                                                 FW_BOLD,                                                // Font Weight
00375                                                 FALSE,                                                  // Italic
00376                                                 FALSE,                                                  // Underline
00377                                                 FALSE,                                                  // Strikeout
00378                                                 ANSI_CHARSET,                                   // Character Set Identifier
00379                                                 OUT_TT_PRECIS,                                  // Output Precision
00380                                                 CLIP_DEFAULT_PRECIS,                    // Clipping Precision
00381                                                 ANTIALIASED_QUALITY,                    // Output Quality
00382                                                 FF_DONTCARE|DEFAULT_PITCH,              // Family And Pitch
00383                                                 "Courier New");                                 // Font Name
00384 
00385         oldfont = (HFONT)SelectObject(hDC, font);           // Selects The Font We Want
00386         wglUseFontBitmaps(hDC, 32, 96, base);                           // Builds 96 Characters Starting At Character 32
00387         SelectObject(hDC, oldfont);                                                     // Selects The Font We Want
00388         DeleteObject(font);                                                                     // Delete The Font
00389 
00390         return base;
00391         */
00392 }
00393 
00394 /* Taken from http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=17 */
00395 GLvoid glfuncs::killFont()                                                                      // Delete The Font List
00396 {
00397 
00398         
00399         glDeleteLists(_bigBase, 96);                                                    // Delete All 96 Characters
00400         glDeleteLists(_smallBase, 96);
00401 }
00402 
00403 /* Taken from http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=17 */
00404 GLvoid glfuncs::glPrint(GLint x, GLint y, std::string text, bool small)
00405 {
00406         // FIXME: HACK!!!!!!
00407         int height;
00408         int width;
00409 
00410         if(small) {
00411                 glBindTexture(GL_TEXTURE_2D, _smallFont);                               // Select Our Font Texture
00412                 height = Screen::height();
00413                 width = Screen::width();
00414         }
00415         else {
00416                 glBindTexture(GL_TEXTURE_2D, _bigFont);
00417                 height = Screen::height();
00418                 width = Screen::width();
00419         }
00420 
00421         glDisable(GL_DEPTH_TEST);                                                       // Disables Depth Testing
00422         glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
00423         glPushMatrix();                                                                         // Store The Projection Matrix
00424         glLoadIdentity();                                                                       // Reset The Projection Matrix
00425         glOrtho(0,width,height,0,-1,1);                                         // Set Up An Ortho Screen
00426         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
00427         glPushMatrix();                                                                         // Store The Modelview Matrix
00428         glLoadIdentity();                                                                       // Reset The Modelview Matrix
00429 
00430         glTranslated(x,y,0);                                                                    // Position The Text (0,0 - Bottom Left)
00431 
00432         if(small)
00433                 glListBase(_smallBase-32);
00434         else
00435                 glListBase(_bigBase-32);
00436 
00437         glCallLists(strlen(text.c_str()),GL_UNSIGNED_BYTE,text.c_str());        // Write The Text To The Screen
00438 
00439         glMatrixMode(GL_PROJECTION);                                            // Select The Projection Matrix
00440         glPopMatrix();                                                                          // Restore The Old Projection Matrix
00441         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
00442         glPopMatrix();                                                                          // Restore The Old Projection Matrix
00443         glEnable(GL_DEPTH_TEST);                                                        // Enables Depth Testing
00444 
00445         
00446 
00447         /*
00448 
00449         if (text == "")                                                                 // If There's No Text
00450                 return;                                                                                 // Do Nothing
00451 
00452         glPushAttrib(GL_LIST_BIT);                                                      // Pushes The Display List Bits
00453 
00454         if(small)
00455                 glListBase(_small - 32);
00456         else
00457                 glListBase(_base - 32);                                                         // Sets The Base Character to 32
00458 
00459         glCallLists(strlen(text.c_str()), GL_UNSIGNED_BYTE, text.c_str());      // Draws The Display List Text
00460         glPopAttrib();                                                                          // Pops The Display List Bits
00461         */
00462 }
00463 
00464 
00465 int glfuncs::loadTexture(std::string filename, GLfloat coords[4], SDL_Rect & rect)
00466 {
00467         SDL_Surface *surface = load_image(filename);
00468         rect.x = 0;
00469     rect.y = 0;
00470     rect.w = surface->w;
00471     rect.h = surface->h;
00472         int texture = SDL_GL_LoadTexture(surface,coords);
00473         SDL_FreeSurface(surface);
00474         return texture;
00475 }

Generated on Fri May 5 00:20:18 2006 for ProjectX by  doxygen 1.4.6-NO