* Add "less" target to view make output through less.
[matthijs/ABM2.git] / ABM2 / Amaltheia / Graphics.cpp
diff --git a/ABM2/Amaltheia/Graphics.cpp b/ABM2/Amaltheia/Graphics.cpp
new file mode 100644 (file)
index 0000000..270f6c5
--- /dev/null
@@ -0,0 +1,1705 @@
+/***************************************************************************
+ *   Copyright (C) 2005 by Dimitris Saougos & Filippos Papadopoulos   *
+ *   <psybases@gmail.com>                                                             *
+ *                                                                                                       *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU Library General Public License as       *
+ *   published by the Free Software Foundation; either version 2 of the    *
+ *   License, or (at your option) any later version.                                    *
+ *                                                                                                           *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU Library General Public     *
+ *   License along with this program; if not, write to the                 *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "Graphics.h"
+// #include <X11/Xlib.h>
+// #include <X11/extensions/xf86vmode.h>
+#include <FTGL/FTGLTextureFont.h>
+#include <GL/glext.h>
+#include <IL/il.h>
+#include <IL/ilu.h>
+#include <IL/ilut.h>
+#include <SDL/SDL.h>
+// #include <SDL/SDL_thread.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <iostream>
+#include <cmath>
+#include <cassert>
+
+// using namespace Amaltheia;
+extern float z_order; //for Sprite
+static bool supportsAnisotropic = false;
+static GLfloat maxAnisotropySupported = 0.0;
+typedef unsigned long COLOUR;
+
+colour COLOUR_RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a )
+{
+       colour c;
+       c.a = a/255.0f;
+       c.r = r/255.0f;
+       c.g = g/255.0f;
+       c.b = b/255.0f;
+
+       return c;
+}
+
+
+ inline COLOUR CLR_RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a )
+{
+       return ( ( COLOUR ) ( ( ( ( a ) & 0xff ) << 24 ) | ( ( ( r ) & 0xff ) << 16 ) | ( ( ( g ) & 0xff ) << 8 ) | ( ( b ) & 0xff ) ) );
+}
+
+
+
+inline void transform_colourv( float *v, COLOUR col )
+{
+       int a, r, g, b;
+       int mask = 0x000000ff;
+
+       b = col & mask;
+       col >>= 8;
+       g = col & mask;
+       col >>= 8;
+       r = col & mask;
+       col >>= 8;
+       a = col & mask;
+
+
+       v[ 3 ] = ( float ) a / 255.0f;
+       v[ 2 ] = ( float ) b / 255.0f;
+       v[ 1 ] = ( float ) g / 255.0f;
+       v[ 0 ] = ( float ) r / 255.0f;
+       
+       return;
+}
+
+float rad( float deg )
+{
+  return ( deg * M_PI ) / 180.f;
+}
+
+float deg( float rad )
+{
+  return ( rad * 180.0f ) / M_PI;
+}
+
+
+inline GLboolean queryExtension(char *extName)
+{
+       char *p = (char *) glGetString(GL_EXTENSIONS);
+       if(p == NULL)
+               return GL_FALSE;
+       char *end = p + strlen(p);
+       unsigned int n = 0;
+       while(p < end)
+       {
+               n = strcspn(p, " ");
+               if((strlen(extName) == n) && (strncmp(extName, p, n) == 0))
+                       return GL_TRUE;
+               p += (n + 1);
+       }
+
+       return GL_FALSE;
+}
+
+
+
+
+
+class FontImp
+{
+       public:
+               FTGLTextureFont *font;
+               int fontSize;
+               Graphics *g;
+       
+};
+
+
+Font::Font()  :  imp( new FontImp() )
+{
+}
+
+Font::~Font()
+{
+       delete imp;
+       //      delete font;
+       return ;
+}
+
+
+Font::Font(const char *name, int size, Graphics *g) :  imp( new FontImp() )
+{
+       assert(g);
+       imp->g = g;
+       imp->fontSize = size;
+       imp->font =  new FTGLTextureFont(name);
+       imp->font->FaceSize(size);
+       imp->font->CharMap(ft_encoding_unicode);
+       imp->fontSize = size;
+       /*this->g = g;
+       this->fontSize = size;
+       font =  new FTGLTextureFont(name);
+       font->FaceSize(size);
+       font->CharMap(ft_encoding_unicode);
+       fontSize = size; */
+}
+
+void Font::print( const wchar_t *str, int x1, int y1, int x2, int y2, colour c )
+{
+       imp->g->enter2dMode();
+       glColor4f( c.r, c.g, c.b, c.a);
+       float h= imp->font->LineHeight()*0.64f;         /* factor 0.64*/
+       glTranslatef(x1, y1 + h, 0);
+       glScalef(1.0, -1.0, 1.0);
+       imp->font->Render(str);
+//     ft_print( our_font, x1 , g->getHeight() - y1 - fontSize, str);
+       imp->g->leave2dMode();
+}
+
+       void Font::print( char *str, int x1, int y1, int x2, int y2, colour c )
+       {
+               imp->g->enter2dMode();
+               glColor4f( c.r, c.g, c.b, c.a);
+               float h= imp->font->LineHeight()*0.64f;         /* factor 0.64*/
+               glTranslatef(x1, y1 + h, 0);
+               glScalef(1.0, -1.0, 1.0);
+               imp->font->Render(str);
+       //      ft_print( our_font, x1 , g->getHeight() - y1 - fontSize, str);
+               imp->g->leave2dMode();
+       }
+
+       
+bool Graphics::oneGraphics = false;
+
+class GraphicsImp
+{
+public:
+       SDL_Surface *screen;
+};
+       
+       
+Graphics::Graphics( int w, int h, int bpp, bool fullScreen, bool a, bool l ) : imp(new GraphicsImp())
+{
+  if ( oneGraphics )
+  {
+    std::cerr << "Only one graphics object allowed!\n";
+    exit( 1 );
+  }
+
+  oneGraphics = true;
+  width = w;
+  height = h;
+  this->fullScreen = fullScreen;
+  this->bpp = bpp;
+  alpha = a;
+  lighting = l;
+  sceneBegin = false;
+  culling = true;
+  cmode = AM_CULL_BACK;
+  zBuffer = true;
+  cursorState = true;
+  bgcolour[ 0 ] = 0;
+  bgcolour[ 1 ] = 0;
+  bgcolour[ 2 ] = 0;
+  bgcolour[ 3 ] = 1;
+
+  cam.camx = 0.0;
+  cam.camy = 0.0;
+  cam.camz = 0.0;
+
+  cam.lookx = 0.0;
+  cam.looky = 0.0;
+  cam.lookz = 1.0;
+
+  cam.upx = 0.0;
+  cam.upy = 1.0;
+  cam.upz = 0.0;
+
+  this->currentTexture = 0;
+}
+
+
+
+Graphics::~Graphics( void )
+{
+  //glDeleteBuffers(1, &gpuBuf); // mono gia OpenGL 1.5
+       delete imp;
+       SDL_Quit();
+       return ;
+}
+
+
+
+void Graphics::setHeight( int h)
+{
+  height = h;
+  return ;
+}
+
+int Graphics::getHeight()
+{
+  return height;
+}
+
+void Graphics::setWidth(int w)
+{
+  width = w;
+  return ;
+}
+int Graphics::getWidth()
+{
+  return width;
+}
+
+void Graphics::setBpp( int b )
+{
+  bpp = b;
+  return ;
+}
+int Graphics::getBpp()
+{
+  return bpp;
+}
+
+void Graphics::enableVsync( bool v )
+{
+  vSync = v;
+  return ;
+}
+bool Graphics::isVsync()
+{
+  return vSync;
+}
+
+
+void Graphics::enableFullScreen( bool f )
+{
+  fullScreen = f;
+  return ;
+}
+bool Graphics::isFullScreen( void )
+{
+  return fullScreen;
+}
+
+                                                                                                                                       
+void Graphics::enableLighting( bool l )
+{
+  lighting = l;
+
+  if ( lighting )
+    glEnable( GL_LIGHTING );
+  else
+    glDisable( GL_LIGHTING );
+
+  return ;
+}
+
+
+bool Graphics::isLighting()
+{
+  return lighting;
+}
+
+void Graphics::enableAlpha( bool a )
+{
+  alpha = a;
+  if ( alpha )
+    glEnable( GL_BLEND );
+  else
+    glDisable( GL_BLEND );
+
+  return ;
+}
+
+
+bool Graphics::isAlpha( void )
+{
+  return alpha;
+}
+
+void Graphics::setTexture( Texture *t )
+{
+  if ( t == 0 )
+    return ;
+
+  currentTexture = t;
+  glBindTexture( GL_TEXTURE_2D, t->gl_Tex );
+
+  return ;
+}
+
+Texture* Graphics::getTexture(void)
+{
+       return currentTexture;
+}
+
+
+int Graphics::createDisplay()
+{
+
+
+  /* Information about the current video settings. */
+  const SDL_VideoInfo * info = 0;
+  /* Flags we will pass into SDL_SetVideoMode. */
+  int flags = 0;
+
+  //   putenv("__GL_SYNC_TO_VBLANK=1");
+
+  /* First, initialize SDL's video subsystem. */
+  if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ) < 0 )
+  {
+    /* Failed, exit. */
+    fprintf( stderr, "Video initialization failed: %s\n", SDL_GetError() );
+    return 2;
+  }
+
+  /* Let's get some video information. */
+  info = SDL_GetVideoInfo( );
+
+  if ( !info )
+  {
+    std::cerr << "Video query failed: " << SDL_GetError() << std::endl;
+    return 2;
+  }
+       ilInit();
+       iluInit();
+       ilutRenderer(ILUT_OPENGL);
+
+  /*
+   * Now, we want to setup our requested
+   * window attributes for our OpenGL window.
+   * We want *at least* 5 bits of red, green
+   * and blue. We also want at least a 16-bit
+   * depth buffer.
+   *
+   * The last thing we do is request a double
+   * buffered window. '1' turns on double
+   * buffering, '0' turns it off.
+   *
+   * Note that we do not use SDL_DOUBLEBUF in
+   * the flags to SDL_SetVideoMode. That does
+   * not affect the GL attribute state, only
+   * the standard 2D blitting setup.
+   */
+  SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+  SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+  SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, bpp );
+  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+  flags = SDL_OPENGL | ( fullScreen ? SDL_FULLSCREEN : 0 );
+
+  /*
+   * Set the video mode
+   */
+  if ( ( imp->screen = SDL_SetVideoMode( width, height, bpp, flags ) ) == 0 )
+  {
+    /*
+     * This could happen for a variety of reasons,
+     * including DISPLAY not being set, the specified
+     * resolution not being available, etc.
+     */
+    std::cerr << "Video mode set failed: " << SDL_GetError() << std::endl;
+    return 2;
+  }
+
+  SDL_SetGamma(1.8, 1.8, 1.8);
+  
+  float ratio = ( float ) width / ( float ) height;
+  /* Our shading model--Gouraud (smooth). */
+  glShadeModel( GL_SMOOTH );
+  glClearDepth( 1.0f );
+
+  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+
+  //   glDepthFunc( GL_LEQUAL );
+  /* Set the clear color. */
+  glClearColor( bgcolour[ 0 ], bgcolour[ 1 ], bgcolour[ 2 ], bgcolour[ 3 ] );
+  glMatrixMode( GL_PROJECTION );
+  glLoadIdentity();
+
+  glViewport( 0, 0, width, height );
+  gluPerspective( 45.0, ratio, 1.0, 10000.0 );
+
+  /* Culling. Boh8aei sto Blending*/
+  glCullFace( GL_BACK );
+/* Polygons whose vertices are in counterclockwise order are called frontfacing but dx thinks different ?*/
+  glFrontFace( GL_CW );
+       if( culling)
+               glEnable( GL_CULL_FACE );
+
+       if(zBuffer)
+               glEnable( GL_DEPTH_TEST );
+       
+       glEnable( GL_TEXTURE_2D );
+  if ( alpha )
+    glEnable( GL_BLEND );
+  if ( lighting )
+    glEnable( GL_LIGHTING );
+
+  //TODO: 8a prepei na oristei synarthsh setMaterial...
+  float diffuse[] = {1.0, 1.0, 1.0, 1.0};
+  float specular[] = {0.0, 0.0, 0.0, 0.0};
+  float ambient[] = {  0.0, 0.0, 0.0, 0.0};
+  float  emissive[] = {0.0, 0.0, 0.0, 0.0};
+       glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse );
+       glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, specular );
+       glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, emissive );
+       glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ambient );
+
+  
+       if ( !queryExtension( "GL_EXT_texture_filter_anisotropic" ) )
+               std::cout << "Extension GL_EXT_texture_filter_anisotropic not found...\n";
+       else
+       {
+               glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropySupported);
+               std::cout << "max Anisotropy supported = " << maxAnisotropySupported << '\n';
+               supportsAnisotropic = true;
+       }
+       
+       /*glGenBuffers(1, &gpuBuf); // mono gia OpenGL 1.5 
+  glBindBuffer(GL_ARRAY_BUFFER, gpuBuf);            // mono gia OpenGL 1.5
+  glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &parameter); // mono gia OpenGL 1.5
+  printf("Buffer size is %d \n", parameter); */
+  if ( !queryExtension( "GL_ARB_point_sprite" ) )
+    std::cout << "Extension GL_ARB_point_sprite not found...\n";
+  else
+  {
+    // This is how will our point sprite's size will be modified by
+    // distance from the viewer
+    float quadratic[] =  { 1.0f, 0.0f, 0.01f };
+    glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic );
+    // Query for the max point size supported by the hardware
+    maxSize = 0.0f;
+    glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize );
+    // Clamp size to 100.0f or the sprites could get a little too big on some
+    // of the newer graphic cards. My ATI card at home supports a max point
+    // size of 1024.0f!
+
+    // The alpha of a point is calculated to allow the fading of points
+    // instead of shrinking them past a defined threshold size. The threshold
+    // is defined by GL_POINT_FADE_THRESHOLD_SIZE_ARB and is not clamped to
+    // the minimum and maximum point sizes.
+    glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, 60.0f );
+    glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, 10.0f );
+    glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, maxSize );
+
+    // Specify point sprite texture coordinate replacement mode for each
+    // texture unit
+    glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
+    glEnable( GL_POINT_SPRITE_ARB );
+    glEnable( GL_ARB_point_sprite );
+  }
+
+  std::cout << "OpenGL Version =" << glGetString( GL_VERSION ) << std::endl;
+  int _red,_green,_blue, _alpha, _depth, _stencil;
+  glGetIntegerv(GL_RED_BITS, &_red);
+  glGetIntegerv(GL_GREEN_BITS, &_green);
+  glGetIntegerv(GL_BLUE_BITS, &_blue);
+  glGetIntegerv(GL_ALPHA_BITS, &_alpha);
+  std::cout << "Color Buffers RGBA bits = " << _red <<  _green <<  _blue << _alpha << std::endl;
+  glGetIntegerv(GL_DEPTH_BITS, &_depth);
+  std::cout << "Depth Buffer bits = " << _depth << "\n";
+  glGetIntegerv(GL_STENCIL_BITS, &_stencil);
+  std::cout << "Stencil Buffer bits = " << _stencil << "\n";
+  int _aux;
+  glGetIntegerv(GL_AUX_BUFFERS, &_aux);
+  std::cout << "Aux buffers = " << _aux << "\n";
+  //   putenv("__GL_SYNC_TO_VBLANK=1");
+
+  //   XF86VidModeModeLine mode;
+  //   int unused;
+
+  //   Display *d = XOpenDisplay(NULL);
+  /*Bool XF86VidModeGetModeLine(
+               Display *display ,
+  int screen ,
+  int *dotclock_return ,
+  XF86VidModeModeLine *modeline );
+  */
+  //   printf("d=%p\n",d);
+  //   if(XF86VidModeGetModeLine(d, 0, &unused, &mode))
+  //   {
+
+  //           printf("OK  %d mexri %d\n", mode.hsyncstart, mode.hsyncend);
+  //   }
+  //   else
+  //           printf("not ok\n");
+  //   glXWaitVideoSyncSGI();
+  //   GLX_SGI_video_sync
+  //   unsigned int k;
+  //   glXGetVideoSyncSGI(&k);
+  //   printf("k=%d\n", k);
+  glMatrixMode( GL_MODELVIEW );
+
+  return 0;
+}
+
+
+
+void Graphics::beginScene( void )
+{
+  /* Clear the color and depth buffers. */
+  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+  glMatrixMode( GL_MODELVIEW );
+  glLoadIdentity();
+  //gia symbatothta me to DirectX
+  glScalef( -1.0, 1.0, 1.0 );
+  sceneBegin = true;
+
+  return ;
+}
+
+
+void Graphics::endScene()
+{
+  glColorMask(GL_TRUE, GL_TRUE,  GL_TRUE,  GL_TRUE);
+  //if(vSync)
+    //glXSwapIntervalSGI(1);
+  SDL_GL_SwapBuffers();
+
+  sceneBegin = false;
+  z_order = 1.0;
+  return ;
+}
+
+
+GLdouble mm[4][4];
+void _gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
+                 GLdouble centerx, GLdouble centery, GLdouble centerz,
+                 GLdouble upx, GLdouble upy, GLdouble upz )
+{
+  GLdouble m[ 16 ];
+  GLdouble x[ 3 ], y[ 3 ], z[ 3 ];
+  GLdouble mag;
+
+  /* Make rotation matrix */
+
+  /* Z vector */
+  z[ 0 ] = ( eyex - centerx );
+  z[ 1 ] = ( eyey - centery );
+  z[ 2 ] = ( eyez - centerz );
+  mag = sqrt( z[ 0 ] * z[ 0 ] + z[ 1 ] * z[ 1 ] + z[ 2 ] * z[ 2 ] );
+  if ( mag )
+  {                    /* mpichler, 19950515 */
+    z[ 0 ] /= mag;
+    z[ 1 ] /= mag;
+    z[ 2 ] /= mag;
+  }
+
+  /* Y vector */
+  y[ 0 ] = upx;
+  y[ 1 ] = upy;
+  y[ 2 ] = upz;
+
+  /* X vector = Y cross Z */
+  x[ 0 ] = y[ 1 ] * z[ 2 ] - y[ 2 ] * z[ 1 ];
+  x[ 1 ] = y[ 2 ] * z[ 0 ] - y[ 0 ] * z[ 2 ] ;
+  x[ 2 ] = y[ 0 ] * z[ 1 ] - y[ 1 ] * z[ 0 ];
+
+  /* Recompute Y = Z cross X */
+  y[ 0 ] = z[ 1 ] * x[ 2 ] - z[ 2 ] * x[ 1 ];
+  y[ 1 ] = -z[ 0 ] * x[ 2 ] + z[ 2 ] * x[ 0 ];
+  y[ 2 ] = z[ 0 ] * x[ 1 ] - z[ 1 ] * x[ 0 ];
+
+  /* mpichler, 19950515 */
+  /* cross product gives area of parallelogram, which is < 1.0 for
+  * non-perpendicular unit-length vectors; so normalize x, y here
+  */
+
+  mag = sqrt( x[ 0 ] * x[ 0 ] + x[ 1 ] * x[ 1 ] + x[ 2 ] * x[ 2 ] );
+  if ( mag )
+  {
+    x[ 0 ] /= mag;
+    x[ 1 ] /= mag;
+    x[ 2 ] /= mag;
+  }
+
+  mag = sqrt( y[ 0 ] * y[ 0 ] + y[ 1 ] * y[ 1 ] + y[ 2 ] * y[ 2 ] );
+  if ( mag )
+  {
+    y[ 0 ] /= mag;
+    y[ 1 ] /= mag;
+    y[ 2 ] /= mag;
+  }
+
+#define M(row,col)  m[col*4+row]
+  M( 0, 0 ) = x[ 0 ];
+  M( 0, 1 ) = x[ 1 ];
+  M( 0, 2 ) = x[ 2 ];
+  M( 0, 3 ) = -( x[ 0 ] * eyex + x[ 1 ] * eyey + x[ 2 ] * eyez );
+
+  M( 1, 0 ) = y[ 0 ];
+  M( 1, 1 ) = y[ 1 ];
+  M( 1, 2 ) = y[ 2 ];
+  M( 1, 3 ) = -( y[ 0 ] * eyex + y[ 1 ] * eyey + y[ 2 ] * eyez );
+
+  M( 2, 0 ) = z[ 0 ];
+  M( 2, 1 ) = z[ 1 ];
+  M( 2, 2 ) = z[ 2 ];
+  M( 2, 3 ) = -( z[ 0 ] * eyex + z[ 1 ] * eyey + z[ 2 ] * eyez );
+
+  M( 3, 0 ) = 0.0;
+  M( 3, 1 ) = 0.0;
+  M( 3, 2 ) = 0.0;
+  M( 3, 3 ) = 1.0;
+  /*   M(0, 0) = x[0];
+       M(1, 0) = y[0];
+       M(2, 0) = z[0];
+       M(3, 0) = 0.0;
+     
+       M(0, 1) = x[1];
+       M(1, 1) = y[1];
+       M(2, 1) = z[1];
+       M(3, 1) = 0.0;
+     
+       M(0, 2) = x[2];
+       M(1, 2) = y[2];
+       M(2, 2) = z[2];
+       M(3, 2) = 0.0;
+     
+       M(0, 3) = 0.0;
+       M(1, 3) = 0.0;
+       M(2, 3) = 0.0;
+       M(3, 3) = 1.0;
+  */
+#undef M
+  glScalef( -1.0, 1.0, 1.0 );
+  glMultMatrixd( m );
+  glScalef( -1.0, 1.0, 1.0 );
+
+}
+
+
+
+int Graphics::setCamera(  float camx,  float camy,  float camz,
+                          float lookx, float looky, float lookz,
+                          float upx,  float upy, float upz )
+{
+
+  _gluLookAt( camx, camy, camz, lookx, looky, lookz, upx, upy, upz );
+
+  cam.camx = camx;
+  cam.camy = camy;
+  cam.camz = camz;
+
+  cam.lookx = lookx;
+  cam.looky = looky;
+  cam.lookz = lookz;
+
+  cam.upx = upx;
+  cam.upy = upy;
+  cam.upz = upz;
+
+  return 0;
+}
+
+
+struct camera Graphics::getCamera()
+{
+  return cam;
+}
+
+
+
+
+int Graphics::renderTriangle(vertex v1, vertex v2, vertex v3 )
+{
+//   GLfloat colour[ 4 ];
+  if ( !sceneBegin )
+  {
+    std::cout << "DEBUG: oust...!\n";
+    exit( 1 );
+    return 1;
+  }
+
+
+//     glPushAttrib(GL_ALL_ATTRIB_BITS); //kyriws gia na epanaferoume to xrwma
+  glBegin( GL_TRIANGLES );
+
+//   transform_colourv( colour, v1.col );
+  glColor4f( v1.col.r, v1.col.g, v1.col.b, v1.col.a);
+  glNormal3f( v1.nx, v1.ny, v1.nz );
+  glTexCoord2f( v1.u, 1.0 - v1.v );
+  glVertex3f( v1.x, v1.y, v1.z );
+
+//   transform_colourv( colour, v2.col );
+//   glColor4f( colour[ 0 ], colour[ 1 ], colour[ 2 ], colour[ 3 ] );
+       glColor4f( v2.col.r, v2.col.g, v2.col.b, v2.col.a);
+  glNormal3f( v2.nx, v2.ny, v2.nz );
+  glTexCoord2f( v2.u, 1.0 - v2.v );
+  glVertex3f( v2.x, v2.y, v2.z );
+
+       glColor4f( v3.col.r, v3.col.g, v3.col.b, v3.col.a);
+  glNormal3f( v3.nx, v3.ny, v3.nz );
+  glTexCoord2f( v3.u, 1.0 - v3.v );
+  glVertex3f( v3.x, v3.y, v3.z );
+
+  glEnd();
+//     glPopAttrib();
+  //isos na prepei na epanafero pisw to arxiko xrwma...
+
+  return 0;
+}
+
+
+
+int Graphics::setWorld( float transx, float transy, float transz,
+                        float rotx, float roty, float rotz, float scalex, float scaley, float scalez,
+                                                        int rotationOrder)
+{
+  glMatrixMode( GL_MODELVIEW );
+  glLoadIdentity();
+
+  struct camera c = getCamera();
+  setCamera( c.camx, c.camy, c.camz, c.lookx, c.looky, c.lookz, c.upx, c.upy, c.upz );
+  
+  glScalef( -1.0, 1.0, 1.0 ); //gia symbatothta me to DirectX
+  glTranslatef( transx, transy, transz );
+
+  if(rotationOrder == AM_XYZ)
+  {
+               glRotatef( rotz, 0, 0, 1 );
+               glRotatef( roty, 0, 1, 0 );
+               glRotatef( rotx, 1, 0, 0 );
+  }
+  else if(rotationOrder == AM_XZY)
+  {
+         glRotatef( roty, 0, 1, 0 );     
+         glRotatef( rotz, 0, 0, 1 );
+         glRotatef( rotx, 1, 0, 0 );
+
+  }
+  else if(rotationOrder == AM_YZX)
+  {
+         glRotatef( rotx, 1, 0, 0 );
+         glRotatef( rotz, 0, 0, 1 );
+         glRotatef( roty, 0, 1, 0 );
+  }
+  else if(rotationOrder == AM_YXZ)
+  {
+         glRotatef( rotz, 0, 0, 1 );
+         glRotatef( rotx, 1, 0, 0 );
+         glRotatef( roty, 0, 1, 0 );
+
+  }
+  else if(rotationOrder == AM_ZXY)
+  {
+         glRotatef( roty, 0, 1, 0 );
+         glRotatef( rotx, 1, 0, 0 );
+         glRotatef( rotz, 0, 0, 1 );
+  }
+  else
+  {
+         glRotatef( rotx, 1, 0, 0 );
+         glRotatef( roty, 0, 1, 0 );
+         glRotatef( rotz, 0, 0, 1 );
+  }
+  
+  glScalef( scalex, scaley, scalez );
+  
+  return 0;
+}
+
+
+
+/*
+
+int Graphics::setWorld2( float transx, float transy, float transz,
+                                                               float rotx, float roty, float rotz, float scalex, float scaley, float scalez )
+{
+       glMatrixMode( GL_MODELVIEW );
+       glLoadIdentity();
+
+
+       struct camera c = getCamera();
+       setCamera( c.camx, c.camy, c.camz, c.lookx, c.looky, c.lookz, c.upx, c.upy, c.upz );
+  
+       glScalef( -1.0, 1.0, 1.0 ); //gia symbatothta me to DirectX
+       glTranslatef( transx, transy, transz );
+       glRotatef( roty, 0, 1, 0 );
+       glRotatef( rotz, 0, 0, 1 );
+       glRotatef( rotx, 1, 0, 0 );
+       glScalef( scalex, scaley, scalez );
+  
+
+       return 0;
+}
+
+  */
+
+
+
+
+
+void Graphics::setBackground( colour colour )
+{
+//   transform_colourv( bgcolour, colour );
+  //   printf( "(%f, %f, %f ,%f)\n", bgcolour[ 0 ], bgcolour[ 1 ], bgcolour[ 2 ], bgcolour[ 3 ] );
+       bgcolour[0] = colour.r;
+       bgcolour[1] = colour.g;
+       bgcolour[2] = colour.b;
+       bgcolour[3] = colour.a;
+       glClearColor( ( float ) bgcolour[ 0 ], ( float ) bgcolour[ 1 ], ( float ) bgcolour[ 2 ], ( float ) bgcolour[ 3 ] );
+       
+return ;
+}
+
+
+colour Graphics::getBackground( void )
+{
+       colour c;
+       c.r = bgcolour[0];
+       c.g = bgcolour[1];
+       c.b = bgcolour[2];
+       c.a = bgcolour[3];
+       return c;
+}
+       
+       
+
+
+void Graphics::project( float objx, float objy, float objz,
+                        //const double modelMatrix[16], const double projMatrix[16], const int viewport[4],
+                                                               float *winx, float *winy, float *winz )
+{
+  double _winx = 0;
+  double _winy = 0;
+  double _winz = 0;
+  GLint viewport[ 4 ];
+  GLdouble mvmatrix[ 16 ], projmatrix[ 16 ];
+
+  glGetIntegerv ( GL_VIEWPORT, viewport );
+  glGetDoublev ( GL_MODELVIEW_MATRIX, mvmatrix );
+  glGetDoublev ( GL_PROJECTION_MATRIX, projmatrix );
+
+  gluProject( objx, objy, objz, mvmatrix, projmatrix, viewport,
+              &_winx, &_winy, &_winz );
+
+  *winx = _winx;
+  *winy = viewport[ 3 ] - ( int ) _winy - 1;
+  *winz = _winz;
+
+  return ;
+}
+
+
+void Graphics::unproject( float winx, float winy, float winz,
+                          //const double modelMatrix[16], const double projMatrix[16], const int viewport[4],
+                                                                 float *objx, float *objy, float *objz )
+{
+  int realy;
+  double _objx = 0;
+  double _objy = 0;
+  double _objz = 0;
+       GLint viewport[ 4 ];
+  GLdouble mvmatrix[ 16 ], projmatrix[ 16 ];
+
+  glGetIntegerv ( GL_VIEWPORT, viewport );
+  glGetDoublev ( GL_MODELVIEW_MATRIX, mvmatrix );
+  glGetDoublev ( GL_PROJECTION_MATRIX, projmatrix );
+   
+  realy = viewport[ 3 ] - ( int ) winy - 1;
+  //    std::cout << "realy=" <<realy << "\n";
+
+  gluUnProject( winx, realy, winz,
+                mvmatrix, projmatrix, viewport,
+                &_objx, &_objy, &_objz );
+
+  *objx = _objx;
+  *objy = _objy;
+  *objz = _objz;
+
+  return ;
+}
+
+
+
+void Graphics::enableCursor( bool state )
+{
+       cursorState = state;
+       if ( state )
+               SDL_ShowCursor( SDL_ENABLE );
+       else
+               SDL_ShowCursor( SDL_DISABLE );
+  return;
+}
+
+bool Graphics::isCursor()
+{
+       return cursorState;
+}
+
+
+
+void Graphics::planeIntersect( float a, float b, float c, float d,
+                               float p1x, float p1y, float p1z, float p2x, float p2y, float p2z,
+                                                                                float *poutx, float *pouty, float *poutz )
+{
+  float numerator = -( a * p1x + b * p1y + c * p1z + d );
+  if ( numerator == 0 )
+  {
+    ( *poutx ) = p1x;
+    ( *pouty ) = p1y;
+    ( *poutz ) = p1z;
+    return ;
+  }
+  else
+  {
+    float denominator = a * ( p2x - p1x ) + b * ( p2y - p1y ) + c * ( p2z - p1z );
+    if ( denominator == 0 )
+    {
+      ( *poutx ) = 0.0;
+      ( *pouty ) = 0.0;
+      ( *poutz ) = 0.0;
+               printf("denominator==0!!!\n");
+               exit(1);
+      return ;
+    }
+    else
+    {
+      float t = numerator / denominator;
+      ( *poutx ) = p1x + t * ( p2x - p1x );
+      ( *pouty ) = p1y + t * ( p2y - p1y );
+      ( *poutz ) = p1z + t * ( p2z - p1z );
+      return ;
+    }
+  }
+
+  return ;
+}
+
+
+
+void Graphics::setLight( int numLight, const light& l )
+{
+       GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+       GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0};
+       GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0};
+       GLfloat position[] = {0.0, 0.0, 1.0, 0.0};
+       GLenum enm = GL_LIGHT0;
+
+       if(numLight == 0)  enm = GL_LIGHT0;
+       else if(numLight == 1) enm = GL_LIGHT1;
+       else if(numLight == 2) enm = GL_LIGHT2;
+       else if(numLight == 3) enm = GL_LIGHT3;
+       else if(numLight == 4) enm = GL_LIGHT4;
+       else if(numLight == 5) enm = GL_LIGHT5;
+       else if(numLight == 6) enm = GL_LIGHT6;
+       else if(numLight == 7 ) enm = GL_LIGHT7;
+
+//   transform_colourv( ambient, l.ambient );
+//   transform_colourv( diffuse, l.diffuse );
+//   transform_colourv( specular, l.specular );
+       ambient[0] = l.ambient.r;               ambient[1] = l.ambient.g;               ambient[2] = l.ambient.b;               ambient[3] = l.ambient.a;
+       diffuse[0] = l.diffuse.r;               diffuse[1] = l.diffuse.g;               diffuse[2] = l.diffuse.b;               diffuse[3] = l.diffuse.a;
+       specular[0] = l.specular.r;             specular[1] = l.specular.g;             specular[2] = l.specular.b;             specular[3] = l.specular.a;
+       
+       if ( l.type == AM_POINT_LIGHT )
+  {
+    position[ 3 ] = 1.0;
+    position[ 0 ] = l.posx;
+    position[ 1 ] = l.posy;
+    position[ 2 ] = l.posz;
+  }
+  else
+    if ( l.type == AM_DIRECTIONAL_LIGHT )
+    {
+                //float val = sqrt(l.dirx*l.dirx + l.diry*l.diry + l.dirz*l.dirz);
+                position[ 3 ] = 0.0;
+                position[ 0 ] = -l.dirx;
+                position[ 1 ] = -l.diry;
+                position[ 2 ] = l.dirz;
+    }
+
+
+  /*glPushMatrix();
+  glBegin(GL_POINTS);
+  glPointSize(1000.);
+  glVertex3f(position[0], position[1], position[2]);
+  glVertex3f(360, 10, 360);
+  glEnd();
+  */
+  glLightfv( enm, GL_AMBIENT, ambient );
+  glLightfv( enm, GL_DIFFUSE, diffuse );
+  glLightfv( enm, GL_SPECULAR, specular );
+  glLightfv( enm, GL_POSITION, position );
+  //   glPopMatrix();
+
+  return ;
+}
+
+
+void Graphics::showLight( int numLight, bool state )
+{
+  GLenum enm = GL_LIGHT0;
+  if ( numLight == 0 )
+    enm = GL_LIGHT0;
+  else
+    if ( numLight == 1 )
+      enm = GL_LIGHT1;
+    else
+      if ( numLight == 2 )
+        enm = GL_LIGHT2;
+
+  if ( state )
+    glEnable( enm );
+  else
+    glDisable( enm );
+
+  return ;
+}
+
+
+
+
+
+void inverseMatrix( double A[16], double B[16])
+{
+
+       double detA;
+       
+       double a11 = A[0];
+       double a12 = A[1];
+       double a13 = A[2];
+       double a14 = A[3];
+       double a21 = A[4];
+       double a22 = A[5];
+       double a23 = A[6];
+       double a24 = A[7];
+       double a31 = A[8];
+       double a32 = A[9];
+       double a33 = A[10];
+       double a34 = A[11];
+       double a41 = A[12];
+       double a42 = A[13];
+       double a43 = A[14];
+       double a44 = A[15];
+       
+       detA =  a11*a22*a33*a44 + a11*a23*a34*a42 + a11*a24*a32*a43 \
+                       +a12*a21*a34*a43 + a12*a23*a31*a44 + a12*a24*a33*a41 \
+                       +a13*a21*a32*a44 + a13*a22*a34*a41 + a13*a24*a31*a42 \
+                       +a14*a21*a33*a42 + a14*a22*a31*a43 + a14*a23*a32*a41 \
+                       -a11*a22*a34*a43 - a11*a23*a32*a44 - a11*a24*a33*a42 \
+                       -a12*a21*a33*a44 - a12*a23*a34*a41 - a12*a24*a31*a43 \
+                       -a13*a21*a34*a42 - a13*a22*a31*a44 - a13*a24*a32*a41 \
+                       -a14*a21*a32*a43 - a14*a22*a33*a41 - a14*a23*a31*a42;
+
+//     printf("detA=%f\n",detA); 
+       
+       B[0] = (a22*a33*a44 + a23*a34*a42 + a24*a32*a43 - a22*a34*a43 - a23*a32*a44 - a24*a33*a42)/detA;
+       B[1] = (a12*a34*a43 + a13*a32*a44 + a14*a33*a42 - a12*a33*a44 - a13*a34*a42 - a14*a32*a43)/detA;
+       B[2] = (a12*a23*a44 + a13*a24*a42 + a14*a22*a43 - a12*a24*a43 - a13*a22*a44 - a14*a23*a42)/detA; 
+       B[3] = (a12*a24*a33 + a13*a22*a34 + a14*a23*a32 - a12*a23*a34 - a13*a24*a32 - a14*a22*a33)/detA;
+       B[4] = (a21*a34*a43 + a23*a31*a44 + a24*a33*a41 - a21*a33*a44 - a23*a34*a41 - a24*a31*a43)/detA;
+       B[5] = (a11*a33*a44 + a13*a34*a41 + a14*a31*a43 - a11*a34*a43 - a13*a31*a44 - a14*a33*a41)/detA;
+       B[6] = (a11*a24*a43 + a13*a21*a44 + a14*a23*a41 - a11*a23*a44 - a13*a24*a41 - a14*a21*a43)/detA;
+       B[7] = (a11*a23*a34 + a13*a24*a31 + a14*a21*a33 - a11*a24*a33 - a13*a21*a34 - a14*a23*a31)/detA;
+       B[8] = (a21*a32*a44 + a22*a34*a41 + a24*a31*a42 - a21*a34*a42 - a22*a31*a44 - a24*a32*a41)/detA;
+       B[9] = (a11*a34*a42 + a12*a31*a44 + a14*a32*a41 - a11*a32*a44 - a12*a34*a41 - a14*a31*a42)/detA;
+       B[10] = (a11*a22*a44 + a12*a24*a41 + a14*a21*a42 - a11*a24*a42 - a12*a21*a44 - a14*a22*a41)/detA;
+       B[11] = (a11*a24*a32 + a12*a21*a34 + a14*a22*a31 - a11*a22*a34 - a12*a24*a31 - a14*a21*a32)/detA;
+       B[12] = (a21*a33*a42 + a22*a31*a43 + a23*a32*a41 - a21*a32*a43 - a22*a33*a41 - a23*a31*a42)/detA;
+       B[13] = (a11*a32*a43 + a12*a33*a41 + a13*a31*a42 - a11*a33*a42 - a12*a31*a43 - a13*a32*a41)/detA;
+       B[14] = (a11*a23*a42 + a12*a21*a43 + a13*a22*a41 - a11*a22*a43 - a12*a23*a41 - a13*a21*a42)/detA;
+       B[15] = (a11*a22*a33 + a12*a23*a31 + a13*a21*a32 - a11*a23*a32 - a12*a21*a33 - a13*a22*a31)/detA;
+
+       return;
+}
+
+
+
+void Graphics::drawBillboardParticle(float x, float y, float z, float size, colour col)
+{
+//   float v[4];
+  
+  glPushAttrib(GL_ALL_ATTRIB_BITS);
+  glDisable(GL_DEPTH_TEST);
+  glDepthMask( GL_FALSE );
+  enableAlpha(true);
+  glBlendFunc( GL_SRC_ALPHA, GL_ONE );
+  glDisable(GL_CULL_FACE);
+  glEnable( GL_TEXTURE_2D );
+  /*********************************/
+  GLdouble modelview[16], B[16];
+  // save the current modelview matrix
+  glPushMatrix();
+  // get the current modelview matrix
+  glGetDoublev(GL_MODELVIEW_MATRIX , modelview);
+  inverseMatrix(modelview, B);
+  // set the modelview with no rotations and scaling
+        glMultMatrixd(B);
+        glLoadMatrixd(modelview);
+       glTranslatef(x,y,z);
+       
+   float s2 = size / 2.0;
+//   transform_colourv(v, col);
+  glBegin(GL_QUADS);
+       glColor4f(col.r, col.g, col.b, col.a);
+       glTexCoord2f( 0.0, 0.0 );       glVertex3f(-s2,s2,0);
+       glTexCoord2f( 1.0, 0.0 );       glVertex3f(s2,s2,0);
+       glTexCoord2f( 1.0, 1.0 );       glVertex3f(s2,-s2,0);
+       glTexCoord2f( 0.0, 1.0 );       glVertex3f(-s2,-s2,0);
+  glEnd();
+
+  // restores the modelview matrix
+  glPopMatrix();
+  /*********************************/
+  glPopAttrib();
+
+  return;
+}
+
+
+void Graphics::renderParticleArray(particle *array, unsigned int sizeOfArray, int type)
+{
+       unsigned int i;
+       
+       if(type == AM_HARDWARE_PARTICLE)
+       {       
+               glPushAttrib(GL_ALL_ATTRIB_BITS);
+                       glEnable(GL_DEPTH_TEST);
+                       glDepthMask( GL_FALSE );
+                       enableAlpha(true);
+                       glBlendFunc( GL_DST_ALPHA, GL_ONE );
+                       
+                       for(i=0; i < sizeOfArray; i++)
+                       {
+                               glPointSize( (array[i].size > maxSize ? maxSize : array[i].size) );
+                               glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, (array[i].size > maxSize ? maxSize : array[i].size)  );
+                               glBegin(GL_POINTS);
+                                       glColor4f(array[i].col.r, array[i].col.g, array[i].col.b, array[i].col.a);
+                                       glVertex3f(array[i].x, array[i].y, array[i].z);
+                               glEnd();
+                       }
+               glPopAttrib();
+       }
+       else
+       if(type == AM_SOFTWARE_PARTICLE)
+       {
+               float mat[16];
+               struct point
+               {
+                       float x,y,z;
+               }quad_lower_left, quad_lower_right;
+  
+               glPushAttrib(GL_ALL_ATTRIB_BITS);
+                       glEnable(GL_DEPTH_TEST);
+                       enableAlpha(true);
+                       glBlendFunc( GL_SRC_ALPHA, GL_ONE );
+                       glDisable(GL_CULL_FACE);
+                       glEnable( GL_TEXTURE_2D );
+                       glGetFloatv( GL_MODELVIEW_MATRIX, mat );
+                       
+                       for(i=0; i < sizeOfArray; i++)
+                       {
+                               float s2 = array[i].size / 2.0;
+                               quad_lower_left.x = (-s2) * (mat[0] + mat[1]);
+                               quad_lower_left.y = (-s2) * (mat[4] + mat[5]);
+                               quad_lower_left.z = (-s2) * (mat[8] + mat[9]);
+                               quad_lower_right.x = (s2) * (mat[0] - mat[1]);
+                               quad_lower_right.y = (s2) * (mat[4] - mat[5]);
+                               quad_lower_right.z = (s2) * (mat[8] - mat[9]);
+
+                               glBegin(GL_QUADS);
+                                       glColor4f(array[i].col.r, array[i].col.g, array[i].col.b, array[i].col.a);
+                                       glTexCoord2f(0.0, 0.0);
+                                       glVertex3f(array[i].x + quad_lower_left.x, array[i].y + quad_lower_left.y, array[i].z + quad_lower_left.z);
+                                       glTexCoord2f(1.0, 0.0);
+                                       glVertex3f(array[i].x + quad_lower_right.x, array[i].y + quad_lower_right.y, array[i].z + quad_lower_right.z);
+                                       glTexCoord2f(1.0, 1.0);
+                                       glVertex3f(array[i].x - quad_lower_left.x, array[i].y - quad_lower_left.y, array[i].z - quad_lower_left.z);
+                                       glTexCoord2f(0.0, 1.0);
+                                       glVertex3f(array[i].x - quad_lower_right.x, array[i].y - quad_lower_right.y, array[i].z - quad_lower_right.z);
+                               glEnd();
+                       }
+               glPopAttrib();
+       }
+       
+       return; 
+}
+
+
+
+
+void Graphics::renderParticle(float x, float y, float z, float size, colour col, int type)
+{
+       if(type == AM_HARDWARE_PARTICLE)
+       {       
+               glPushAttrib(GL_ALL_ATTRIB_BITS);
+               glPointSize( (size > maxSize ? maxSize : size) );
+               glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, (size > maxSize ? maxSize : size)  );
+               glEnable(GL_DEPTH_TEST);
+               glDepthMask( GL_FALSE );
+               enableAlpha(true);
+//             glBlendFunc( GL_SRC_ALPHA, GL_ONE );
+               glBlendFunc( GL_DST_ALPHA, GL_ONE );
+               glBegin(GL_POINTS);
+//             float v[4];
+//             transform_colourv(v, col);
+               glColor4f(col.r , col.g, col.b, col.a);
+               glVertex3f(x,y,z);
+               glEnd();
+               glPopAttrib();
+       }
+       else
+               if(type == AM_SOFTWARE_PARTICLE)
+               {
+//                     float v[4];
+                       float mat[16];
+                       struct point
+                       {
+                               float x,y,z;
+               
+                       }quad_lower_left,quad_lower_right;
+  
+                       glPushAttrib(GL_ALL_ATTRIB_BITS);
+                       glEnable(GL_DEPTH_TEST);
+//     glDepthMask( GL_FALSE );
+                       enableAlpha(true);
+                       glBlendFunc( GL_SRC_ALPHA, GL_ONE );
+                       glDisable(GL_CULL_FACE);
+                       glEnable( GL_TEXTURE_2D );
+
+//     glPushMatrix();
+       // Get modelview matrix. We will only use the upper left 3x3 part of
+    // the matrix, which represents the rotation.
+                       glGetFloatv( GL_MODELVIEW_MATRIX, mat );
+
+    // 1) & 2) We do it in one swift step:
+                       // Although not obvious, the following six lines represent two matrix/
+    // vector multiplications. The matrix is the inverse 3x3 rotation
+    // matrix (i.e. the transpose of the same matrix), and the two vectors
+    // represent the lower left corner of the quad, PARTICLE_SIZE/2 *
+    // (-1,-1,0), and the lower right corner, PARTICLE_SIZE/2 * (1,-1,0).
+    // The upper left/right corners of the quad is always the negative of
+    // the opposite corners (regardless of rotation).
+                       float s2 = size / 2.0;
+                       quad_lower_left.x = (-s2) * (mat[0] + mat[1]);
+                       quad_lower_left.y = (-s2) * (mat[4] + mat[5]);
+                       quad_lower_left.z = (-s2) * (mat[8] + mat[9]);
+                       quad_lower_right.x = (s2) * (mat[0] - mat[1]);
+                       quad_lower_right.y = (s2) * (mat[4] - mat[5]);
+                       quad_lower_right.z = (s2) * (mat[8] - mat[9]);
+
+            // 3) Translate the quad to the correct position in modelview
+            // space and store its parameters in vertex arrays (we also
+            // store texture coord and color information for each vertex).
+//                     transform_colourv(v, col);
+                       glBegin(GL_QUADS);
+                       glColor4f(col.r, col.g, col.b, col.a);
+               // Lower left corner
+                       glTexCoord2f(0.0, 0.0);
+                       glVertex3f(x + quad_lower_left.x, y + quad_lower_left.y, z + quad_lower_left.z);
+//             printf("1. %f %f %f\n",x + quad_lower_left.x, y + quad_lower_left.y, z + quad_lower_left.z);
+            // Lower right corner
+                       glTexCoord2f(1.0, 0.0);
+                       glVertex3f(x + quad_lower_right.x, y + quad_lower_right.y, z + quad_lower_right.z);
+//             printf("2. %f %f %f\n",x + quad_lower_right.x, y + quad_lower_right.y, z + quad_lower_right.z); 
+            // Upper right corner
+                       glTexCoord2f(1.0, 1.0);
+                       glVertex3f(x - quad_lower_left.x, y - quad_lower_left.y, z - quad_lower_left.z);
+//             printf("3. %f %f %f\n", x - quad_lower_left.x, y - quad_lower_left.y, z - quad_lower_left.z);
+            // Upper left corner
+                       glTexCoord2f(0.0, 1.0);
+                       glVertex3f(x - quad_lower_right.x, y - quad_lower_right.y, z - quad_lower_right.z);
+//             printf("4. %f %f %f\n", x - quad_lower_right.x, y - quad_lower_right.y, z - quad_lower_right.z);
+                       glEnd();
+ // restores the modelview matrix
+//     glPopMatrix();
+                       /*********************************/
+                       glPopAttrib();
+               }
+                       
+       return;
+}
+
+
+/* - fov
+                       Specifies the field of view angle, in degrees, in the y direction.
+       -       ratio
+                       Specifies the aspect ratio that determines the field of view in the x direction. 
+                       The aspect ratio is the ratio of x (width) to y (height).
+  -    zNear
+                       Specifies the distance from the viewer to the near clipping plane (always positive).
+  -    zFar
+                       Specifies the distance from the viewer to the far clipping plane (always positive).
+*/
+void Graphics::setPerspective(float fov, float ratio, float zNear, float zFar)
+{
+       int matrixMode;
+       
+       glGetIntegerv( GL_MATRIX_MODE, &matrixMode);
+       glMatrixMode( GL_PROJECTION );
+       glLoadIdentity();
+       gluPerspective( fov, ratio, zNear, zFar );
+       glMatrixMode( matrixMode );
+       return;
+}
+
+
+void Graphics::renderVertexArray(vertex *array, unsigned int numOfPrimitives, int type)
+{
+       int t = type;
+       if(type == AM_TRIANGLE_STRIP)
+               t = GL_TRIANGLE_STRIP;
+       else if (type == AM_TRIANGLE_FAN)
+               t = GL_TRIANGLE_FAN;
+       else if (type == AM_TRIANGLES)
+               t = GL_TRIANGLES;
+       else if (type == AM_POINT_LIST)
+               t = GL_POINTS;
+       else if (type ==  AM_LINE_LIST)
+               t = GL_LINES;
+       else if (type == AM_LINE_STRIP)
+               t = GL_LINE_STRIP;
+       
+        // UGLY hack to reverse texture coordinate...implement an operator in struct vertex..?!?
+       vertex *tmp = new vertex[numOfPrimitives];
+       memcpy(tmp, array, numOfPrimitives*sizeof(vertex));
+       int i;
+       for(i=0; i < numOfPrimitives; i++)
+               tmp[i].v = 1 - tmp[i].v;
+
+       glInterleavedArrays( GL_T2F_C4F_N3F_V3F, 0, (void *) tmp);
+       glDrawArrays( t, 0, numOfPrimitives);
+
+       delete tmp;
+       return;
+}
+
+
+void Graphics::setCullingMode(int mode)
+{
+       cmode = mode;
+       if(mode == AM_CULL_NONE)
+   {
+      culling = false;
+      glDisable(GL_CULL_FACE );
+      return;
+   }
+   else
+   {
+               if(!culling)
+               {
+                       culling = true;
+                       glEnable( GL_CULL_FACE );
+               }
+               if(mode == AM_CULL_FRONT)
+                       glCullFace(GL_FRONT);
+               else if (mode == AM_CULL_BACK) 
+                       glCullFace(GL_BACK);
+   }
+   return;
+} 
+
+int Graphics::getCullingMode()
+{
+       return cmode;
+}
+
+
+
+void Graphics::enter2dMode(void)
+{
+       glPushAttrib( GL_ALL_ATTRIB_BITS );
+       glDisable( GL_LIGHTING );
+       glDisable( GL_DEPTH_TEST );
+       glDisable( GL_CULL_FACE );
+       glEnable( GL_TEXTURE_2D );
+       glViewport( 0, 0, getWidth(), getHeight() );
+       glMatrixMode( GL_PROJECTION );
+       glPushMatrix();
+       glLoadIdentity();
+       glOrtho( 0.0, ( GLdouble ) getWidth(), ( GLdouble ) getHeight(), 0.0, 0.0, 1.0 );
+       glMatrixMode( GL_MODELVIEW );
+       glPushMatrix();
+       glLoadIdentity();
+       //      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+       return ;
+}
+void Graphics::leave2dMode(void)
+{
+       glMatrixMode( GL_MODELVIEW );
+       glPopMatrix();
+       glMatrixMode( GL_PROJECTION );
+       glPopMatrix();
+       glPopAttrib();
+       return ;
+}
+
+
+void Graphics::enableDepthBuffer( bool b )
+{
+       zBuffer = b;
+       if(b)
+               glEnable( GL_DEPTH_TEST );
+       else
+               glDisable( GL_DEPTH_TEST );
+               
+       return;
+}
+
+
+bool Graphics::isDepthBuffer()
+{
+       return zBuffer;
+}
+
+
+
+/*--------------------------------------------------
+*                                                                               Texture
+*-----------------------------------------------------*/
+
+
+
+Texture::Texture(  char *file, colour key, Graphics *g )
+{
+       gl_Tex = 0;
+       filteringDefinition = filtering = AM_LINEAR;
+       this->g = g;
+       glEnable( GL_TEXTURE_2D );
+       colourKey = key;
+       colourKeyEnabled = true;
+
+       // CreateTexture(&gl_Tex, file, 0);
+       LoadGLTextures( &gl_Tex, file );
+       std::cout << "file=" << file << ", gl_Tex=" << gl_Tex << "\n";
+
+  return ;
+}
+
+
+Texture::Texture( char *file, Graphics *g)
+{
+       gl_Tex = 0;
+  this->g = g;
+  filteringDefinition = filtering = AM_LINEAR;
+  glEnable( GL_TEXTURE_2D );
+  assert(g);
+  colourKeyEnabled = false;
+  // CreateTexture(&gl_Tex, file, 0);
+  LoadGLTextures( &gl_Tex, file );
+  std::cout << "file=" << file << ", gl_Tex=" << gl_Tex << "\n";
+
+  return ;
+}
+
+Texture::Texture(void *data, unsigned int w, unsigned int h, int format, int type, Graphics *g)
+{
+       gl_Tex = 0;
+       filteringDefinition = filtering = AM_LINEAR;
+       this->g = g;
+       assert(g);
+       colourKeyEnabled = false;
+       
+       glEnable( GL_TEXTURE_2D );
+       glGenTextures(1, &gl_Tex);
+       glBindTexture( GL_TEXTURE_2D, gl_Tex );
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+       
+       GLenum f = GL_RGBA, t = GL_UNSIGNED_BYTE;
+       int c = 4;
+       
+       if(format == AM_ALPHA)
+       {
+               f = GL_ALPHA;
+               c = GL_ALPHA; /* Warning!!! Dont change this value cause font rendering depends on it!*/
+       }       
+       else if (format == AM_RGBA)
+       {
+                       f = GL_RGBA;
+                       c = 4;
+       }
+       
+       if(type == AM_UBYTE)
+               t = GL_UNSIGNED_BYTE;
+       
+       //glTexImage2D( GL_TEXTURE_2D, 0, c, w, h, 0,   f, t, data);
+       gluBuild2DMipmaps( GL_TEXTURE_2D, c, w, h,      f, t, data);
+               
+       this->width = w;
+       this->height = h;
+
+       std::cout << "gl_Tex=" << gl_Tex << "\n";
+
+       return ;
+}
+
+
+
+Texture::~Texture()
+{
+  return ;
+}
+
+
+/*
+unsigned int Texture::gl_getGLTex()
+{
+  return gl_Tex;
+}
+*/
+
+void Texture::texSubImage2D(int xoff, int yoff, unsigned int w, unsigned int h, int format, int type, const void *pixels)
+{
+       GLenum f = GL_RGBA, t = GL_UNSIGNED_BYTE;
+       
+       if(format == AM_ALPHA)
+               f = GL_ALPHA;
+       else if (format == AM_RGBA)
+               f = GL_RGBA;
+       
+       if(type == AM_UBYTE)
+               t = GL_UNSIGNED_BYTE;
+
+       glBindTexture(GL_TEXTURE_2D, this->gl_Tex);
+       glTexSubImage2D(GL_TEXTURE_2D, 0, xoff, yoff, w, h, f, t, pixels);
+       
+       //TODO kane popAttributes etsi wste na einai current texture auto pou htan prin...
+        
+       return;
+}
+
+unsigned long Texture::getWidth()
+{
+  return width;
+}
+
+unsigned long Texture::getHeight()
+{
+  return height;
+}
+
+
+int Texture::getFiltering()
+{
+       return filteringDefinition;
+}
+
+
+/* this function needs some fixes and some rewrite */
+void Texture::setFiltering(int f, float anisotropyLevel)
+{
+       int _f  = f;
+       if(f == AM_LINEAR)
+               _f = GL_LINEAR;
+       else if (f == AM_PLAIN)
+               _f = GL_NEAREST;
+       
+       filteringDefinition = filtering = f;
+       if(_f == AM_ANISOTROPIC)
+       {
+               if(supportsAnisotropic)
+               {
+                       float a = anisotropyLevel;
+                       if( a > maxAnisotropySupported) //fix this for round-off errors
+                               a = maxAnisotropySupported;
+                       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, a);
+               }
+               filtering = GL_LINEAR;
+       }
+       // 'filtering' cannot have here a value of AM_ANISOTROPIC
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering );
+       
+       return;
+}
+
+
+void Texture::LoadGLTextures( GLuint *gl_Tex, const char * filename )
+{
+       /*gl_Tex = ilutGLLoadImage( (char *) filename);
+       glBindTexture( GL_TEXTURE_2D, *gl_Tex ); 
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+*/
+       
+       // Generate the main image name to use.
+       ilGenImages (1, gl_Tex);
+       ilBindImage (*gl_Tex);
+       ilEnable(IL_ORIGIN_SET);
+       ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
+       if (!ilLoadImage ((char *)filename)) 
+               printf("cannot load image %s \n", filename);
+       
+       ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
+
+       ILinfo imageInfo;
+       iluGetImageInfo(&imageInfo); 
+       ILubyte *data = ilGetData();
+       printf("image info. %d x %d depth=%d Bp=%d data=%d\n", imageInfo.Width, imageInfo.Height, imageInfo.Depth, imageInfo.Bpp,
+                                                       imageInfo.SizeOfData);
+       bool a = false;
+       if ( colourKeyEnabled )
+       {
+               //ksepaketaroume to colourkey
+               unsigned char ckR = 0, ckG = 0, ckB = 0, ckA = 255;
+               unsigned long mR, mG, mB, mA;
+               mB = 0x000000FF;
+               mG = 0x0000FF00;
+               mR = 0x00FF0000;
+               mA = 0xFF000000;
+       ckR = (unsigned char) (colourKey.r * 255.0) ;
+       ckG = (unsigned char) (colourKey.g * 255.0) ;
+       ckB = (unsigned char) (colourKey.b * 255.0) ;
+       ckA = (unsigned char) (colourKey.a * 255.0) ;
+               unsigned char _r, _g, _b; 
+               assert(g);
+               a = g->isAlpha();
+               g->enableAlpha(true);
+               int step = imageInfo.Bpp;
+               for(unsigned long i=0; i <  imageInfo.SizeOfData; i+=step)
+               {
+                       _r = data[i];
+                       _g = data[i + 1];
+                       _b= data[i + 2];
+               
+       if ( _r == ckR && _g == ckG && _b == ckB )
+                               data[i + 3] = 0;
+               }
+       }
+
+       glBindTexture( GL_TEXTURE_2D, *gl_Tex ); 
+
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering );
+       
+//     glTexImage2D( GL_TEXTURE_2D, 0, 4, imageInfo.Width, imageInfo.Height, 0,        GL_RGBA, GL_UNSIGNED_BYTE, data );
+       
+       gluBuild2DMipmaps( GL_TEXTURE_2D, 4, imageInfo.Width, imageInfo.Height,
+                                                        GL_RGBA, GL_UNSIGNED_BYTE, data);
+       
+       
+       width = imageInfo.Width;
+       height = imageInfo.Height;
+       if ( colourKeyEnabled ) 
+               g->enableAlpha(a);
+
+       return ;
+}