COMPUTACIÓN GRÁFICA
LABORATORIO: Primitivas en OpenGL
Tipos de Primitivas de OpenGL
Primitiva Descripción
GL_POINTS Dibuja los vértices como puntos individuales.
GL_LINES Cada par de vértices formaría una línea individual.
GL_LINE_STRIP Cada vértice está unido con el anterior formando segmentos conectados.
Al igual que GL_LINE_STRIP, pero implementando un segmento más entre
GL_LINE_LOOP
el primer y último vértice.
GL_TRIANGLES Tres vértices son interpretados como tres triángulos
GL_TRIANGLE_STRIP Cada vértice se une con los dos anteriores para formar un triángulo.
GL_TRIANGLE_FAN Cada vértice se une con los dos primeros para formar un triángulo.
Tipos De Datos De Opengl
OpenGL incorpora tipos de datos propios para facilitar la portabilidad. Los tipos de datos, junto
con su correspondencia en C y el sufijo que se suele utilizar habitualmente para nombrar las
variables son:
Primitivas De Diseño
El diseño en OpenGL se realiza utilizando tres primitivas básicas: puntos, líneas y polígonos. Todas
ellas se basan en un elemento fundamental: los vértices. La función de creación de vértices es
glVertex. Esta función tiene alrededor de 25 versiones en función del número y tipo de los
argumentos. Algunas de las versiones más utilizadas son:
· void glVertex2f (GLfloat x, GLfloat y)
· void glVertex3f (GLfloat x, GLfloat y, GLfloat z)
· void glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w)
x, y, z: coordenadas de la posición del vértice. Si z no se especifica, vale 0.
w: cuarta coordenada cuando se utilizan coordenadas homogéneas. Si no se
especifica, vale 1.
La definición de primitivas comienza siempre con la función glBegin y termina con glEnd. Entre
estas dos funciones debemos definir los vértices que forman la primitiva.
void glBegin (GLenum primitiva)
Esta función marca el inicio de un conjunto de vértices que definen una o varias primitivas.
Primitiva: tipo de primitiva que iniciamos. Puede valer:
GL_POINTS (puntos), GL_LINES (líneas), GL_LINE_STRIP (polilíneas), GL_LINE_LOOP (polilíneas
cerradas), GL_TRIANGLES (triángulos), GL_TRIANGLE_STRIP (triángulos encadenados),
GL_TRIANGLE_FAN (triángulos alrededor de un punto), GL_QUADS (cuadriláteros),
GL_QUAD_STRIP (cuadriláteros encadenados), GL_POLYGON (polígono convexo con cualquier
número de vértices).
void glEnd (void)
Marca el final de la última primitiva que se haya iniciado con glBegin.
Entre las sentencias glBegin y glEnd puede aparecer código adicional para el cálculo de los
vértices y para fijar algunos atributos de las primitivas. Sólo las siguientes llamadas a funciones
de OpenGL se permiten dentro del bloque glBegin-glEnd:
· glVertex
· glColor
· glIndex
· glNormal
· glEvalCoord
· glCallList
· glCallLists
· glTextCoord
· glEdgeFlag
· glMaterial
PUNTOS
Los puntos son las primitivas más sencillas. En este caso pueden definirse varios puntos dentro del
un solo bloque glBegin-glEnd. Los dos ejemplos siguientes producen el mismo efecto, aunque el
segundo es más compacto y más rápido:
EJEMPLO
glBegin (GL_POINTS);
glVertex3f (0.0, 0.0, 0.0);
glVertex3f (0.5, 0.5, 0.5);
glEnd ();
void glPointSize (GLfloat tamaño) tamaño: diámetro en pixeles del punto.
DIBUJO DE LÍNEAS.
En OpenGL, cada línea queda definida por dos puntos, un punto inicial donde comienza la línea y
un punto final donde acaba. Para dibujar líneas, se ha de pasar a la función glBegin () el parámetro
GL_LINES, siendo evaluados los vértices por parejas. A continuación, se muestra el código donde
se dibujan dos líneas en el plano Z=0, que se unen en el punto (0.0.0).
glBegin(GL_LINES);
{
glVertex3f ( -0.10f, -0.10f, 0.0f);
glVertex3f ( 0.10f, 0.10f, 0.0f);
glVertex3f ( -0.10f, 0.10f, 0.0f);
glVertex3f ( 0.10f, -0.10f, 0.0f);
}
glEnd();
Probar los cambios con lo siguiente:
· Ancho de la línea (default es 1.0)
void glLineWidth( GLfloat width );
· Patrón de líneas punteadas
void glLineStipple( GLint factor,GLushort pattern );
DIBUJO DE TRIÁNGULOS.
En OpenGL, un triángulo queda definido por tres puntos. Para dibujar triángulos, se ha de pasar
como parámetro a la función glBegin () el parámetro GL_TRIANGLES, evaluándose los vértices de
tres en tres. En la definición de un triángulo es importante el orden que se sigue en la definición de
los vértices, horario o anti horario. Cuando un polígono se define en sentido horario, OpenGL
interpreta que tiene que mostrar la cara posterior, mientras que si el sentido es anti horario,
OpenGL interpreta que tiene que mostrar la capa anterior. Esta particularización es importante
debido a que dependiendo de los parámetros configurados en OpenGL, solo una de las caras
anterior o posterior es visible.
A continuación se muestra el código que dibuja un triángulo en el plano Z=0, que ha sido definido
en sentido horario, consecuentemente muestra su cara anterior.
glBegin(GL_TRIANGLES);
{
glVertex3f ( -0.50f, 0.0f, 0.0f);
glVertex3f ( 0.0f, 0.50f, 0.0f);
glVertex3f ( 0.50f, 0.0f, 0.0f);
}
glEnd();
Obteniendo como resultado
DIBUJO DE CUADRADOS.
Esta primitiva funciona exactamente igual que la de triángulos, con la salvedad de que los vértices
son evaluados de 4 en 4.
COLOR DE RELLENO.
Para elegir el color de los polígonos, basta con hacer una llamada a glColor entre la definición de
cada polígono (glBegin () – glEnd()).
La función glColor define el color de rellenado actual y lleva como parámetros los valores de las
componentes RGB del color deseado, y, opcionalmente, un cuarto parámetro con el valor alpha. Al
igual que con la función glVertexXX(), existen muchas funciones para definir el color, en función
del número de componentes de color utilizadas y el formato de estas componentes (entero,
flotante, …).
A continuación se muestra el código para dibujar un triangulo en el plano Z=0 de color ROJO.
glBegin(GL_TRIANGLES);
{
glColor3f(1.0,0,0);
glVertex3f ( -0.50f, 0.0f, 0.0f);
glVertex3f ( 0.0f, 0.50f, 0.0f);
glVertex3f ( 0.50f, 0.0f, 0.0f);
}
glEnd();
MODELO DE SOMBREADO.
Es el método que utiliza OpenGL para rellenar de color los polígonos. Se especifica con la función
glShadeModel. Si el parámetro es GL_FLAT, OpenGL rellenará los polígonos con el color activo en
el momento que se definió el último parámetro; si es GL_SMOOTH, OpenGL rellenará el polígono
interpolando los colores activos en la definición de cada vértice.
Este código es un ejemplo de GL_FLAT:
glShadeModel (GL_FLAT);
glBegin(GL_TRIANGLES);
{
glColor3f ( 0.0f, 0.0f, 1.0f); // Activamos el color Azul.
glVertex3f ( -0.50f, 0.0f, 0.0f);
glColor3f ( 1.0f, 0.0f, 0.0f); // Activamos el color Rojo.
glVertex3f ( 0.0f, 0.50f, 0.0f);
glColor3f ( 0.0f, 1.0f, 0.0f); // Activamos el color Verde.
glVertex3f ( 0.50f, 0.0f, 0.0f);
}
glEnd();
Obteniendo como resultado un triángulo de color Verde
Sin embargo, el mismo código cambiando la primera línea,
glShadeModel (GL_SMOOTH);
se obtiene un triángulo donde se han interpolado los colores asignados a los vértice, como se
puede ver en la figura.
EJERCICIOS DE LA PRÁCTICA.
1. En base al siguiente código, dibujar las Iniciales de su nombre completo (Ejemplo: WLC).
static void display(void)
{
glClearColor(1,1,1,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
typedef GLfloat point2[2];
point2 vertice[8] = {
{100.0,100.0}, //v0
{300.0,100.0}, //v1
{300.0,300.0}, //v2
{100.0,300.0}, //v3
{400.0,200.0}, //v4
{400.0,400.0}, //v5
{200.0,400.0}, //v6
{200.0,200.0}}; //v7
glColor3f(0.0,0.0,1.0);
gluOrtho2D(0.0, 500.0, 0.0, 500.0);
glBegin(GL_LINES);
glVertex2fv(vertice[0]);
glVertex2fv(vertice[1]);
glVertex2fv(vertice[1]);
glVertex2fv(vertice[2]);
glVertex2fv(vertice[2]);
glVertex2fv(vertice[3]);
glVertex2fv(vertice[3]);
glVertex2fv(vertice[0]);
glVertex2fv(vertice[1]);
glVertex2fv(vertice[4]);
glVertex2fv(vertice[2]);
glVertex2fv(vertice[5]);
glVertex2fv(vertice[5]);
glVertex2fv(vertice[4]);
glVertex2fv(vertice[5]);
glVertex2fv(vertice[6]);
glVertex2fv(vertice[6]);
glVertex2fv(vertice[3]);
glVertex2fv(vertice[0]);
glVertex2fv(vertice[7]);
glVertex2fv(vertice[4]);
glVertex2fv(vertice[7]);
glVertex2fv(vertice[6]);
glVertex2fv(vertice[7]);
glEnd();
glutSwapBuffers();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(512,512);
glutInitWindowPosition(20,20);
glutCreateWindow("Cubo 2D");
glutDisplayFunc(display);
glutMainLoop();
return EXIT_SUCCESS;
}
2. Definición del eje de coordenadas.
En la ventana del área de trabajo, dibujar los ejes de coordenadas X de color rojo, Y de color verde
y Z de color azul con líneas discontinuas, como se indica en la figura.
3. Dibujo de un cubo sólido
En el espacio tridimensional creado, con centro en el origen de coordendas, dibujar un cubo sólido
de color amarillo, como se indica en la figura:
4. Dibujo de toro y esfera.
En el espacio tridimensional establecido, dibujar sobre cada uno de los ejes coordenados y del
color de estos un toro y una esfera como se muestran en la figura adjunto.