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