Principal | Gráficos 3D | Gráficos 2D | Fractales | Math | Códigos | Tutoriales | Links

Cubo 3D

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.


cubo_wire.jpg


cubo_flat.jpg


Codigo Fuente

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