Professional Documents
Culture Documents
MANUAL
APRENDA A GRAFICAR CON OPENGL
EN 20 PRÁCTICAS
Nivel Básico
ISIDRO MOCTEZUMA
CANTORÁN
Primera edición en español: 2008 DIRECTORIO
El Autor
PRÓLOGO
Por fortuna, se tiene este manual de graficación con OpenGL, una herramienta de
las más utilizadas para cumplir con propósitos de animación en gráficos y una de
las mejores en su ramo. Con este manual aprenderás las bases de la graficación,
una vez que se termine de leer y hacer los ejercicios que en el vienen, bastará con
echar a andar tu imaginación y descubrir hasta donde puedes llegar en el
desarrollo de los gráficos, verás que podrás realizar cosas fascinantes, de las
cuales tu mismo te sorprenderás.
El autor de este documento, así como las personas que intervinieron para que
fuera posible su creación, invirtieron muchas horas de esfuerzo y años de
experiencia en el tema para dejar un buen sabor de boca al lector, además de
hacer todo lo posible para poner al alcance un material de alta calidad, fácil de
leer, de seguir y de entender.
Se invita por lo tanto, a todos aquellos que tengan interés en aprender a graficar,
que sigan el presente manual de principio a fin, con mucho ahínco y tenacidad,
siendo persistentes en todo momento, hasta que obtengan los resultados
deseados y cumplan con sus propias metas.
Introducción …………………………………………………………… 6
Práctica 1: Instalación de OpenGL ………………………………… 7
Práctica 2: Color de fondo y archivos de cabecera ……………… 8
Práctica 3: Generalidades de OpenGL ……………………………. 10
Práctica 4: Dibujar un rectángulo …………………………………... 13
Práctica 5: Funciones básicas de OpenGL ………………………. 16
Práctica 6: Dibujar un punto ………………………………………… 20
Práctica 7: Tamaño de un punto …………………………………… 24
Práctica 8: Dibujar líneas ……………………………………………. 31
Práctica 9: Más de líneas …………………………………………… 34
Práctica 10: Dibujo de triángulos …………………………………… 38
Práctica 11: Profundidad y eliminación de superficies y selectiva 43
Práctica 12: Polígonos ………………………………………………. 50
Práctica 13: Relleno de polígonos …………………………………. 53
Práctica 14: Polígonos en vista de puntos, líneas y rellenos …… 57
Práctica 15: Limpiar el buffer de color …………………………….. 62
Práctica 16: Rotación, translación y escalamiento ………………. 64
Práctica 17: Proyección ortogonal y en perspectiva ……………... 68
Práctica 18: Luz ambiental, difusa y especular …………………… 72
Práctica 19: Sombras ………………………………………………... 78
Práctica 20: Transparencia …………………………………………. 84
Ejemplos ……………………………………………………………… 87
Conclusiones ………………………………………………………… 94
______________________________________________________________________________________________________________
INTRODUCCIÓN
Los requerimientos mínimos que debe tener el lector para el desarrollo de las
prácticas son: manejo del lenguaje de programación C ó C++, conocimientos
básicos del entorno de C++ Builder 5, manejo de MS DOS (básico), nociones de
2D y 3D, y algo indispensable; el gusto graficación por computadora.
______________________________________________________________________________________________ 6
M.C. Isidro Moctezuma Cantorán
______________________________________________________________________________________________________________
Para iniciar esta práctica se requiere del componente de OpenGL para C++
Builder 5, el cual puede descargarse en la página: http://www.opengl.org, Guarde
los archivos en una carpeta llamada “ComponentesOpenGL”, para instalar el
componente siga los siguientes pasos:
Después de copiar los archivos en sus respectivas carpetas, en el Prompt del MS-
DOS ir a la carpeta de Lib de C++ Builder5 y escribir:
implib glut.lib c:\windows\system32\glut.dll
implib glut32.lib c:\windows\system32\glut32.dll
Icono de
OpenGL
Ventana
de
OpenGL
______________________________________________________________________________________________ 7
M.C. Isidro Moctezuma Cantorán
______________________________________________________________________________________________________________
Para asignarle color de fondo a la venta de OpenGL y declarar los archivos *.h
siga los siguientes pasos:
#include<gl/gl.h>
#include<gl/glu.h>.
______________________________________________________________________________________________ 8
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Ventana de
OpenGL con
Color de
fondo
______________________________________________________________________ 9
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
OpenGL
OpenGL, del inglés Open Graphic Library (Librería de Gráficos Abierta o Libre)
no es un Lenguaje es una API (Interfaz de Programación de Aplicación).
Cuando se hace mención que una aplicación esta hecho en OpenGL, quiere decir
que está hecho en algún lenguaje de programación: C, C++, Visual C++ Builder
C++, Visual Basic, Java, etc., y que el lenguaje es el que llama a una o más
bibliotecas de OpenGL.
#include <gl/gl.h>
#include <gl/glu.h>
Los apuntadores y las matrices no tienen una mención especial, debido a que
manejan similar a lenguaje C, por ejemplo:
______________________________________________________________________ 10
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
GLshort s[10];
GLdouble *d[10];
Para C++ Builder 5, puede utilizar los tipos de datos de OpenGL o C o C++.
Ejemplo:
glColor3f(…)
Comando Raíz Número de
Biblioteca GL argumentos Tipo de
argumentos
______________________________________________________________________ 11
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 12
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
int w=OpenGLPanel1->Width;
int h=OpenGLPanel1->Height;
//int nRange=OpenGLPanel1->Width/2;
GLfloat nRango;
// Evitar la división entre cero
if(h == 0)
h = 1;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
______________________________________________________________________ 13
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Figura 3. Rectángulo
______________________________________________________________________ 14
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glLoadIdentity();
______________________________________________________________________ 15
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
• glClearColor
Finalidad: Establece los valores de color y transparencia a usar para borrar los
búferes de color.
Archivo <gl.h>
include:
Sintaxis: void glClearColor(GLclampf rojo, GLclampf verde, GLclampf azul,
GLclampf alfa);
Descripción: Esta función establece los valores de relleno que se van a utilizar
cuando se borren los búferes de rojo, verde, azul y transparencia
(denominados conjuntamente búfer de color).
Los valores especificados se ajustan al rango [0.0f, 1.0f]
Parámetros
rojo: GLclampf: componente rojo del valor de relleno.
verde: GLclampf: componente verde del valor de relleno.
azul: GLclampf: componente azul del valor de relleno.
alfa: GLclampf: componente de transparencia (alfa) del valor de relleno.
Devuelve: Nada.
• glDisable, glEnable
Archivo <gl.h>
include:
Sintaxis: void glDisable(GLenum característica );
void glEnable(GLenum característica );
Descripción: glDisable .- deshabilita una opción de dibujo de OpenGL
glEnable .- Habilita una opción de dibujo de OpenGL.
Parámetros
Característica: GLenum: Opción a activar o desactivar. En la especificación de
OpenGL se proporciona una lista completa de estados y crece
regularmente con las nuevas actualizaciones. (Ver tabla 1.)
Devuelve: Nada.
______________________________________________________________________ 16
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
• glFinish
• glFlush
Parámetros: ninguno
Devuelve: Nada.
______________________________________________________________________ 17
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
• glOrtho
• glRect
Archivo <gl.h>
include:
Sintaxis: void glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble
y2);
Variantes: void glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
void glRecti (GLint x1, GLint y1, GLint x2, GLint y2);
void glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
void glRectdv(const GLdouble *v1, const GLdouble *v2);
void glRectfv(const GLfloat *v1, const GLfloat *v2);
void glRectiv(const GLint *v1, const GLint *v2);
void glRectsv(const GLshort *v1, const GLshort *v2);
Descripción: Esta función proporciona un método sencillo para especificar el
rectángulo como dos puntos de esquina. El rectángulo se dibuja en
el plano xy, siendo z=0;
Parámetros
x1, y1: Especifican las esquina superior izquierda del rectángulo
______________________________________________________________________ 18
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
• glViewport
______________________________________________________________________ 19
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// color de fondo
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
______________________________________________________________________ 20
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
void TForm1::Puntos()
{
glBegin(GL_POINTS);
glVertex3f(0,0,0);
glEnd();
}
12. Ejecute el programa (Run), y le aparecerá un punto verde en la coordenada
(0, 0, 0), figura 4
Aquí está el
punto
______________________________________________________________________ 21
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
(20, 10, 0)
glBegin(GL_POINTS);
glVertex3f (0, 0, 0);
glEnd();
Por ejemplo:
______________________________________________________________________ 22
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glBegin(GL_POINTS);
glVertex3f (5, 10, 3);
glVertex3f (20,-15, 15);
glEnd();
glBegin(GL_POINTS);
glVertex3f(20,-15,15);
glEnd();
Aunque este código se ejecutará más lentamente.
Debe escribir:
glBegin(GL_POINTS); y
glVertex3f(-1,1,0);
glVertex3f(1,-1,0);
glVertex3f(-1,-1,0);
glVertex3f(0,1,2);
glEnd();
______________________________________________________________________ 23
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Para saber como graficar un punto en el espacio 3D siga los siguientes pasos:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
______________________________________________________________________ 24
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
// Limpiar ventana
glClear(GL_COLOR_BUFFER_BIT);
//aquí se dibuja todo
// color verde para los objetos
glColor3f(0.0f, 1.0f, 0.0f);
// Reestablecer transformaciones
glPopMatrix();
{
glBegin(GL_POINTS);
glVertex3f(0,0,0);
glEnd();
}
//-------------------------------------------------------------
void TForm1::VariosPuntos()
{
GLfloat x,y,z,i;
glBegin(GL_POINTS);
z = 0;
for(i = 0.0f; i<= 360; i+= 5)
{
x = 50.0f*sin(i);
y = 50.0f*cos(i);
glVertex3f(x, y, z);
}
glEnd();
}
______________________________________________________________________ 26
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
z=-50;
for(i = 0.0f; i<= 360; i+= 0.1)
{
x = 50.0f*sin(i);
y = 50.0f*cos(i);
glVertex3f(x, y, z);
z+=1;
}
glEnd();
______________________________________________________________________ 27
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glPointSize(2);
glBegin(GL_POINTS);
glColor3f(1,1,0);
glVertex3f(10,10,10);
glEnd();
______________________________________________________________________ 28
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glPointSize(3);
glBegin(GL_POINTS);
glColor3f(1,0,1);
glVertex3f(20,20,20);
glEnd();
glPointSize(4);
glBegin(GL_POINTS);
glColor3f(1,0,0);
glVertex3f(-1,-1,-1);
glEnd();
glPointSize(0.50);
glBegin(GL_POINTS);
glColor3f(1,1,0);
glVertex3f(-20,-10,10);
glEnd();
glPointSize(50);
glBegin(GL_POINTS);
glColor3f(1,0,1);
glVertex3f(-90,-20,-20);
glEnd();
20 En el evento onPaint de OpenGL realice la llamada a VariosPuntos3() y
ejecute el programa, visualizará una imagen similar a la figura 8.
______________________________________________________________________ 29
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
21. Agregue una función más llámela VariosPuntos4() agregue el siguiente código
glPointSize(0);
nota: esta función dibuja un espiral e incrementa los tamaños de los puntos.
______________________________________________________________________ 30
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
1. Realice un función llamada ejes que usando OpenGL que dibuje las
siguientes líneas
Eje Coordenada Coordenada
inicial Final
x (100,0,0) (-100,0,0)
y (0,100,0) (0,-100,0)
Z (0,0,100) (0,0,-100)
2. Agregue una función (con el nombre EjesColor), tal que dibuje una línea en
cada eje con el color respectivo:
Eje Color
x Rojo
y Verde
z Azul
3. Agregue una función (Sol) que dibuje líneas alrededor del origen (0, 0,0) de
color amarillo.
• Líneas continuas
Para realizar líneas continuas se utiliza la primitiva GL_LINE_STRIP, es decir, el
vértice final sirve de inicio para la siguiente línea y así sucesivamente.
Por ejemplo el siguiente código dibuja 2 líneas continuas dados tres vértices,
figura 10.
glBegin(GL_LINE_STRIP);
glVertex3f(0,5,0);
glVertex3f(100,5,0);
glVertex3f(100,100,0);
glEnd();
______________________________________________________________________ 31
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
100,5,0
0,0,0 100,0,0
• GL_LINE_LOOP
La primitiva GL_LINE_LOOP se comporta de manera similar a GL_LINE_STRIP a
diferencia de que se dibuja una línea final entre el último vértice especificado con
el primer vértice especificado, ejemplo el siguiente código:
glBegin(GL_LINE_LOOP);
glVertex3f(0,5,0);
glVertex3f(0,5,100);
glVertex3f(0,100,100);
glEnd();
______________________________________________________________________ 32
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Y
(100,100, 0)
X
(0,5, 0)
(100,5, 0)
______________________________________________________________________ 33
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Para dibujar líneas con ancho y punteadas siga los siguientes pasos:
______________________________________________________________________ 34
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
void TForm1::LineasParalelas()
{
GLfloat x,y,z;
x=0;
float Inc=0;
glColor3f(1,1,0);
for(y=-100.0f; y<100.0f; y+=20)
{
glLineWidth(Inc);
glBegin(GL_LINES);
glVertex3f(x,y,100);
glVertex3f(x,y,-100);
glEnd();
Inc+=2;
}
}
______________________________________________________________________ 35
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Por ejemplo:
0 0 F F
Binario = 0000 0000 1111 1111
X x x x x x x x
Patrón de línea=
Línea = |_______ ______ _______ _______|
Ejemplo:
Si el patrón es 0x5555 = 21845
Binario: 0101 0101 0101 0101
Patrón de línea: x x x x x x x x
Si factor = 5, es decir cada bit del patrón representa 5 píxeles en una fila
Línea:
glEnd();
factor++;
}
//Deshabilitando el Punteo
glDisable(GL_LINE_STIPPLE);
______________________________________________________________________ 37
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glColor3f(1,1,0);
glBegin(GL_TRIANGLES);
glVertex3f(0,0,0);
glVertex3f(100,100,0);
glVertex3f(100,0,0);
glEnd();
glColor3f(0,1,0);
glBegin(GL_TRIANGLES);
glVertex3f(0,0,0);
glVertex3f(-100,100,0);
glVertex3f(-100,0,0);
glEnd();
______________________________________________________________________ 38
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
V4 V1
V3 V2
V5 V0
Figura 16. Figura derecha: triángulo dibujado en el sentido las manecillas del reloj, figura
Izquierda: triángulo dibujado en el sentido contrario a las manecillas del reloj.
______________________________________________________________________ 39
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Primitiva GL_TRIANGLE_STRIP
Dibuja un triángulo, y cada nuevo vértice se interpreta como un triángulo entre los
dos anteriores vértices y el nuevo.
glColor3f(0.5,0.5,1);
glVertex3f(60,25,0);
glColor3f(0.5,0.5,0.5);
glVertex3f(50,50,0);
glEnd();
Figura 17. a.
______________________________________________________________________ 40
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Figura 17. b.
Figura 17. c.
Primitiva GL_TRIANGLE_FAN
Genera un conjunto de triángulos rellenos conectados entre sí, con la
característica de que todos los triángulos tienen un vértice en común. El primer
triángulo define el vértice común a todos los triángulos.
glColor3f(1,1,0);
glVertex3f(35,25,0);
______________________________________________________________________ 41
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glColor3f(1,0,0);
glVertex3f(0,35,0);
glColor3f(1,0,1);
glVertex3f(-25,25,0);
glColor3f(0,1,1);
glVertex3f(-35,0,0);
glColor3f(1,1,1);
glVertex3f(-25,-25,0);
glColor3f(0.5,1,1);
glVertex3f(0,-35,0);
glColor3f(0.5,0.5,1);
glVertex3f(25,-25,0);
glEnd();
______________________________________________________________________ 42
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
//Polígonos con giro en el sentido de las agujas del reloj miran de frente
//se invierte porque estamos usando un abanico
glFrontFace(GL_CW);
PI=3.1415;
OpenGLPanel1->Width=Form1->Width;
OpenGLPanel1->Height=Form1->Height;
iSeleccionar = 0;
iContorno = 0;
iProfundidad = 0;
______________________________________________________________________ 43
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 44
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
// glFrontFace(GL_CCW);
// Iniciar un nuevo abanico de triángulos para cubrir la parte inferior
______________________________________________________________________ 45
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glBegin(GL_TRIANGLE_FAN);
______________________________________________________________________ 46
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glShadeModel(GL_FLAT);
Le especifica a OpenGL que rellene los polígonos con el color sólido del último
vértice especificado.
glShadeModel(GL_SMOOTH);
Le especifica a OpenGL que sombreará los triángulos suavemente desde cada
vértice.
• Eliminación de superficies
Verifique que el rotar el cono la parte inferior se tambalea, es decir, en OpenGL el
último objeto dibujado aparecerá sobre los anteriores, para corregir se usa una
opción denominada prueba de profundidad, figura 20.
Para activar llamamos a:
glEnable(GL_DEPTH_TEST);
En código encontrará esto:
• El búfer de profundidad
Limpiar la ventana y el búfer de profundidad es análogo al de color en cuánto qué
contiene información sobre la distancia de los píxeles desde espectador, esta
información se usa para determinar si algún píxel quedó oculto por píxeles que se
encuentran más cerca del espectador.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
______________________________________________________________________ 47
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Modos de Polígono
No es necesario rellenar los polígonos con el color actual, de forma
predeterminada los polígono se rellenan de este color, pero puede cambiarse este
comportamiento especificando que los polígonos deben dibujarse como esquemas
o sólo puntos (sólo se tranzan los vértices).
______________________________________________________________________ 48
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 49
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Vértice 2 Vértice 3
Vértice 1 Vértice 4
glColor3f(1,0,0);
glBegin(GL_QUADS);
glVertex3f(-50,-50,50);
glVertex3f(-50,50,50);
glVertex3f(50,50,50);
glVertex3f(50,-50,50);
glEnd();
//banda de cuadriláteros
glColor3f(1,1,0);
glBegin(GL_QUAD_STRIP);
glVertex3f(-50,-50,-50);
glVertex3f(-50,50,-50);
glVertex3f(50,-50,-50);
glVertex3f(50,50,-50);
______________________________________________________________________ 50
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glColor3f(0,1,1);
glVertex3f(100,-50,-50);
glVertex3f(100,50,-50);
glColor3f(1,1,1);
glVertex3f(150,-50,-50);
glVertex3f(150,50,-50);
glEnd();
5. Para dibujar un polígono con cualquier número de lados, figura 27, se utiliza
la primitiva GL_POLYGON, Para dibujar un polígono similar al de figura 27
con el siguiente código:
//polígonos
______________________________________________________________________ 51
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glColor3f(0,1,0);
glBegin(GL_POLYGON);
glVertex3f(-50,50,0);
glVertex3f(40,40,0);
glVertex3f(50,30,0);
glVertex3f(50,-50,0);
glVertex3f(-50,-50,0);
glEnd();
Vértice 1 Vértice 2
Vértice 3
Vértice 4
Vértice 6
______________________________________________________________________ 52
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Cuando genera un polígono, éste se rellena de forma sólida con el último color
especificado, tal como se vio en la práctica 12, para rellenar un polígono en forma
de punteo siga los siguientes pasos:
1. Abrir un proyecto en el cual muestre los ejes x, y y z de color diferente.
2. Aplique rotación en el x, y y z.
3. Dibuje un polígono con 8 lados de igual tamaño
Patrón de Relleno
Para rellenar un polígono existen dos formas: texturas (no incluye en este manual)
y un patrón de punteo, similar al de líneas realizado en la práctica nueve.
Un patrón de punteo de polígonos es un mapa de bits de 32 x 32 que usa para el
patrón de relleno.
glEnable(GL_POLYGON_STIPPLE)
Y enseguida se llama a
glPolygonStipple(pBitmap);
donde:
pBitmap es un apuntador a un área de datos que contiene el patrón de punteo. A
partir de ese momento todos los polígonos se rellenarán con el patrón de punteo
especificado por pBitmap (GLubyte *).
______________________________________________________________________ 53
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
1 6 3 1 8 4 2 1 1 6 3 1 8 4 2 1 1 6 3 1 8 4 2 1 1 6 3 1 8 4 2 1
2 4 2 6 2 4 2 6 2 4 2 6 2 4 2 6
8 8 8 8
Figura 28. Firma en una cuadrícula.
Tomando una línea (marcada con x, figura 29) de la figura 28, los valores en
hexadecimal corresponden a la tabla 1.
______________________________________________________________________ 54
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
6. Declare la matriz
GLubyte fuego[128] = { 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
______________________________________________________________________ 55
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glColor3f(1.0f,0.0f,0.2f); //rojo
Poly() ; // función que dibuja un polígono
______________________________________________________________________ 57
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
bool bContorno=1;
// guardar el estado de la matriz y hacer la rotación
glBegin(GL_TRIANGLES);
glEdgeFlag(bContorno);
glVertex2f(-20.0f, 0.0f);
glEdgeFlag(0);
glVertex2f(20.0f, 0.0f);
glVertex2f(0.0f, 40.0f);
glEnd();
______________________________________________________________________ 58
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
if(iModo == MODO_PUNTO)
glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
if(iModo == MODO_SOLIDO)
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
______________________________________________________________________ 59
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glBegin(GL_TRIANGLES);
glEdgeFlag(bContorno);
glVertex2f(-20.0f, 0.0f);
glEdgeFlag(TRUE);
glVertex2f(20.0f, 0.0f);
glVertex2f(0.0f, 40.0f);
glVertex2f(-20.0f,0.0f);
glVertex2f(-60.0f,-20.0f);
glEdgeFlag(bContorno);
glVertex2f(-20.0f,-40.0f);
glEdgeFlag(TRUE);
glVertex2f(-20.0f,-40.0f);
glVertex2f(0.0f, -80.0f);
glEdgeFlag(bContorno);
glVertex2f(20.0f, -40.0f);
glEdgeFlag(TRUE);
glVertex2f(20.0f, -40.0f);
glVertex2f(60.0f, -20.0f);
glEdgeFlag(bContorno);
glVertex2f(20.0f, 0.0f);
glEdgeFlag(TRUE);
glVertex2f(-20.0f,-40.0f);
glVertex2f(20.0f, -40.0f);
glVertex2f(20.0f, 0.0f);
glEdgeFlag(TRUE);
glEnd();
glPopMatrix();
}
______________________________________________________________________ 60
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
a) b)
c) d)
Figura 32. a) Polígono relleno, b) Polígono en modo línea, c) Polígono en modo puntos y d)
Polígono en modo línea con contorno.
______________________________________________________________________ 61
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
if (angulo<=0.2)
glClear(GL_COLOR_BUFFER_BIT); // limpiar buffer
glPointSize(3);
glBegin(GL_POINTS);
glVertex2d(radio*cos(angulo), radio*sin(angulo));
glEnd();
if(angulo>20)
{
radio=1;
angulo=0;
}
En la condición
if (angulo<=0.2)
glClear(GL_COLOR_BUFFER_BIT);
Se manda a limpiar el buffer cuando esta condición se cumple
______________________________________________________________________ 62
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 63
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Rotación
void glRotatef(GLfloat angulo, GLfloat x, GLfloat y, GLfloat z);
Realiza un giro alrededor del eje especificado (x, y y z). El ángulo de giro se
encuentra en la dirección contraria a las agujas del reloj, medidos en grados y
especificados en el argumento ángulo.
Translación
void glTranslatef(GLfloat x, GLfloat y, GLfloat z);
Acepta como parámetros la cantidad de translación a los largo de los ejes x, y y z.
Escalado
glScalef(GLfloat x, GLfloat y, GLfloat z);
Expande o reduce los objetos a lo largo de distintas direcciones en los ejes x, y y
z.
void __fastcall
void __fastcall TForm1::ScrollBar4Change(TObject
TForm1::ScrollBar2Change(TObject *Sender)
*Sender) {
{ zRot=ScrollBar4->Position;
xRot=ScrollBar2->Position; OpenGLPanel1->Invalidate();
OpenGLPanel1->Invalidate(); }
} void __fastcall
//------------------------------------------------- TForm1::ScrollBar5Change(TObject
*Sender)
void __fastcall {
TForm1::ScrollBar3Change(TObject xEsc=ScrollBar5->Position;
*Sender) OpenGLPanel1->Invalidate();
{ }
yRot=ScrollBar3->Position; //-------------------------------------------------
OpenGLPanel1->Invalidate(); --------------------------
}
//-------------------------------------------------
______________________________________________________________________ 64
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
void __fastcall
TForm1::ScrollBar6Change(TObject
*Sender)
{
yEsc=ScrollBar6->Position;
OpenGLPanel1->Invalidate();
}
//-------------------------------------------------
void __fastcall
TForm1::ScrollBar7Change(TObject
*Sender)
{
zEsc=ScrollBar7->Position;
OpenGLPanel1->Invalidate();
}
//-------------------------------------------------
void __fastcall
TForm1::ScrollBar8Change(TObject
*Sender)
{
xTra=ScrollBar8->Position;
OpenGLPanel1->Invalidate();
}
//-------------------------------------------------
void __fastcall
TForm1::ScrollBar9Change(TObject
*Sender)
{
yTra=ScrollBar9->Position;
OpenGLPanel1->Invalidate();
}
//-------------------------------------------------
void __fastcall
TForm1::ScrollBar10Change(TObject
*Sender)
{
zTra=ScrollBar10->Position;
OpenGLPanel1->Invalidate();
}
______________________________________________________________________ 65
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
3. En código antes de dibujar el cubo llame las funciones para rotar, trasladar y
escalar
glRotatef(xRot,1,0,0);
glRotatef(yRot, 0,1,0);
glRotatef(zRot,0,0,1);
glScalef(xEsc,yEsc,zEsc);
glTranslatef(xTra,yTra,zTra);
a) b)
Figura 35. a) Cubo, b) cubo con rotación, translación y escalamiento.
______________________________________________________________________ 66
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 67
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
donde:
xmin y ymin, representan la esquina inferior de una vista rectangular
xmax y ymax, representan la esquina superior de una vista rectangular
cerca y lejos son los planos de recorte de la vista rectangular, cerca y lejos
respectivamente del observador.
Nota: los objetos dibujados deben estar dentro de las coordenadas de los planos
cerca y lejos, de lo contrario, si un objeto es dibujado fuera de este rango no se
visualizará.
Hasta aquí todos lo ejemplos mostrados se han graficado usando la proyección
ortogonal, la función glOrtho() se encuentra especificada en el evento OnInit() de
la ventana de OpenGL.
______________________________________________________________________ 68
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
//---------------------------------------------------------------------------
void __fastcall TForm1::OpenGLPanel1Init(TObject *Sender)
{
int h=OpenGLPanel1->Height;
int w=OpenGLPanel1->Width;
GLfloat Rango = 140.0f;
if(h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho (-Rango, Rango, -Rango*h/w, Rango*h/w, -Rango*2.0f, Rango*2.0f);
else
glOrtho (-Rango*w/h, Rango*w/h, -Rango, Rango, -Rango*2.0f, Rango*2.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
______________________________________________________________________ 69
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
int h=OpenGLPanel1->Height;
int w=OpenGLPanel1->Width;
GLfloat Aspecto;
if(h == 0)
h = 1;
glViewport(0, 0, w, h);
Aspecto = w/h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Produce la proyección de perspectiva
gluPerspective(70.0f, Aspecto, 1.0, 400.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
donde:
Apertura corresponde al ángulo de apertura de la cámara virtual, este ángulo
puede tomar valores comprendidos entre 0º y 180º.
El valor de aspect, vendrá dado por la relación entre el alto y ancho del plano de
corte, por lo tanto aspect toma el valor de alto plano dividido entre largo plano.
Los valores de pcerca y plejos corresponden a los planos de corte cercano y
lejano.
La proyección en perspectiva gráficamente se representa como la figura 39.
______________________________________________________________________ 70
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 71
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Luz Ambiental. Es la luz que proviene de muchas partes y que permite iluminar a
un objeto, por ejemplo, la luz que existe en un cuarto cerrado, por tal motivo se
llama ambiental, porque es la que existe en un ambiente, figura 41 a.
Luz difusa. Es luz que proviene de un reflejo, que puede ser un ventana, un
espejo, etc., figura 41 b.
Luz especular. Es la luz que proviene de una fuente en específico, tal como, un
foco, el sol, etc., figura 41 c.
a b c
La combinación de las luces produce efectos sobre los objetos (materiales), tales
como brillo y color, los cuales se les denomina reflectancia. La intensidad de
iluminación de cada punto de las superficies de los materiales dependerá de:
Intensidad= Luz ambiente + Luz difusa + Luz especular.
OpenGL tiene las siguientes funciones para especificar la luz tanto de los
materiales como de iluminación que son: glLightModelfv() y glLightfv().
Para dar una iluminación plana a los materiales se utiliza la función: glShadeModel
(GL_FLAT ) y para una iluminación suave se utiliza la función: glShadeModel
(GL_SMOOTH ) ;
Para visualizar una esfera, figura 42, con iluminación el código fuente es el
siguiente:
______________________________________________________________________ 72
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "OpenGLPanel"
#pragma resource "*.dfm"
TForm1 *Form1;
// Rotación
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
// valores y coordenadas de la luz
GLfloat PosicionLuz[] = { 0.0f, 0.0f, 75.0f, 1.0f };
GLfloat LuzEspecular[] = { 1.0f, 0.0f, 0.0f, 1.0f};
GLfloat Reflectancia[] = { 1.0f, 1.0f, 1.0f, 1.0f};
a)
b)
Figura 42. a) Iluminación en modo plano. b) Iluminación en modo suave.
______________________________________________________________________ 73
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Colocar primero la luz
// Guardar las transformadas de las coordenadas
glPushMatrix();
// Rotar el sistema de coordenadas
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
//Especificar la nueva posición y dirección en coordenada rotadas
glLightfv(GL_LIGHT0,GL_POSITION,PosicionLuz);
glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,DirPunto);
// dibujar un cono rojo para introducir la fuente de luz
glColor3ub(255,0,0);
// glColor3ub(0,255,0);
// Trasladar origen para mover el cono donde esta la luz situada
glTranslatef(PosicionLuz[0],PosicionLuz[1],PosicionLuz[2]);
// gluCylinder(pObj, 5,1,7, 15, 15);
gluCylinder(pObj, 2,3,17, 15, 15);
// Dibujar una esfera desplazada para denotar la bobilla de luz
//guardar las variables de estado de iluminación
glPushAttrib(GL_LIGHTING_BIT);
// Apagar la iluminación y especificar una esfera amarilla brillante
glDisable(GL_LIGHTING);
//glColor3ub(255,255,0);
glColor3ub(255,0,0);
// gluSphere(pObj, 4, 15, 15);
gluSphere(pObj, 2, 5, 5);
// Restablecer las variables del estado de iluminación
glPopAttrib();
// Restablecer las transformaciones de coordenadas
glPopMatrix();
// Establecer el color del material y dibujar una esfera en el centro
glColor3ub(255,0, 0 ); //rojo
gluSphere(pObj, 55, 50, 50);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ScrollBar1Change(TObject *Sender)
{
xRot=ScrollBar1->Position;
OpenGLPanel1->Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ScrollBar2Change(TObject *Sender)
{
yRot=ScrollBar2->Position;
OpenGLPanel1->Invalidate();
}
______________________________________________________________________ 76
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
//---------------------------------------------------------------------------
void __fastcall TForm1::Plano1Click(TObject *Sender)
{
Forma = MODO_PLANO;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Suave1Click(TObject *Sender)
{
Forma = MODO_SUAVE;
}
//---------------------------------------------------------------------------
En el archivo .h de c++ builder 5 declare de forma pública la función “LuzPunto”
______________________________________________________________________ 77
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
La sombra es un efecto que permite dar una apariencia más real a los objetos
graficados, una sombra es la ausencia de luz producida por la superposición de un
cuerpo opaco entre una fuente de luz y otro cuerpo, en OpenGL para generar el
efecto de sombra se tienen que especificar los siguientes puntos:
1. Graficar un objeto
2. Especificar un punto como fuente de luz
3. Generar una matriz de proyección en la cual se calculará el plano de
proyección donde se quiere la sombra.
En la figura 43 se observa el efecto de sombra, donde la fuente de luz se
representa por un círculo amarillo, el objeto opaco que se superpone a la luz y la
sombra.
#include <GL/glu.h>
#include <vcl.h> #include <GL/gl.h>
#pragma hdrstop //-----------------------------------------------------------
----------------
#include "Unit1.h" #pragma package(smart_init)
#include <math.h> #pragma link "OpenGLPanel"
#include <math.h> #pragma resource "*.dfm"
//#include <GL/glaux.h> TForm1 *Form1;
#include <GL/glut.h> void Base();
______________________________________________________________________ 78
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 79
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 80
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
xRot=ScrollBar1->Position;
OpenGLPanel1->Invalidate(); // Realizar ahora la proyección
} // primer columna
//----------------------------------------------------------- destMat[0] = dot - vLightPos[0] *
---------------- vPlaneEquation[0];
void __fastcall destMat[4] = 0.0f - vLightPos[0] *
TForm1::ScrollBar2Change(TObject *Sender) vPlaneEquation[1];
{ destMat[8] = 0.0f - vLightPos[0] *
yRot=ScrollBar2->Position; vPlaneEquation[2];
OpenGLPanel1->Invalidate(); destMat[12] = 0.0f - vLightPos[0] *
} vPlaneEquation[3];
//-----------------------------------------------------------
---------------- // Segunda columna
destMat[1] = 0.0f - vLightPos[1] *
void TForm1::Dibujo(int Tipo) vPlaneEquation[0];
{ destMat[5] = dot - vLightPos[1] *
vPlaneEquation[1];
if(Tipo == 0) destMat[9] = 0.0f - vLightPos[1] *
glColor3ub(128, 128, 128); vPlaneEquation[2];
else destMat[13] = 0.0f - vLightPos[1] *
glColor3ub(0,0,0); vPlaneEquation[3];
______________________________________________________________________ 81
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 82
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 83
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
El reflejo es un efecto que permite dar una apariencia más real a los objetos
graficados, para conseguir el efecto se utiliza la transparencia de la superficie
reflectante, en OpenGL para generar el efecto se deben seguir los siguientes
pasos:
1. Graficar el objeto de fondo (reflejo)
2. Graficar la superficie reflectante
3. Graficar de forma normal el objeto
Ejemplo, graficar una tetera con reflejo, figura 44, se grafica una tetera (fondo) con
orientación inversa para dar el efecto de reflejo, enseguida se grafica la superficie
que hará el papel de reflejo y por último sobre la superficie se grafica nuevamente
la tetera de forma norma.
#include "Unit1.h"
#include<gl/glut.h> //-----------------------------------------------------------
//----------------------------------------------------------- ----------------
---------------- __fastcall TForm1::TForm1(TComponent*
#pragma package(smart_init) Owner)
#pragma link "OpenGLPanel" : TForm(Owner)
______________________________________________________________________ 84
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
{ glPushMatrix();
} glFrontFace(GL_CW);
//----------------------------------------------------------- glScalef(1,-1,1);
---------------- glColor3f(0,0,0);
void __fastcall Escena(); //fondo
TForm1::OpenGLPanel1Init(TObject
*Sender) glFrontFace(GL_CCW);
{ glPopMatrix();
int w=OpenGLPanel1->Width;
int h=OpenGLPanel1->Height; //Dibujar el suelo transparente sobre el
GLfloat fAspect; reflejo
glDisable(GL_LIGHTING);
if(h == 0) glEnable(GL_BLEND); //fundido de color
h = 1; glBlendFunc(GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA); //efecto de
glViewport(0, 0, w, h); dibujar un objeto transparente delante de
algún objeto opaco
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glColor4f(0.5,0.5,0.5,0.5);
Suelo();
fAspect = (GLfloat)w/(GLfloat)h; //transparencia
gluPerspective(60.0f, fAspect, 1.0, 300.0); glColor4f(1,0,0,0.5);
glMatrixMode(GL_MODELVIEW); glDisable(GL_BLEND);
glLoadIdentity(); glEnable(GL_LIGHTING);
______________________________________________________________________ 85
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
} fColor = 0.0f;
//---------------------------------------
void TForm1::Suelo() glColor4f(fColor, fColor, fColor,
{ 0.5f);
glVertex3f(iStrip, y, iRun);
glBegin(GL_QUADS); glVertex3f(iStrip + fStep, y, iRun);
glVertex3f(200,0,200);
glVertex3f(200,0,-200); iBounce++;
glVertex3f(-200,0,-200); }
glVertex3f(-200,0,200); glEnd();
}
glEnd(); glShadeModel(GL_SMOOTH);
}
} void __fastcall
//----------------------------------------------------------- TForm1::ScrollBar1Change(TObject *Sender)
---------------- {
void DrawGround(void) xRot=ScrollBar1->Position;
{ OpenGLPanel1->Invalidate();
GLfloat fExtent = 200.0f; }
GLfloat fStep = 5; //-----------------------------------------------------------
GLfloat y = 0.0f; ----------------
GLfloat fColor; void __fastcall
GLfloat iStrip, iRun; TForm1::ScrollBar2Change(TObject *Sender)
GLint iBounce = 0; {
yRot=ScrollBar2->Position;
glShadeModel(GL_FLAT); OpenGLPanel1->Invalidate();
for(iStrip = -fExtent; iStrip <= fExtent; iStrip }
+= fStep) //-----------------------------------------------------------
{ ----------------
glBegin(GL_TRIANGLE_STRIP); void __fastcall TForm1::FormCreate(TObject
for(iRun = fExtent; iRun >= -fExtent; *Sender)
iRun -= fStep) {
{ xRot=0;
if((iBounce %2) == 0) yRot=0;
fColor = 1.0f; }
else //-----------------------------------------------------------
//--------------------------------------------------------------
______________________________________________________________________ 86
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 87
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 88
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 89
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 90
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 91
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 92
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
______________________________________________________________________ 93
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Conclusiones
Los efectos 3D, color, iluminación, sombra, transparencia, sin duda alguna ayudan
a tener gráficos con mayor realismo, otros no presentados en este manual son
suavizado de bordes, texturas, manejo de líneas y superficies, música, etc.
Este manual fue presentado con el fin de fomentar el arte por el manejo de los
gráficos y para incrementar el acervo bibliográfico con material de calidad y
utilidad.
______________________________________________________________________ 94
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Agradecimientos
______________________________________________________________________ 95
M.C. Isidro Moctezuma Cantorán
________________________________________________________________________________________
Bibliografía
http://www.opengl.org, 2008.
http://www.1av10.nu/~gerry/c/common/MatrixMath, 2008
______________________________________________________________________ 96
M.C. Isidro Moctezuma Cantorán