// ************************************************ // DrawVoxel.cpp // Sample file for SmallVR // Authors: Marcio Serolli Pinho, André B. Trombetta, // Felipe Bacim, Régis Kopper // // Email: pinho@inf.pucrs.br // Homepages: // http://www.smallvr.org // http://grv.inf.pucrs.br // http://www.inf.pucrs.br/~pinho // // Porto Alegre, Brazil, 2002. // ************************************************ #ifdef WIN32 #include #endif #include // SmallVR header file #include "SmVR.h" float WindowRatio; // ****************************** // User stuff // see "PosicUser" function // on how to use these variables // ****************************** // User position SmVR_CPoint User(6.5,20.6,25); // Target position SmVR_CPoint Target(0,0,0); // Root Object to represent the entire scene SmVR_CGeometricObject *RootObject; // Viewing angle in degrees float ViewAngle = 90; // ****************************** // Light stuff // ****************************** GLint especMaterial = 60; GLfloat posicaoLuz1 [4] = { 0.0, 3.0, 0.5, 1.0}; GLfloat luzAmbiente [4] = { 0.3, 0.3, 0.3, 1.0}; GLfloat luzDifusa [4] = { 0.7, 0.7, 0.7, 1.0}; // "cor" do objeto GLfloat luzEspecular [4] = { 0.5, 0.5, 0.5, 1.0}; // brilho do objeto GLfloat especularidade[4] = { 0.17, 0.17, 0.17, 1.0}; // capacidade de brilho do material // ********************************************************************** // void PosicUser() // // // ********************************************************************** void PosicUser() { // Set the clipping volume glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(ViewAngle,WindowRatio,1,200); // Set the user Position glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(User.X,User.Y, User.Z, Target.X,Target.Y, Target.Z, 0.0f,1.0f,0.0f); } // ********************************************************************** // void reshape( int w, int h ) // trata o redimensionamento da janela OpenGL // // ********************************************************************** void reshape( int w, int h ) { // Prevent a divide by zero, when window is too short // (you cant make a window of zero width). if(h == 0) h = 1; WindowRatio = 1.0f * w / h; // Reset the coordinate system before modifying glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Set the viewport to be the entire window glViewport(0, 0, w, h); PosicUser(); } // ********************************************************************** // void display( void ) // // // ********************************************************************** void display( void ) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); PosicUser(); glMatrixMode(GL_MODELVIEW); RootObject->Render(); glutSwapBuffers(); } // ********************************************************************** // void specialFunc (int key, int x, int y) // // ********************************************************************** void specialFunc (int key, int x, int y) { SmVR_CGeometricObject *temp; temp = RootObject->FindChildObject("Voxels"); switch (key) { case GLUT_KEY_PAGE_UP: break; case GLUT_KEY_PAGE_DOWN: break; case GLUT_KEY_LEFT: temp->RotateBy(-5,0,1,0); break; case GLUT_KEY_RIGHT: temp->RotateBy(5,0,1,0); break; case GLUT_KEY_UP: temp->RotateBy(5,1,0,0); break; case GLUT_KEY_DOWN: temp->RotateBy(-5,1,0,0); break; } glutPostRedisplay(); } // ********************************************************************** // void keyboard ( unsigned char key, int x, int y ) // // ********************************************************************** void keyboard ( unsigned char key, int x, int y ) { switch ( key ) { case 27: exit(0); break; } } // ********************************************************************** // void init(void) // Inicializa os parâmetros globais de OpenGL // // ********************************************************************** void init(void) { glShadeModel(GL_SMOOTH); // Habilita o modelo de tonalizacao de Gouraud glClearColor(1.0f, 1.0f, 1.0f, 0.0f); // Cor de fundo de tela glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMaterialfv(GL_FRONT,GL_SPECULAR, especularidade); // Define a refletancia do material glMateriali(GL_FRONT,GL_SHININESS,especMaterial); // Define a concentracao do brilho glLightModelfv(GL_LIGHT_MODEL_AMBIENT, luzAmbiente); // Ativa o uso da luz ambiente // Define os parametros da luz de numero 0 glLightfv(GL_LIGHT0, GL_AMBIENT , luzAmbiente ); glLightfv(GL_LIGHT0, GL_DIFFUSE , luzDifusa ); glLightfv(GL_LIGHT0, GL_SPECULAR, luzEspecular); glLightfv(GL_LIGHT0, GL_POSITION, posicaoLuz1 ); glEnable(GL_COLOR_MATERIAL); // Habilita a definicao da cor do material a partir da cor corrente glEnable(GL_LIGHTING); // Habilita o uso de iluminacao glEnable(GL_LIGHT0); // Habilita a luz de numero 0 glEnable(GL_DEPTH_TEST); // Habilita o depth-buffering glEnable(GL_NORMALIZE); // Habilita a normalizacao das normais glEnable(GL_CULL_FACE); } // ********************************************************************** // Esta roteina deverá ser alterada de forma a determinar se o voxel // (x,y,z) está dentro do objeto ou não. // // // ********************************************************************** int IsInside(float cx, float cy, float cz) { // este é apenas um teste exemplo que testa se o // centro do voxel está ou não dentro de uma esfera // de raio 15 (15*15==225) if ((cx*cx+cy*cy+cz*cz) < 225) return 1; else return 0; } // ********************************************************************** // int DrawCube(void *p) // Função de desenho // // ********************************************************************** int DrawCube(void *p) { float EnvelopeMin = -17; float EnvelopeMax = 17; // Reposiciona o observador em função do tamanho do objeto User.X = (EnvelopeMax + EnvelopeMin) / 2; User.Y = User.X; User.Z = EnvelopeMax * 3; Target.X = Target.Y = Target.Z = 0; // nro de voxels em uma linha/coluna int NVoxels = 30; // tamanho da aresta de cada voxel float LargVoxel = (EnvelopeMax - EnvelopeMin) / NVoxels; // Translação a ser aplicada a cada voxel para // o posicionamento do vizinho float TX = LargVoxel * 1.1; float TY = LargVoxel * 1.1; float TZ = LargVoxel * 1.1; float cx,cy,cz; // posição do centro do voxel // Números dos voxels inicial e final int Inicio = -NVoxels/2; int Fim = NVoxels/2; glColor3f(1,0,0); glPushMatrix(); glTranslatef (Inicio, Inicio, Inicio); for (int x = Inicio; x < Fim; x++) { glTranslatef(TX,0,0); glPushMatrix(); for (int y = Inicio; y < Fim; y++) { glTranslatef(0,TY,0); glPushMatrix(); for (int z = Inicio; z < Fim; z++) { glTranslatef(0,0,TZ); // calcula o centro do voxel cx = x * TX; cy = y * TY; cz = z * TZ; if (IsInside(cx,cy,cz)) glutSolidCube(LargVoxel); } glPopMatrix(); } glPopMatrix(); } glPopMatrix(); return 0; } // ********************************************************************** // void CriaCenario() // Função de Criação do Cenários // // ********************************************************************** void CriaVoxel() { // Cria o objeto SmallVR SmVR_CGeometricObject *TestObject; TestObject = new SmVR_CGeometricObject("Voxels", DrawCube); // Adiciona o objeto recém criado ao grafo de cena RootObject->AddChild(TestObject); } // ********************************************************************** // void main ( int argc, char** argv ) // // // ********************************************************************** int main ( int argc, char** argv ) { // GLUT initialization glutInit ( &argc, argv ); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);// | GLUT_DOUBLE | GLUT_RGBA ); glutInitWindowPosition (0,0); glutInitWindowSize ( 700, 500 ); glutCreateWindow ( "SmallVR Test - Voxel program" ); // initialize OpenGL parameters init (); // initialize the library RootObject = SmVR_Init(NULL); CriaVoxel(); // GLUT stuff glutDisplayFunc ( display ); glutReshapeFunc ( reshape ); glutKeyboardFunc ( keyboard ); glutSpecialFunc ( specialFunc ); glutIdleFunc ( display ); glutMainLoop ( ); return 0; }