Principal | Gráficos 3D | Gráficos 2D | Fractales | Math | Códigos | Tutoriales | Links
Manipulacion interactiva de un cubo 3D, utilizando el mouse, los vertices, caras, estan
definidos en el codigo, las normales las calcula el programa en base a los vertices que forman
cada una de las caras. Utilizo las rutinas de trackball para
manipular el cubo.
En la imagen de abajo, en color negro las coordenadas de los vertices y sus indices, en azul
los indices de las caras, los vertices que forman cada una de ella y la direccion de sus
normales. El cubo tiene 8 vertices y 12 caras.
Codigo fuente y ejecutable: cubo.zip
/* Ejemplo que dibuja un Cubo utilizando proyeccion en perspectiva, una fuente de luz puntual y un material. Los vertices, caras y normales del cubo se definen en los siguientes arreglos, las normales son calculadas por el programa v[8][3] vertices faces[6][4] caras n[12][3] normales autor : Ramiro Alcocer email : valcoey@hotmail.com www : www.oocities.org/valcoey/index.html */ #include <GL/glut.h> #include <stdlib.h> #include <math.h> #include "trackball.h" float LightPos[] = { 0.0f, 0.0f, 1.0f, 0.0f}; float LightAmb[] = { 0.2f, 0.2f, 0.2f, 1.0f}; float LightDif[] = { 1.0f, 1.0f, 1.0f, 1.0f}; float LightSpc[] = { 0.5f, 0.5f, 0.5f, 1.0f}; static GLint mouse_state; static GLint mouse_button; GLdouble pan_x = 0.0; GLdouble pan_y = 0.0; GLdouble pan_z = 0.0; // indice de los vertices que forman cada una de las 6 caras del cubo GLint faces[12][3] ={{0,2,3}, {3,1,0}, {4,5,7},{7,6,4}, {0,1,5}, {5,4,0}, {1,3,7}, {7,5,1}, {3,2,6}, {6,7,3}, {2,0,4}, {4,6,2}}; // arreglo que contiene los vertices del cubo GLfloat v[8][3]={{-5,-5,-5},{5,-5,-5},{-5,5,-5},{5,5,-5}, {-5,-5,5},{5,-5,5},{-5,5,5},{5,5,5}}; // arreglo de los vectores normales a cada una de las caras del cubo GLfloat n[12][3]; void CalcularNormales(void) { float x1, y1, z1; float x2, y2, z2; float x3, y3, z3; float length; int a, b, c; for (int i=0; i<12; i++) { a = faces[i][0]; b = faces[i][1]; c = faces[i][2]; x1 = v[b][0] - v[a][0]; y1 = v[b][1] - v[a][1]; z1 = v[b][2] - v[a][2]; x2 = v[c][0] - v[a][0]; y2 = v[c][1] - v[a][1]; z2 = v[c][2] - v[a][2]; z3 = x1*y2 - y1*x2; x3 = y1*z2 - z1*y2; y3 = z1*x2 - x1*z2; length = sqrt(x3*x3 + y3*y3 + z3*z3); if (length == 0) { n[i][0]=1; n[i][1]=1; n[i][2]=1; } else { n[i][0]=x3/length; n[i][1]=y3/length; n[i][2]=z3/length; } } } void DibujarCubo(void) { // Propiedades del material del Cubo GLfloat mat_ambient[] = { 0.02f, 0.16f, 0.16f, 1.0f }; GLfloat mat_diffuse[] = { 0.1f, 0.8f, 0.8f, 1.0f }; GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat mat_shininess[] = { 100.0f }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); for (int i=0; i<12; i++) { glBegin(GL_TRIANGLES); glNormal3fv(&n[i][0]); glVertex3fv(&v[faces[i][0]][0]); glVertex3fv(&v[faces[i][1]][0]); glVertex3fv(&v[faces[i][2]][0]); glEnd(); } } void reshape(int w, int h) { if (!h) return; gltbReshape(w, h); glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -30.0); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); gltbMatrix(); DibujarCubo(); glPopMatrix(); glFlush(); glutSwapBuffers(); } void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_SMOOTH); glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glLightfv(GL_LIGHT0, GL_POSITION, LightPos); glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb); glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif); glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpc); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); CalcularNormales(); gltbInit(GLUT_MIDDLE_BUTTON); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } void mouse(int button, int state, int x, int y) { GLdouble model[4*4]; GLdouble proj[4*4]; GLint view[4]; /* fix for two-button mice -- left mouse + shift = middle mouse */ if (button == GLUT_LEFT_BUTTON && glutGetModifiers() & GLUT_ACTIVE_SHIFT) button = GLUT_MIDDLE_BUTTON; gltbMouse(button, state, x, y); mouse_state = state; mouse_button = button; if (state == GLUT_DOWN && button == GLUT_MIDDLE_BUTTON) { glGetDoublev(GL_MODELVIEW_MATRIX, model); glGetDoublev(GL_PROJECTION_MATRIX, proj); glGetIntegerv(GL_VIEWPORT, view); gluProject((GLdouble)x, (GLdouble)y, 0.0, model, proj, view, &pan_x, &pan_y, &pan_z); gluUnProject((GLdouble)x, (GLdouble)y, pan_z, model, proj, view, &pan_x, &pan_y, &pan_z); pan_y = -pan_y; } glutPostRedisplay(); } void motion(int x, int y) { GLdouble model[4*4]; GLdouble proj[4*4]; GLint view[4]; gltbMotion(x, y); if (mouse_state == GLUT_DOWN && mouse_button == GLUT_MIDDLE_BUTTON) { glGetDoublev(GL_MODELVIEW_MATRIX, model); glGetDoublev(GL_PROJECTION_MATRIX, proj); glGetIntegerv(GL_VIEWPORT, view); gluProject((GLdouble)x, (GLdouble)y, 0.0, model, proj, view, &pan_x, &pan_y, &pan_z); gluUnProject((GLdouble)x, (GLdouble)y, pan_z, model, proj, view, &pan_x, &pan_y, &pan_z); pan_y = -pan_y; } glutPostRedisplay(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitWindowSize(300, 300); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutCreateWindow("Cubo 3D "); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); glutMotionFunc(motion); glutMainLoop(); return 0; } |
valcoey@hotmail.com
Ramiro Alcocer, 2001
Principal | Gráficos 3D | Gráficos 2D | Fractales | Math | Códigos | Tutoriales | Links