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
00023
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
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
00124 w = power_of_two(surface->w);
00125 h = power_of_two(surface->h);
00126 texcoord[0] = 0.0f;
00127 texcoord[1] = 0.0f;
00128 texcoord[2] = (GLfloat)surface->w / w;
00129 texcoord[3] = (GLfloat)surface->h / h;
00130
00131 image = SDL_CreateRGBSurface(
00132 SDL_SWSURFACE,
00133 w, h,
00134 32,
00135 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
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
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
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
00166 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
00167 SDL_SetAlpha(surface, saved_flags, saved_alpha);
00168 }
00169
00170
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);
00184
00185 return texture;
00186 }
00187
00188 SDL_Surface *glfuncs::load_image( std::string filename )
00189 {
00190
00191 SDL_Surface* loadedImage = NULL;
00192
00193
00194 SDL_Surface* optimizedImage = NULL;
00195
00196
00197 loadedImage = IMG_Load( filename.c_str() );
00198
00199
00200 if( loadedImage != NULL )
00201 {
00202
00203 optimizedImage = SDL_DisplayFormatAlpha( loadedImage );
00204
00205 SDL_FreeSurface( loadedImage );
00206 }
00207
00208
00209 return optimizedImage;
00210 }
00211
00212
00213
00214
00215
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
00227 int leftA, leftB;
00228 int rightA, rightB;
00229
00230
00231 leftA = A.x;
00232 rightA = A.x + A.w;
00233
00234
00235 leftB = B.x;
00236 rightB = B.x + B.w;
00237
00238
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
00250
00251 bool left;
00252
00253 if(returnme)
00254 left = (centerAx >= centerBx);
00255 else
00256 left = (centerAx <= centerBx);
00257
00258
00259 *x = min(abs(leftB-rightA),abs(leftA-rightB));
00260
00261
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
00272 int topA, topB;
00273 int bottomA, bottomB;
00274
00275
00276 topA = A.y;
00277 bottomA = A.y + A.h;
00278
00279
00280 topB = B.y;
00281 bottomB = B.y + B.h;
00282
00283
00284
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
00297
00298 bool up;
00299
00300 if(returnme)
00301 up = (centerAy >= centerBy);
00302 else
00303 up = (centerAy <= centerBy);
00304
00305
00306 *y = min(abs(bottomB-topA),abs(bottomA-topB));
00307
00308
00309 if(up)
00310 *y = -(*y);
00311
00312
00313 }
00314
00315
00316
00317 return returnme;
00318 }
00319
00320
00321 GLuint glfuncs::buildFont(double scale, double width, double height, int fontTexture)
00322 {
00323 GLuint base;
00324
00325 double cx;
00326 double cy;
00327
00328 base=glGenLists(96);
00329 glBindTexture(GL_TEXTURE_2D, fontTexture);
00330
00331 double invW = 0.0625;
00332 double invH = 0.125;
00333
00334 for (int loop=0; loop<96; loop++)
00335 {
00336 cx=(loop%16)*invW;
00337 cy=(loop/16)*invH;
00338
00339 glNewList(base+loop,GL_COMPILE);
00340 glBegin(GL_QUADS);
00341 glTexCoord2f(cx,cy+invH);
00342 glVertex2i(0,height*scale);
00343 glTexCoord2f(cx+invW,cy+invH);
00344 glVertex2i(width*scale,height*scale);
00345 glTexCoord2f(cx+invW,cy);
00346 glVertex2i(width*scale,0);
00347 glTexCoord2f(cx,cy);
00348 glVertex2i(0,0);
00349 glEnd();
00350 glTranslated(width*scale-1,0,0);
00351 glEndList();
00352 }
00353
00354 return base;
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 }
00393
00394
00395 GLvoid glfuncs::killFont()
00396 {
00397
00398
00399 glDeleteLists(_bigBase, 96);
00400 glDeleteLists(_smallBase, 96);
00401 }
00402
00403
00404 GLvoid glfuncs::glPrint(GLint x, GLint y, std::string text, bool small)
00405 {
00406
00407 int height;
00408 int width;
00409
00410 if(small) {
00411 glBindTexture(GL_TEXTURE_2D, _smallFont);
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);
00422 glMatrixMode(GL_PROJECTION);
00423 glPushMatrix();
00424 glLoadIdentity();
00425 glOrtho(0,width,height,0,-1,1);
00426 glMatrixMode(GL_MODELVIEW);
00427 glPushMatrix();
00428 glLoadIdentity();
00429
00430 glTranslated(x,y,0);
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());
00438
00439 glMatrixMode(GL_PROJECTION);
00440 glPopMatrix();
00441 glMatrixMode(GL_MODELVIEW);
00442 glPopMatrix();
00443 glEnable(GL_DEPTH_TEST);
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
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 }