Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Manual
Manual
1)
Por Jorge Garca -aka Bardok (2004)-
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike icense. To view a cop! of this license" visit http://creativecommons.or#/licenses/b!-nc-sa/$.%/ or send a letter to Creative Commons" &&' Nathan Abbott (a!" Stanford" California ')*%&" +SA
ndice de contenido
Cap2tulo 0: 3ntroducci,n....................................................................................4 0.0 5rop,sito de este manual........................................................................4 0.$ 6A 7ui8n est9 diri#ido:............................................................................4 0.* Acerca del manual...................................................................................; Cap2tulo $: -pen. ! .N+/ inu<.....................................................................' $.0 a librer2a -pen. ..................................................................................' $.$ .N+/ inu< ! -pen. ............................................................................0% $.$.0 6=u8 es necesario para desarrollar aplicaciones -pen. :...........00 Cap2tulo *: Conceptos b9sicos sobre -pen. .................................................0* *.0 -pen. como m97uina de estados.......................................................0* *.$ >l espacio *?.........................................................................................0) *.$.0 as transformaciones de los ob@etos..............................................0& *.$.$ as coordenadas homo#8neas........................................................04 *.* Sobre . +T...........................................................................................04 *.) as funciones b9sicas de -pen. .........................................................0; *.).0 Activaci,n/desactivaci,n de opciones............................................0; *.).$ as matrices ! -pen. ..................................................................0; *.).* >l dibu@ado en -pen. ...................................................................0' *.).) >l color en -pen. ........................................................................$% *.).& a orientaci,n de las caras en -pen. .........................................$% *.).A as transformaciones en -pen. ..................................................$% *.).4 a pro!ecci,n en -pen. ..............................................................$% *.& 5rimer contacto con -pen. ................................................................$0 *.&.0 Bi primer pro#rama -pen. .........................................................$$ *.&.$ CisualiDando en perspectiva...........................................................$) *.&.* -cultaci,n de ob@etos /E-Fuffer1....................................................$A *.&.) Gerar7u2as.......................................................................................$; Cap2tulo ): Animaciones..................................................................................*& ).0 os vectores para animar fi#uras..........................................................*& ).$ >l doble bufferin#..................................................................................*' Cap2tulo &: 3luminaci,n...................................................................................)* &.0 >l modelo de iluminaci,n en -pen. ...................................................)* &.0.0 uces..............................................................................................)) &.0.$ Bateriales.......................................................................................)) &.0.* Normales........................................................................................)) &.$ +tiliDando iluminaci,n en -pen. ........................................................)& &.$.0 uces..............................................................................................)& &.$.$ Bateriales.......................................................................................)4 &.$.* >@emplo: iluminaci,n direccional sobre una superficie.................); &.$.) >@emplo: moviendo un foco alrededor de una esfera.....................&% &.$.& >@ercicio propuesto.........................................................................&$ Cap2tulo A: Te<turas........................................................................................&& A.0 as coordenadas de te<tura...................................................................&& A.$ Aplicar las te<turas................................................................................&A A.$.0 Hepetici,n de te<turas....................................................................&; Cap2tulo 4: 3nteracci,n b9sica con . +T........................................................A* 4.0 3nteracci,n con el teclado.....................................................................A*
Gor#e .arc2a -Fardok- /$%%)1 *
4.$ Hedimensionado de la ventana..............................................................A) Cap2tulo ;: Hecursos de inter8s.......................................................................A4 Ane<o A: C,di#o de los pro#ramas de e@emplo...............................................A' A.a m!firstopen#lpro#ram.c........................................................................A' A.b 7uadortho.c...........................................................................................4% A.c 7uadpersp.c...........................................................................................40 A.d Dbuffer-!es.c..........................................................................................4$ A.e simple#u!.c............................................................................................4* A.f @erar7uia-cuadro.c..................................................................................4& A.# @erar7uia-cuadro-recursivo.c.................................................................4A A.h sphere-rebotes.cpp................................................................................44 A.i sphere-rebotes-multi.cpp.......................................................................;% A.@ normals-perp.c.......................................................................................;0 A.k lit-sphere.c.............................................................................................;$ A.l l-sphere-rebotes-multi.cpp.....................................................................;) A.m trian#-te<ture.c.....................................................................................;A A.n normals-perp-te<ture.c..........................................................................;; A.o te<ture-no-clamp.c I te<ture-!es-clamp.c............................................;' A.p lit-sphere-ke!b.c....................................................................................'0
>S3?>-.host
ndice de ilustraciones
Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura Ji#ura $.0. Acceso al hardware a trav8s de -pen. /.N+/ inu<1................00 *.0. >@es de coordenadas en -pen. ..................................................0) *.$. Traslaci,n de un ob@eto.................................................................0& *.*. Hotaci,n de un ob@eto...................................................................0A *.). >scalado en el e@e K......................................................................0A *.&. C8rtices de un pol2#ono................................................................$% *.A. ColLmen de pro!ecci,n orto#r9fico..............................................$0 *.4. ColLmen de visualiDaci,n en perspectiva.....................................$0 *.;. Salida del pro#rama Mm!firstopen#lpro#ramM..............................$) *.'. Salida del pro#rama M7uadorthoM.................................................$& *.0%. Salida del pro#rama N7uadperspO...............................................$A *.00. ?ibu@ado sin E-Fuffer..................................................................$4 *.0$. ?ibu@ado con E-Fuffer /salida del pro#rama Dbuffer-!es1...........$; *.0*. Gerar7u2a sencilla /salida del pro#rama @erar7uia-cuadro.c1......*% *.0). Gerar7u2a fractal /pro#rama @erar7uia-cuadro-recursivo.c1........*% *.0&. Salida del pro#rama Msimple#u!M................................................*$ *.0A. Hotaci,n del braDo /simple#u!1..................................................** ).0. Hepresentaci,n de la posici,n ! velocidad con vectores..............*A ).$. Comportamiento del pro#rama MrebotesM.....................................*A ).*. 5osici,n de la c9mara en el e@emplo Msphere-rebotesM.................*; ).). Salida del pro#rama Msphere-rebotesM..........................................)% ).&. Salida del pro#rama Msphere-rebotes-multiM................................)0 &.0. >fecto de las normales en la iluminaci,n.....................................)& &.$. Tipos de luces...............................................................................)A &.*. Salida del pro#rama Mlit-sphereM...................................................&$ &.). Salida del pro#rama Ml-sphere-rebotes-multiM..............................&* A.0. Coordenadas de te<tura................................................................&A A.$. Bapeado de te<tura......................................................................&A A.*. ?iferencias entre . PH>5 AC> ! . PB-?+ AT>.....................&; A.). Te<turas para suelo ! pared..........................................................&' A.&. Salida del pro#rama Mte<ture-no-clampM.......................................A% A.A. Salida del pro#rama Mte<ture-!es-clampM.....................................A0
&
ndice de tablas
Tabla *.0. 5rimitivas de dibu@ado....................................................................0' Tabla ).0. B8todos de la clase TSphere..........................................................*4
>S3?>-.host
Cap2tulo 0: 3ntroducci,n
Captulo 1: Introduccin
>l manual no se recomienda a personas con conocimientos avanDados de -pen. " !a 7ue no va a contar nada revolucionario acerca de esta tecnolo#2a #r9fica *?" si bien" 7ui8n sabe" siempre se puede aprender al#o nuevo...
>S3?>-.host
No permitas que los rboles te impidan ver al chalado que te persigue con una motosierra... (Bardok)
2.1 La librera
pen!L
-pen. es un est9ndar creado por Silicon .raphics en el aQo 0''$ para el diseQo de una librer2a $?/*? portable R-5>N. S. Actualmente es una de las tecnolo#2as m9s empleadas en el diseQo de aplicaciones *?" ! su Lltima versi,n" a la fecha de ho! /$%%)1" es la 0.&" ! est9 en proceso la especificaci,n de la versi,n $.%" 7ue incluir9 muchas me@oras.. Se divide en tres partes funcionales:
a librer2a -pen. " 7ue proporciona todo lo necesario para acceder a las funciones de dibu@ado de -pen. . a librer2a . + /-pen. +tilit! ibrar!1" una librer2a de utilidades 7ue proporciona acceso r9pido a al#unas de las funciones m9s comunes de -pen. " a trav8s de la e@ecuci,n de comandos de m9s ba@o nivel" pertenecientes a la librer2a -pen. propiamente dicha RH>?F--TS. . K /-pen. ><tension to the K (indow S!stem1 proporciona un acceso a -pen. para poder interactuar con un sistema de ventanas K (indow" ! est9 incluido en la propia implementaci,n de -pen. /su e7uivalente en (indows es la librer2a (. " e<terna a la implementaci,n de -pen. 1.
Adem9s de estas tres librer2as" la librer2a . +T /-pen. +tilit! Toolkit1 proporciona una interfaD independiente de plataforma para crear aplicaciones de ventanas totalmente portables R. +TS.
Gor#e .arc2a -Fardok- /$%%)1 '
pen!L
-pen. aparece en .N+/ inu<" habitualmente ba@o la librer2a Besa *? RB>SAS" una implementaci,n libre de -pen. . >sta implementaci,n es" de por s2" una implementaci,n totalmente software de la librer2a -pen. /e<cepto para las tar@etas *df< Coodoo0" Coodoo$" Coodoo Hush" Coodoo Fanshee" Coodoo*" 7ue tienen acceso al hardware a trav8s del driver Besa/.lide 7ue proporciona Besa1" por lo 7ue s,lo es aconse@able utiliDarla en el caso de no disponer de nin#una otra implementaci,n de -pen. . Actualmente /$%%)1 la versi,n estable de esta librer2a es la A.%.0" 7ue implementa el est9ndar -pen. 0.&. a utiliDaci,n m9s habitual de esta librer2a" no obstante" se realiDa a partir de la librer2a <libmesa. >sta librer2a forma parte del sistema Kfree;A" ! proporciona acceso a aceleraci,n #r9fica por hardware" siempre 7ue la tar@eta #r9fica ! los drivers instalados lo permitan" a trav8s de ?H3 /?irect Henderin# 3nfraestructure R?H3S1. >ste es el modo a trav8s del 7ue podemos acceder a aceleraci,n por hardware para tar@etas de v2deo como *df<" 3ntel" Batro<" AT3... ?H3 est9 presente en las implementaciones del servidor Kfree;A a partir de la versi,n ) del mismo. B9s concretamente" la versi,n ).* de Kfree;A trae consi#o la librer2a <libmesa ).%.)" 7ue implementa el est9ndar -pen. 0.*. Jinalmente" las tar@etas NC3?3A proporcionan su propia implementaci,n de la librer2a -pen. " independientemente de la librer2a Besa" si bien es cierto 7ue ciertas partes de Besa /las librer2as de utilidades . + ! . +T1 pueden utiliDarse @unto con la implementaci,n de NC3?3A. >n resumen" podemos utiliDar la librer2a -pen. se#Ln nuestra confi#uraci,n de hardware: de diferentes maneras"
0%
>S3?>-.host
Apli a i!n "D Interfaz OpenGL Mesa Xlibmesa #$IDIA OpenGL Dri%er
Mesa/Glide
Software Render
DRI
HARDWARE
/.N+/ inu<1
-pen.
ba@o
.N+/ inu<"
os binarios de la librer2a -pen. " !a sea Besa /compilado e instalado a partir del c,di#o fuente1" <libmesa /incluido con Kfree;A ) ! posteriores1 o drivers propios. os pa7uetes de desarrollo de estas librer2as /<libmesa-dev" en el caso de <libmesa" #lut#*-dev... para drivers propios depender9 del fabricante" ! para Besa" si se ha instalado compilando el c,di#o fuente" no deber2a de haber problemas1. +n compilador del len#ua@e en el 7ue vamos a pro#ramar" en este caso" en C" para lo 7ue usaremos el compilador #cc" ! #II si utiliDamos CII. +n editor de te<to" !a sea en modo consola" o ba@o el entorno K (indows /a m2 me #usta el Tate de T?>" pero cada cual tiene sus preferencias1.
00
Por qu narices habr puesto que despus de el nombre de un captulo, me pida poner una cita de manera automtica? (Bardok)
3.1
-pen. es una librer2a 7ue traba@a como una m97uina de estados. >sto es al#o 7ue oiremos hasta la saciedad al pro#ramar con -pen. ... 6pero 7u8 si#nifica: a utiliDaci,n de -pen. consiste en activar ! desactivar opciones" ! realiDar ciertas acciones" 7ue tendr9n como fruto una representaci,n en pantalla /o no1 de una serie de datos" dependiendo en el estado en 7ue nos encontremos... As2" no ser9 lo mismo dibu@ar un tri9n#ulo ! activar una te<tura" 7ue activar una te<tura ! dibu@ar un tri9n#ulo... en -pen. " el orden de las acciones resulta cr2tico en la ma!or2a de las ocasiones... de i#ual manera" no ser9 lo mismo trasladar ! rotar al#o" 7ue rotarlo ! trasladarlo" como veremos m9s adelante" en lo referente a las transformaciones... ?e este modo" de manera mu! abstracta" la manera de dibu@ar al#o en -pen. suele ser la si#uiente: 0. Activar todas las opciones 7ue van a ser persistentes a la escena /ponemos la c9mara" activamos la iluminaci,n #lobal...1 $. Activar las opciones 7ue establecen el estado de un ob@eto espec2fico /su posici,n en el espacio" su te<tura...1
0*
*. ?ibu@ar el ob@eto. ). ?esactivar las opciones propias de ese ob@eto /volver a la posici,n ori#inal" desactivar su te<tura1 &. Colver al punto $ hasta haber dibu@ado todos los ob@etos. >sto" evidentemente" es un es7uema sencillo... como se ver9 m9s adelante" estas operaciones pueden a#ruparse en @erar7u2as" lo 7ue proporciona una #ran potencia ! fle<ibilidad a la hora de pro#ramar /6se nota 7ue so! fan de -pen. : U-1
Z
Ji#ura *.0. >@es de coordenadas en -pen.
a cuarta coordenada se utiliDa entre otras raDones" para representar la perspectiva" pero no nos meteremos con ello en este momento... de este modo" el sistema de coordenadas inicial de un sistema -pen. puede representarse con esta matriD:
0)
>S3?>-.host
Jinalmente" es recomendable desempolvar nuestros al#ebraicos b9sicos /vectores" normales" etc.1" por7ue como veremos" nos van a resultar de #ran utilidad a la hora de pro#ramar en *?... a situaci,n de los e@es de coordenadas se refle@a en la matriD de transformaci,n. >sta matriD representa la transformaci,n 7ue se aplicar9 a todos los v8rtices 7ue se dibu@en mientras ella est8 activa.
[ ]
1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
Traslaci,n: una traslaci,n es un desplaDamiento de un ob@eto en el espacio... por e@emplo" movemos un ob@eto a una nueva posici,n desde la actual
Hotaci,n: como su nombre indica" un ob@eto rota alrededor de un e@e 7ue pasa por su Ncentro de #iroO
0&
>l espacio *?
>scalado: un ob@eto puede ver afectado el tamaQo con 7ue se visualiDa por su transformaci,n de escalado
Sin entrar en demasiados detalles" es conveniente saber 7ue toda trasformaci,n constru!e una matriD de cuatro dimensiones 7ue se multiplicar9 por la matriD de transformaci,n inicial /a7uella 7ue define el e@e de coordenadas1. 5or e@emplo" al trasladar un ob@eto dos unidades en el e@e K" se #enera la si#uiente matriD de transformaci,n:
[
0A
1 0 0 0
0 1 0 0
0 0 1 0
2 0 0 1
]
>S3?>-.host
Si aplicamos esta transformaci,n a la matriD ori#inal" nos 7uedar9 7ue la nueva matriD de transformaci,n es:
Si ahora dibu@amos el punto /0"%"%1" teniendo en cuenta 7ue la matriD indica un desplaDamiento de dos unidades en e@e K" el punto deber2a de dibu@arse en la posici,n /*"%"%1. 5ara esto" se multiplica el punto por la matriD de transformaci,n:
[ ][ ][ ]
1 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 0 2 1 0 0 0 1 = 0 0 0 1 0 0 0 0 1 0 2 0 0 1
5ara poder multiplicar el punto /0"%"%1 por la matriD" lo hemos convertido a coordenadas homo#8neas" ! para ello" hemos aQadido una Lltima componente con el valor 0.
[ ][][]
1 0 0 0 0 1 0 0 0 0 1 0 2 1 3 0 0 0 = 0 0 0 1 1 1
Sobre . +T
e@emplos" iremos profundiDando en las funciones utiliDadas. 3nicialmente" s,lo vamos a comentar 7ue . +T funciona #eneralmente a trav8s de funciones de callback" es decir" como par9metro de una funci,n" se le pasa un puntero a otra funci,n 7ue ser9 llamada por la funci,n principal.
pen!L
5ara comenDar a utiliDar -pen. hemos de tener claras diversas funciones 7ue vamos a utiliDar mu! a menudo.
Wtransformaci,n comLn para la escenaX #l5ushBatri</1U Wtrasformaci,n propia del elemento 0X Wdibu@ado del elemento 0X
0; >S3?>-.host
#l5opBatri</1U // volvemos a la transformaci,n comLn #l5ushBatri</1U Wtransformaci,n propia del elemento $X Wdibu@ado del elemento $X #l5opBatri</1U // volvemos a la transformaci,n comLn ...
Jinalmente" comentar la operaci,n #l oad3dentit!/1" 7ue car#a la matriD identidad como matriD activa.
. PTH3AN. >S Cada triplete de v8rtices de interpreta como un tri9n#ulo . P=+A?S . P 3N>PSTH35 . P 3N>P --5 . PTH3AN. >P STH35 . PTH3AN. >P JAN Cada cuarteto de v8rtices se interpreta como un cuadril9tero 2neas conectadas 2neas conectadas" con uni,n entre el primer ! Lltimo v8rtice Se dibu@a un tri9n#ulo" ! cada nuevo v8rtice se interpreta con un tri9n#ulo entre los dos anteriores v8rtices ! el nuevo Se dibu@an tri9n#ulos con un v8rtice comLn
>ntre las funciones 7ue permiten establecer los atributos de cada v8rtice" est9n a7uellas 7ue nos permiten seleccionar su color /#lColorZ1" normal /#lNormalZ1" coordenadas de te<tura /#lTe<CoordZ1" etc.
Gor#e .arc2a -Fardok- /$%%)1 0'
Si dibu@amos los vertices en el orden 0"*")"$" estaremos dibu@ando la cara delantera mirando hacia nosotros" pero si el orden es" por e@emplo" 0"$")"*" estaremos mirando la cara trasera del pol2#ono.
#lTranslateZ: nos va a permitir trasladar un ob@eto en el espacio #lHotateZ: nos va a permitir rotar un ob@eto #lScaleZ: nos va a permitir escalar un ob@eto #lBultBatri<: multiplica la matriD de transformaci,n actual por una matriD dada. >sto es al#o mu! utiliDado en motores *?
>s mu! importante el orden en el 7ue va!amos a realiDar las transformaciones. No es lo mismo trasladar al#o ! despu8s rotarlo" 7ue primero rotarlo ! lue#o trasladarlo" como podremos comprobar posteriormente...
a pro!ecci,n orto#r9fica: a pro!ecci,n orto#r9fica nos permite visualiDar todo a7uello 7ue se encuentre dentro de un cubo" delimitado por los par9metros de la funci,n #l-rto. A la hora de visualiDar" la distancia al observador s,lo se tiene en cuenta para determinar si el ob@eto est9 dentro o fuera del cubo...
Alt'ra
r( La a 'r
An &'ra
a pro!ecci,n perspectiva: a pro!ecci,n perspectiva delimita un volLmen de visualiDaci,n dado por un 9n#ulo de c9mara" ! una relaci,n alto/ancho. a distancia al observador determinar9 el tamaQo con el 7ue un ob@eto se visualiDa.
)n('lo
Alt'ra
pen!L
Fueno" a7u2 est9 lo 7ue todo pro#ramador desea tocar: el c,di#o U-1 vamos a comenDar con unos sencillos pro#ramas con los 7ue podremos
Gor#e .arc2a -Fardok- /$%%)1 $0
S,lo inclu2mos este archivo" por7ue !a inclu!e las cabeceras N#l.hO ! N#lu.hO. ComenDamos con la funci,n main:
int main(int argc, char * argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(20,20); glutInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; } sa cuatro primeras llamadas crean la ventana con la librer2a . +T:
0. 3nicialiDamos los modos con los 7ue se crear9 la ventana: con un s,lo buffer de dibu@ado" ! modelo de color H.FA /ro@o" verde" aDLl ! canal alfa [ transparencias1. $. >stablecemos el tamaQo ! posici,n de la ventana *. Creamos la ventana ?espu8s establecemos 7ue funci,n indica 7u8 ha! 7ue dibu@ar en la ventana. Ndispla!O es un puntero a una funci,n 7ue contiene el c,di#o de lo 7ue vamos a dibu@ar" ! llamamos a la funci,n 7ue comienDa el dibu@ado. Ahora s,lo nos 7ueda definir la funci,n Ndispla!O:
void display(void) { glClearColor(0.0,0.0,0.0,0.0); // Color de fondo: negro glClear(GL_COLOR_BUFFER_BIT); // Boramos la pantalla glMatrixMode(GL_PROJECTION); // Modo proyeccin glLoadIdentity(); // Cargamos la matriz identidad glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0); // Proyeccin ortogrfica, dentro del cubo sealado glMatrixMode(GL_MODELVIEW); // Modo de modelado
$$ >S3?>-.host
glBegin(GL_TRIANGLES); // Dibujamos un tringulo glColor3f(1.0,0.0,0.0); // Color del primer vrtice: rojo glVertex3f(0.0,0.8,0.0); // Coordenadas del primer vrtice glColor3f(0.0,1.0,0.0); // Color del segundo vrtice: verde glVertex3f(-0.6,-0.2,0.0); // Coordenadas del segundo vrtice glColor3f(0.0,0.0,1.0); // Color del tercer vrtice: azl glVertex3f(0.6,-0.2,0.0); // Coordenadas del tercer vrtice glEnd(); // Terminamos de dibujar glFlush(); // Forzamos el dibujado sleep(10); // Esperamos 10 segundos exit(0); // Salimos del programa }
a funci,n #lClearColor especifica cu9l va a ser el color con el 7ue se va rellenar el buffer de pantalla cuando se borre Con #lClear ordenamos a -pen. 7ue borre los buffers indicados como par9metro. 5ara borrar la pantalla /el buffer de color1 lo indicamos con la constante . PC- -HPF+JJ>HPF3T >stablecemos el volLmen de visualiDaci,n" en modo pro!ecci,n ! con #l-rtho. ?ibu@amos el tri9n#ulo
.uardamos el c,di#o como Nm!firtsopen#lpro#ram.cO" ! lo compilamos con la si#uiente l2nea de c,di#o en una consola:
user@machine:$gcc myfirtsopenglprogram.c -lglut -lGL -lGLU -o myfirtsopenglprogram
>@ecutamos con:
user@machine:$./myfirstopenglprogram
$*
Si estudiamos el c,di#o" observamos 7ue la parte superior del cuadrado est9 m9s ale@ada del observador 7ue la inferior" pero como se e<plic, en el apartado relativo a las pro!ecciones" esto no se tiene en cuenta para la pro!ecci,n orto#r9fica. Si 7ueremos 7ue esto se refle@e" tendremos 7ue crear una pro!ecci,n perspectiva... 5ara ello vamos a sustituir la llamada a #l-rtho por una llamada a #lu5erspective" 7ue establecer9 el modo de visualiDaci,n en perspectiva:
gluPerspective(60.0,1.0,1.0,100.0); // Proyeccin perspectiva. El ngulo de visualizacin es de 60 grados, la razn ancho/alto es 1 (son inguales), la distancia mnima es z=1.0, y la distancia mxima es z=100.0
\Y nos encontramos con 7ue no se ve nada] =ue no cunda el p9nico... todo tiene sentido... tal ! como est9 todo planteado" el cuadrado se va a dibu@ar con centro en el ori#en de coordenadas... 6pero d,nde est9 el observador: >n la visualiDaci,n perspectiva" la posici,n del observador determina c,mo
Gor#e .arc2a -Fardok- /$%%)1 $&
se ven las cosas... vamos a tomar 7ue el observador" !a 7ue no hemos indicado lo contrario" se encuentra en la posici,n /%"%"%1. Camos a retrasar un poco el cuadrado" para ale@arlo del observador" por7ue sino" se dibu@a @usto en el mimo lu#ar 7ue 8ste" ! no puede verse nada... para ello" despu8s de entrar en el modo de modelado/visualiDaci,n" aQadimos:
glTranslatef(0.0,0.0,-2.0); // Alejamos el cuadrado del observador dos unidades en el eje Z
...\perfecto] :-?
$A
>S3?>-.host
Como podemos observar" no se tiene en cuenta 7ue la parte inferior del tri9n#ulo deber2a de estar tapada por el cuadrado" por7ue su coordenada E" 7ue indica la profundidad" es ma!or /-%.& para el cuadrado ! % para el tri9n#ulo1. 5ara poder visualiDar los ob@etos con oclusi,n" tenemos 7ue activar el E-Fuffer.
>l E-Fuffer es un arra! 7ue #uarda la profundidad /coordenada E1 para todos los p2<els del 9rea de dibu@ado" de manera 7ue cuando un p2<el va a ser dibu@ado" se mira si su coordenada E es menor 7ue la coordenada en el E-Fuffer para ese p2<el en pantalla. 5ara activarlo" hemos de aQadir las si#uientes l2neas de c,di#o" antes del dibu@ado:
glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glClearDepth(1.0);
Con la llamada a #l>nable/. P?>5TVPT>ST1 habilitamos la comprobaci,n de la profundidad en el dibu@ado. Con #l?epthJunc/. P >=+A 1 decimos 7ue el nuevo p2<el se dibu@e si su coordenada E es m9s cercana al punto de visualiDaci,n" o i#ual" 7ue la 7ue ha! actualmente en E-Fuffer. Con #lClear?epth/0.%1 decimos 7ue cada veD 7ue 7uedamos borrar el buffer de profundidad" se inicialicen sus posiciones al valor 0.%.
$4
Gunto con esto" al borrar la pantalla" le indicamos al pro#rama 7ue inicialice el E-Fuffer con:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Jinalmente" s,lo nos 7ueda indicar al pro#rama 7ue" cuando se cree la ventana" se reserve espacio para el E-Fuffer. >sto lo indicamos al crear la ventana con:
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
(.2./ ;erar<uas
Ya hemos visto los conceptos b9sicos para dibu@ar fi#uras en -pen. " ahora vamos a N@u#arO un poco con transformaciones ! matrices... .enalmente" los ob@etos se a#rupan en @erar7u2as. >n ellas" e<iste al#Ln ob@eto de cu!a posici,n depende la posici,n del resto de ob@etos. >l e@emplo m9s claro es el cuerpo humano: de la posici,n del tronco depende la posici,n de los braDos" ! de la posici,n de los braDos" la de las manos. 5ara representar @erar7u2as con -pen. " utiliDaremos las pilas de matrices. >l procedimiento es el si#uiente:
$; >S3?>-.host
0. Se sitLa el elemento principal $. Se dibu@a el elemento principal *. Se apila la matriD actual /#l5ushBatri<1 ). Se sitLa el primer elemento secundario con respecto al primero &. Se dibu@a el primer elemento secundario A. Cuelta a la situaci,n del elemento principal /#l5opBatri<1 4. Se repite para los dem9s elementos secundarios 5ara ver el funcionamiento de las @erar7u2as vamos a realiDar un pro#rama 7ue dibu@e un cuadrado /fi#ura principal1 ! cuatro cuadrados secundarios" dibu@ados con respecto al principal. 5ara ello" definimos" por comodidad" una funci,n Ndibu@arCuadroO 7ue recibe el tamaQo del cuadrado" ! lo dibu@a centrado:
void dibujarCuadro(float tam) { glBegin(GL_QUADS); glVertex3f(-tam/2.0,tam/2.0,0.0); glVertex3f(-tam/2.0,-tam/2.0,0.0); glVertex3f(tam/2.0,-tam/2.0,0.0); glVertex3f(tam/2.0,tam/2.0,0.0); glEnd(); }
$'
Si el procedimiento de dibu@ado se realiDa de manera recursiva" se puede obtener un fractal como el de la fi#ura:
Camos a dibu@ar ahora una especie de Nfi#ura humanoideO" con un cuerpo /un cubo1" dos braDos /compuestos por tres partes" braDo" antebraDo ! manos" con dos cilindros ! un cubo respectivamente1 dos piernas /similares a los braDos1 ! una cabeDa /una esfera1. as fi#uras #eom8tricas las vamos a dibu@ar mediante funciones de la librer2a . +T.
*% >S3?>-.host
*0
Camos a estudiar m9s detalladamente el #iro del braDo" !a 7ue puede resultar dif2cil de ver:
*$
>S3?>-.host
>n el primer recuadro" tenemos el cuerpo @unto con el braDo" sin rotar. ?esplaDamos el braDo de manera 7ue su centro de #iro se encuentre en la posci,n sobre la 7ue ori#inalmente 7uer2amos pivotar el braDo. .iramos el braDo el 9n#ulo deseado" ! ahora" con ese #iro desplaDamos el braDo hacia aba@o" se#Ln su e@e de coordenadas" la misma distancia 7ue lo hab2amos desplaDado antes.
**
Cap2tulo ): Animaciones
Captulo /: 0ni+aciones
>n este cap2tulo vamos a describir de manera mu! breve c,mo animar las escenas 7ue creamos con -pen. . >n un principio" animar una fi#ura es al#o mu! sencillo. Fasta con: 0. actualiDar los datos de la fi#ura $. borrar la pantalla *. dibu@ar la fi#ura ). volver al punto 0
*&
$/412123 ./0"1"123
5 es el vector de posci,n" ! C el de direcci,n. Si despu8s de dibu@ar un frame" sumamos al vector de posci,n el de direcci,n" tenemos 7ue en el si#uiente frame el vector de posci,n ser9 5/-$"*"%1" con lo 7ue la fi#ura habr9 avanDado por el e@e K a la velocidad antes especificada. Si 7ueremos cambiar el movimiento" podemos variar la direcci,n del vector C" con lo 7ue se modificar9 la direcci,n del movimiento" o su m,dulo" con lo 7ue se modificar9 la velocidad del movimiento. Camos con un e@emplo. >l pro#rama 7ue vamos a elaborar va a consistir en una esfera 7ue se va a mover dentro de un cubo" de manera 7ue cuando lle#ue a una de las paredes va a rebotar:
S2 est9: invertir la componente del vector de direcci,n correspondiente al lado con el 7ue ha rebotado /p. e@. si hemos lle#ado al l2mite por la derecha" el valor de la K se volver9 ne#ativo...1
*A
Cap2tulo ): Animaciones
5ara este pro#rama vamos a definir una clase 7ue se encar#ue de representar la esfera" ! 7ue #uardar9 su posici,n ! velocidad. os m8todos 7ue proporciona esta clase se definen en la si#uiente tabla:
Mtodos Funcin
Tsphere (float maxpos, float Crea una instancia de la clase. a esfera speed); rebotar9 si lle#a a la posci,n I-Oma<posO" ! tendr9 una velocidad NspeedO. Su situaci,n ! direcci,n iniciales son aleatorias. void test();
Comprueba 7ue la fi#ura est8 dentro de los m9r#enes" ! si no le est9" corre#ir9 su direcci,n. ?espu8s" actualiDa su posci,n -btiene un vector con la posci,n de la esfera /en la posici,n %" la coord. K" en la 0 la Y ! en la $ la E1
5ara las animaciones vamos a utiliDar varias funciones de . +T. 5or un lado" #lut?ispla!Junc/1" 7ue como !a hemos visto" dibu@a un frame" ! #lut3dleJunc/1" 7ue especifica la operaci,n 7ue se realiDar9 entre dos frames. Adem9s" a#ruparemos todas las llamadas a -pen. previas al dibu@ado de cual7uier frame en una funci,n de inicialiDaci,n. Con esto" el c,di#o 7uedar9 de la si#uiente manera: Camos a utiliDar una variable #lobal para indicar la posici,n de la esfera" ! otra para apuntar a la propia esfera:
float * pos; TSphere * sphere;
a inicialiDaci,n de -pen.
void initgl() { glEnable(GL_DEPTH_TEST); glClearColor(0.0,0.0,0.0,0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); sphere = new TSphere(5,1); glMatrixMode(GL_MODELVIEW); gluLookAt(3,3,14,0,0,0,0,1,0); }
>n esta inicialiDaci,n vamos a hacer todo lo relativo a -pen. 7ue s,lo tiene 7ue hacerse una Lnica veD: establecer el color de fondo" habilitar el
Gor#e .arc2a -Fardok- /$%%)1 *4
modo de perspectiva" ale@ar la c9mara" ! de paso" crear la esfera" 7ue se va a mover en el ran#o R-&"&S con una velocidad de 0. 5ara ale@ar la c9mara" utiliDaremos la funci,n N#lu ookAtO. >sta funci,n posiciona la c9mara" ahorrando la realiDaci,n de #iros ! traslaciones manuales" de la si#uiente manera: recibe tres ternas: la posci,n de la c9mara en el espacio" la posici,n hacia la 7ue est9 mirando" ! un vector 7ue seQala a la parte superior de la escena... en este caso:
5op
a c9mara se situa por delante" ! li#eramente por encima del e@e de coordenadas" ! al#o desplaDada en el e@e K. >st9 mirando hacia el centro de coordenadas" ! la parte superior de la escena est9 apuntada por el vector NtopO. a si#uiente funci,n ser9 la funci,n de dibu@ado de cada frame" su cuerpo ser9 el si#uiente:
void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0,1.0,1.0); glutWireCube(10); glPushMatrix(); glColor3f(0.0,0.0,1.0); pos = sphere->getPosv(); glTranslatef(pos[0],pos[1],pos[2]); glutSolidSphere(1,10,10); glPopMatrix(); glFlush(); }
5or cada frame" se borra la pantalla" se dibu@a el cubo" se dibu@a la esfera /deshaciendo su transformaci,n" para no tener 7ue rehacer la transformaci,n de la c9mara en cada pasada1. Jinalmente vamos a crear una funci,n llamada NidleO 7ue va a e@ecutar la actualiDaci,n de la esfera entre dos frames" ! va a esperar ** milise#undos para dibu@ar el si#uiente foto#rama:
void idle(void) { sphere->test(); usleep(33);
*; >S3?>-.host
Cap2tulo ): Animaciones
glutPostRedisplay(); }
a Lltima llamada a #lut5ostHedispla!/1 hace 7ue tras la actualiDaci,n se dibu@e el si#uiente frame. 5ara re#istrar estas funciones hacemos" en el pro#rama principal:
initgl(); glutDisplayFunc(display); glutIdleFunc(idle);
5ero si e@ecutamos el pro#rama" vemos un pe7ueQo problema al visualiDar: ha! parpadeo /flickerin#1. >sto se debe a 7ue la pantalla est9 continuamente borr9ndose /se pone a ne#ro1 ! redibu@ando la im9#en. 5ara 7ue esto no ocurra hemos de utiliDar el llamado Ndoble bufferin#O.
Y despu8s de dibu@ar un frame hemos de cambiar el buffer oculto por el activo con:
glutSwapBuffers();
+na veD aQadido esto" el c,di#o 7uedar2a como el 7ue se encuentra en el ane<o. >l resultado del pro#rama es el si#uiente:
*'
Y con una pe7ueQa modificaci,n /sphere-rebotes-multi1 podemos conse#uir una locura como esta:
)%
>S3?>-.host
Cap2tulo ): Animaciones
)0
Captulo 2: Ilu+inacin
Ratones: Los roedores durante muchos aos han estado "compartiendo" el alimento del hombre, son omnvoros, aunque muestran preferencia por las semillas de los cereales y productos derivados. Cuando stas faltan pueden comer las cosas ms extraas que nos podamos imaginar : jabn, cuero, cera, plsticos o papel etc (www.amezdy.com/ratones.htm)
a iluminaci,n nos permitir9 crear escenas m9s realistas con -pen. . Cada implementaci,n de -pen. puede mantener un nLmero de luces ma!or o i#ual a ; /nunca menor1" aun7ue no se recomienda abusar de 8stas" !a 7ue el consumo de C5+ por la utiliDaci,n de luces es mu! #rande.
pen!L
a iluminaci,n de -pen. se basa en luces ! materiales. +na luD es una fuente de iluminaci,n para la escena. >mite un haD de luD de un color determinado" dividido en las tres componentes de color H.F. +n material determina la cantidad de cada color 7ue refle@a un ob@eto determinado. 5or e@emplo" si un ob@eto tiene un material de color ro@o -H.F/0"%"%1-" es decir" refle@a todo el color ro@o" ! es iluminado por una luD blanca -H.F /0"0"01-" refle@ar9 toda la componente de color ro@o" pero nada de la verde ! aDul" por lo 7ue se ver9 de color ro@o. Si este mismo ob@eto fuese iluminado por una luD verde -H.F/%"0"%1-" se ver2a de color ne#ro" al no tener nada de luD ro@a 7ue poder refle@ar. Adem9s" dependiendo del tipo de luD" el color
Gor#e .arc2a -Fardok- /$%%)1 )*
final con el 7ue se vea el ob@eto puede verse afectado por el 9n#ulo de incidencia de la luD" la distancia a 8sta" etc.
2.1.1 Luces
Como se ha dicho" una luD aporta iluminaci,n a una escena" se#Ln unas determinadas componentes de color. A partir de ahora distin#uiremos entre fuente de luD" como entidad 7ue proporciona luD a una escena" ! luD" como aportaci,n de esa fuente a la iluminaci,n de la escena. +na fuente puede emitir tipos diferentes de luD" 7ue son complementarias" ! pueden darse a la veD para un cierto tipo de luD. os tipos de luD son:
N>mittedO /emitida1: es la luD emitida por un ob@eto. No se ve afectada por nin#Ln otro tipo de luD. 5or e@emplo" un fue#o emite una determinada luD" ! si lo miramos" lo veremos de ese color" independientemente del color de las luces 7ue est8n apuntando al fue#o. N?iffuseO /difusa1: es la luD 7ue indice sobre un ob@eto" ! proviene de un determinado punto. a intensidad con la 7ue se refle@a en la superficie del ob@eto puede depender del 9n#ulo de incidencia" direcci,n" etc. +na veD incide sobre un ob@eto se refle@a en todas direcciones. NSpecularO /especular1: es la luD 7ue" al incidir sobre un ob@eto" se ve refle@ada con un 9n#ulo similar al de incidencia. 5odemos pensar 7ue es la luD 7ue produce los brillos. NAmbientO /ambiental1: podemos considerarlo como los restos de luD 7ue aparecen defido a la refle<i,n residual de una luD 7ue !a se ha refle@ado sobre muchos ob@etos" ! es imposible determinar su procedencia. >s al#o as2 como la iluminaci,n #lobal de una escena.
2.1.2 5ateriales
+n material define" para un determinado ob@eto" 7u8 componentes refle@a de cada tipo de luD. 5or e@emplo" un pl9stico ro@o" emitir9 toda la componente ro@a de las luces ambiental ! difusa" pero #eneralmente emitir9 brillos de color blanco ba@o una luD blanca" por lo 7ue su componente especular ser9 de color blanco. ?e este modo" la componente de emisi,n ser9 ne#ra" puesto 7ue un plastico no emite luD /aun7ue si es un pl9stico radioactivo" puede emitir un leve destello fantasmal U-1 >n un modelo con iluminaci,n" el color de un ob@eto se define por su material" no por el color de sus v8rtices" tal ! como hemos visto hasta ahora.
2.1.(
or+ales
se calcula a nivel de v8rtice" es decir" por cada
>S3?>-.host
a iluminaci,n en -pen.
))
v8rtice" se calcula su color a partir del material activo" las luces activas" ! c,mo estas luces inciden sobre el v8rtice. 5ara saber c,mo incide una luD sobre un v8rtice" empleamos la normal del v8rtice" un vector" 7ue" #eneralmente" ser9 perpendicular a la cara 7ue estemos dibu@ando" aun7ue podremos variarlo para conse#uir distintos efectos. >n la fi#ura" podemos ver c,mo incide la misma luD en el mismo ob@eto" pero con las normales cambiadas.
L'z
L'z
pen!L
es
>l primer paso para utiliDar la iluminaci,n en una aplicaci,n -pen. activarla" mediante la llamada
glEnable(GL_LINGHTING); +na veD activada" hemos de establecer las propiedades de cada luD en la escena" ! activarlas. a especificaci,n inicial de -pen. comtempla 7ue" al menos" cada implementaci,n debe de poder definir ; luces" identificadas por las constantes . P 3.VTn" d,nde ^n^ es el nLmero de la luD" comenDando por %.
5ara establecer las propiedades de una luD utiliDaremos llamadas a las funciones del tipo #l i#htZ/1. as propiedades de toda luD son las si#uientes:
5osici,n/?irecci,n:
)&
3ndica la posici,n/direcci,n de la luD" ! especifica si 8sta es una luD posicional o direccional. +na luD posicional tiene una posici,n concreta en el espacio" mientras 7ue una luD direccional consiste en un con@unto de haces de luD paralelos. +n e@emplo de luD posicional es una lampara" mientras 7ue" debido a su distancia" podr2amos considerar al sol como una fuente de luD direccional. as luces posicionales pueden ser de dos tipos: luces puntuales" 7ue emiten luD a su alrededor de manera radial" ! en todas direcciones" ! luces focales" 7ue emiten luD en una direcci,n concreta" en un radio de acci,n con forma de cono /como un foco1. 5odemos ver los diferentes tipos de luces en la si#uiente fi#ura:
L'z p'nt'al
L'z fo al
Ji#ura &.$. Tipos de luces
L'z dire
ional
?irecci,n del foco: >n el caso de una luD focal" debemos establecer su direcci,n. >sto lo haremos con la llamada:
glLightfv(GL_LIGHTn,GL_SPOT_DIRECTION,val_prt); NvalPptrO es un puntero a un vector con la direcci,n" en formato /<"!"D1.
Apertura del foco: >l 9n#ulo de apertura del foco se define mediante:
glLightf(GL_LIGHTn,GL_SPOT_CUTOFF,val); NvalO e<presa en #rados la mitad del 9n#ulo de apertura del foco.
Atenuaci,n del foco: a atenuaci,n del foco /de#radaci,n de la intensidad a medida 7ue nos acercamos al borde1 se define mediante:
)A
>S3?>-.host
Atenuaci,n de la luD ?efine la p8rdida de intensidad de la luD a medida 7ue nos ale@amos del foco /no afecta a las luces direccionales1. Se establece mediante: #l i#htf/. P 3.VTn". PRC-NSTANT_ 3N>AH_=+A?HAT3CS PATT>N+AT3-N"val1U >l factor de atenuaci,n de la luD se calcula se#Ln la f,rmula:
1 k c k l d k 2 q
+na veD establecidas las propiedades de una determinada luD" las activaremos con la llamada:
glEnable(GL_LIGHTn);
2.2.2 5ateriales
Tras definir las luces" antes de dibu@ar un ob@eto" hemos de definir su material. 5ara ello" estableceremos los valores de las diversas caracter2sticas del mismo" mediante las funciones del tipo #lBaterialZ/1. >stas funciones reciben tres par9metros: 0. Caras del pol2#ono a las 7ue se aplica el material. 5odemos aplicar el material a la cara frontal /. PJH-NT1 o a ambas caras del pol2#ono /. PJH-NTPAN?PFACT1. $. Caracter2stica 7ue definimos" mediante su correspondiente constante. *. Calor de la caracter2stica. as diferentes caracter2sticas son:
Color del material: ?efine el comportamiento del material para los distintos tipos de luD descritos anteriormente. >l color ambiental" difuso ! especular definen los colores del espectro 7ue este material refle@a de las luces 7ue recibe. >l color emitido es el tipo de luminosidad 7ue posee el material" intedependientemente de la luD 7ue le afecte. Se define mediante la llamada:
glMaterialfv(GL_FRONT[_AND_BACK],[GL_AMBIENT|GL_DIFUSSE| GL_AMBIENT_AND_DIFUSSE|GL_SPECULAR],val_ptr); NvalPptrO es un puntero a un con@unto de valores H.FA 7ue especifica el
)4
color de la componente espec2fica. Como antes se ha comentado" es habitual 7ue el comportamiento ante la luD difusa ! la ambiental sea el mismo" por lo 7ue es posible establecer ambos al mismo tiempo.
Frillo de los refle@os: a intensidad del brillo puede definirse a trav8s de la llamada:
glMaterialf(GL_FRONT[_AND_BACK],GL_SHININESS,val); Adem9s" podemos cambiar al#uno de los valores establecidos para los colores de un material mediante la funci,n #lColorBaterial/1. Bediante esta funci,n" 7ue debemos activar" podemos cambiar al#uno de los colores del material.
glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); Activamos la luD" ! sus caracter2sticas" e<cepto la direcci,n: glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); glLightfv(GL_LIGHT0,GL_DIFFUSE,light_color); glLightfv(GL_LIGHT0,GL_SPECULAR,light_color); glEnable(GL_LIGHT0); Seleccionamos el color del material: glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_color); >stablecemos la perspectiva ! posicionamos al observador: glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); glTranslatef(-0.3,-0.6,-4.0); >stablecemos la direcci,n de la luD: glLightfv(GL_LIGHT0,GL_POSITION,light_dir); >sta direcci,n la establecemos despu8s de la transformaci,n de la c9mara" por7ue 7ueremos 7ue" en este caso" est8 tambi8n sometida a la transformaci,n de la c9mara /por e@emplo" si dibu@amos una lampara" su posici,n en la escena ser9 relativa a d,nde est8 el espectador de la escena1.
?ibu@amos el cuadrado" ! antes de cada vertice" establecemos su normal. >n el caso de 7ue el s2mbolo NS3N. >PN-HBA O est8 definido" la normal ser9 siempre la misma. >n caso contrario" los v8rtices 0 ! * tendr9n una normal distinta" para lo#rar el efecto 7ue se muestra en la fi#ura &.0:
glBegin(GL_QUADS); #ifdef SINGLE_NORMAL glNormal3fv(normal); #else glNormal3f(1.0,1.0,-1.0); #endif glVertex3f(-1.0,0.0,-1.0); glNormal3fv(normal); glVertex3f(-1.0,0.0,1.0); #ifdef SINGLE_NORMAL glNormal3fv(normal); #else glNormal3f(-1.0,1.0,-1.0); #endif glVertex3f(1.0,0.0,1.0); glNormal3fv(normal); glVertex3f(1.0,0.0,-1.0); glEnd(); Jinalmente" forDamos el dibu@ado" esperamos" ! salimos del pro#rama: glFlush(); sleep(20); exit(0);
)'
float mat_ambient_diffuse [] = {0.0,0.8,1.0,1.0}; float mat_specular [] = {0.7,0.0,0.0,1.0}; float mat_emission [] = {0.0,0.0,0.0,1.0}; float mat_shininess = 0.4; Camos a poner un pe7ueQo cono cu!o material ten#a una Nemisi,nO similar al color de la luD" 7ue nos indicar9 d,nde est9 el foco. >ste es su color de Nemisi,nO:
float focus_emission [] = {0.8,0.8,0.8,1.0}; ?efinimos un par de variables 7ue indican la rotaci,n del foco:
float rot_angle_y = 0.0; float rot_angle_x = 0.0; Vabilitamos el DFuffer ! establecemos el color de fondo: glEnable(GL_DEPTH_TEST); glClearColor(0.0,0.0,0.0,0.0); Activamos las luces ! sus caracter2sticas. a primera llamada establece 7ue las caras traseras de los pol2#onos no se iluminar9n: glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse_specular); glLightfv(GL_LIGHT0,GL_SPECULAR,light_diffuse_specular); glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,spot_cutoff); glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,spot_exponent); glEnable(GL_LIGHT0); >stablecemos el material de la esfera: glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE, mat_ambient_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialf(GL_FRONT,GL_SHININESS,mat_shininess); >stablecemos la perspectiva ! trasladamos la c9mara: glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); glTranslatef(0.0,0.0,-5.0);
&% >S3?>-.host
A continuaci,n tenemos el bucle de dibu@ado /#lut?ispla!Junc1. >n 8l" una veD borrada la pantalla" rotamos la luD" la posicionamos" ! establecemos su direcci,n" 7ue ser9n relativas a su rotaci,n. ?espu8s" dibu@amos un cono en la posici,n de la luD. >ste cono tendr9 como color de emisi,n el definido como tal. >l cambio lo hacemos con #lColorBaterial/1. +na veD dibu@ado" deshacemos estas transformaciones" dibu@amos la esfera" dibu@amos ! cambiamos los buffers:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(30.0,0.0,0.0,1.0); glRotatef(rot_angle_y,0.0,1.0,0.0); glRotatef(rot_angle_x,1.0,0.0,0.0); glLightfv(GL_LIGHT0,GL_POSITION,light_pos); glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_dir); glTranslatef(light_pos[0],light_pos[1],light_pos[2]); glColorMaterial(GL_FRONT,GL_EMISSION); glEnable(GL_COLOR_MATERIAL); glColor4fv(focus_emission); glutSolidCone(0.2,0.5,7,7); glColor4fv(mat_emission); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glutSolidSphere(1.0,20,20); glFlush(); glutSwapBuffers(); Jinalmente" definimos 7ue" entre frame ! frame /#lut3dleJunc1" la acci,n a realiDar ser9 actualiDar la rotaci,n del foco:
rot_angle_y = (rot_angle_y > 360.0)?0:rot_angle_y + ROT_INC; rot_angle_x = (rot_angle_x > 360.0)?0:rot_angle_x + ROT_INC/ (2*3.1416); glutPostRedisplay(); Y a7u2 tenemos un frame de la animaci,n 7ue hemos creado:
&0
+n efecto curioso es el hecho de observar los refle@os de color ro@o 7ue se emiten desde los bordes de la esfera" #racias a 7ue hemos definido este color como el color NespecularO del material. Como puede observarse" en todos estos e@emplos ha! #ran cantidad de troDos de c,di#o 7ue se repiten. 5or ello" es conveniente la a#rupaci,n de estas llamadas en funciones de motores #r9ficos.
&$
>S3?>-.host
+na soluci,n a este e@ercicio aparece en el ane<o A" ba@o el ep2#rafe Nlsphere-rebotes-multi.cppO.
&*
Cap2tulo A: Te<turas
Captulo 3: =e#turas
as te<turas permiten personaliDar aLn m9s el material de un ob@eto" ! nos permiten obtener im9#enes mucho m9s realistas en nuestras escenas. 5or e@emplo" si 7ueremos dibu@ar una pared de ladrillo" tenemos dos opciones: dibu@ar cada ladrillo" definiendo su material con colores" ! dibu@ar el cemento entre los ladrillos" a base de pol2#onos" definiendo tambi8n su material" o dibu@ar un Lnico cuadrado con la e<tensi,n de la pared" ! hacer 7ue su material" sea" por e@emplo" la foto de una pared de ladrillo.
&&
as coordenadas de te<tura
(0,0)
(1,0)
(0,1)
Ji#ura A.0. Coordenadas de te<tura
(1,1)
?e esta manera" si 7ueremos dibu@ar un tri9n#ulo con una te<tura" ! aplicacamos a cada v8rtice las coordenadas de te<tura indicadas en la fi#ura" tenemos el si#uiente resultado:
(0,0)
(1,0)
(0.5,0)
+
(0,1) (1,1) (0,1) (1,1)
Ji#ura A.$. Bapeado de te<tura
Creaci,n de la te<tura RT>KTS: 5rimero hemos de obtener un identificador para la te<tura. 5ara ello pedimos a -pen. 7ue nos devuelva un identificador de te<tura libre:
int texture; glGenTextures(1,&texture);
&A
>S3?>-.host
Cap2tulo A: Te<turas
Creamos la te<tura. >l modo m9s sencillo de hacerlo es a trav8s de una funci,n de . + 7ue crea la te<tura ! sus variaciones a aplicar se#Ln la distancia a la 7ue se encuentre:
gluBuild2DMipmaps( GL_TEXTURE_2D, gimp_image.bytes_per_pixel, gimp_image.width, gimp_image.height,GL_RGB, GL_UNSIGNED_BYTE, gimp_image.pixel_data );
Con el primer par9metro indicamos el tipo de te<tura. >n este caso /. PT>KT+H>P$?1 es una te<tura $?. os si#uentes par9metros indican el nLmero de b!tes por cada pi<el" 7ue depender9n de la im9#en /p. e@. * para H.F ! ) para H.FAU en este caso" la im9#en es de tipo H.F1" su anchura ! altura /7ue han de ser pares" ! mu! recomendable" mLltiplos de $1" el formato de los datos /. PH.F" . PH.FA"...1" el tipo de los datos" 7ue en nuestro caso vendr9 dado por b!tes sin si#no" por lo 7ue usaremos la constante . P+NS3.N>?PFYT>" ! finalmente" un puntero a los datos. >n este e@emplo" hemos utiliDado una estructura para #enerar la im9#en con el si#uiente formato:
static const struct { unsigned int width; unsigned int height; unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */ unsigned char pixel_data[128 * 128 * 3 + 1]; } gimp_image = { 128, 128, 3, [...] }
>ste formato de datos es producido de manera autom9tica por el pro#rama N.impO al #rabar una im9#en como un archivo en NcO.
?efinir las condiciones en 7ue se va a aplicar la te<tura: >stas condiciones se establecen a trav8s de la funci,n #lTe<>nvf/1.
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
>n nuestro caso" hemos especificado 7ue la te<tura se va a fundir con el color de fondo del pol2#ono /. PB-?+ AT>1" aun7ue bien podr2a sustituirlo /usando . PH>5 AC>1. a fusi,n con el color de fondo se utiliDa para aplicar la iluminaci,n a un ob@eto con te<tura. >n el e@emplo vemos c,mo se visualiDa un ob@eto iluminado" con la te<tura aplicada mediante . PB-?+ AT>" ! mediante . PH>5 AC>:
&4
Si en al#Ln momento 7ueremos cambiar la te<tura activa" tan s,lo hemos de indicar 7u8 te<tura 7ueremos activar mediante la llamada:
glBindTexture(GL_TEXTURE_2D,texture);
Nte<tureO es el identificador de la te<tura 7ue 7ueremos activar. >l c,di#o completo de los e@emplos utiliDados puede verse en el ane<o A.
&;
>S3?>-.host
Cap2tulo A: Te<turas
>l suelo va a ser u cuadrado" ! la pared un rect9n#ulo" ! vamos a mapear las es7uinas del suelo ! de la pared con las es7uinas de de las te<turas /c,di#o completo en el ane<o A1:
glBindTexture(GL_TEXTURE_2D,texture_floor); glBegin(GL_QUADS); glTexCoord2d(0.0,0.0); glVertex3f(-6.0,0.0,-6.0); glTexCoord2d(0.0,1.0); glVertex3f(-6.0,0.0,6.0); glTexCoord2d(1.0,1.0); glVertex3f(6.0,0.0,6.0); glTexCoord2d(1.0,0.0); glVertex3f(6.0,0.0,-6.0); glEnd(); glBindTexture(GL_TEXTURE_2D,texture_wall); glBegin(GL_QUADS); glTexCoord2d(0.0,0.0); glVertex3f(-6.0,4.0,-6.0); glTexCoord2d(0.0,1.0); glVertex3f(-6.0,0.0,-6.0); glTexCoord2d(1.0,1.0); glVertex3f(6.0,0.0,-6.0); glTexCoord2d(1.0,0.0); glVertex3f(6.0,4.0,-6.0); glEnd(); +n aspecto a resaltar es 7ue la operaci,n #lFindTe<ture" para seleccionar cu9l es la te<tura activa en este momento" tiene 7ue realiDarse fuera del conte<to de #lFe#in/#l>nd" o de lo contrario no funcionar9.
&'
Como podemos observar" los ladrillos de la pared salen demasiado alar#ados" ! el suelo demasiado distorsionado" por el hecho de 7ue estamos a#randando las te<turas para acomodarlas al tamaQo de los ob@etos. 5ero" 6! si repetimos las te<turas: 5or e@emplo" podr2amos repetir la te<tura de la en * divisiones verticales" ! la del suelo *A veces /A horiDontales < A verticales1. 5ara ello" debemos especificar 7ue 7ueremos repetir las te<turas con las si#uientes llamadas a funci,n:
glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); a primera permite 7ue las te<turas se repitan en horiDontal" ! la se#unda" en vertical.
Con este cambio" podr2amos mapear las te<turas con coordenadas ma!ores a 0" de manera 7ue las te<turas se repetir2an" de esta manera:
glBindTexture(GL_TEXTURE_2D,texture_floor); glBegin(GL_QUADS); glTexCoord2d(0.0,0.0); glVertex3f(-6.0,0.0,-6.0); glTexCoord2d(0.0,6.0); glVertex3f(-6.0,0.0,6.0); glTexCoord2d(6.0,6.0); glVertex3f(6.0,0.0,6.0); glTexCoord2d(6.0,0.0); glVertex3f(6.0,0.0,-6.0); glEnd(); glBindTexture(GL_TEXTURE_2D,texture_wall); glBegin(GL_QUADS); glTexCoord2d(0.0,0.0); glVertex3f(-6.0,4.0,-6.0); glTexCoord2d(0.0,1.0);
A% >S3?>-.host
Cap2tulo A: Te<turas
glVertex3f(-6.0,0.0,-6.0); glTexCoord2d(3.0,1.0); glVertex3f(6.0,0.0,-6.0); glTexCoord2d(3.0,0.0); glVertex3f(6.0,4.0,-6.0); glEnd(); a te<tura de la pared ha sido mapeada entre /%"%1 ! /*"01" para repetirla * veces horiDontalmente" ! la te<tura del suelo entre /%"%1 ! /A"A1. >l resultado es sensiblemente distinto:
A0
Como Lltimo apartado" vamos a comentar de manera breve c,mo interactuar con las ventanas utiliDando . +T. Ya se ha comentado anteriormente 7ue . +T traba@a #eneralmente a trav8s de funciones CA FACT. >n la ma!or parte de los casos" tendremos 7ue re#istrar en . +T a 7u8 funci,n 7ueremos 7ue se llame cuando se produDca cierto evento sobre la ventana /pulsaci,n de una tecla" movimiento del rat,n...1.
>s decir" recibe un puntero a funci,n" 7ue no devuelve nada" ! recibe tres enteros: la tecla pulsada" ! la posci,n K e Y del rat,n en la pantalla. a rotaci,n alrededor de los e@es K e Y la vamos a controlar mediante dos variables #lobales /rotPan#leP<" rotPan#leP!1. >l c,di#o de la funci,n a la 7ue ha! 7ue llamar al pulsar al#una tecla NespecialO ser9 el si#uiente:
void specialKeys(int key, int x, int y) { switch (key) { case GLUT_KEY_UP: rot_angle_x--; break; case GLUT_KEY_DOWN: rot_angle_x++; break; case GLUT_KEY_RIGHT: rot_angle_y++; break; case GLUT_KEY_LEFT: rot_angle_y--; break; } glutPostRedisplay(); }
Con esto" modificaremos la rotaci,n se#Ln la tecla pulsada. Adem9s" para facilitar la salida del pro#rama" vamos a aQadir 7ue" al pulsar la tecla N>sc.O" el pro#rama termine. 5ara ello utiliDaremos la funci,n #lutTe!boardJunc/1" 7ue recibir9 como par9metro un puntero a la si#uiente funci,n:
static void keys(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } glutPostRedisplay(); }
>l resto del pro#rama es pr9cticamente id8ndico al comentado en el cap2tulo de iluminaci,n /la funci,n idle se hace innecesaria" ! ha! 7ue dar de alta los dos nuevos mane@adores de eventos aQadiendo al pro#rama principal:
glutSpecialFunc(specialKeys); glutKeyboardFunc(keys);
visualiDaci,n:
void reshape(int width, int height) { GLfloat h = (GLfloat) height / (GLfloat) width; glViewport(0, 0, (GLint) width, (GLint) height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0,0.0,-5.0); glutPostRedisplay(); }
#lCiewport/1 nos permitir9 establecer 7u8 porci,n de la ventana ser9 el 9rea visualiDable. >n este caso" establecemos 7ue el 9rea visualiDable ser9 toda la ventana con su nuevo tamaQo. Adem9s" vamos a hacer 7ue" al pulsar la tecla NfO pasemos a pantalla completa/modo ventana de manera alternativa. 5ara ello" aQadiremos una variable #lobal 7ue indi7ue el modo actual de la pantalla" ! el tratamiento para la pulsaci,n de la tecla NfO" 7ue ser9:
case 'f': if (windowed == 1){glutFullScreen(); windowed = 0;} else{ glutPositionWindow ( 20 , 20 ); glutReshapeWindow ( 350,350); windowed = 0; } break;
Si estamos en modo ventana" se pasa a pantalla completa. >n caso contrario" se reposiciona ! reforma la ventana" para pasar de nuevo a modo ventana.
A&
>n este Lltimo ep2#rafe" me #ustar2a comentar al#unos recursos /libros ! p9#inas web1 7ue considero de #ran inter8s:
>l libro ro@o de -pen. /The Hed Fook1: es un libro b9sico para cual7uier persona 7ue 7uiera empeDar a pro#ramar con -pen. . Tambi8n se conoce como Nla biblia de -pen. O. NThe -pen. +tilit! Toolkit /. +T1 5ro#rammin# 3nterfaceO: contiene todo lo necesario para la utiliDaci,n de la librer2a . +T. os tutoriales de NneheO /nehe.#amedev.net/1: estos tutoriales tienen una #ran cantidad de informaci,n destinada" en #ran parte" a la pro#ramaci,n de @ue#os.
Buchas #racias por tu inter8s en este curso. 5ara cual7uier duda o su#erencia" no dudes en contactar conmi#o en Nshadow@bardok.netO.
A4
Ja ja ja! Con este libro, tengo el poder de controlar hasta los rboles, y la propia ordenacin de todos los elementos...! (Bardok, en 1 de carrera, con el libro de EDA en la mano...)
A.a m&,irstopenglprogram.c
#include <GL/glut.h> void display(void) { glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0); glMatrixMode(GL_MODELVIEW); glBegin(GL_TRIANGLES); glColor3f(1.0,0.0,0.0); glVertex3f(0.0,0.8,0.0); glColor3f(0.0,1.0,0.0); glVertex3f(-0.6,-0.2,0.0); glColor3f(0.0,0.0,1.0); glVertex3f(0.6,-0.2,0.0); glEnd(); glFlush();
A'
Hecursos de inter8s
sleep(10); exit(0); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(20,20); glutInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; }
A.b quadort4o.c
#include <GL/glut.h> void display(void) { glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0); glMatrixMode(GL_MODELVIEW); glBegin(GL_QUADS); // Dibujamos un cuadrado glColor3f(0.0,1.0,1.0); // Color para el cuadrado glVertex3f(-0.5,0.5,-0.5); // Coordenadas del primer vrtice (superior-izquierda) glVertex3f(-0.5,-0.5,0.5); // Coordenadas del segundo vrtice (inferior-izquierda) glVertex3f(0.5,-0.5,0.5); // Coordenadas del primer vrtice (inferior-derecha) glVertex3f(0.5,0.5,-0.5); // Coordenadas del primer vrtice (superior-derecha) glEnd(); // Terminamos de dibujar glFlush(); sleep(10); exit(0); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(20,20); glutInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop();
4% >S3?>-.host
return 0; }
A.c quadpersp.c
#include <GL/glut.h> void display(void) { glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); // Proyeccin perspectiva. El ngulo de visualizacin es de 60 grados, la razn ancho/alto es 1 (son inguales), la distancia mnima es z=1.0, y la distancia mxima es z=100.0 glMatrixMode(GL_MODELVIEW); glTranslatef(0.0,0.0,-2.0); glBegin(GL_QUADS); // Dibujamos un cuadrado glColor3f(0.0,1.0,1.0); // Color para el cuadrado glVertex3f(-0.5,0.5,-0.5); // Coordenadas del primer vrtice (superior-izquierda) glVertex3f(-0.5,-0.5,0.5); // Coordenadas del segundo vrtice (inferior-izquierda) glVertex3f(0.5,-0.5,0.5); // Coordenadas del primer vrtice (inferior-derecha) glVertex3f(0.5,0.5,-0.5); // Coordenadas del primer vrtice (superior-derecha) glEnd(); // Terminamos de dibujar glFlush(); sleep(20); exit(0); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(20,20); glutInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; }
40
Hecursos de inter8s
A.d /bu,,er5&es.c
#include <GL/glut.h> void display(void) { glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); // Activamos el el Z-Buffer glClearColor(0.0,0.0,0.0,0.0); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Borramos el buffer de color y el Z-Buffer glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); // Proyeccin perspectiva. El ngulo de visualizacin es de 60 grados, la razn ancho/alto es 1 (son inguales), la distancia mnima es z=1.0, y la distancia mxima es z=100.0 glMatrixMode(GL_MODELVIEW); glTranslatef(0.0,0.0,-2.0); glBegin(GL_QUADS); // Dibujamos un cuadrado glColor3f(0.0,1.0,1.0); // Color para el cuadrado glVertex3f(-0.5,0.5,-0.5); // Coordenadas del primer vrtice (superior-izquierda) glVertex3f(-0.5,-0.5,0.5); // Coordenadas del segundo vrtice (inferior-izquierda) glVertex3f(0.5,-0.5,0.5); // Coordenadas del primer vrtice (inferior-derecha) glVertex3f(0.5,0.5,-0.5); // Coordenadas del primer vrtice (superior-derecha) glEnd(); // Terminamos de dibujar glBegin(GL_TRIANGLES); glColor3f(1.0,0.0,0.0); glVertex3f(0.0,0.5,0.0); glVertex3f(-0.7,-0.5,0.0); glVertex3f(0.7,-0.5,0.0); glEnd(); glFlush(); sleep(20); exit(0); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowPosition(20,20); glutInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0;
4$ >S3?>-.host
A.e simplegu&.c
#include <GL/glut.h> #include <unistd.h> // Medidas del cuerpo #define #define #define #define #define #define #define #define #define #define BODY_HEIGHT BODY_WIDTH BODY_LENGTH ARM_HEIGHT ARM_WIDTH ARM_LENGTH LEG_HEIGHT LEG_WIDTH LEG_LENGTH HEAD_RADIUS 4.0 2.5 1.0 3.5 1.0 1.0 4.5 1.0 1.0 1.1
void display(void) { glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); // Activamos el el Z-Buffer glClearColor(0.0,0.0,0.0,0.0); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Borramos el buffer de color y el Z-Buffer glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); // Proyeccin perspectiva. El ngulo de visualizacin es de 60 grados, la razn ancho/alto es 1 (son inguales), la distancia mnima es z=1.0, y la distancia mxima es z=100.0 glMatrixMode(GL_MODELVIEW); glTranslatef(0.0,0.0,-16.0); // Dibujamos el cuerpo glTranslatef(0,BODY_HEIGHT/2,0); glPushMatrix(); glScalef(BODY_WIDTH,BODY_HEIGHT,BODY_LENGTH); glColor3f(0.0,0.3,0.8); glutSolidCube(1); glPopMatrix(); // Dibujamos el brazo derecho glPushMatrix(); glTranslatef(-(BODY_WIDTH)/2,(BODY_HEIGHT-ARM_HEIGHT)/2,0); glTranslatef(0,ARM_HEIGHT/2,0); glRotatef(-30,0,0,1); glTranslatef(0,-ARM_HEIGHT/2,0); glPushMatrix(); glScalef(ARM_WIDTH,ARM_HEIGHT,ARM_LENGTH); glutSolidCube(1); glPopMatrix();
Gor#e .arc2a -Fardok- /$%%)1 4*
Hecursos de inter8s
// ya tenemos el brazo... la mano glTranslatef(0,-(ARM_HEIGHT+ARM_WIDTH)/2,0); glColor3f(1,0.6,0.6); glScalef(ARM_WIDTH,ARM_WIDTH,ARM_LENGTH); glutSolidCube(1); glPopMatrix(); // Dibujamos el brazo izquierdo glColor3f(0.0,0.3,0.8); glPushMatrix(); glTranslatef((BODY_WIDTH)/2,(BODY_HEIGHT-ARM_HEIGHT)/2,0); glTranslatef(0,ARM_HEIGHT/2,0); glRotatef(30,0,0,1); glTranslatef(0,-ARM_HEIGHT/2,0); glPushMatrix(); glScalef(ARM_WIDTH,ARM_HEIGHT,ARM_LENGTH); glutSolidCube(1); glPopMatrix(); // ya tenemos el brazo... la mano glTranslatef(0,-(ARM_HEIGHT+ARM_WIDTH)/2,0); glColor3f(1,0.6,0.6); glScalef(ARM_WIDTH,ARM_WIDTH,ARM_LENGTH); glutSolidCube(1); glPopMatrix(); //Dibujamos la pierna derecha glColor3f(0.0,0.3,0.8); glPushMatrix(); glTranslatef(-(BODY_WIDTH-LEG_WIDTH)/2,(BODY_HEIGHT+LEG_HEIGHT)/2,0); glPushMatrix(); glScalef(LEG_WIDTH,LEG_HEIGHT,LEG_LENGTH); glutSolidCube(1); glPopMatrix(); // ahora el pe glTranslatef(0,-(LEG_HEIGHT+LEG_WIDTH)/2,LEG_LENGTH); glColor3f(0.3,0.4,0.4); glScalef(LEG_WIDTH,LEG_WIDTH,LEG_LENGTH*2); glutSolidCube(1); glPopMatrix(); //Dibujamos la pierna izquierda glColor3f(0.0,0.3,0.8); glPushMatrix(); glTranslatef((BODY_WIDTH-LEG_WIDTH)/2,(BODY_HEIGHT+LEG_HEIGHT)/2,0); glPushMatrix(); glScalef(LEG_WIDTH,LEG_HEIGHT,LEG_LENGTH); glutSolidCube(1); glPopMatrix(); // ahora el pe glTranslatef(0,-(LEG_HEIGHT+LEG_WIDTH)/2,LEG_LENGTH); glColor3f(0.3,0.4,0.4); glScalef(LEG_WIDTH,LEG_WIDTH,LEG_LENGTH*2); glutSolidCube(1); glPopMatrix(); // Dibujamos la cabeza glColor3f(1,0.6,0.6); glPushMatrix(); glTranslatef(0,BODY_HEIGHT/2 + HEAD_RADIUS*3/4,0); glutSolidSphere(HEAD_RADIUS,10,10); glPopMatrix(); glFlush();
4) >S3?>-.host
sleep(20); exit(0); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowPosition(20,20); glutInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; }
A., 6erarquia5cuadro.c
#include "GL/glut.h" void dibujarCuadro(float tam) { glBegin(GL_QUADS); glVertex3f(-tam/2.0,tam/2.0,0.0); glVertex3f(-tam/2.0,-tam/2.0,0.0); glVertex3f(tam/2.0,-tam/2.0,0.0); glVertex3f(tam/2.0,tam/2.0,0.0); glEnd(); } void display() { glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0,0.0,-6.0); glColor4f(1.0,0.0,0.0,1.0); dibujarCuadro(1.0); glPushMatrix(); glTranslatef(0.0, 2.0, 0.0); dibujarCuadro(0.5); glPopMatrix(); glPushMatrix(); glTranslatef(0.0, -2.0, 0.0); dibujarCuadro(0.5); glPopMatrix(); glPushMatrix(); glTranslatef(2.0, 0.0, 0.0); dibujarCuadro(0.5); glPopMatrix();
4&
Hecursos de inter8s
glPushMatrix(); glTranslatef(-2.0, 0.0, 0.0); dibujarCuadro(0.5); glPopMatrix(); glFlush(); } int main(int argc, char **argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(20,20); glutInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; }
A.g 6erarquia5cuadro5recursi.o.c
#include "GL/glut.h" void dibujarCuadro(float tam) { glBegin(GL_QUADS); glVertex3f(-tam/2.0,tam/2.0,0.0); glVertex3f(-tam/2.0,-tam/2.0,0.0); glVertex3f(tam/2.0,-tam/2.0,0.0); glVertex3f(tam/2.0,tam/2.0,0.0); glEnd(); } void dibujarCuadroRecursivo(float tam) { if (tam > 0.005) { dibujarCuadro(tam); glPushMatrix(); glTranslatef(0.0, tam * 2.0, 0.0); dibujarCuadroRecursivo(tam / 2.0); glPopMatrix(); glPushMatrix(); glTranslatef(0.0, -tam * 2.0, 0.0); dibujarCuadroRecursivo(tam / 2.0); glPopMatrix(); glPushMatrix(); glTranslatef(tam * 2.0, 0.0, 0.0); dibujarCuadroRecursivo(tam / 2.0); glPopMatrix(); glPushMatrix(); glTranslatef(-tam * 2.0, 0.0, 0.0); dibujarCuadroRecursivo(tam / 2.0); glPopMatrix(); } }
4A
>S3?>-.host
void display() { glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0,0.0,-6.0); glColor4f(1.0,0.0,0.0,1.0); dibujarCuadroRecursivo(1.0); glFlush(); } int main(int argc, char **argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(20,20); glutInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; }
A.4 sp4ere5rebotes.cpp
///////////////////////////////////////////////////////// // Fichero sphere-rebotes.cpp ///////////////////////////////////////////////////////// #include <GL/glut.h> #include <unistd.h> #include "sphere.h" float * pos; TSphere * sphere = NULL; void initgl() { glEnable(GL_DEPTH_TEST); glClearColor(0.0,0.0,0.0,0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); // Proyeccin perspectiva. El ngulo de visualizacin es de 60 grados, la razn ancho/alto es 1 (son inguales), la distancia mnima es z=1.0, y la distancia mxima es z=100.0 sphere = new TSphere(5,0.1);
Gor#e .arc2a -Fardok- /$%%)1 44
Hecursos de inter8s
glMatrixMode(GL_MODELVIEW); gluLookAt(3,3,14,0,0,0,0,1,0); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0,1.0,1.0); glutWireCube(10); glPushMatrix(); glColor3f(0.0,0.0,1.0); pos = sphere->getPosv(); glTranslatef(pos[0],pos[1],pos[2]); glutSolidSphere(1,10,10); glPopMatrix(); glFlush(); } void idle(void) { sphere->test(); usleep(33); glutPostRedisplay(); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowPosition(20,20); glutInitWindowSize(500,500); glutCreateWindow(argv[0]); initgl(); glutDisplayFunc(display); glutIdleFunc(idle); glutMainLoop(); return 0; } ///////////////////////////////////////////////////////// // Fichero sphere.h ///////////////////////////////////////////////////////// #ifndef sphere_h #define sphere_h #include <stdlib.h> #include <time.h> #include <math.h> typedef class TSphere { private: float maxpos; float pos[3]; float dir[3]; float speed; public: TSphere(float maxpos, float speed); void test(); void modifySpeed(float inc);
4; >S3?>-.host
float * getPosv(); } TSphere; #endif ///////////////////////////////////////////////////////// // Fichero sphere.cpp ///////////////////////////////////////////////////////// #include "sphere.h" int pass=0; TSphere::TSphere(float maxpos, float speed) { this->maxpos = maxpos; if (!pass) { srandom(time(NULL)); pass = 1; } pos[0] = (random() % (int)maxpos) - maxpos/2; pos[1] = (random() % (int)maxpos) - maxpos/2; pos[2] = (random() % (int)maxpos) - maxpos/2; dir[0] = random(); dir[1] = random(); dir[2] = random(); float dirmod = sqrt(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir [2]); dir[0] /= dirmod; dir[1] /= dirmod; dir[2] /= dirmod; dir[0] *= speed; dir[1] *= speed; dir[2] *= speed; } void TSphere::test() { ((pos[0] < -maxpos) || (pos[0] > maxpos))?dir[0]*=-1:0; ((pos[1] < -maxpos) || (pos[1] > maxpos))?dir[1]*=-1:0; ((pos[2] < -maxpos) || (pos[2] > maxpos))?dir[2]*=-1:0; pos[0] += dir[0]; pos[1] += dir[1]; pos[2] += dir[2]; } void TSphere::modifySpeed(float inc) { float factor = (speed+inc)/speed; speed += inc; dir[0] *= factor; dir[1] *= factor; dir[2] *= factor; }
4'
Hecursos de inter8s
A.i sp4ere5rebotes5multi.cpp
#include #include #include #include #define #define <GL/glut.h> <unistd.h> "sphere.h" <math.h> NUM_SPHERES SPHERE_RADIUS 50 0.3
float * pos; TSphere * sphere[NUM_SPHERES]; void initgl() { glEnable(GL_DEPTH_TEST); glClearColor(0.0,0.0,0.0,0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); for (int i=0;i<NUM_SPHERES;i++) sphere[i] = new TSphere(5,((random() % 10)/(float)20)+0.1); glMatrixMode(GL_MODELVIEW); gluLookAt(3,3,14,0,0,0,0,1,0); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0,1.0,1.0); glutWireCube(10); for (int i=0;i<NUM_SPHERES;i++) { glPushMatrix(); glColor3f(0.0,0.0,1.0); pos = sphere[i]->getPosv(); glTranslatef(pos[0],pos[1],pos[2]); glutSolidSphere(SPHERE_RADIUS,10,10); glPopMatrix(); sphere[i]->test(); } glFlush(); glutSwapBuffers(); } void idle(void) { usleep(33); glutPostRedisplay(); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowPosition(20,20);
;% >S3?>-.host
A.6 normals5perp.c
#include <GL/glut.h> #include <stdlib.h> //#define SINGLE_NORMAL
void display(void) { GLfloat mat_color [] = {0.0,1.0,1.0,1.0}; GLfloat light_color [] = {1.0,1.0,1.0,1.0}; GLfloat light_ambient [] = {0.0,0.0,0.0,1.0}; GLfloat normal [] = {0.0,1.0,0.0}; GLfloat light_dir [] = {0.0,1.0,0.0,0.0}; glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); glLightfv(GL_LIGHT0,GL_DIFFUSE,light_color); glLightfv(GL_LIGHT0,GL_SPECULAR,light_color); glEnable(GL_LIGHT0); glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_color); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); glTranslatef(-0.3,-0.6,-4.0); glLightfv(GL_LIGHT0,GL_POSITION,light_dir); glBegin(GL_QUADS); #ifdef SINGLE_NORMAL glNormal3fv(normal); #else glNormal3f(1.0,1.0,-1.0); #endif glVertex3f(-1.0,0.0,-1.0); glNormal3fv(normal); glVertex3f(-1.0,0.0,1.0); #ifdef SINGLE_NORMAL glNormal3fv(normal); #else glNormal3f(-1.0,1.0,-1.0);
Gor#e .arc2a -Fardok- /$%%)1 ;0
Hecursos de inter8s
#endif glVertex3f(1.0,0.0,1.0); glNormal3fv(normal); glVertex3f(1.0,0.0,-1.0); glEnd(); glFlush(); sleep(20); exit(0); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(20,20); glutInitWindowSize(500,500); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; }
A.7 lit5sp4ere.c
#include <GL/glut.h> #include <unistd.h> #define float float float float float float float float float float ROT_INC 1.0
light_ambient [] = {0.0,0.2,0.0,1.0}; light_diffuse_specular [] = {0.8,0.8,0.8,1.0}; light_pos [] = {0.0,0.0,2.0,1.0}; spot_dir [] = {0.0,0.0,-1.0}; spot_cutoff = 30.0; spot_exponent = 1.0; mat_ambient_diffuse [] = {0.0,0.8,1.0,1.0}; mat_specular [] = {0.7,0.0,0.0,1.0}; mat_emission [] = {0.0,0.0,0.0,1.0}; mat_shininess = 0.4;
float focus_emission [] = {0.8,0.8,0.8,1.0}; float rot_angle_y = 0.0; float rot_angle_x = 0.0; void initgl() { glEnable(GL_DEPTH_TEST); glClearColor(0.0,0.0,0.0,0.0); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse_specular); glLightfv(GL_LIGHT0,GL_SPECULAR,light_diffuse_specular); glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,spot_cutoff); glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,spot_exponent);
;$ >S3?>-.host
glEnable(GL_LIGHT0); glMaterialfv (GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_ambient_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialf(GL_FRONT,GL_SHININESS,mat_shininess); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); glTranslatef(0.0,0.0,-5.0); } void idle(void) { rot_angle_y = (rot_angle_y > 360.0)?0:rot_angle_y + ROT_INC; rot_angle_x = (rot_angle_x > 360.0)?0:rot_angle_x + ROT_INC/ (2*3.1416); glutPostRedisplay(); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(30.0,0.0,0.0,1.0); glRotatef(rot_angle_y,0.0,1.0,0.0); glRotatef(rot_angle_x,1.0,0.0,0.0); glLightfv(GL_LIGHT0,GL_POSITION,light_pos); glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_dir); glTranslatef(light_pos[0],light_pos[1],light_pos[2]); glColorMaterial(GL_FRONT,GL_EMISSION); glEnable(GL_COLOR_MATERIAL); glColor4fv(focus_emission); glutSolidCone(0.2,0.5,7,7); glColor4fv(mat_emission); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glutSolidSphere(1.0,20,20); glFlush(); glutSwapBuffers(); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowPosition(20,20); glutInitWindowSize(350,350); glutCreateWindow(argv[0]); initgl(); glutDisplayFunc(display); glutIdleFunc(idle); glutMainLoop(); return 0; }
;*
Hecursos de inter8s
A.l l5sp4ere5rebotes5multi.cpp
///////////////////////////////////////////////////////// // Fichero l-sphere.h ///////////////////////////////////////////////////////// #ifndef l_sphere_h #define l_sphere_h #include <stdlib.h> #include <time.h> #include <math.h> typedef class TSphere { private: float maxpos; float pos[3]; float dir[3]; float color[3]; float speed; public: TSphere(float maxpos, float speed); void test(); void modifySpeed(float inc); float * getPosv(); float * getColor(); } TSphere; #endif ///////////////////////////////////////////////////////// // Fichero l-sphere.cpp ///////////////////////////////////////////////////////// #include "l-sphere.h" int pass=0; TSphere::TSphere(float maxpos, float speed) { this->maxpos = maxpos; if (!pass) { srandom(time(NULL)); pass = 1; } pos[0] = (random() % (int)maxpos) - maxpos/2; pos[1] = (random() % (int)maxpos) - maxpos/2; pos[2] = (random() % (int)maxpos) - maxpos/2; dir[0] = random(); dir[1] = random(); dir[2] = random(); color[0] = (random() % 1001)/1000.0; color[1] = (random() % 1001)/1000.0; color[2] = (random() % 1001)/1000.0; float dirmod = sqrt(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir [2]);
;) >S3?>-.host
dir[0] /= dirmod; dir[1] /= dirmod; dir[2] /= dirmod; dir[0] *= speed; dir[1] *= speed; dir[2] *= speed; } void TSphere::test() { ((pos[0] < -maxpos) || (pos[0] > maxpos))?dir[0]*=-1:0; ((pos[1] < -maxpos) || (pos[1] > maxpos))?dir[1]*=-1:0; ((pos[2] < -maxpos) || (pos[2] > maxpos))?dir[2]*=-1:0; pos[0] += dir[0]; pos[1] += dir[1]; pos[2] += dir[2]; } void TSphere::modifySpeed(float inc) { float factor = (speed+inc)/speed; speed += inc; dir[0] *= factor; dir[1] *= factor; dir[2] *= factor; } float * TSphere::getPosv() { return pos; } float * TSphere::getColor() { return color; } ///////////////////////////////////////////////////////// // Fichero l-sphere-rebotes-multi.cpp ///////////////////////////////////////////////////////// #include <GL/glut.h> #include <unistd.h> #include "l-sphere.h" #include <math.h> #define #define NUM_SPHERES SPHERE_RADIUS 75 0.3
float light_color [] = {1.0,1.0,1.0,1.0}; float light_pos [] = {1.0,1.0,1.0,0.0}; float * pos; TSphere * sphere[NUM_SPHERES]; void initgl() { glEnable(GL_DEPTH_TEST); glClearColor(0.0,0.0,0.0,0.0); glLightfv(GL_LIGHT0,GL_DIFFUSE,light_color);
Gor#e .arc2a -Fardok- /$%%)1 ;&
Hecursos de inter8s
glLightfv(GL_LIGHT0,GL_SPECULAR,light_color); glEnable(GL_LIGHT0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); for (int i=0;i<NUM_SPHERES;i++) sphere[i] = new TSphere(5,((random() % 10)/(float)20)+0.1); glMatrixMode(GL_MODELVIEW); gluLookAt(3,3,14,0,0,0,0,1,0); glLightfv(GL_LIGHT0,GL_POSITION,light_pos); } void idle(void) { usleep(33); glutPostRedisplay(); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_LIGHTING); glColor3f(1.0,1.0,1.0); glutWireCube(10); glEnable(GL_LIGHTING); glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); for (int i=0;i<NUM_SPHERES;i++) { glPushMatrix(); glColor4fv(sphere[i]->getColor()); pos = sphere[i]->getPosv(); glTranslatef(pos[0],pos[1],pos[2]); glutSolidSphere(SPHERE_RADIUS,10,10); glPopMatrix(); sphere[i]->test(); } glDisable(GL_COLOR_MATERIAL); glFlush(); glutSwapBuffers(); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowPosition(20,20); glutInitWindowSize(400,400); glutCreateWindow(argv[0]); initgl(); glutDisplayFunc(display); glutIdleFunc(idle); glutMainLoop(); return 0; }
A.m triang5te%ture.c
#include <GL/glut.h>
;A >S3?>-.host
static const struct { unsigned int width; unsigned int height; unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */ unsigned char pixel_data[128 * 128 * 3 + 1]; } gimp_image = { 128, 128, 3, ">@2>@2@B4@B4?A3>@2<>0;=/=?1@B4<>0CE7CE7DF8FH:HJ<LJ=OM@OM@NL>LJ >IG:GE8FE8" [... image data ...] "\6\22\23\16\11\12\5", }; void display(void) { int texture; glGenTextures(1,&texture); glBindTexture(GL_TEXTURE_2D,texture); glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); gluBuild2DMipmaps( GL_TEXTURE_2D, gimp_image.bytes_per_pixel, gimp_image.width, gimp_image.height,GL_RGB, GL_UNSIGNED_BYTE, gimp_image.pixel_data ); glEnable(GL_TEXTURE_2D); glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); glTranslatef(0.0,0.0,-2.0); glBegin(GL_TRIANGLES); glTexCoord2d(0.0,1.0); glVertex3f(-0.5,-0.5,0.5); glTexCoord2d(1.0,1.0); glVertex3f(0.5,-0.5,0.5); glTexCoord2d(0.5,0.0); glVertex3f(0.0,0.5,0.5); glEnd(); glFlush(); sleep(20); exit(0); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(20,20); glutInitWindowSize(300,300); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; }
;4
Hecursos de inter8s
A.n normals5perp5te%ture.c
#include <GL/glut.h> #include <stdlib.h> static const struct { unsigned int width; unsigned int height; unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */ unsigned char pixel_data[128 * 128 * 3 + 1]; } gimp_image = { 128, 128, 3, ">@2>@2@B4@B4?A3>@2<>0;=/=?1@B4<>0CE7CE7DF8FH:HJ<LJ=OM@OM@NL>LJ >IG:GE8FE8" [... image data ...] "\6\22\23\16\11\12\5", }; void display(void) { GLfloat mat_color [] = {0.5,1.0,1.0,1.0}; GLfloat light_color [] = {1.0,1.0,1.0,1.0}; GLfloat light_ambient [] = {0.2,0.2,0.2,1.0}; GLfloat normal [] = {0.0,1.0,0.0}; GLfloat light_dir [] = {0.0,1.0,0.0,0.0}; int texture; glGenTextures(1,&texture); glBindTexture(GL_TEXTURE_2D,texture); glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); // Descomentar esta lnea y comentar la anterior en el caso // de querer utilizar GL_REPLACE //glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); gluBuild2DMipmaps( GL_TEXTURE_2D, gimp_image.bytes_per_pixel, gimp_image.width, gimp_image.height,GL_RGB, GL_UNSIGNED_BYTE, gimp_image.pixel_data ); glEnable(GL_TEXTURE_2D); glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); glLightfv(GL_LIGHT0,GL_DIFFUSE,light_color); glLightfv(GL_LIGHT0,GL_SPECULAR,light_color); glEnable(GL_LIGHT0); glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_color); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); glTranslatef(-0.3,-0.6,-4.0); glRotatef(90.0,1.0,0.0,0.0); glLightfv(GL_LIGHT0,GL_POSITION,light_dir); glBegin(GL_QUADS); glNormal3f(1.0,-1.0,1.0);
;; >S3?>-.host
glTexCoord2d(0.0,0.0); glVertex3f(-1.5,0.0,-1.5); glNormal3fv(normal); glTexCoord2d(0.0,1.0); glVertex3f(-1.5,0.0,1.5); glNormal3f(1.0,-1.0,1.0); glTexCoord2d(1.0,1.0); glVertex3f(1.5,0.0,1.5); glNormal3fv(normal); glTexCoord2d(1.0,0.0); glVertex3f(1.5,0.0,-1.5); glEnd(); glFlush(); sleep(20); exit(0); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(20,20); glutInitWindowSize(350,350); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; }
Hecursos de inter8s
// En caso de no querer repetir las texturas, comentar estas // dos lneas glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); glEnable(GL_TEXTURE_2D); glClearColor(0.1,0.6,1.0,0.0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); gluLookAt(-0.0,3.0,6.0,0.0,2.0,0.0,0.0,1.0,0.0); // En caso de no querer repetir las texturas, mapearlas // entre 0 y 1 (sustituir 6 por 1 en glTexCoord2d). glBindTexture(GL_TEXTURE_2D,texture_floor); glBegin(GL_QUADS); glTexCoord2d(0.0,0.0); glVertex3f(-6.0,0.0,-6.0); glTexCoord2d(0.0,6.0); glVertex3f(-6.0,0.0,6.0); glTexCoord2d(6.0,6.0); glVertex3f(6.0,0.0,6.0); glTexCoord2d(6.0,0.0); glVertex3f(6.0,0.0,-6.0); glEnd(); // En caso de no querer repetir las texturas, mapearlas // entre 0 y 1 (sustituir 3 por 1 en glTexCoord2d). glBindTexture(GL_TEXTURE_2D,texture_wall); glBegin(GL_QUADS); glTexCoord2d(0.0,0.0); glVertex3f(-6.0,4.0,-6.0); glTexCoord2d(0.0,1.0); glVertex3f(-6.0,0.0,-6.0); glTexCoord2d(3.0,1.0); glVertex3f(6.0,0.0,-6.0); glTexCoord2d(3.0,0.0); glVertex3f(6.0,4.0,-6.0); glEnd(); glFlush(); sleep(20); exit(0); } int main(int argc, char ** argv) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(20,20); glutInitWindowSize(300,300); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; }
'% >S3?>-.host
A.p lit5sp4ere57e&b.c
#include <GL/glut.h> #include <unistd.h> #include <stdio.h> #define ROT_INC 1.0
float rot_angle_y = 0.0; float rot_angle_x = 0.0; int windowed = 1; void specialKeys(int key, int x, int y) { switch (key) { case GLUT_KEY_UP: rot_angle_x--; break; case GLUT_KEY_DOWN: rot_angle_x++; break; case GLUT_KEY_RIGHT: rot_angle_y++; break; case GLUT_KEY_LEFT: rot_angle_y--; break; } glutPostRedisplay(); } static void keys(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; case 'f': if (windowed == 1) {glutFullScreen(); windowed = 0;} else{ glutPositionWindow(20,20); glutReshapeWindow(350,350); windowed = 0; } break; } glutPostRedisplay(); } static void display(void) { float light_pos [] = {0.0,0.0,2.0,1.0}; float spot_dir [] = {0.0,0.0,-1.0}; float mat_emission [] = {0.0,0.0,0.0,1.0}; float focus_emission [] = {0.8,0.8,0.8,1.0}; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(rot_angle_y,0.0,1.0,0.0); glRotatef(rot_angle_x,1.0,0.0,0.0); glLightfv(GL_LIGHT0,GL_POSITION,light_pos); glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spot_dir); glTranslatef(light_pos[0],light_pos[1],light_pos[2]); glColorMaterial(GL_FRONT,GL_EMISSION); glEnable(GL_COLOR_MATERIAL);
Gor#e .arc2a -Fardok- /$%%)1 '0
Hecursos de inter8s
glColor4fv(focus_emission); glutSolidCone(0.2,0.5,7,7); glColor4fv(mat_emission); glDisable(GL_COLOR_MATERIAL); glPopMatrix(); glutSolidSphere(1.0,20,20); glFlush(); glutSwapBuffers(); } void glInit() { float light_ambient [] = {0.0,0.2,0.0,1.0}; float light_diffuse_specular [] = {0.8,0.8,0.8,1.0}; float spot_cutoff = 30.0; float spot_exponent = 1.0; float mat_ambient_diffuse [] = {0.0,0.8,1.0,1.0}; float mat_specular [] = {0.7,0.0,0.0,1.0}; float mat_shininess = 0.4; glEnable(GL_DEPTH_TEST); glClearColor(0.0,0.0,0.0,0.0); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse_specular); glLightfv(GL_LIGHT0,GL_SPECULAR,light_diffuse_specular); glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,spot_cutoff); glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,spot_exponent); glEnable(GL_LIGHT0); glMaterialfv (GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_ambient_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialf(GL_FRONT,GL_SHININESS,mat_shininess); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0,0.0,-5.0); } void reshape(int width, int height) { GLfloat h = (GLfloat) height / (GLfloat) width; glViewport(0, 0, (GLint) width, (GLint) height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,1.0,1.0,100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0,0.0,-5.0); glutPostRedisplay(); } int main(int argc, char ** argv)
'$ >S3?>-.host
{ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowPosition(20,20); glutInitWindowSize(350,350); glutCreateWindow(argv[0]); glInit(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutSpecialFunc(specialKeys); glutKeyboardFunc(keys); glutMainLoop(); return 0; }
'*
Hecursos de inter8s
:iblio.ra*a
-5>N. : -pen. - Vi#h 5erformance $?/*? .raphics" $%%*" http://www.open#l.or# H>?F--T: Gackie Naider" Tom ?avis and Bason (oo" -pen. .uide or ^The Hed Fook^. Addison-(esle!" 0'') . +T: Bark G. Til#ard" The -pen. 3nterface" 0''A 5ro#rammin#
B>SA: Besa Vome 5a#e" $%%*" http://www.mesa*d.or# ?H3: ?H3 - ?irect Henderin# 3nfraestructure" $%%*" http://dri.sourcefor#e.net/ T>KT: -pen. Te<ture Tutorial" $%%*" http://www.nullterminator.net/#lte<ture.html
')
>S3?>-.host