Sie sind auf Seite 1von 5

Programando en OpenGL y GLUT

Ahora hay que decirle a OpenGL como queremos "Dibujar", le indicamos que vamos a usar
un buffer unico con la constante GLUT_SINGLE y ademas le tenemos que decir comos se
Este primer programa de ejemplo dibuja una "Tetera", una fuente de luz puntual, se define van a aplicar los colores, los cuales van a estar definidos por tres valores numericos, uno
ademas un material el que se aplica a la "Tetera". Utilizo GLUT (OpenGL Utility Toolkit) que para el Rojo, otro para el Verde y otro para el azul, para esto usamos la constante
es una interface de programación para C y FORTRAN para escribir programas OpenGL GLUT_RGB.
independientes del sistema de ventanas.
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
El código esta compuesto por las siguientes partes :
GLUT nos permite definir las dimensiones de nuestra ventana de visualización.
#includes
glutInitWindowSize (300, 300);

void main(void) También hay que "colocar" la ventana en algún punto determinado de la pantalla.

glutInitWindowPosition (0, 0);


void init(void)
Una vez ya definido como "Dibujar", con que medidas de ventana y en que posición física de
void reshape(int w, int la pantalla creamos la ventana, le damos un nombre cualquiera que sera el título que
aparecerá en esta.
h)
glutCreateWindow ("Teapot");
void display(void) Creamos una función llamada Init() que se encargará de la Inicialización de las variables de
OpenGL.
void keyboard()
init();

Código Fuente Tras inicializar el sistema le decimos a OpenGL cual es la función que debe llamarse cada
vez que se requiera dibujar en la pantalla. Esta función la tendremos que crear nosotros por
supuesto y será dónde le diremos a OpenGL que es lo que debe dibujarse en la ventana que
includes hemos creado para tal fin.

En la primer parte del código estan los #includes que indican al compilador que debe incluir glutDisplayFunc(display);
otros archivos fuentes.
Esta funcion no retorna ningun valor, y tampoco recibe argumento alguno.
//Incluimos las librerias
#include <GL/glut.h> void display(void)
{
#include <stdlib.h>
.................................
//aqui va el codigo de la funcion
main() .................................
}
Cualquier programa en C se caracteriza por su función main o principal, función que se llama
En caso de que se modifique el tamaño de nuestra ventana, lo indicamos en la funcion que
automáticamente al iniciar la ejecución del programa. Para empezar llamaremos reshape().
definimos main como int ya que debe retornar un entero :
glutReshapeFunc(reshape);
int main (int argc, char **argv);
esta funcion la definimos de la siguiente manera
La llamada que sigue es a GLUT, esta funcion me inicializa OpenGL.
void reshape(int w, int h )
glutInit (&argc, argv);
{ si hubiera sido :
................................
//código que deseemos se ejecute GLfloat light_position[] = { 1.0, 1.0, 1.0, 1.0 };
................................
} la fuente de luz estaria en el en la posicion (1.0, 1.0, 1.0).

Los parámetros que nos llegan a la función se refieren al nuevo ANCHO (w) y al nuevo ALTO Activamos todo el calculo de ilumincaion :
(h) de la ventana tras ser redimensionada por el usuario. En esta función deberemos
asegurarnos de que la imagen no se distorsione. glEnable(GL_LIGHTING);

El control del teclado se realiza mediante Activamos la fuente de luz :

glutKeyboardFunc(keyboard); glEnable(GL_LIGHT0);

esto lo añadimos a nuestra función de main y entonces definimos a parte la función de control Elijo el modo de comparacion para el test del Depth Buffe.
propiamente dicha para el teclado :
glDepthFunc(GL_LESS);
void keyboard( unsigned char key, int x, int y )
{ Activo el Depth Buffer, es usado generalmente para la eliminacion de superficies ocultas.
................................
//código que deseemos se ejecute glEnable(GL_DEPTH_TEST);
................................
} Aqui le decimos que dibuje sólo las caras frontales GL_FRONT y rellenadas, es decir con
color en su interior además de en los bordes GL_FILL. Para dibujar sólo las caras traseras
Bueno ya sabemos dónde dibujar, en la ventana, y qué dibujar. Sólo falta entrar en el bucle utilizaríamos GL_BACK y para dibujar ambas GL_FRONT_AND_BACK. En el caso del color
infinito que domina cualquier aplicación OpenGL. Con la función que sigue, que siempre se de relleno, si deseamos evitarlo coloreando solo los bordes de cada polígono usaremos la
pone al final del main, le decimos a la librería que espere eternamente a que se produzcan constante GL_LINE :
"eventos".
glPolygonMode (GL_FRONT, GL_FILL);
glutMainLoop ();
Eso es todo lo que tengo en mi rutina de inicializacion por ahora.
Por ultimo se requiere que la funcion main retorne un entero aunque no sirva literalmente
para nada :
display()
return 0;
Defino las caracteristicas del material que voy a usar :
Init()
GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
GLfloat mat_diffuse[] = { 0.1f, 0.5f, 0.8f, 1.0f };
Bueno todo programador que se precie de no hacerlo muy mal sabrá que hay que ahorrarse GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
el máximo de sentencias en el propio main e incluirlas en una rutina de inicialización que se
GLfloat mat_shininess[] = { 100.0f };
llama desde éste, para eso esta Init() como que no se le pasa ningún parámetro ni retorna
ningún valor la declaramos tal como :
La función glClear nos permite borrar tanto buffer de color, como el de profundidad.
void inicio (void)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
En primer lugar le indico la ubicacion de la fuente de luz, en este caso se trata de una fuente
de luz puntual situada en el infinito, que pasa por el origen de coordenadas y por el punto Selecciono la matriz de modelado :
(1.0, 1.0, 1.0) :
glMatrixMode (GL_MODELVIEW);
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
y la "limpio" con la matriz identidad :
Procedemos a "limpiarla" para que no contenga ningún valor que pueda falsear los cálculos y
glLoadIdentity (); por tanto nos haga obtener resultados inexactos. Para ello cargamos a la matriz activa
(proyeccion) con la matriz identidad :
Roto el objeto 25 grados en torno al eje x.
glLoadIdentity ();
glRotated(25.0, 1.0, 0.0, 0.0);
Tengo la matriz de proyección limpia, pero ahora tengo que decirle a OpenGL de que manera
Lo vuelvo a rotar pero esta ves -30 grados en torno al eje y. quiero que proyecte mis gráficos en la ventana que he creado. Usaremos la función
glOrtho(...). Así creo el volumen de visualización. Todo lo que esté dentro de este volumen
glRotated(-30.0, 0.0, 1.0, 0.0); será proyectado de la forma más simple, eliminando su coordenada Z, o de profundidad. Es
la llamada proyección ortográfica y no permite que se distinga la distancia de los objetos a la
Aplico el material al objeto cámara :

glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glOrtho (-200, 200, -200, 200, -200, 200);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glOrtho()
Se utiliza para especificar
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); una proyección ortográfica.
Dibujo una "Tetera" de dimensiones 125.0, este objeto esta definido Este tipo de proyección
define un volumen de vista
en GLUT. rectangular, concretamente
define un paralelepípedo de
tamaño infinito, este hecho
nos lleva a definir una serie
glutSolidTeapot(125.0); de planos de corte para
detallar con exactitud el
volumen de vista. OpenGL
Fuerzo a dibujar el objeto. define la sentencia como:

glOrtho(xmin, xmax, ymin,


ymax, cerca, lejos);
glFlush();
Estos seis argumentos
definen la ventana de
visualización y los planos de
corte tanto cercano como
reshape() lejano. Para definir la
ventana de visualización es
suficiente definir las
Definimos primero un viewport es un área rectangular de la ventana de visualización. Por coordenadas de dos
defecto es la ventana entera pero podemos variarlo a gusto. Se utiliza la funció : esquinas de la ventana, con
estos dos valores queda
void glViewport(GLint x, GLint y, GLsizei w, GLsizei h) totalmente definida. Los
valores
de cerca y lejos representan
dónde (x,y) es la esquina inferior izquierda del rectangulo o viewport. Esta coordenada debe el plano cercano y el plano
especificarse con relación a la esquina inferior izquierda de la ventana. Claro está que w, h lejano. Hay que tener en
son la anchura y altura de nuestro viewport dentro de la ventana. Todos los valores son cuenta que el objeto a
enteros ya que se tratan de pixels. visualizar debe encontrarse
dentro de ambos planos, si
sobrepasan estos dos planos
glViewport(0, 0, (GLsizei) w, (GLsizei) h); el objeto se recortará
automáticamente.
En primer lugar tenemos decirle a OpenGL como debe proyectar nuestros gráficos en
pantalla. Por ello y para empezar le decimos que active la matriz de proyección :
Ya hemos terminado con la matriz de proyección. El sistema ya sabe como debe proyectar en
glMatrixMode (GL_PROJECTION); pantalla. Ahora pasemos a la matriz de modelado/visionado, o sea, la matriz que
rota/escala/traslada....Dado que queremos operar sobre ella la seleccionamos con :
glMatrixMode (GL_MODELVIEW);

Procedemos a "limpiarla" con la matriz identidad. /* Este programa utiliza proyeccion ortografica para
* visualizar una "Tetera", este objeto esta definido
glLoadIdentity(); * en GLUT, se crea una fuente de luz, y un material */

//Incluimos las librerias


keyboard() #include <GL/glut.h>
#include <stdlib.h>
Esta funcion termina la aplicacion si es presionada la tecla Esc
void init(void)
{
void keyboard(unsigned char key, int x, int y) // Ubicamos la fuente de luz en el punto (1.0, 1.0, 1.0)
{ GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
switch (key)
{ // Activamos la fuente de luz
case 27: exit(0); glEnable(GL_LIGHTING);
break; glEnable(GL_LIGHT0);
} glDepthFunc(GL_LESS);
} glEnable(GL_DEPTH_TEST);
// Queremos que se dibujen las caras frontales
Código Fuente del ejemplo // y con un color solido de relleno.
glPolygonMode(GL_FRONT, GL_FILL);
}
Codigo fuente (ejemplo1.zip 4kb)
void reshape(int w, int h)
{
if (!h)
return;
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
// Activamos la matriz de proyeccion.
glMatrixMode(GL_PROJECTION);
// "limpiamos" esta con la matriz identidad.
glLoadIdentity();
// Usamos proyeccion ortogonal
glOrtho(-200, 200, -200, 200, -200, 200);
// Activamos la matriz de modelado/visionado.
glMatrixMode(GL_MODELVIEW);
// "Limpiamos" la matriz
glLoadIdentity();
}

// Aqui ponemos lo que queremos dibujar.


void display(void)
{
// Propiedades del material
GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
GLfloat mat_diffuse[] = { 0.1f, 0.5f, 0.8f, 1.0f }; // de visualizacion en pixels
GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glutInitWindowSize (300, 300);
GLfloat mat_shininess[] = { 100.0f };
// Posicionamos la ventana en la esquina superior izquierda
// "Limpiamos" el frame buffer con el color de "Clear", en de
este // la pantalla.
// caso negro. glutInitWindowPosition (0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Creamos literalmente la ventana y le adjudicamos el
glMatrixMode( GL_MODELVIEW_MATRIX ); nombre que se
glLoadIdentity(); // observara en su barra de titulo.
glutCreateWindow ("Teapot");
// Rotacion de 30 grados en torno al eje x
glRotated(25.0, 1.0, 0.0, 0.0); // Inicializamos el sistema
// Rotacion de -30 grados en torno al eje y init();
glRotated(-30.0, 0.0, 1.0, 0.0);
// Dibujamos una "Tetera" y le aplico el material glutDisplayFunc(display);
glutReshapeFunc(reshape);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glutKeyboardFunc(keyboard);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glutMainLoop();
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); // ANSI C requiere que main retorne un valor entero.
glutSolidTeapot(125.0); return 0;
}
glFlush();
}

// Termina la ejecucion del programa cuando se presiona ESC


void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27: exit(0);
break;
}
}

// Main del programa.


int main(int argc, char **argv)
{
// Inicializo OpenGL
glutInit(&argc, argv);

// Activamos buffer simple y colores del tipo RGB


glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);

// Definimos una ventana de medidas 300 x 300 como ventana

Das könnte Ihnen auch gefallen