Principal | Gráficos 3D | Gráficos 2D | Fractales | Math | Códigos | Tutoriales | Links
Los Evaluators son primitivas sumisnistradas por OpenGL para evaluación polinomial de curvas y superficies de Bézier.
Los Evaluators de OpenGL nos permiten especificar una superficie solo usando sus puntos de control, podemos crear superficies compuestas por puntos, modelos de alambre (wireframe) o dibujar modelos sombreados (shaded) ya que los vectores normales a la superficie son calculados en forma automatica, y hasta superficies con la aplicacion de Texturas.
El procedimiento para usar evaluators es:
Ubicacion de los puntos de control de la superficie de Bézier de 5x5. |
Los puntos de control estan dados de la siguiente forma ctrlpoints[5][5][3].
[3]=(0,1,2) me indican las cordenadas x, y, z de cada punto. [5]=(0,1,2,3,4) columnas, j=0,1,2,3,4. [5]=(0,1,2,3,4) filas, i=0,1,2,3,4.
Usar glMap2f() para definir un Evaluator 2D de OpenGL.
Sintaxis: void glMap2f(GLenum target, TYPEu1, TYPEu2, GLint ustride, GLint uorder, TYPEv1, TYPEv2, GLint vstride, GLint vorder, TYPE points);
En mi ejemplo tenemos:
glMap2f(GL_MAP2_VERTEX_3,0,1,3,5,0,1,15,5,&ctrlpoints[0][0][0]) GL_MAP2_VERTEX_3 = Tipo del punto de control, coordenadas x,y,z de los vertices. 0 = el valor mas bajo del parametro u. 1 = el valor mas alto del parametro u. 5 = dimencion en la direccion u, en este caso 5. 3 = es el numero de datos por punto de control, en este caso 3 ya que tenemos x,y,z. 0 = el valor mas chico de v 1 = el valor mas grande de v. 15 = distancia entre los puntos en ctrlpoints, en este caso 3*5 = 15. 5 = dimencion en la direccion v. &ctrlpoints[0][0][0]=es el array que contiene los puntos de control.
Con glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0), me crea una grilla con 20 puntos que estan comprendidos entre 0.0 y 1.0, eso para u y v.
Bueno con glEvalMesh2(GL_FILL, 0, 20, 0, 20) me dibuja la superficie en modo shaded y con glEvalMesh2(GL_LINE, 0, 20, 0, 20) en modo wireframe (solo lineas).
Modo wireframe | Modo shaded |
Con glEnable(GL_AUTO_NORMAL) le indicamos que me calcule en forma automatica las normales, para utilizar el modo de dibujo shaded y con glEnable(GL_NORMALIZE) hace que estas normales esten normalizadas (es decir vectores de modulo 1.0).
/* OpenGL Evaluators Autor : Ramiro Alcocer Email : valcoey@hotmail.com www : www.oocities.org/valcoey/index.html */ #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #include <math.h> //puntos de control de la superficie de Bezier GLfloat ctrlpoints[5][5][3] = { {{-2.0, -2.0, 0.5}, {-1.0, -2.0, -0.4}, {0.0, -2.0, -0.5}, {1.0, -2.0, -0.4}, {2.0, -2.0, 0.5}}, {{-2.0, -1.0, 0.5}, {-1.0, -1.0, 0.5}, {0.0, -1.0, 0.75}, {1.0, -1.0, 0.5}, {2.0, -1.0, 0.25}}, {{-2.0, 0.0, 0.6}, {-1.0, 0.0, 1.0}, {0.0, 0.0, 1.5}, {1.0, 0.0, 1.0}, {2.0, 0.0, 0.26}}, {{-2.0, 1.0, 0.5}, {-1.0, 1.0, 1.0}, {0.0, 1.0, 1.25}, {1.0, 1.0, 1.0}, {2.0, 1.0, 0.25}}, {{-2.0, 2.0, 1.0}, {-1.0, 2.0, 0.5}, {0.0, 2.0, 0.25}, {1.0, 2.0, 0.5}, {2.0, 2.0, 1.0}} }; //propiedades del material GLfloat mat_ambient[] = {0.0f, 0.05f, 0.06f, 1.0f}; GLfloat mat_diffuse[] = {0.0f, 0.50980392f, 0.50980392f, 1.0f}; GLfloat mat_specular[] = {0.90196078f, 0.90196078f, 0.90196078f, 1.0f}; //angulos de rotacion GLfloat rotx = 0.0; GLfloat roty = 0.0; GLfloat rotz = 0.0; //parametros de la fuente de luz void initlights(void) { //propiedades de la fuente de luz GLfloat ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f }; GLfloat diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat position[] = { 0.0f, 0.0f, 1.0f, 0.0f }; glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } //dibuja los puntos de control de la superficie void DrawPoints(void) { int i,j; glPushAttrib( GL_LIGHTING_BIT ); glDisable( GL_LIGHTING ); //cambio el tamaņo del pexels para hacerlo mas visible glPointSize(4.0f); //dibujo todos los puntos de control de la superficie glColor3f( 0.0, 1.0, 1.0); glBegin(GL_POINTS); for(j=0; j<5; j++) for (i=0; i<5; i++) glVertex3fv(ctrlpoints[j][i]); glEnd(); glColor3f( 0.0, 0.25, 0.5); glBegin(GL_LINES); for (j=0; j<4; j++) for (i=0; i<4; i++) { glVertex3fv(ctrlpoints[j][i]); glVertex3fv(ctrlpoints[j][i+1]); } for (i=0; i<4; i++) for (j=0; j<4; j++) { glVertex3fv(ctrlpoints[j][i]); glVertex3fv(ctrlpoints[j+1][i]); } glEnd(); glPopAttrib(); } //dibuja la superficie void display(void) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_MODELVIEW_MATRIX ); glLoadIdentity(); glTranslated(0.0, 0.0, -12.0); glRotatef(rotx, 1.0, 0.0, 0.0); glRotatef(roty, 0.0, 1.0, 0.0); glRotatef(rotz, 0.0, 0.0, 1.0); //material para la superficie de Bezier glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular); glMaterialf (GL_FRONT, GL_SHININESS, 128.0f); glEvalMesh2(GL_FILL, 0, 20, 0, 20); DrawPoints(); glFlush(); } void init(void) { glClearColor (0.0, 0.0, 0.0, 1.0); glEnable (GL_DEPTH_TEST); glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 5,0, 1, 15, 5, &ctrlpoints[0][0][0]); //activa el evaluador glEnable(GL_MAP2_VERTEX_3); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); //me crea una grilla de 400 puntos (20x20) glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0); initlights(); } void reshape(int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(30, (GLfloat) w/(GLfloat) h, 1.0, 50.0); glMatrixMode (GL_MODELVIEW); } void keyboard(unsigned char key, int x, int y) { switch (key) { case '1': rotx = rotx + 10.0f; glutPostRedisplay(); break; case '2': rotx = rotx - 10.0f; glutPostRedisplay(); break; case '3': roty = roty + 10.0f; glutPostRedisplay(); break; case '4': roty = roty - 10.0f; glutPostRedisplay(); break; case '5': rotz = rotz + 10.0f; glutPostRedisplay(); break; case '6': rotz = rotz - 10.0f; glutPostRedisplay(); break; case 27: exit(0); break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (300, 300); glutInitWindowPosition (100, 100); glutCreateWindow ("Superficie de Bazier"); init (); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutDisplayFunc(display); glutMainLoop(); return 0; } |
valcoey@hotmail.com
Ramiro Alcocer, 2001
Principal | Gráficos 3D | Gráficos 2D | Fractales | Math | Códigos | Tutoriales | Links