///****************************************************************************** //* //* Projeto: Visualizador em Tempo Real //* //* Modulo: lua_scene_text.cpp //* //* Objetivo: A simple solar system Sun+Earth+Moon using the concept of scene //* graph. //* //* Versao Original: 1.0 Data: October 2001 //* //* Autor: Ismael H F Santos //* //* Email: ismael@cenpes.petrobras.com.br, //* ismael@tecgraf.puc-rio.br, //* ismaelh@uol.com.br //* //******************************************************************************* //* //* Historico de Alteracoes: //* //* DATA AUTOR COMENTARIO //* ---- ----- ---------- //* xx/yy/00 .... .... //* //*******************************************************************************/ // The debugger can't handle symbols more than 255 characters long. // STL often crias symbols longer than that. // When symbols are longer than 255 characters, the warning is disabled. #pragma warning(disable:4786) #include using namespace std; #include #include #include #include #include #ifdef WIN32 #include #endif #include "GL/gl.h" #include "GL/glu.h" #include "GL/glut.h" #include #include "nrutil.h" #include "util_gl.h" //#include "arqs.h" /* define variable to control the current time */ static double time = 0.0; /* in hours */ /* define numerical constants */ static const double TimeStep = 0.1; /* time step in hours */ static const double OneDay = 24; /* 24 hours in one day */ static const double OneYear = 365; /* 50 days in one year */ static const double OneHour = 1; /* 60 minutos em uma hora */ static const double SunRadius = 10; /* sun radius */ static const double EarthRadius = 6; /* planet radius */ static const double EarthDistance = 40; /* planet EarthDistance from the sun */ static const double MoonRadius = 2;/* moon radius */ static const double MoonEarthDistance = 10;/* moon EarthDistance from the planet */ /* Vetor de Texturas carregadas */ typedef enum { SUN_TEXTURE =0, MOON_TEXTURE =1, EARTH_TEXTURE=2, MAX_TEXTURAS =3 } TEXTURE_INDICE; typedef struct { char *file; GLuint name; // OpenGL id for texture bool mipmap; // texture parameters bool modulate; int height, width, border; // Image parameters unsigned char *image; } TEXTURA; static TEXTURA Texture[MAX_TEXTURAS]; /*---------------------*/ /* applyTexture */ /*---------------------*/ static void applyTexture( const TEXTURA const *texture ) { // Aplica textura corrente //------------------------ glBindTexture(GL_TEXTURE_2D, texture->name); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); //GL_REPEAT//GL_CLAMP glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); if ( texture->mipmap ) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //GL_NEAREST//GL_LINEAR glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); //GL_NEAREST//GL_LINEAR_MIPMAP_LINEAR } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //GL_NEAREST//GL_LINEAR glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } // Faz modulacao da textura //------------------------- if( texture->modulate ) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); else glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); //GL_REPLACE//GL_DECAL//GL_MODULATE // Checa ocorrencia de erro no OpenGL CheckGLError(OUTPUT_SCREEN); } /*---------------------*/ /* loadTexture */ /*---------------------*/ static void loadTexture( char *texFile, TEXTURA *const texture, bool mipmap, bool modulate ) { cerr<<"Carregando Textura: "<file = strdup(texFile); texture->mipmap = mipmap; texture->modulate = modulate; int type, palSize, width, height; if( imImageInfo((char*)texFile, &width, &height, &type, &palSize) != IM_ERR_NONE ) return; if ( type == IM_MAP ) // So trata imagens em truecolor return; else { // Leitura do arquivo de imagem //----------------------------- unsigned char *red, *green, *blue; ALOC_VECTOR_CAST(unsigned char*, red, 0, height*width-1); ALOC_VECTOR_CAST(unsigned char*, green, 0, height*width-1); ALOC_VECTOR_CAST(unsigned char*, blue, 0, height*width-1); // Cadastra callback de leitura da imagem //--------------------------------------- // imRegisterCallback(imCounterCb, IM_COUNTER_CB, IM_ALL); if( imLoadRGB((char*)texFile, red, green, blue) != IM_ERR_NONE ) { cerr<<"Erro ao ler arquivo de texura: #"<border=0; texture->width = 1; while( texture->width+2*texture->border < width ) texture->width *= 2; texture->width += 2*texture->border; texture->height = 1; while( texture->height+2*texture->border < height ) texture->height *= 2; texture->height += 2*texture->border; ALOC_VECTOR_CAST(unsigned char*, texture->image, 0, 3*texture->height*texture->width-1); unsigned char *pix=texture->image, *r=red, *g=green, *b=blue; for( int j=0; jname); glBindTexture(GL_TEXTURE_2D, texture->name); if ( mipmap ) gluBuild2DMipmaps(GL_TEXTURE_2D, 3, (GLint)texture->height, (GLint)texture->width, GL_RGB, GL_UNSIGNED_BYTE, texture->image); else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)texture->width, (GLsizei)texture->height, (GLint)texture->border, GL_RGB, GL_UNSIGNED_BYTE, texture->image); //Libera espacos alocados // FREE_VECTOR(texture->image); } // Checa ocorrencia de erro no OpenGL CheckGLError(OUTPUT_SCREEN); } // Fim de loadTexture /*-----------------------*/ /* draw sphere using GLU */ /*-----------------------*/ static void drawSphere( double radius, const TEXTURA const *texture ) { static GLUquadricObj* qObj = NULL; if (!qObj) qObj = gluNewQuadric(); glRotated(-90,1,0,0); if( texture != NULL ) { glEnable(GL_TEXTURE_2D); applyTexture(texture); // gluQuadricOrientation(qObj, GLU_OUTSIDE); gluQuadricTexture(qObj, GL_TRUE); gluSphere(qObj,radius,64,64); glDisable(GL_TEXTURE_2D); } else { gluSphere(qObj,radius,64,64); } } /*---------------------*/ /* draw disk using GLU */ /*---------------------*/ static void drawDisk( double inerRadius, double outerRadius, const TEXTURA const *texture ) { static GLUquadricObj* qObj = NULL; if (!qObj) qObj = gluNewQuadric(); glRotated(90,1,0,0); if( texture != NULL ) { glEnable(GL_TEXTURE_2D); applyTexture(texture); gluQuadricOrientation(qObj, GLU_OUTSIDE); gluQuadricTexture(qObj, GL_TRUE); gluDisk(qObj,inerRadius,outerRadius,64,64); glDisable(GL_TEXTURE_2D); } else { gluDisk(qObj,inerRadius,outerRadius,64,64); } } /*---------------------*/ /* render moon */ /*---------------------*/ static void drawMoon( void ) { /*----------------------*/ /* define Moon material */ /*----------------------*/ { GLfloat color[] = {1,1,1,1}; glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,color); } /*-----------*/ /* draw moon */ /*-----------*/ { double teta_moon = 360.*time/(OneDay*OneHour); glPushMatrix(); glRotated(teta_moon,0,1,0); drawSphere(MoonRadius, &Texture[MOON_TEXTURE]); glPopMatrix(); } /*------------------*/ /* restore material */ /*------------------*/ { GLfloat none[] = {0,0,0,1}; glMaterialfv(GL_FRONT,GL_EMISSION,none); } } static void renderMoon(void) { /*----------------------------------------*/ /* Apply transform for sub-tree of Earth */ /*----------------------------------------*/ glPushMatrix(); double angle_day = 360.*time/(1.*OneDay); // Divide by 10. to smooth moonīs movement !!! glRotated(angle_day,0,1,0); glTranslated(MoonEarthDistance,0,0); /*-----------*/ /* draw moon */ /*-----------*/ drawMoon(); glPopMatrix(); } /*-----------------------*/ /* render planet */ /*-----------------------*/ static void drawEarth(void) { /*-------------*/ /* draw planet */ /*-------------*/ glPushMatrix(); double teta_plan = 360.*time/(OneDay*OneHour); glRotated(teta_plan,0,1,0); /*------------------------*/ /* define planet material */ /*------------------------*/ { GLfloat color[] = {1,1,1,1}; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE,color); } drawSphere(EarthRadius, &Texture[EARTH_TEXTURE]); /*------------------*/ /* restore material */ /*------------------*/ { GLfloat none[] = {0,0,0,1}; glMaterialfv(GL_FRONT,GL_EMISSION,none); } glPopMatrix(); } static void renderEarth(void) { /*----------------------------------------*/ /* Apply transform for sub-tree of Earth */ /*----------------------------------------*/ glPushMatrix(); double angle_year = 360.*time/(OneDay*OneYear); glTranslated(EarthDistance,0,0); glRotated(angle_year,0,1,0); /*-------------*/ /* draw planet */ /*-------------*/ drawEarth(); renderMoon(); glPopMatrix(); } /*-------------------------------*/ /* render sun -- fixed at origin */ /*-------------------------------*/ static void renderEarthOrbit(void) { /*----------------------------------------*/ /* Apply Transform Node for Earthīs orbit */ /*----------------------------------------*/ glPushMatrix(); /*---------------------*/ /* define orbit material */ /*---------------------*/ { GLfloat color[] = {1,1,1,1}; glMaterialfv(GL_FRONT,GL_EMISSION,color); /* it is a source of light */ } drawDisk(EarthDistance-0.1, EarthDistance+0.1, NULL); /*------------------*/ /* restore material */ /*------------------*/ { GLfloat none[] = {0,0,0,1}; glMaterialfv(GL_FRONT,GL_EMISSION,none); } glPopMatrix(); } static void renderSun(void) { /*------------------------------*/ /* Apply Transform Node for Sun */ /*------------------------------*/ glPushMatrix(); double teta_sol = 20*360.*time/(OneDay*OneYear); glRotated(teta_sol,0,1,0); /*---------------------*/ /* define sun material */ /*---------------------*/ { GLfloat color[] = {1,1,0.2F,1}; glMaterialfv(GL_FRONT,GL_EMISSION,color); /* it is a source of light */ } drawSphere(SunRadius, &Texture[SUN_TEXTURE]); /*------------------*/ /* restore material */ /*------------------*/ { GLfloat none[] = {0,0,0,1}; glMaterialfv(GL_FRONT,GL_EMISSION,none); } glPopMatrix(); } static void renderSolarSystem(void) { /*----------------------*/ /* render Sunīs subtree */ /*----------------------*/ renderSun(); /*------------------------*/ /* render Earthīs subtree */ /*------------------------*/ renderEarth(); renderEarthOrbit(); /*------------------------------*/ /* render others planet subtree */ /*------------------------------*/ // renderXXXOrbit(); // renderXXX(); // ..... } /*----------------------------------------*/ /* render setupLights -- fixed at origin */ /*----------------------------------------*/ static void setupLights(void) { /* position light at origin */ { GLfloat pos[] = {0,0,0,1}; glLightfv(GL_LIGHT0,GL_POSITION,pos); } /* enable lighting */ glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); /* representing the sun light */ } /*----------------------------------------*/ /* render setupLights -- fixed at origin */ /*----------------------------------------*/ static void setupCamera(void) { /* position camera */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45,1,0.1,100*EarthDistance); } static void placeCamera(void) { /* position camera */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,1.5*EarthDistance,3*EarthDistance,0,0,0,0,1,0); } //////////////////////////////////////////////// // GLU Functions //////////////////////////////////////////////// /*------------------------------*/ /* move and render solar-system */ /*------------------------------*/ static void display(void) { /* clear buffers */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* render Lights */ setupLights(); /* set projection */ setupCamera(); /* position camera */ placeCamera(); /* render Solar System */ renderSolarSystem(); time += TimeStep; /* update time */ glutSwapBuffers(); } /*---------------------*/ /* function redraw */ /*---------------------*/ static void redraw (int width, int height) { /* specify black as background */ glClearColor(0,0,0,1); /* enable z-buffer test for hiddern surface removal */ glEnable(GL_DEPTH_TEST); display(); } /*---------------------*/ /* keyboard callback */ /*---------------------*/ static void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } /*---------------------*/ /* GL main program */ /*---------------------*/ int main (int argc, char **argv) { /* GLUT - Initialization */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow("CG2001-T1"); /* Registrando callbacks */ glutDisplayFunc(display); glutReshapeFunc(redraw); // glutMouseFunc(mouseCall); // glutMotionFunc(motionCall); glutKeyboardFunc(keyboard); glutIdleFunc(display); /* Lendo Texturas */ loadTexture("Sun.jpg", &Texture[SUN_TEXTURE], true, false); loadTexture("Moon.jpg", &Texture[MOON_TEXTURE], true, true); loadTexture("Earth.jpg", &Texture[EARTH_TEXTURE], true, true); /* GLUT main loop */ glutMainLoop(); return 0; }