1 /***************************************************************************
2 * Copyright (C) 2005 by Dimitris Saougos & Filippos Papadopoulos *
3 * <psybases@gmail.com> *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU Library General Public License as *
7 * published by the Free Software Foundation; either version 2 of the *
8 * License, or (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU Library General Public *
16 * License along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
22 // #include <X11/Xlib.h>
23 // #include <X11/extensions/xf86vmode.h>
24 #include <FTGL/FTGLTextureFont.h>
30 // #include <SDL/SDL_thread.h>
37 // using namespace Amaltheia;
38 extern float z_order; //for Sprite
39 static bool supportsAnisotropic = false;
40 static GLfloat maxAnisotropySupported = 0.0;
41 typedef unsigned long COLOUR;
43 colour COLOUR_RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a )
55 inline COLOUR CLR_RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a )
57 return ( ( COLOUR ) ( ( ( ( a ) & 0xff ) << 24 ) | ( ( ( r ) & 0xff ) << 16 ) | ( ( ( g ) & 0xff ) << 8 ) | ( ( b ) & 0xff ) ) );
62 inline void transform_colourv( float *v, COLOUR col )
65 int mask = 0x000000ff;
76 v[ 3 ] = ( float ) a / 255.0f;
77 v[ 2 ] = ( float ) b / 255.0f;
78 v[ 1 ] = ( float ) g / 255.0f;
79 v[ 0 ] = ( float ) r / 255.0f;
85 float rad( float deg )
87 return ( deg * M_PI ) / 180.f;
90 float deg( float rad )
92 return ( rad * 180.0f ) / M_PI;
96 inline GLboolean queryExtension(char *extName)
98 char *p = (char *) glGetString(GL_EXTENSIONS);
101 char *end = p + strlen(p);
106 if((strlen(extName) == n) && (strncmp(extName, p, n) == 0))
121 FTGLTextureFont *font;
128 Font::Font() : imp( new FontImp() )
140 Font::Font(const char *name, int size, Graphics *g) : imp( new FontImp() )
144 imp->fontSize = size;
145 imp->font = new FTGLTextureFont(name);
146 imp->font->FaceSize(size);
147 imp->font->CharMap(ft_encoding_unicode);
148 imp->fontSize = size;
150 this->fontSize = size;
151 font = new FTGLTextureFont(name);
152 font->FaceSize(size);
153 font->CharMap(ft_encoding_unicode);
158 void Font::print( const wchar_t *str, int x1, int y1, int x2, int y2, colour c )
160 imp->g->enter2dMode();
161 glColor4f( c.r, c.g, c.b, c.a);
162 float h= imp->font->LineHeight()*0.64f; /* factor 0.64*/
163 glTranslatef(x1, y1 + h, 0);
164 glScalef(1.0, -1.0, 1.0);
165 imp->font->Render(str);
166 // ft_print( our_font, x1 , g->getHeight() - y1 - fontSize, str);
167 imp->g->leave2dMode();
170 void Font::print( char *str, int x1, int y1, int x2, int y2, colour c )
172 imp->g->enter2dMode();
173 glColor4f( c.r, c.g, c.b, c.a);
174 float h= imp->font->LineHeight()*0.64f; /* factor 0.64*/
175 glTranslatef(x1, y1 + h, 0);
176 glScalef(1.0, -1.0, 1.0);
177 imp->font->Render(str);
178 // ft_print( our_font, x1 , g->getHeight() - y1 - fontSize, str);
179 imp->g->leave2dMode();
183 bool Graphics::oneGraphics = false;
192 Graphics::Graphics( int w, int h, int bpp, bool fullScreen, bool a, bool l ) : imp(new GraphicsImp())
196 std::cerr << "Only one graphics object allowed!\n";
203 this->fullScreen = fullScreen;
209 cmode = AM_CULL_BACK;
229 this->currentTexture = 0;
234 Graphics::~Graphics( void )
236 //glDeleteBuffers(1, &gpuBuf); // mono gia OpenGL 1.5
244 void Graphics::setHeight( int h)
250 int Graphics::getHeight()
255 void Graphics::setWidth(int w)
260 int Graphics::getWidth()
265 void Graphics::setBpp( int b )
270 int Graphics::getBpp()
275 void Graphics::enableVsync( bool v )
280 bool Graphics::isVsync()
286 void Graphics::enableFullScreen( bool f )
291 bool Graphics::isFullScreen( void )
297 void Graphics::enableLighting( bool l )
302 glEnable( GL_LIGHTING );
304 glDisable( GL_LIGHTING );
310 bool Graphics::isLighting()
315 void Graphics::enableAlpha( bool a )
319 glEnable( GL_BLEND );
321 glDisable( GL_BLEND );
327 bool Graphics::isAlpha( void )
332 void Graphics::setTexture( Texture *t )
338 glBindTexture( GL_TEXTURE_2D, t->gl_Tex );
343 Texture* Graphics::getTexture(void)
345 return currentTexture;
349 int Graphics::createDisplay()
353 /* Information about the current video settings. */
354 const SDL_VideoInfo * info = 0;
355 /* Flags we will pass into SDL_SetVideoMode. */
358 // putenv("__GL_SYNC_TO_VBLANK=1");
360 /* First, initialize SDL's video subsystem. */
361 if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ) < 0 )
364 fprintf( stderr, "Video initialization failed: %s\n", SDL_GetError() );
368 /* Let's get some video information. */
369 info = SDL_GetVideoInfo( );
373 std::cerr << "Video query failed: " << SDL_GetError() << std::endl;
378 * Now, we want to setup our requested
379 * window attributes for our OpenGL window.
380 * We want *at least* 5 bits of red, green
381 * and blue. We also want at least a 16-bit
384 * The last thing we do is request a double
385 * buffered window. '1' turns on double
386 * buffering, '0' turns it off.
388 * Note that we do not use SDL_DOUBLEBUF in
389 * the flags to SDL_SetVideoMode. That does
390 * not affect the GL attribute state, only
391 * the standard 2D blitting setup.
393 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
394 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
395 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
396 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, bpp );
397 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
399 flags = SDL_OPENGL | ( fullScreen ? SDL_FULLSCREEN : 0 );
404 if ( ( imp->screen = SDL_SetVideoMode( width, height, bpp, flags ) ) == 0 )
407 * This could happen for a variety of reasons,
408 * including DISPLAY not being set, the specified
409 * resolution not being available, etc.
411 std::cerr << "Video mode set failed: " << SDL_GetError() << std::endl;
417 ilutRenderer(ILUT_OPENGL);
419 SDL_SetGamma(1.8, 1.8, 1.8);
421 float ratio = ( float ) width / ( float ) height;
422 /* Our shading model--Gouraud (smooth). */
423 glShadeModel( GL_SMOOTH );
424 glClearDepth( 1.0f );
426 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
428 // glDepthFunc( GL_LEQUAL );
429 /* Set the clear color. */
430 glClearColor( bgcolour[ 0 ], bgcolour[ 1 ], bgcolour[ 2 ], bgcolour[ 3 ] );
431 glMatrixMode( GL_PROJECTION );
434 glViewport( 0, 0, width, height );
435 gluPerspective( 45.0, ratio, 1.0, 10000.0 );
437 /* Culling. Boh8aei sto Blending*/
438 glCullFace( GL_BACK );
439 /* Polygons whose vertices are in counterclockwise order are called frontfacing but dx thinks different ?*/
440 glFrontFace( GL_CW );
442 glEnable( GL_CULL_FACE );
445 glEnable( GL_DEPTH_TEST );
447 glEnable( GL_TEXTURE_2D );
449 glEnable( GL_BLEND );
451 glEnable( GL_LIGHTING );
453 //TODO: 8a prepei na oristei synarthsh setMaterial...
454 float diffuse[] = {1.0, 1.0, 1.0, 1.0};
455 float specular[] = {0.0, 0.0, 0.0, 0.0};
456 float ambient[] = { 0.0, 0.0, 0.0, 0.0};
457 float emissive[] = {0.0, 0.0, 0.0, 0.0};
458 glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse );
459 glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, specular );
460 glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, emissive );
461 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ambient );
464 if ( !queryExtension( "GL_EXT_texture_filter_anisotropic" ) )
465 std::cout << "Extension GL_EXT_texture_filter_anisotropic not found...\n";
468 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropySupported);
469 std::cout << "max Anisotropy supported = " << maxAnisotropySupported << '\n';
470 supportsAnisotropic = true;
473 /*glGenBuffers(1, &gpuBuf); // mono gia OpenGL 1.5
474 glBindBuffer(GL_ARRAY_BUFFER, gpuBuf); // mono gia OpenGL 1.5
475 glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, ¶meter); // mono gia OpenGL 1.5
476 printf("Buffer size is %d \n", parameter); */
477 if ( !queryExtension( "GL_ARB_point_sprite" ) )
478 std::cout << "Extension GL_ARB_point_sprite not found...\n";
481 // This is how will our point sprite's size will be modified by
482 // distance from the viewer
483 float quadratic[] = { 1.0f, 0.0f, 0.01f };
484 glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic );
485 // Query for the max point size supported by the hardware
487 glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize );
488 // Clamp size to 100.0f or the sprites could get a little too big on some
489 // of the newer graphic cards. My ATI card at home supports a max point
492 // The alpha of a point is calculated to allow the fading of points
493 // instead of shrinking them past a defined threshold size. The threshold
494 // is defined by GL_POINT_FADE_THRESHOLD_SIZE_ARB and is not clamped to
495 // the minimum and maximum point sizes.
496 glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, 60.0f );
497 glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 10.0f );
498 glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, maxSize );
500 // Specify point sprite texture coordinate replacement mode for each
502 glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
503 glEnable( GL_POINT_SPRITE_ARB );
504 glEnable( GL_ARB_point_sprite );
507 std::cout << "OpenGL Version =" << glGetString( GL_VERSION ) << std::endl;
508 int _red,_green,_blue, _alpha, _depth, _stencil;
509 glGetIntegerv(GL_RED_BITS, &_red);
510 glGetIntegerv(GL_GREEN_BITS, &_green);
511 glGetIntegerv(GL_BLUE_BITS, &_blue);
512 glGetIntegerv(GL_ALPHA_BITS, &_alpha);
513 std::cout << "Color Buffers RGBA bits = " << _red << _green << _blue << _alpha << std::endl;
514 glGetIntegerv(GL_DEPTH_BITS, &_depth);
515 std::cout << "Depth Buffer bits = " << _depth << "\n";
516 glGetIntegerv(GL_STENCIL_BITS, &_stencil);
517 std::cout << "Stencil Buffer bits = " << _stencil << "\n";
519 glGetIntegerv(GL_AUX_BUFFERS, &_aux);
520 std::cout << "Aux buffers = " << _aux << "\n";
521 // putenv("__GL_SYNC_TO_VBLANK=1");
523 // XF86VidModeModeLine mode;
526 // Display *d = XOpenDisplay(NULL);
527 /*Bool XF86VidModeGetModeLine(
530 int *dotclock_return ,
531 XF86VidModeModeLine *modeline );
533 // printf("d=%p\n",d);
534 // if(XF86VidModeGetModeLine(d, 0, &unused, &mode))
537 // printf("OK %d mexri %d\n", mode.hsyncstart, mode.hsyncend);
540 // printf("not ok\n");
541 // glXWaitVideoSyncSGI();
542 // GLX_SGI_video_sync
544 // glXGetVideoSyncSGI(&k);
545 // printf("k=%d\n", k);
546 glMatrixMode( GL_MODELVIEW );
553 void Graphics::beginScene( void )
555 /* Clear the color and depth buffers. */
556 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
557 glMatrixMode( GL_MODELVIEW );
559 //gia symbatothta me to DirectX
560 glScalef( -1.0, 1.0, 1.0 );
567 void Graphics::endScene()
569 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
571 //glXSwapIntervalSGI(1);
572 SDL_GL_SwapBuffers();
581 void _gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
582 GLdouble centerx, GLdouble centery, GLdouble centerz,
583 GLdouble upx, GLdouble upy, GLdouble upz )
586 GLdouble x[ 3 ], y[ 3 ], z[ 3 ];
589 /* Make rotation matrix */
592 z[ 0 ] = ( eyex - centerx );
593 z[ 1 ] = ( eyey - centery );
594 z[ 2 ] = ( eyez - centerz );
595 mag = sqrt( z[ 0 ] * z[ 0 ] + z[ 1 ] * z[ 1 ] + z[ 2 ] * z[ 2 ] );
597 { /* mpichler, 19950515 */
608 /* X vector = Y cross Z */
609 x[ 0 ] = y[ 1 ] * z[ 2 ] - y[ 2 ] * z[ 1 ];
610 x[ 1 ] = y[ 2 ] * z[ 0 ] - y[ 0 ] * z[ 2 ] ;
611 x[ 2 ] = y[ 0 ] * z[ 1 ] - y[ 1 ] * z[ 0 ];
613 /* Recompute Y = Z cross X */
614 y[ 0 ] = z[ 1 ] * x[ 2 ] - z[ 2 ] * x[ 1 ];
615 y[ 1 ] = -z[ 0 ] * x[ 2 ] + z[ 2 ] * x[ 0 ];
616 y[ 2 ] = z[ 0 ] * x[ 1 ] - z[ 1 ] * x[ 0 ];
618 /* mpichler, 19950515 */
619 /* cross product gives area of parallelogram, which is < 1.0 for
620 * non-perpendicular unit-length vectors; so normalize x, y here
623 mag = sqrt( x[ 0 ] * x[ 0 ] + x[ 1 ] * x[ 1 ] + x[ 2 ] * x[ 2 ] );
631 mag = sqrt( y[ 0 ] * y[ 0 ] + y[ 1 ] * y[ 1 ] + y[ 2 ] * y[ 2 ] );
639 #define M(row,col) m[col*4+row]
643 M( 0, 3 ) = -( x[ 0 ] * eyex + x[ 1 ] * eyey + x[ 2 ] * eyez );
648 M( 1, 3 ) = -( y[ 0 ] * eyex + y[ 1 ] * eyey + y[ 2 ] * eyez );
653 M( 2, 3 ) = -( z[ 0 ] * eyex + z[ 1 ] * eyey + z[ 2 ] * eyez );
680 glScalef( -1.0, 1.0, 1.0 );
682 glScalef( -1.0, 1.0, 1.0 );
688 int Graphics::setCamera( float camx, float camy, float camz,
689 float lookx, float looky, float lookz,
690 float upx, float upy, float upz )
693 _gluLookAt( camx, camy, camz, lookx, looky, lookz, upx, upy, upz );
711 struct camera Graphics::getCamera()
719 int Graphics::renderTriangle(vertex v1, vertex v2, vertex v3 )
721 // GLfloat colour[ 4 ];
724 std::cout << "DEBUG: oust...!\n";
730 // glPushAttrib(GL_ALL_ATTRIB_BITS); //kyriws gia na epanaferoume to xrwma
731 glBegin( GL_TRIANGLES );
733 // transform_colourv( colour, v1.col );
734 glColor4f( v1.col.r, v1.col.g, v1.col.b, v1.col.a);
735 glNormal3f( v1.nx, v1.ny, v1.nz );
736 glTexCoord2f( v1.u, 1.0 - v1.v );
737 glVertex3f( v1.x, v1.y, v1.z );
739 // transform_colourv( colour, v2.col );
740 // glColor4f( colour[ 0 ], colour[ 1 ], colour[ 2 ], colour[ 3 ] );
741 glColor4f( v2.col.r, v2.col.g, v2.col.b, v2.col.a);
742 glNormal3f( v2.nx, v2.ny, v2.nz );
743 glTexCoord2f( v2.u, 1.0 - v2.v );
744 glVertex3f( v2.x, v2.y, v2.z );
746 glColor4f( v3.col.r, v3.col.g, v3.col.b, v3.col.a);
747 glNormal3f( v3.nx, v3.ny, v3.nz );
748 glTexCoord2f( v3.u, 1.0 - v3.v );
749 glVertex3f( v3.x, v3.y, v3.z );
753 //isos na prepei na epanafero pisw to arxiko xrwma...
760 int Graphics::setWorld( float transx, float transy, float transz,
761 float rotx, float roty, float rotz, float scalex, float scaley, float scalez,
764 glMatrixMode( GL_MODELVIEW );
767 struct camera c = getCamera();
768 setCamera( c.camx, c.camy, c.camz, c.lookx, c.looky, c.lookz, c.upx, c.upy, c.upz );
770 glScalef( -1.0, 1.0, 1.0 ); //gia symbatothta me to DirectX
771 glTranslatef( transx, transy, transz );
773 if(rotationOrder == AM_XYZ)
775 glRotatef( rotz, 0, 0, 1 );
776 glRotatef( roty, 0, 1, 0 );
777 glRotatef( rotx, 1, 0, 0 );
779 else if(rotationOrder == AM_XZY)
781 glRotatef( roty, 0, 1, 0 );
782 glRotatef( rotz, 0, 0, 1 );
783 glRotatef( rotx, 1, 0, 0 );
786 else if(rotationOrder == AM_YZX)
788 glRotatef( rotx, 1, 0, 0 );
789 glRotatef( rotz, 0, 0, 1 );
790 glRotatef( roty, 0, 1, 0 );
792 else if(rotationOrder == AM_YXZ)
794 glRotatef( rotz, 0, 0, 1 );
795 glRotatef( rotx, 1, 0, 0 );
796 glRotatef( roty, 0, 1, 0 );
799 else if(rotationOrder == AM_ZXY)
801 glRotatef( roty, 0, 1, 0 );
802 glRotatef( rotx, 1, 0, 0 );
803 glRotatef( rotz, 0, 0, 1 );
807 glRotatef( rotx, 1, 0, 0 );
808 glRotatef( roty, 0, 1, 0 );
809 glRotatef( rotz, 0, 0, 1 );
812 glScalef( scalex, scaley, scalez );
821 int Graphics::setWorld2( float transx, float transy, float transz,
822 float rotx, float roty, float rotz, float scalex, float scaley, float scalez )
824 glMatrixMode( GL_MODELVIEW );
828 struct camera c = getCamera();
829 setCamera( c.camx, c.camy, c.camz, c.lookx, c.looky, c.lookz, c.upx, c.upy, c.upz );
831 glScalef( -1.0, 1.0, 1.0 ); //gia symbatothta me to DirectX
832 glTranslatef( transx, transy, transz );
833 glRotatef( roty, 0, 1, 0 );
834 glRotatef( rotz, 0, 0, 1 );
835 glRotatef( rotx, 1, 0, 0 );
836 glScalef( scalex, scaley, scalez );
848 void Graphics::setBackground( colour colour )
850 // transform_colourv( bgcolour, colour );
851 // printf( "(%f, %f, %f ,%f)\n", bgcolour[ 0 ], bgcolour[ 1 ], bgcolour[ 2 ], bgcolour[ 3 ] );
852 bgcolour[0] = colour.r;
853 bgcolour[1] = colour.g;
854 bgcolour[2] = colour.b;
855 bgcolour[3] = colour.a;
856 glClearColor( ( float ) bgcolour[ 0 ], ( float ) bgcolour[ 1 ], ( float ) bgcolour[ 2 ], ( float ) bgcolour[ 3 ] );
862 colour Graphics::getBackground( void )
875 void Graphics::project( float objx, float objy, float objz,
876 //const double modelMatrix[16], const double projMatrix[16], const int viewport[4],
877 float *winx, float *winy, float *winz )
883 GLdouble mvmatrix[ 16 ], projmatrix[ 16 ];
885 glGetIntegerv ( GL_VIEWPORT, viewport );
886 glGetDoublev ( GL_MODELVIEW_MATRIX, mvmatrix );
887 glGetDoublev ( GL_PROJECTION_MATRIX, projmatrix );
889 gluProject( objx, objy, objz, mvmatrix, projmatrix, viewport,
890 &_winx, &_winy, &_winz );
893 *winy = viewport[ 3 ] - ( int ) _winy - 1;
900 void Graphics::unproject( float winx, float winy, float winz,
901 //const double modelMatrix[16], const double projMatrix[16], const int viewport[4],
902 float *objx, float *objy, float *objz )
909 GLdouble mvmatrix[ 16 ], projmatrix[ 16 ];
911 glGetIntegerv ( GL_VIEWPORT, viewport );
912 glGetDoublev ( GL_MODELVIEW_MATRIX, mvmatrix );
913 glGetDoublev ( GL_PROJECTION_MATRIX, projmatrix );
915 realy = viewport[ 3 ] - ( int ) winy - 1;
916 // std::cout << "realy=" <<realy << "\n";
918 gluUnProject( winx, realy, winz,
919 mvmatrix, projmatrix, viewport,
920 &_objx, &_objy, &_objz );
931 void Graphics::enableCursor( bool state )
935 SDL_ShowCursor( SDL_ENABLE );
937 SDL_ShowCursor( SDL_DISABLE );
941 bool Graphics::isCursor()
948 void Graphics::planeIntersect( float a, float b, float c, float d,
949 float p1x, float p1y, float p1z, float p2x, float p2y, float p2z,
950 float *poutx, float *pouty, float *poutz )
952 float numerator = -( a * p1x + b * p1y + c * p1z + d );
953 if ( numerator == 0 )
962 float denominator = a * ( p2x - p1x ) + b * ( p2y - p1y ) + c * ( p2z - p1z );
963 if ( denominator == 0 )
968 printf("denominator==0!!!\n");
974 float t = numerator / denominator;
975 ( *poutx ) = p1x + t * ( p2x - p1x );
976 ( *pouty ) = p1y + t * ( p2y - p1y );
977 ( *poutz ) = p1z + t * ( p2z - p1z );
987 void Graphics::setLight( int numLight, const light& l )
989 GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
990 GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0};
991 GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0};
992 GLfloat position[] = {0.0, 0.0, 1.0, 0.0};
993 GLenum enm = GL_LIGHT0;
995 if(numLight == 0) enm = GL_LIGHT0;
996 else if(numLight == 1) enm = GL_LIGHT1;
997 else if(numLight == 2) enm = GL_LIGHT2;
998 else if(numLight == 3) enm = GL_LIGHT3;
999 else if(numLight == 4) enm = GL_LIGHT4;
1000 else if(numLight == 5) enm = GL_LIGHT5;
1001 else if(numLight == 6) enm = GL_LIGHT6;
1002 else if(numLight == 7 ) enm = GL_LIGHT7;
1004 // transform_colourv( ambient, l.ambient );
1005 // transform_colourv( diffuse, l.diffuse );
1006 // transform_colourv( specular, l.specular );
1007 ambient[0] = l.ambient.r; ambient[1] = l.ambient.g; ambient[2] = l.ambient.b; ambient[3] = l.ambient.a;
1008 diffuse[0] = l.diffuse.r; diffuse[1] = l.diffuse.g; diffuse[2] = l.diffuse.b; diffuse[3] = l.diffuse.a;
1009 specular[0] = l.specular.r; specular[1] = l.specular.g; specular[2] = l.specular.b; specular[3] = l.specular.a;
1011 if ( l.type == AM_POINT_LIGHT )
1013 position[ 3 ] = 1.0;
1014 position[ 0 ] = l.posx;
1015 position[ 1 ] = l.posy;
1016 position[ 2 ] = l.posz;
1019 if ( l.type == AM_DIRECTIONAL_LIGHT )
1021 //float val = sqrt(l.dirx*l.dirx + l.diry*l.diry + l.dirz*l.dirz);
1022 position[ 3 ] = 0.0;
1023 position[ 0 ] = -l.dirx;
1024 position[ 1 ] = -l.diry;
1025 position[ 2 ] = l.dirz;
1032 glVertex3f(position[0], position[1], position[2]);
1033 glVertex3f(360, 10, 360);
1036 glLightfv( enm, GL_AMBIENT, ambient );
1037 glLightfv( enm, GL_DIFFUSE, diffuse );
1038 glLightfv( enm, GL_SPECULAR, specular );
1039 glLightfv( enm, GL_POSITION, position );
1046 void Graphics::showLight( int numLight, bool state )
1048 GLenum enm = GL_LIGHT0;
1049 if ( numLight == 0 )
1052 if ( numLight == 1 )
1055 if ( numLight == 2 )
1070 void inverseMatrix( double A[16], double B[16])
1092 detA = a11*a22*a33*a44 + a11*a23*a34*a42 + a11*a24*a32*a43 \
1093 +a12*a21*a34*a43 + a12*a23*a31*a44 + a12*a24*a33*a41 \
1094 +a13*a21*a32*a44 + a13*a22*a34*a41 + a13*a24*a31*a42 \
1095 +a14*a21*a33*a42 + a14*a22*a31*a43 + a14*a23*a32*a41 \
1096 -a11*a22*a34*a43 - a11*a23*a32*a44 - a11*a24*a33*a42 \
1097 -a12*a21*a33*a44 - a12*a23*a34*a41 - a12*a24*a31*a43 \
1098 -a13*a21*a34*a42 - a13*a22*a31*a44 - a13*a24*a32*a41 \
1099 -a14*a21*a32*a43 - a14*a22*a33*a41 - a14*a23*a31*a42;
1101 // printf("detA=%f\n",detA);
1103 B[0] = (a22*a33*a44 + a23*a34*a42 + a24*a32*a43 - a22*a34*a43 - a23*a32*a44 - a24*a33*a42)/detA;
1104 B[1] = (a12*a34*a43 + a13*a32*a44 + a14*a33*a42 - a12*a33*a44 - a13*a34*a42 - a14*a32*a43)/detA;
1105 B[2] = (a12*a23*a44 + a13*a24*a42 + a14*a22*a43 - a12*a24*a43 - a13*a22*a44 - a14*a23*a42)/detA;
1106 B[3] = (a12*a24*a33 + a13*a22*a34 + a14*a23*a32 - a12*a23*a34 - a13*a24*a32 - a14*a22*a33)/detA;
1107 B[4] = (a21*a34*a43 + a23*a31*a44 + a24*a33*a41 - a21*a33*a44 - a23*a34*a41 - a24*a31*a43)/detA;
1108 B[5] = (a11*a33*a44 + a13*a34*a41 + a14*a31*a43 - a11*a34*a43 - a13*a31*a44 - a14*a33*a41)/detA;
1109 B[6] = (a11*a24*a43 + a13*a21*a44 + a14*a23*a41 - a11*a23*a44 - a13*a24*a41 - a14*a21*a43)/detA;
1110 B[7] = (a11*a23*a34 + a13*a24*a31 + a14*a21*a33 - a11*a24*a33 - a13*a21*a34 - a14*a23*a31)/detA;
1111 B[8] = (a21*a32*a44 + a22*a34*a41 + a24*a31*a42 - a21*a34*a42 - a22*a31*a44 - a24*a32*a41)/detA;
1112 B[9] = (a11*a34*a42 + a12*a31*a44 + a14*a32*a41 - a11*a32*a44 - a12*a34*a41 - a14*a31*a42)/detA;
1113 B[10] = (a11*a22*a44 + a12*a24*a41 + a14*a21*a42 - a11*a24*a42 - a12*a21*a44 - a14*a22*a41)/detA;
1114 B[11] = (a11*a24*a32 + a12*a21*a34 + a14*a22*a31 - a11*a22*a34 - a12*a24*a31 - a14*a21*a32)/detA;
1115 B[12] = (a21*a33*a42 + a22*a31*a43 + a23*a32*a41 - a21*a32*a43 - a22*a33*a41 - a23*a31*a42)/detA;
1116 B[13] = (a11*a32*a43 + a12*a33*a41 + a13*a31*a42 - a11*a33*a42 - a12*a31*a43 - a13*a32*a41)/detA;
1117 B[14] = (a11*a23*a42 + a12*a21*a43 + a13*a22*a41 - a11*a22*a43 - a12*a23*a41 - a13*a21*a42)/detA;
1118 B[15] = (a11*a22*a33 + a12*a23*a31 + a13*a21*a32 - a11*a23*a32 - a12*a21*a33 - a13*a22*a31)/detA;
1125 void Graphics::drawBillboardParticle(float x, float y, float z, float size, colour col)
1129 glPushAttrib(GL_ALL_ATTRIB_BITS);
1130 glDisable(GL_DEPTH_TEST);
1131 glDepthMask( GL_FALSE );
1133 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
1134 glDisable(GL_CULL_FACE);
1135 glEnable( GL_TEXTURE_2D );
1136 /*********************************/
1137 GLdouble modelview[16], B[16];
1138 // save the current modelview matrix
1140 // get the current modelview matrix
1141 glGetDoublev(GL_MODELVIEW_MATRIX , modelview);
1142 inverseMatrix(modelview, B);
1143 // set the modelview with no rotations and scaling
1145 glLoadMatrixd(modelview);
1146 glTranslatef(x,y,z);
1148 float s2 = size / 2.0;
1149 // transform_colourv(v, col);
1151 glColor4f(col.r, col.g, col.b, col.a);
1152 glTexCoord2f( 0.0, 0.0 ); glVertex3f(-s2,s2,0);
1153 glTexCoord2f( 1.0, 0.0 ); glVertex3f(s2,s2,0);
1154 glTexCoord2f( 1.0, 1.0 ); glVertex3f(s2,-s2,0);
1155 glTexCoord2f( 0.0, 1.0 ); glVertex3f(-s2,-s2,0);
1158 // restores the modelview matrix
1160 /*********************************/
1167 void Graphics::renderParticleArray(particle *array, unsigned int sizeOfArray, int type)
1171 if(type == AM_HARDWARE_PARTICLE)
1173 glPushAttrib(GL_ALL_ATTRIB_BITS);
1174 glEnable(GL_DEPTH_TEST);
1175 glDepthMask( GL_FALSE );
1177 glBlendFunc( GL_DST_ALPHA, GL_ONE );
1179 for(i=0; i < sizeOfArray; i++)
1181 glPointSize( (array[i].size > maxSize ? maxSize : array[i].size) );
1182 glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, (array[i].size > maxSize ? maxSize : array[i].size) );
1184 glColor4f(array[i].col.r, array[i].col.g, array[i].col.b, array[i].col.a);
1185 glVertex3f(array[i].x, array[i].y, array[i].z);
1191 if(type == AM_SOFTWARE_PARTICLE)
1197 }quad_lower_left, quad_lower_right;
1199 glPushAttrib(GL_ALL_ATTRIB_BITS);
1200 glEnable(GL_DEPTH_TEST);
1202 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
1203 glDisable(GL_CULL_FACE);
1204 glEnable( GL_TEXTURE_2D );
1205 glGetFloatv( GL_MODELVIEW_MATRIX, mat );
1207 for(i=0; i < sizeOfArray; i++)
1209 float s2 = array[i].size / 2.0;
1210 quad_lower_left.x = (-s2) * (mat[0] + mat[1]);
1211 quad_lower_left.y = (-s2) * (mat[4] + mat[5]);
1212 quad_lower_left.z = (-s2) * (mat[8] + mat[9]);
1213 quad_lower_right.x = (s2) * (mat[0] - mat[1]);
1214 quad_lower_right.y = (s2) * (mat[4] - mat[5]);
1215 quad_lower_right.z = (s2) * (mat[8] - mat[9]);
1218 glColor4f(array[i].col.r, array[i].col.g, array[i].col.b, array[i].col.a);
1219 glTexCoord2f(0.0, 0.0);
1220 glVertex3f(array[i].x + quad_lower_left.x, array[i].y + quad_lower_left.y, array[i].z + quad_lower_left.z);
1221 glTexCoord2f(1.0, 0.0);
1222 glVertex3f(array[i].x + quad_lower_right.x, array[i].y + quad_lower_right.y, array[i].z + quad_lower_right.z);
1223 glTexCoord2f(1.0, 1.0);
1224 glVertex3f(array[i].x - quad_lower_left.x, array[i].y - quad_lower_left.y, array[i].z - quad_lower_left.z);
1225 glTexCoord2f(0.0, 1.0);
1226 glVertex3f(array[i].x - quad_lower_right.x, array[i].y - quad_lower_right.y, array[i].z - quad_lower_right.z);
1238 void Graphics::renderParticle(float x, float y, float z, float size, colour col, int type)
1240 if(type == AM_HARDWARE_PARTICLE)
1242 glPushAttrib(GL_ALL_ATTRIB_BITS);
1243 glPointSize( (size > maxSize ? maxSize : size) );
1244 glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, (size > maxSize ? maxSize : size) );
1245 glEnable(GL_DEPTH_TEST);
1246 glDepthMask( GL_FALSE );
1248 // glBlendFunc( GL_SRC_ALPHA, GL_ONE );
1249 glBlendFunc( GL_DST_ALPHA, GL_ONE );
1252 // transform_colourv(v, col);
1253 glColor4f(col.r , col.g, col.b, col.a);
1259 if(type == AM_SOFTWARE_PARTICLE)
1267 }quad_lower_left,quad_lower_right;
1269 glPushAttrib(GL_ALL_ATTRIB_BITS);
1270 glEnable(GL_DEPTH_TEST);
1271 // glDepthMask( GL_FALSE );
1273 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
1274 glDisable(GL_CULL_FACE);
1275 glEnable( GL_TEXTURE_2D );
1278 // Get modelview matrix. We will only use the upper left 3x3 part of
1279 // the matrix, which represents the rotation.
1280 glGetFloatv( GL_MODELVIEW_MATRIX, mat );
1282 // 1) & 2) We do it in one swift step:
1283 // Although not obvious, the following six lines represent two matrix/
1284 // vector multiplications. The matrix is the inverse 3x3 rotation
1285 // matrix (i.e. the transpose of the same matrix), and the two vectors
1286 // represent the lower left corner of the quad, PARTICLE_SIZE/2 *
1287 // (-1,-1,0), and the lower right corner, PARTICLE_SIZE/2 * (1,-1,0).
1288 // The upper left/right corners of the quad is always the negative of
1289 // the opposite corners (regardless of rotation).
1290 float s2 = size / 2.0;
1291 quad_lower_left.x = (-s2) * (mat[0] + mat[1]);
1292 quad_lower_left.y = (-s2) * (mat[4] + mat[5]);
1293 quad_lower_left.z = (-s2) * (mat[8] + mat[9]);
1294 quad_lower_right.x = (s2) * (mat[0] - mat[1]);
1295 quad_lower_right.y = (s2) * (mat[4] - mat[5]);
1296 quad_lower_right.z = (s2) * (mat[8] - mat[9]);
1298 // 3) Translate the quad to the correct position in modelview
1299 // space and store its parameters in vertex arrays (we also
1300 // store texture coord and color information for each vertex).
1301 // transform_colourv(v, col);
1303 glColor4f(col.r, col.g, col.b, col.a);
1304 // Lower left corner
1305 glTexCoord2f(0.0, 0.0);
1306 glVertex3f(x + quad_lower_left.x, y + quad_lower_left.y, z + quad_lower_left.z);
1307 // printf("1. %f %f %f\n",x + quad_lower_left.x, y + quad_lower_left.y, z + quad_lower_left.z);
1308 // Lower right corner
1309 glTexCoord2f(1.0, 0.0);
1310 glVertex3f(x + quad_lower_right.x, y + quad_lower_right.y, z + quad_lower_right.z);
1311 // printf("2. %f %f %f\n",x + quad_lower_right.x, y + quad_lower_right.y, z + quad_lower_right.z);
1312 // Upper right corner
1313 glTexCoord2f(1.0, 1.0);
1314 glVertex3f(x - quad_lower_left.x, y - quad_lower_left.y, z - quad_lower_left.z);
1315 // printf("3. %f %f %f\n", x - quad_lower_left.x, y - quad_lower_left.y, z - quad_lower_left.z);
1316 // Upper left corner
1317 glTexCoord2f(0.0, 1.0);
1318 glVertex3f(x - quad_lower_right.x, y - quad_lower_right.y, z - quad_lower_right.z);
1319 // printf("4. %f %f %f\n", x - quad_lower_right.x, y - quad_lower_right.y, z - quad_lower_right.z);
1321 // restores the modelview matrix
1323 /*********************************/
1332 Specifies the field of view angle, in degrees, in the y direction.
1334 Specifies the aspect ratio that determines the field of view in the x direction.
1335 The aspect ratio is the ratio of x (width) to y (height).
1337 Specifies the distance from the viewer to the near clipping plane (always positive).
1339 Specifies the distance from the viewer to the far clipping plane (always positive).
1341 void Graphics::setPerspective(float fov, float ratio, float zNear, float zFar)
1345 glGetIntegerv( GL_MATRIX_MODE, &matrixMode);
1346 glMatrixMode( GL_PROJECTION );
1348 gluPerspective( fov, ratio, zNear, zFar );
1349 glMatrixMode( matrixMode );
1354 void Graphics::renderVertexArray(vertex *array, unsigned int numOfPrimitives, int type)
1357 if(type == AM_TRIANGLE_STRIP)
1358 t = GL_TRIANGLE_STRIP;
1359 else if (type == AM_TRIANGLE_FAN)
1360 t = GL_TRIANGLE_FAN;
1361 else if (type == AM_TRIANGLES)
1363 else if (type == AM_POINT_LIST)
1365 else if (type == AM_LINE_LIST)
1367 else if (type == AM_LINE_STRIP)
1370 // UGLY hack to reverse texture coordinate...implement an operator in struct vertex..?!?
1371 vertex *tmp = new vertex[numOfPrimitives];
1372 memcpy(tmp, array, numOfPrimitives*sizeof(vertex));
1374 for(i=0; i < numOfPrimitives; i++)
1375 tmp[i].v = 1 - tmp[i].v;
1377 glInterleavedArrays( GL_T2F_C4F_N3F_V3F, 0, (void *) tmp);
1378 glDrawArrays( t, 0, numOfPrimitives);
1385 void Graphics::setCullingMode(int mode)
1388 if(mode == AM_CULL_NONE)
1391 glDisable(GL_CULL_FACE );
1399 glEnable( GL_CULL_FACE );
1401 if(mode == AM_CULL_FRONT)
1402 glCullFace(GL_FRONT);
1403 else if (mode == AM_CULL_BACK)
1404 glCullFace(GL_BACK);
1409 int Graphics::getCullingMode()
1416 void Graphics::enter2dMode(void)
1418 glPushAttrib( GL_ALL_ATTRIB_BITS );
1420 glDisable( GL_LIGHTING );
1421 glDisable( GL_DEPTH_TEST );
1422 glDisable( GL_CULL_FACE );
1423 glEnable( GL_TEXTURE_2D );
1425 glViewport( 0, 0, getWidth(), getHeight() );
1427 glMatrixMode( GL_PROJECTION );
1431 glOrtho( 0.0, ( GLdouble ) getWidth(), ( GLdouble ) getHeight(), 0.0, 0.0, 1.0 );
1433 glMatrixMode( GL_MODELVIEW );
1436 // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
1441 void Graphics::leave2dMode(void)
1443 glMatrixMode( GL_MODELVIEW );
1446 glMatrixMode( GL_PROJECTION );
1454 void Graphics::enableDepthBuffer( bool b )
1458 glEnable( GL_DEPTH_TEST );
1460 glDisable( GL_DEPTH_TEST );
1466 bool Graphics::isDepthBuffer()
1473 /*--------------------------------------------------
1475 *-----------------------------------------------------*/
1479 Texture::Texture( char *file, colour key, Graphics *g )
1482 filteringDefinition = filtering = AM_LINEAR;
1484 glEnable( GL_TEXTURE_2D );
1486 colourKeyEnabled = true;
1488 // CreateTexture(&gl_Tex, file, 0);
1489 LoadGLTextures( &gl_Tex, file );
1490 std::cout << "file=" << file << ", gl_Tex=" << gl_Tex << "\n";
1496 Texture::Texture( char *file, Graphics *g)
1500 filteringDefinition = filtering = AM_LINEAR;
1501 glEnable( GL_TEXTURE_2D );
1503 colourKeyEnabled = false;
1504 // CreateTexture(&gl_Tex, file, 0);
1505 LoadGLTextures( &gl_Tex, file );
1506 std::cout << "file=" << file << ", gl_Tex=" << gl_Tex << "\n";
1511 Texture::Texture(void *data, unsigned int w, unsigned int h, int format, int type, Graphics *g)
1514 filteringDefinition = filtering = AM_LINEAR;
1517 colourKeyEnabled = false;
1519 glEnable( GL_TEXTURE_2D );
1520 glGenTextures(1, &gl_Tex);
1521 glBindTexture( GL_TEXTURE_2D, gl_Tex );
1522 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1523 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1524 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1525 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1527 GLenum f = GL_RGBA, t = GL_UNSIGNED_BYTE;
1530 if(format == AM_ALPHA)
1533 c = GL_ALPHA; /* Warning!!! Dont change this value cause font rendering depends on it!*/
1535 else if (format == AM_RGBA)
1541 if(type == AM_UBYTE)
1542 t = GL_UNSIGNED_BYTE;
1544 //glTexImage2D( GL_TEXTURE_2D, 0, c, w, h, 0, f, t, data);
1545 gluBuild2DMipmaps( GL_TEXTURE_2D, c, w, h, f, t, data);
1550 std::cout << "gl_Tex=" << gl_Tex << "\n";
1564 unsigned int Texture::gl_getGLTex()
1570 void Texture::texSubImage2D(int xoff, int yoff, unsigned int w, unsigned int h, int format, int type, const void *pixels)
1572 GLenum f = GL_RGBA, t = GL_UNSIGNED_BYTE;
1574 if(format == AM_ALPHA)
1576 else if (format == AM_RGBA)
1579 if(type == AM_UBYTE)
1580 t = GL_UNSIGNED_BYTE;
1582 glBindTexture(GL_TEXTURE_2D, this->gl_Tex);
1583 glTexSubImage2D(GL_TEXTURE_2D, 0, xoff, yoff, w, h, f, t, pixels);
1585 //TODO kane popAttributes etsi wste na einai current texture auto pou htan prin...
1590 unsigned long Texture::getWidth()
1595 unsigned long Texture::getHeight()
1601 int Texture::getFiltering()
1603 return filteringDefinition;
1607 /* this function needs some fixes and some rewrite */
1608 void Texture::setFiltering(int f, float anisotropyLevel)
1613 else if (f == AM_PLAIN)
1616 filteringDefinition = filtering = f;
1617 if(_f == AM_ANISOTROPIC)
1619 if(supportsAnisotropic)
1621 float a = anisotropyLevel;
1622 if( a > maxAnisotropySupported) //fix this for round-off errors
1623 a = maxAnisotropySupported;
1624 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, a);
1626 filtering = GL_LINEAR;
1628 // 'filtering' cannot have here a value of AM_ANISOTROPIC
1629 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
1630 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering );
1636 void Texture::LoadGLTextures( GLuint *gl_Tex, const char * filename )
1638 /*gl_Tex = ilutGLLoadImage( (char *) filename);
1639 glBindTexture( GL_TEXTURE_2D, *gl_Tex );
1640 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
1641 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
1644 // Generate the main image name to use.
1645 ilGenImages (1, gl_Tex);
1646 ilBindImage (*gl_Tex);
1647 ilEnable(IL_ORIGIN_SET);
1648 ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
1649 if (!ilLoadImage ((char *)filename))
1650 printf("cannot load image %s \n", filename);
1652 ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
1655 iluGetImageInfo(&imageInfo);
1656 ILubyte *data = ilGetData();
1657 printf("image info. %d x %d depth=%d Bp=%d data=%d\n", imageInfo.Width, imageInfo.Height, imageInfo.Depth, imageInfo.Bpp,
1658 imageInfo.SizeOfData);
1660 if ( colourKeyEnabled )
1662 //ksepaketaroume to colourkey
1663 unsigned char ckR = 0, ckG = 0, ckB = 0, ckA = 255;
1664 unsigned long mR, mG, mB, mA;
1669 ckR = (unsigned char) (colourKey.r * 255.0) ;
1670 ckG = (unsigned char) (colourKey.g * 255.0) ;
1671 ckB = (unsigned char) (colourKey.b * 255.0) ;
1672 ckA = (unsigned char) (colourKey.a * 255.0) ;
1673 unsigned char _r, _g, _b;
1676 g->enableAlpha(true);
1677 int step = imageInfo.Bpp;
1678 for(unsigned long i=0; i < imageInfo.SizeOfData; i+=step)
1684 if ( _r == ckR && _g == ckG && _b == ckB )
1689 glBindTexture( GL_TEXTURE_2D, *gl_Tex );
1691 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
1692 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering );
1694 // glTexImage2D( GL_TEXTURE_2D, 0, 4, imageInfo.Width, imageInfo.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
1696 gluBuild2DMipmaps( GL_TEXTURE_2D, 4, imageInfo.Width, imageInfo.Height,
1697 GL_RGBA, GL_UNSIGNED_BYTE, data);
1700 width = imageInfo.Width;
1701 height = imageInfo.Height;
1702 if ( colourKeyEnabled )