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 ilutRenderer(ILUT_OPENGL);
381 * Now, we want to setup our requested
382 * window attributes for our OpenGL window.
383 * We want *at least* 5 bits of red, green
384 * and blue. We also want at least a 16-bit
387 * The last thing we do is request a double
388 * buffered window. '1' turns on double
389 * buffering, '0' turns it off.
391 * Note that we do not use SDL_DOUBLEBUF in
392 * the flags to SDL_SetVideoMode. That does
393 * not affect the GL attribute state, only
394 * the standard 2D blitting setup.
396 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
397 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
398 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
399 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, bpp );
400 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
402 flags = SDL_OPENGL | ( fullScreen ? SDL_FULLSCREEN : 0 );
407 if ( ( imp->screen = SDL_SetVideoMode( width, height, bpp, flags ) ) == 0 )
410 * This could happen for a variety of reasons,
411 * including DISPLAY not being set, the specified
412 * resolution not being available, etc.
414 std::cerr << "Video mode set failed: " << SDL_GetError() << std::endl;
418 SDL_SetGamma(1.8, 1.8, 1.8);
420 float ratio = ( float ) width / ( float ) height;
421 /* Our shading model--Gouraud (smooth). */
422 glShadeModel( GL_SMOOTH );
423 glClearDepth( 1.0f );
425 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
427 // glDepthFunc( GL_LEQUAL );
428 /* Set the clear color. */
429 glClearColor( bgcolour[ 0 ], bgcolour[ 1 ], bgcolour[ 2 ], bgcolour[ 3 ] );
430 glMatrixMode( GL_PROJECTION );
433 glViewport( 0, 0, width, height );
434 gluPerspective( 45.0, ratio, 1.0, 10000.0 );
436 /* Culling. Boh8aei sto Blending*/
437 glCullFace( GL_BACK );
438 /* Polygons whose vertices are in counterclockwise order are called frontfacing but dx thinks different ?*/
439 glFrontFace( GL_CW );
441 glEnable( GL_CULL_FACE );
444 glEnable( GL_DEPTH_TEST );
446 glEnable( GL_TEXTURE_2D );
448 glEnable( GL_BLEND );
450 glEnable( GL_LIGHTING );
452 //TODO: 8a prepei na oristei synarthsh setMaterial...
453 float diffuse[] = {1.0, 1.0, 1.0, 1.0};
454 float specular[] = {0.0, 0.0, 0.0, 0.0};
455 float ambient[] = { 0.0, 0.0, 0.0, 0.0};
456 float emissive[] = {0.0, 0.0, 0.0, 0.0};
457 glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse );
458 glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, specular );
459 glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, emissive );
460 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ambient );
463 if ( !queryExtension( "GL_EXT_texture_filter_anisotropic" ) )
464 std::cout << "Extension GL_EXT_texture_filter_anisotropic not found...\n";
467 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropySupported);
468 std::cout << "max Anisotropy supported = " << maxAnisotropySupported << '\n';
469 supportsAnisotropic = true;
472 /*glGenBuffers(1, &gpuBuf); // mono gia OpenGL 1.5
473 glBindBuffer(GL_ARRAY_BUFFER, gpuBuf); // mono gia OpenGL 1.5
474 glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, ¶meter); // mono gia OpenGL 1.5
475 printf("Buffer size is %d \n", parameter); */
476 if ( !queryExtension( "GL_ARB_point_sprite" ) )
477 std::cout << "Extension GL_ARB_point_sprite not found...\n";
480 // This is how will our point sprite's size will be modified by
481 // distance from the viewer
482 float quadratic[] = { 1.0f, 0.0f, 0.01f };
483 glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic );
484 // Query for the max point size supported by the hardware
486 glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize );
487 // Clamp size to 100.0f or the sprites could get a little too big on some
488 // of the newer graphic cards. My ATI card at home supports a max point
491 // The alpha of a point is calculated to allow the fading of points
492 // instead of shrinking them past a defined threshold size. The threshold
493 // is defined by GL_POINT_FADE_THRESHOLD_SIZE_ARB and is not clamped to
494 // the minimum and maximum point sizes.
495 glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, 60.0f );
496 glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 10.0f );
497 glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, maxSize );
499 // Specify point sprite texture coordinate replacement mode for each
501 glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
502 glEnable( GL_POINT_SPRITE_ARB );
503 glEnable( GL_ARB_point_sprite );
506 std::cout << "OpenGL Version =" << glGetString( GL_VERSION ) << std::endl;
507 int _red,_green,_blue, _alpha, _depth, _stencil;
508 glGetIntegerv(GL_RED_BITS, &_red);
509 glGetIntegerv(GL_GREEN_BITS, &_green);
510 glGetIntegerv(GL_BLUE_BITS, &_blue);
511 glGetIntegerv(GL_ALPHA_BITS, &_alpha);
512 std::cout << "Color Buffers RGBA bits = " << _red << _green << _blue << _alpha << std::endl;
513 glGetIntegerv(GL_DEPTH_BITS, &_depth);
514 std::cout << "Depth Buffer bits = " << _depth << "\n";
515 glGetIntegerv(GL_STENCIL_BITS, &_stencil);
516 std::cout << "Stencil Buffer bits = " << _stencil << "\n";
518 glGetIntegerv(GL_AUX_BUFFERS, &_aux);
519 std::cout << "Aux buffers = " << _aux << "\n";
520 // putenv("__GL_SYNC_TO_VBLANK=1");
522 // XF86VidModeModeLine mode;
525 // Display *d = XOpenDisplay(NULL);
526 /*Bool XF86VidModeGetModeLine(
529 int *dotclock_return ,
530 XF86VidModeModeLine *modeline );
532 // printf("d=%p\n",d);
533 // if(XF86VidModeGetModeLine(d, 0, &unused, &mode))
536 // printf("OK %d mexri %d\n", mode.hsyncstart, mode.hsyncend);
539 // printf("not ok\n");
540 // glXWaitVideoSyncSGI();
541 // GLX_SGI_video_sync
543 // glXGetVideoSyncSGI(&k);
544 // printf("k=%d\n", k);
545 glMatrixMode( GL_MODELVIEW );
552 void Graphics::beginScene( void )
554 /* Clear the color and depth buffers. */
555 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
556 glMatrixMode( GL_MODELVIEW );
558 //gia symbatothta me to DirectX
559 glScalef( -1.0, 1.0, 1.0 );
566 void Graphics::endScene()
568 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
570 //glXSwapIntervalSGI(1);
571 SDL_GL_SwapBuffers();
580 void _gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
581 GLdouble centerx, GLdouble centery, GLdouble centerz,
582 GLdouble upx, GLdouble upy, GLdouble upz )
585 GLdouble x[ 3 ], y[ 3 ], z[ 3 ];
588 /* Make rotation matrix */
591 z[ 0 ] = ( eyex - centerx );
592 z[ 1 ] = ( eyey - centery );
593 z[ 2 ] = ( eyez - centerz );
594 mag = sqrt( z[ 0 ] * z[ 0 ] + z[ 1 ] * z[ 1 ] + z[ 2 ] * z[ 2 ] );
596 { /* mpichler, 19950515 */
607 /* X vector = Y cross Z */
608 x[ 0 ] = y[ 1 ] * z[ 2 ] - y[ 2 ] * z[ 1 ];
609 x[ 1 ] = y[ 2 ] * z[ 0 ] - y[ 0 ] * z[ 2 ] ;
610 x[ 2 ] = y[ 0 ] * z[ 1 ] - y[ 1 ] * z[ 0 ];
612 /* Recompute Y = Z cross X */
613 y[ 0 ] = z[ 1 ] * x[ 2 ] - z[ 2 ] * x[ 1 ];
614 y[ 1 ] = -z[ 0 ] * x[ 2 ] + z[ 2 ] * x[ 0 ];
615 y[ 2 ] = z[ 0 ] * x[ 1 ] - z[ 1 ] * x[ 0 ];
617 /* mpichler, 19950515 */
618 /* cross product gives area of parallelogram, which is < 1.0 for
619 * non-perpendicular unit-length vectors; so normalize x, y here
622 mag = sqrt( x[ 0 ] * x[ 0 ] + x[ 1 ] * x[ 1 ] + x[ 2 ] * x[ 2 ] );
630 mag = sqrt( y[ 0 ] * y[ 0 ] + y[ 1 ] * y[ 1 ] + y[ 2 ] * y[ 2 ] );
638 #define M(row,col) m[col*4+row]
642 M( 0, 3 ) = -( x[ 0 ] * eyex + x[ 1 ] * eyey + x[ 2 ] * eyez );
647 M( 1, 3 ) = -( y[ 0 ] * eyex + y[ 1 ] * eyey + y[ 2 ] * eyez );
652 M( 2, 3 ) = -( z[ 0 ] * eyex + z[ 1 ] * eyey + z[ 2 ] * eyez );
679 glScalef( -1.0, 1.0, 1.0 );
681 glScalef( -1.0, 1.0, 1.0 );
687 int Graphics::setCamera( float camx, float camy, float camz,
688 float lookx, float looky, float lookz,
689 float upx, float upy, float upz )
692 _gluLookAt( camx, camy, camz, lookx, looky, lookz, upx, upy, upz );
710 struct camera Graphics::getCamera()
718 int Graphics::renderTriangle(vertex v1, vertex v2, vertex v3 )
720 // GLfloat colour[ 4 ];
723 std::cout << "DEBUG: oust...!\n";
729 // glPushAttrib(GL_ALL_ATTRIB_BITS); //kyriws gia na epanaferoume to xrwma
730 glBegin( GL_TRIANGLES );
732 // transform_colourv( colour, v1.col );
733 glColor4f( v1.col.r, v1.col.g, v1.col.b, v1.col.a);
734 glNormal3f( v1.nx, v1.ny, v1.nz );
735 glTexCoord2f( v1.u, 1.0 - v1.v );
736 glVertex3f( v1.x, v1.y, v1.z );
738 // transform_colourv( colour, v2.col );
739 // glColor4f( colour[ 0 ], colour[ 1 ], colour[ 2 ], colour[ 3 ] );
740 glColor4f( v2.col.r, v2.col.g, v2.col.b, v2.col.a);
741 glNormal3f( v2.nx, v2.ny, v2.nz );
742 glTexCoord2f( v2.u, 1.0 - v2.v );
743 glVertex3f( v2.x, v2.y, v2.z );
745 glColor4f( v3.col.r, v3.col.g, v3.col.b, v3.col.a);
746 glNormal3f( v3.nx, v3.ny, v3.nz );
747 glTexCoord2f( v3.u, 1.0 - v3.v );
748 glVertex3f( v3.x, v3.y, v3.z );
752 //isos na prepei na epanafero pisw to arxiko xrwma...
759 int Graphics::setWorld( float transx, float transy, float transz,
760 float rotx, float roty, float rotz, float scalex, float scaley, float scalez,
763 glMatrixMode( GL_MODELVIEW );
766 struct camera c = getCamera();
767 setCamera( c.camx, c.camy, c.camz, c.lookx, c.looky, c.lookz, c.upx, c.upy, c.upz );
769 glScalef( -1.0, 1.0, 1.0 ); //gia symbatothta me to DirectX
770 glTranslatef( transx, transy, transz );
772 if(rotationOrder == AM_XYZ)
774 glRotatef( rotz, 0, 0, 1 );
775 glRotatef( roty, 0, 1, 0 );
776 glRotatef( rotx, 1, 0, 0 );
778 else if(rotationOrder == AM_XZY)
780 glRotatef( roty, 0, 1, 0 );
781 glRotatef( rotz, 0, 0, 1 );
782 glRotatef( rotx, 1, 0, 0 );
785 else if(rotationOrder == AM_YZX)
787 glRotatef( rotx, 1, 0, 0 );
788 glRotatef( rotz, 0, 0, 1 );
789 glRotatef( roty, 0, 1, 0 );
791 else if(rotationOrder == AM_YXZ)
793 glRotatef( rotz, 0, 0, 1 );
794 glRotatef( rotx, 1, 0, 0 );
795 glRotatef( roty, 0, 1, 0 );
798 else if(rotationOrder == AM_ZXY)
800 glRotatef( roty, 0, 1, 0 );
801 glRotatef( rotx, 1, 0, 0 );
802 glRotatef( rotz, 0, 0, 1 );
806 glRotatef( rotx, 1, 0, 0 );
807 glRotatef( roty, 0, 1, 0 );
808 glRotatef( rotz, 0, 0, 1 );
811 glScalef( scalex, scaley, scalez );
820 int Graphics::setWorld2( float transx, float transy, float transz,
821 float rotx, float roty, float rotz, float scalex, float scaley, float scalez )
823 glMatrixMode( GL_MODELVIEW );
827 struct camera c = getCamera();
828 setCamera( c.camx, c.camy, c.camz, c.lookx, c.looky, c.lookz, c.upx, c.upy, c.upz );
830 glScalef( -1.0, 1.0, 1.0 ); //gia symbatothta me to DirectX
831 glTranslatef( transx, transy, transz );
832 glRotatef( roty, 0, 1, 0 );
833 glRotatef( rotz, 0, 0, 1 );
834 glRotatef( rotx, 1, 0, 0 );
835 glScalef( scalex, scaley, scalez );
847 void Graphics::setBackground( colour colour )
849 // transform_colourv( bgcolour, colour );
850 // printf( "(%f, %f, %f ,%f)\n", bgcolour[ 0 ], bgcolour[ 1 ], bgcolour[ 2 ], bgcolour[ 3 ] );
851 bgcolour[0] = colour.r;
852 bgcolour[1] = colour.g;
853 bgcolour[2] = colour.b;
854 bgcolour[3] = colour.a;
855 glClearColor( ( float ) bgcolour[ 0 ], ( float ) bgcolour[ 1 ], ( float ) bgcolour[ 2 ], ( float ) bgcolour[ 3 ] );
861 colour Graphics::getBackground( void )
874 void Graphics::project( float objx, float objy, float objz,
875 //const double modelMatrix[16], const double projMatrix[16], const int viewport[4],
876 float *winx, float *winy, float *winz )
882 GLdouble mvmatrix[ 16 ], projmatrix[ 16 ];
884 glGetIntegerv ( GL_VIEWPORT, viewport );
885 glGetDoublev ( GL_MODELVIEW_MATRIX, mvmatrix );
886 glGetDoublev ( GL_PROJECTION_MATRIX, projmatrix );
888 gluProject( objx, objy, objz, mvmatrix, projmatrix, viewport,
889 &_winx, &_winy, &_winz );
892 *winy = viewport[ 3 ] - ( int ) _winy - 1;
899 void Graphics::unproject( float winx, float winy, float winz,
900 //const double modelMatrix[16], const double projMatrix[16], const int viewport[4],
901 float *objx, float *objy, float *objz )
908 GLdouble mvmatrix[ 16 ], projmatrix[ 16 ];
910 glGetIntegerv ( GL_VIEWPORT, viewport );
911 glGetDoublev ( GL_MODELVIEW_MATRIX, mvmatrix );
912 glGetDoublev ( GL_PROJECTION_MATRIX, projmatrix );
914 realy = viewport[ 3 ] - ( int ) winy - 1;
915 // std::cout << "realy=" <<realy << "\n";
917 gluUnProject( winx, realy, winz,
918 mvmatrix, projmatrix, viewport,
919 &_objx, &_objy, &_objz );
930 void Graphics::enableCursor( bool state )
934 SDL_ShowCursor( SDL_ENABLE );
936 SDL_ShowCursor( SDL_DISABLE );
940 bool Graphics::isCursor()
947 void Graphics::planeIntersect( float a, float b, float c, float d,
948 float p1x, float p1y, float p1z, float p2x, float p2y, float p2z,
949 float *poutx, float *pouty, float *poutz )
951 float numerator = -( a * p1x + b * p1y + c * p1z + d );
952 if ( numerator == 0 )
961 float denominator = a * ( p2x - p1x ) + b * ( p2y - p1y ) + c * ( p2z - p1z );
962 if ( denominator == 0 )
967 printf("denominator==0!!!\n");
973 float t = numerator / denominator;
974 ( *poutx ) = p1x + t * ( p2x - p1x );
975 ( *pouty ) = p1y + t * ( p2y - p1y );
976 ( *poutz ) = p1z + t * ( p2z - p1z );
986 void Graphics::setLight( int numLight, const light& l )
988 GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
989 GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0};
990 GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0};
991 GLfloat position[] = {0.0, 0.0, 1.0, 0.0};
992 GLenum enm = GL_LIGHT0;
994 if(numLight == 0) enm = GL_LIGHT0;
995 else if(numLight == 1) enm = GL_LIGHT1;
996 else if(numLight == 2) enm = GL_LIGHT2;
997 else if(numLight == 3) enm = GL_LIGHT3;
998 else if(numLight == 4) enm = GL_LIGHT4;
999 else if(numLight == 5) enm = GL_LIGHT5;
1000 else if(numLight == 6) enm = GL_LIGHT6;
1001 else if(numLight == 7 ) enm = GL_LIGHT7;
1003 // transform_colourv( ambient, l.ambient );
1004 // transform_colourv( diffuse, l.diffuse );
1005 // transform_colourv( specular, l.specular );
1006 ambient[0] = l.ambient.r; ambient[1] = l.ambient.g; ambient[2] = l.ambient.b; ambient[3] = l.ambient.a;
1007 diffuse[0] = l.diffuse.r; diffuse[1] = l.diffuse.g; diffuse[2] = l.diffuse.b; diffuse[3] = l.diffuse.a;
1008 specular[0] = l.specular.r; specular[1] = l.specular.g; specular[2] = l.specular.b; specular[3] = l.specular.a;
1010 if ( l.type == AM_POINT_LIGHT )
1012 position[ 3 ] = 1.0;
1013 position[ 0 ] = l.posx;
1014 position[ 1 ] = l.posy;
1015 position[ 2 ] = l.posz;
1018 if ( l.type == AM_DIRECTIONAL_LIGHT )
1020 //float val = sqrt(l.dirx*l.dirx + l.diry*l.diry + l.dirz*l.dirz);
1021 position[ 3 ] = 0.0;
1022 position[ 0 ] = -l.dirx;
1023 position[ 1 ] = -l.diry;
1024 position[ 2 ] = l.dirz;
1031 glVertex3f(position[0], position[1], position[2]);
1032 glVertex3f(360, 10, 360);
1035 glLightfv( enm, GL_AMBIENT, ambient );
1036 glLightfv( enm, GL_DIFFUSE, diffuse );
1037 glLightfv( enm, GL_SPECULAR, specular );
1038 glLightfv( enm, GL_POSITION, position );
1045 void Graphics::showLight( int numLight, bool state )
1047 GLenum enm = GL_LIGHT0;
1048 if ( numLight == 0 )
1051 if ( numLight == 1 )
1054 if ( numLight == 2 )
1069 void inverseMatrix( double A[16], double B[16])
1091 detA = a11*a22*a33*a44 + a11*a23*a34*a42 + a11*a24*a32*a43 \
1092 +a12*a21*a34*a43 + a12*a23*a31*a44 + a12*a24*a33*a41 \
1093 +a13*a21*a32*a44 + a13*a22*a34*a41 + a13*a24*a31*a42 \
1094 +a14*a21*a33*a42 + a14*a22*a31*a43 + a14*a23*a32*a41 \
1095 -a11*a22*a34*a43 - a11*a23*a32*a44 - a11*a24*a33*a42 \
1096 -a12*a21*a33*a44 - a12*a23*a34*a41 - a12*a24*a31*a43 \
1097 -a13*a21*a34*a42 - a13*a22*a31*a44 - a13*a24*a32*a41 \
1098 -a14*a21*a32*a43 - a14*a22*a33*a41 - a14*a23*a31*a42;
1100 // printf("detA=%f\n",detA);
1102 B[0] = (a22*a33*a44 + a23*a34*a42 + a24*a32*a43 - a22*a34*a43 - a23*a32*a44 - a24*a33*a42)/detA;
1103 B[1] = (a12*a34*a43 + a13*a32*a44 + a14*a33*a42 - a12*a33*a44 - a13*a34*a42 - a14*a32*a43)/detA;
1104 B[2] = (a12*a23*a44 + a13*a24*a42 + a14*a22*a43 - a12*a24*a43 - a13*a22*a44 - a14*a23*a42)/detA;
1105 B[3] = (a12*a24*a33 + a13*a22*a34 + a14*a23*a32 - a12*a23*a34 - a13*a24*a32 - a14*a22*a33)/detA;
1106 B[4] = (a21*a34*a43 + a23*a31*a44 + a24*a33*a41 - a21*a33*a44 - a23*a34*a41 - a24*a31*a43)/detA;
1107 B[5] = (a11*a33*a44 + a13*a34*a41 + a14*a31*a43 - a11*a34*a43 - a13*a31*a44 - a14*a33*a41)/detA;
1108 B[6] = (a11*a24*a43 + a13*a21*a44 + a14*a23*a41 - a11*a23*a44 - a13*a24*a41 - a14*a21*a43)/detA;
1109 B[7] = (a11*a23*a34 + a13*a24*a31 + a14*a21*a33 - a11*a24*a33 - a13*a21*a34 - a14*a23*a31)/detA;
1110 B[8] = (a21*a32*a44 + a22*a34*a41 + a24*a31*a42 - a21*a34*a42 - a22*a31*a44 - a24*a32*a41)/detA;
1111 B[9] = (a11*a34*a42 + a12*a31*a44 + a14*a32*a41 - a11*a32*a44 - a12*a34*a41 - a14*a31*a42)/detA;
1112 B[10] = (a11*a22*a44 + a12*a24*a41 + a14*a21*a42 - a11*a24*a42 - a12*a21*a44 - a14*a22*a41)/detA;
1113 B[11] = (a11*a24*a32 + a12*a21*a34 + a14*a22*a31 - a11*a22*a34 - a12*a24*a31 - a14*a21*a32)/detA;
1114 B[12] = (a21*a33*a42 + a22*a31*a43 + a23*a32*a41 - a21*a32*a43 - a22*a33*a41 - a23*a31*a42)/detA;
1115 B[13] = (a11*a32*a43 + a12*a33*a41 + a13*a31*a42 - a11*a33*a42 - a12*a31*a43 - a13*a32*a41)/detA;
1116 B[14] = (a11*a23*a42 + a12*a21*a43 + a13*a22*a41 - a11*a22*a43 - a12*a23*a41 - a13*a21*a42)/detA;
1117 B[15] = (a11*a22*a33 + a12*a23*a31 + a13*a21*a32 - a11*a23*a32 - a12*a21*a33 - a13*a22*a31)/detA;
1124 void Graphics::drawBillboardParticle(float x, float y, float z, float size, colour col)
1128 glPushAttrib(GL_ALL_ATTRIB_BITS);
1129 glDisable(GL_DEPTH_TEST);
1130 glDepthMask( GL_FALSE );
1132 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
1133 glDisable(GL_CULL_FACE);
1134 glEnable( GL_TEXTURE_2D );
1135 /*********************************/
1136 GLdouble modelview[16], B[16];
1137 // save the current modelview matrix
1139 // get the current modelview matrix
1140 glGetDoublev(GL_MODELVIEW_MATRIX , modelview);
1141 inverseMatrix(modelview, B);
1142 // set the modelview with no rotations and scaling
1144 glLoadMatrixd(modelview);
1145 glTranslatef(x,y,z);
1147 float s2 = size / 2.0;
1148 // transform_colourv(v, col);
1150 glColor4f(col.r, col.g, col.b, col.a);
1151 glTexCoord2f( 0.0, 0.0 ); glVertex3f(-s2,s2,0);
1152 glTexCoord2f( 1.0, 0.0 ); glVertex3f(s2,s2,0);
1153 glTexCoord2f( 1.0, 1.0 ); glVertex3f(s2,-s2,0);
1154 glTexCoord2f( 0.0, 1.0 ); glVertex3f(-s2,-s2,0);
1157 // restores the modelview matrix
1159 /*********************************/
1166 void Graphics::renderParticleArray(particle *array, unsigned int sizeOfArray, int type)
1170 if(type == AM_HARDWARE_PARTICLE)
1172 glPushAttrib(GL_ALL_ATTRIB_BITS);
1173 glEnable(GL_DEPTH_TEST);
1174 glDepthMask( GL_FALSE );
1176 glBlendFunc( GL_DST_ALPHA, GL_ONE );
1178 for(i=0; i < sizeOfArray; i++)
1180 glPointSize( (array[i].size > maxSize ? maxSize : array[i].size) );
1181 glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, (array[i].size > maxSize ? maxSize : array[i].size) );
1183 glColor4f(array[i].col.r, array[i].col.g, array[i].col.b, array[i].col.a);
1184 glVertex3f(array[i].x, array[i].y, array[i].z);
1190 if(type == AM_SOFTWARE_PARTICLE)
1196 }quad_lower_left, quad_lower_right;
1198 glPushAttrib(GL_ALL_ATTRIB_BITS);
1199 glEnable(GL_DEPTH_TEST);
1201 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
1202 glDisable(GL_CULL_FACE);
1203 glEnable( GL_TEXTURE_2D );
1204 glGetFloatv( GL_MODELVIEW_MATRIX, mat );
1206 for(i=0; i < sizeOfArray; i++)
1208 float s2 = array[i].size / 2.0;
1209 quad_lower_left.x = (-s2) * (mat[0] + mat[1]);
1210 quad_lower_left.y = (-s2) * (mat[4] + mat[5]);
1211 quad_lower_left.z = (-s2) * (mat[8] + mat[9]);
1212 quad_lower_right.x = (s2) * (mat[0] - mat[1]);
1213 quad_lower_right.y = (s2) * (mat[4] - mat[5]);
1214 quad_lower_right.z = (s2) * (mat[8] - mat[9]);
1217 glColor4f(array[i].col.r, array[i].col.g, array[i].col.b, array[i].col.a);
1218 glTexCoord2f(0.0, 0.0);
1219 glVertex3f(array[i].x + quad_lower_left.x, array[i].y + quad_lower_left.y, array[i].z + quad_lower_left.z);
1220 glTexCoord2f(1.0, 0.0);
1221 glVertex3f(array[i].x + quad_lower_right.x, array[i].y + quad_lower_right.y, array[i].z + quad_lower_right.z);
1222 glTexCoord2f(1.0, 1.0);
1223 glVertex3f(array[i].x - quad_lower_left.x, array[i].y - quad_lower_left.y, array[i].z - quad_lower_left.z);
1224 glTexCoord2f(0.0, 1.0);
1225 glVertex3f(array[i].x - quad_lower_right.x, array[i].y - quad_lower_right.y, array[i].z - quad_lower_right.z);
1237 void Graphics::renderParticle(float x, float y, float z, float size, colour col, int type)
1239 if(type == AM_HARDWARE_PARTICLE)
1241 glPushAttrib(GL_ALL_ATTRIB_BITS);
1242 glPointSize( (size > maxSize ? maxSize : size) );
1243 glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, (size > maxSize ? maxSize : size) );
1244 glEnable(GL_DEPTH_TEST);
1245 glDepthMask( GL_FALSE );
1247 // glBlendFunc( GL_SRC_ALPHA, GL_ONE );
1248 glBlendFunc( GL_DST_ALPHA, GL_ONE );
1251 // transform_colourv(v, col);
1252 glColor4f(col.r , col.g, col.b, col.a);
1258 if(type == AM_SOFTWARE_PARTICLE)
1266 }quad_lower_left,quad_lower_right;
1268 glPushAttrib(GL_ALL_ATTRIB_BITS);
1269 glEnable(GL_DEPTH_TEST);
1270 // glDepthMask( GL_FALSE );
1272 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
1273 glDisable(GL_CULL_FACE);
1274 glEnable( GL_TEXTURE_2D );
1277 // Get modelview matrix. We will only use the upper left 3x3 part of
1278 // the matrix, which represents the rotation.
1279 glGetFloatv( GL_MODELVIEW_MATRIX, mat );
1281 // 1) & 2) We do it in one swift step:
1282 // Although not obvious, the following six lines represent two matrix/
1283 // vector multiplications. The matrix is the inverse 3x3 rotation
1284 // matrix (i.e. the transpose of the same matrix), and the two vectors
1285 // represent the lower left corner of the quad, PARTICLE_SIZE/2 *
1286 // (-1,-1,0), and the lower right corner, PARTICLE_SIZE/2 * (1,-1,0).
1287 // The upper left/right corners of the quad is always the negative of
1288 // the opposite corners (regardless of rotation).
1289 float s2 = size / 2.0;
1290 quad_lower_left.x = (-s2) * (mat[0] + mat[1]);
1291 quad_lower_left.y = (-s2) * (mat[4] + mat[5]);
1292 quad_lower_left.z = (-s2) * (mat[8] + mat[9]);
1293 quad_lower_right.x = (s2) * (mat[0] - mat[1]);
1294 quad_lower_right.y = (s2) * (mat[4] - mat[5]);
1295 quad_lower_right.z = (s2) * (mat[8] - mat[9]);
1297 // 3) Translate the quad to the correct position in modelview
1298 // space and store its parameters in vertex arrays (we also
1299 // store texture coord and color information for each vertex).
1300 // transform_colourv(v, col);
1302 glColor4f(col.r, col.g, col.b, col.a);
1303 // Lower left corner
1304 glTexCoord2f(0.0, 0.0);
1305 glVertex3f(x + quad_lower_left.x, y + quad_lower_left.y, z + quad_lower_left.z);
1306 // printf("1. %f %f %f\n",x + quad_lower_left.x, y + quad_lower_left.y, z + quad_lower_left.z);
1307 // Lower right corner
1308 glTexCoord2f(1.0, 0.0);
1309 glVertex3f(x + quad_lower_right.x, y + quad_lower_right.y, z + quad_lower_right.z);
1310 // printf("2. %f %f %f\n",x + quad_lower_right.x, y + quad_lower_right.y, z + quad_lower_right.z);
1311 // Upper right corner
1312 glTexCoord2f(1.0, 1.0);
1313 glVertex3f(x - quad_lower_left.x, y - quad_lower_left.y, z - quad_lower_left.z);
1314 // printf("3. %f %f %f\n", x - quad_lower_left.x, y - quad_lower_left.y, z - quad_lower_left.z);
1315 // Upper left corner
1316 glTexCoord2f(0.0, 1.0);
1317 glVertex3f(x - quad_lower_right.x, y - quad_lower_right.y, z - quad_lower_right.z);
1318 // printf("4. %f %f %f\n", x - quad_lower_right.x, y - quad_lower_right.y, z - quad_lower_right.z);
1320 // restores the modelview matrix
1322 /*********************************/
1331 Specifies the field of view angle, in degrees, in the y direction.
1333 Specifies the aspect ratio that determines the field of view in the x direction.
1334 The aspect ratio is the ratio of x (width) to y (height).
1336 Specifies the distance from the viewer to the near clipping plane (always positive).
1338 Specifies the distance from the viewer to the far clipping plane (always positive).
1340 void Graphics::setPerspective(float fov, float ratio, float zNear, float zFar)
1344 glGetIntegerv( GL_MATRIX_MODE, &matrixMode);
1345 glMatrixMode( GL_PROJECTION );
1347 gluPerspective( fov, ratio, zNear, zFar );
1348 glMatrixMode( matrixMode );
1353 void Graphics::renderVertexArray(vertex *array, unsigned int numOfPrimitives, int type)
1356 if(type == AM_TRIANGLE_STRIP)
1357 t = GL_TRIANGLE_STRIP;
1358 else if (type == AM_TRIANGLE_FAN)
1359 t = GL_TRIANGLE_FAN;
1360 else if (type == AM_TRIANGLES)
1362 else if (type == AM_POINT_LIST)
1364 else if (type == AM_LINE_LIST)
1366 else if (type == AM_LINE_STRIP)
1369 // UGLY hack to reverse texture coordinate...implement an operator in struct vertex..?!?
1370 vertex *tmp = new vertex[numOfPrimitives];
1371 memcpy(tmp, array, numOfPrimitives*sizeof(vertex));
1373 for(i=0; i < numOfPrimitives; i++)
1374 tmp[i].v = 1 - tmp[i].v;
1376 glInterleavedArrays( GL_T2F_C4F_N3F_V3F, 0, (void *) tmp);
1377 glDrawArrays( t, 0, numOfPrimitives);
1384 void Graphics::setCullingMode(int mode)
1387 if(mode == AM_CULL_NONE)
1390 glDisable(GL_CULL_FACE );
1398 glEnable( GL_CULL_FACE );
1400 if(mode == AM_CULL_FRONT)
1401 glCullFace(GL_FRONT);
1402 else if (mode == AM_CULL_BACK)
1403 glCullFace(GL_BACK);
1408 int Graphics::getCullingMode()
1415 void Graphics::enter2dMode(void)
1417 glPushAttrib( GL_ALL_ATTRIB_BITS );
1419 glDisable( GL_LIGHTING );
1420 glDisable( GL_DEPTH_TEST );
1421 glDisable( GL_CULL_FACE );
1422 glEnable( GL_TEXTURE_2D );
1424 glViewport( 0, 0, getWidth(), getHeight() );
1426 glMatrixMode( GL_PROJECTION );
1430 glOrtho( 0.0, ( GLdouble ) getWidth(), ( GLdouble ) getHeight(), 0.0, 0.0, 1.0 );
1432 glMatrixMode( GL_MODELVIEW );
1435 // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
1440 void Graphics::leave2dMode(void)
1442 glMatrixMode( GL_MODELVIEW );
1445 glMatrixMode( GL_PROJECTION );
1453 void Graphics::enableDepthBuffer( bool b )
1457 glEnable( GL_DEPTH_TEST );
1459 glDisable( GL_DEPTH_TEST );
1465 bool Graphics::isDepthBuffer()
1472 /*--------------------------------------------------
1474 *-----------------------------------------------------*/
1478 Texture::Texture( char *file, colour key, Graphics *g )
1481 filteringDefinition = filtering = AM_LINEAR;
1483 glEnable( GL_TEXTURE_2D );
1485 colourKeyEnabled = true;
1487 // CreateTexture(&gl_Tex, file, 0);
1488 LoadGLTextures( &gl_Tex, file );
1489 std::cout << "file=" << file << ", gl_Tex=" << gl_Tex << "\n";
1495 Texture::Texture( char *file, Graphics *g)
1499 filteringDefinition = filtering = AM_LINEAR;
1500 glEnable( GL_TEXTURE_2D );
1502 colourKeyEnabled = false;
1503 // CreateTexture(&gl_Tex, file, 0);
1504 LoadGLTextures( &gl_Tex, file );
1505 std::cout << "file=" << file << ", gl_Tex=" << gl_Tex << "\n";
1510 Texture::Texture(void *data, unsigned int w, unsigned int h, int format, int type, Graphics *g)
1513 filteringDefinition = filtering = AM_LINEAR;
1516 colourKeyEnabled = false;
1518 glEnable( GL_TEXTURE_2D );
1519 glGenTextures(1, &gl_Tex);
1520 glBindTexture( GL_TEXTURE_2D, gl_Tex );
1521 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1522 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1523 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1524 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1526 GLenum f = GL_RGBA, t = GL_UNSIGNED_BYTE;
1529 if(format == AM_ALPHA)
1532 c = GL_ALPHA; /* Warning!!! Dont change this value cause font rendering depends on it!*/
1534 else if (format == AM_RGBA)
1540 if(type == AM_UBYTE)
1541 t = GL_UNSIGNED_BYTE;
1543 //glTexImage2D( GL_TEXTURE_2D, 0, c, w, h, 0, f, t, data);
1544 gluBuild2DMipmaps( GL_TEXTURE_2D, c, w, h, f, t, data);
1549 std::cout << "gl_Tex=" << gl_Tex << "\n";
1563 unsigned int Texture::gl_getGLTex()
1569 void Texture::texSubImage2D(int xoff, int yoff, unsigned int w, unsigned int h, int format, int type, const void *pixels)
1571 GLenum f = GL_RGBA, t = GL_UNSIGNED_BYTE;
1573 if(format == AM_ALPHA)
1575 else if (format == AM_RGBA)
1578 if(type == AM_UBYTE)
1579 t = GL_UNSIGNED_BYTE;
1581 glBindTexture(GL_TEXTURE_2D, this->gl_Tex);
1582 glTexSubImage2D(GL_TEXTURE_2D, 0, xoff, yoff, w, h, f, t, pixels);
1584 //TODO kane popAttributes etsi wste na einai current texture auto pou htan prin...
1589 unsigned long Texture::getWidth()
1594 unsigned long Texture::getHeight()
1600 int Texture::getFiltering()
1602 return filteringDefinition;
1606 /* this function needs some fixes and some rewrite */
1607 void Texture::setFiltering(int f, float anisotropyLevel)
1612 else if (f == AM_PLAIN)
1615 filteringDefinition = filtering = f;
1616 if(_f == AM_ANISOTROPIC)
1618 if(supportsAnisotropic)
1620 float a = anisotropyLevel;
1621 if( a > maxAnisotropySupported) //fix this for round-off errors
1622 a = maxAnisotropySupported;
1623 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, a);
1625 filtering = GL_LINEAR;
1627 // 'filtering' cannot have here a value of AM_ANISOTROPIC
1628 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
1629 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering );
1635 void Texture::LoadGLTextures( GLuint *gl_Tex, const char * filename )
1637 /*gl_Tex = ilutGLLoadImage( (char *) filename);
1638 glBindTexture( GL_TEXTURE_2D, *gl_Tex );
1639 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
1640 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
1643 // Generate the main image name to use.
1644 ilGenImages (1, gl_Tex);
1645 ilBindImage (*gl_Tex);
1646 ilEnable(IL_ORIGIN_SET);
1647 ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
1648 if (!ilLoadImage ((char *)filename))
1649 printf("cannot load image %s \n", filename);
1651 ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
1654 iluGetImageInfo(&imageInfo);
1655 ILubyte *data = ilGetData();
1656 printf("image info. %d x %d depth=%d Bp=%d data=%d\n", imageInfo.Width, imageInfo.Height, imageInfo.Depth, imageInfo.Bpp,
1657 imageInfo.SizeOfData);
1659 if ( colourKeyEnabled )
1661 //ksepaketaroume to colourkey
1662 unsigned char ckR = 0, ckG = 0, ckB = 0, ckA = 255;
1663 unsigned long mR, mG, mB, mA;
1668 ckR = (unsigned char) (colourKey.r * 255.0) ;
1669 ckG = (unsigned char) (colourKey.g * 255.0) ;
1670 ckB = (unsigned char) (colourKey.b * 255.0) ;
1671 ckA = (unsigned char) (colourKey.a * 255.0) ;
1672 unsigned char _r, _g, _b;
1675 g->enableAlpha(true);
1676 int step = imageInfo.Bpp;
1677 for(unsigned long i=0; i < imageInfo.SizeOfData; i+=step)
1683 if ( _r == ckR && _g == ckG && _b == ckB )
1688 glBindTexture( GL_TEXTURE_2D, *gl_Tex );
1690 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
1691 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering );
1693 // glTexImage2D( GL_TEXTURE_2D, 0, 4, imageInfo.Width, imageInfo.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
1695 gluBuild2DMipmaps( GL_TEXTURE_2D, 4, imageInfo.Width, imageInfo.Height,
1696 GL_RGBA, GL_UNSIGNED_BYTE, data);
1699 width = imageInfo.Width;
1700 height = imageInfo.Height;
1701 if ( colourKeyEnabled )