+/***************************************************************************
+ * 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, ¶meter); // 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 ;
+}