domingo, enero 25, 2009
recopilación de programas
http://personas.confidare.cl/jcataldo/articulo.php?id=opengl-glut
viernes, noviembre 17, 2006
Screenshots Parque de diversiones OpenGL
Ejemplo OpenGL - PARQUE DE DIVERSIONES
/********************************************/
/* */
/* MENU AYUDA PARQUE DE DIVERSIONES */
/* Desarrollado por: */
/* - Angelo Figueroa */
/* - Carlos Saez */
/********************************************/
/*
A continuacion se describen las teclas para manipular la camara del parque de diversiones:
MOVIMIENTOS DE TRASLACION
G: Avanzar
V: Retroceder
C: Movimiento Hacia La Izquierda
B: Movimiento Hacia La Derecha
K: Subir
M: Bajar
Z: Rotar Hacia La Derecha
X: Rotar Hacia La Izquierda
MOVIMIENTOS DE TRASLACION
UP: Mirar Hacia Arriba
DOWN: Mirar Hacia Abajo
LEFT: Mirar Hacia La Izquierda
RIGHT: Mirar Hacia La Derecha
Q o ESC Para Avandonar...
*/
#include GL/glut.h //agregar < >
#include stdlib.h //agregar < >
#define PI 3.1415926535898
//parametros para construir la grilla
#define DEF_floorGridScale 5.0
#define DEF_floorGridXSteps 10.0
#define DEF_floorGridZSteps 30.0
#define angulo 45
static int slices = 16;
static int stacks = 16;
double j=0.1;
int i,c;
float x;
int planox=15,planoy=180,planoz=0;
float puntovistax=0.0,puntovistay=-40.0,puntovistaz=240.0;
double luz;
double vo;
int ek;
double vk=0;
float tiempok=0;
int topek=0;
int er,aux;
float vr=0,tiempor=0;
int ecv1;
int ecv2;
float vcv=0;
float ccv=0;
int aux1=0;
int a=9;
float vcs;
int r,cx,z,rotar;
float vbz,vby;
int eb=0;
double angle,circle_points;
void Rueda();
void kamikaze();
void c_voladores();
void ovni();
void carrusel();
void cuncuna();
void Boomerang();
void arbol(int,int);
void Panel_control(float,float,float);
void PosicionPC();
void tren();
void xtremfall();
void Postes(int,int);
void personas(float,float,float,int);
/* GLUT callback Handlers */
static void
resize(int width, int height){
const float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 3.0, 390.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void specialFunc( int key, int x, int y )
{
switch( key ){
//giro a la izquierda
case GLUT_KEY_LEFT:
planoy--;
break;
// giro a la derecha.
case GLUT_KEY_RIGHT:
planoy++;
break;
// mirar hacia arriba.
case GLUT_KEY_UP:
planox--;
break;
// mirar hacia abajo
case GLUT_KEY_DOWN:
planox++;
break;
}
}
void keyboard(unsigned char key, int x, int y){
GLfloat angulo_camara;
#define M_PI 3.141592653
switch(key){
// Zoom: movimiento hacia adelante
case 'g': case 'G':
angulo_camara = ( ( -planoy + 180 ) * M_PI / 180.0 );
puntovistax -= 2*sin( angulo_camara );
puntovistaz -= 2*cos( angulo_camara );
break;
// desplazamiento hacia el lado izquierdo
case 'c': case 'C':
angulo_camara = ( ( -planoy + 270 ) * M_PI / 180.0 );
puntovistax -= sin( angulo_camara );
puntovistaz -= cos( angulo_camara );
break;
// desplazamiento hacia el lado derecho
case 'b': case 'B':
angulo_camara = ( ( -planoy + 90 ) * M_PI / 180.0 );
puntovistax -= sin( angulo_camara );
puntovistaz -= cos( angulo_camara );
break;
// retroceder: desplazamiento hacia atrás
case 'v': case 'V':
angulo_camara = ( ( -planoy + 0 ) * M_PI / 180.0 );
puntovistax -= sin( angulo_camara );
puntovistaz -= cos( angulo_camara );
break;
//subir: desplazamiento hacia arriba
case 'k': case 'K':
puntovistay=puntovistay-2;
break;
//bajar: desplazamiento hacia abajo
case 'm': case 'M':
puntovistay=puntovistay+2;
break;
//rotar en el eje z
case 'z': case 'Z':
planoz++;
break;
case 'x': case 'X':
planoz--;
break;
//Esc salir
case 27: case'q': case 'Q':
exit(0);
break;
}
}
void grilla(){
GLfloat zExtent, xExtent, xLocal, zLocal, loopX, loopZ;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Dibujo la Grilla
glPushMatrix();
glPushAttrib( GL_LIGHTING_BIT );
glDisable( GL_LIGHTING );
glColor3f(0.6,0.4,0.14);
glBegin( GL_LINES );
zExtent = DEF_floorGridScale * DEF_floorGridZSteps;
for(loopX = -DEF_floorGridXSteps; loopX <= DEF_floorGridXSteps; loopX++ )
{
xLocal = DEF_floorGridScale * loopX;
glVertex3f( xLocal, 0.0, -zExtent );
glVertex3f( xLocal, 0.0, zExtent );
}
xExtent = DEF_floorGridScale * DEF_floorGridXSteps;
for(loopZ = -DEF_floorGridZSteps; loopZ <= DEF_floorGridZSteps; loopZ++ )
{
zLocal = DEF_floorGridScale * loopZ;
glVertex3f( -xExtent, 0.0, zLocal );
glVertex3f( xExtent, 0.0, zLocal );
}
glEnd();
glPopAttrib();
glPopMatrix();
}
static float y=2;
int flag1=1,flag2=0;
static float donay=4.0; //variables funcion xtremfall
static void display(void){
glPushMatrix();
glRotated(planox,1,0,0);
glRotated(planoy,0,1,0);
glRotated(planoz,0,0,1);
glTranslated(0,0,puntovistaz);
glTranslated(0,puntovistay,0);
glTranslated(puntovistax,0,0);
int i;
const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
const double a = t*90.0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3d(1,0,0);
grilla();
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 0.0f, 5.5f, -4.0f, 0.0f };
const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };
glClearColor(0,0,0,0);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
for(i=0,z=150;i<6;i++){z-=50; arbol(-50,z);}
for(i=0,z=150;i<6;i++){z-=50; arbol(50,z);}
for(i=0,z=75;i<5;i++){z-=25; arbol(z,150);}
for(i=0,z=125;i<6;i++){Postes(-50,z);z-=50;}
for(i=0,z=125;i<6;i++){Postes(50,z);z-=50;}
for(i=0,z=-100;i<5;i++){personas(10,1.6,z,0);z+=2;}
for(i=0,z=-100;i<7;i++){personas(35,1.6,z,0);z+=2;}
for(i=0,z=-80;i<4;i++){personas(-22,1.6,z,0);z-=3;}
for(i=0,z=-10;i<5;i++){personas(-22,1.6,z,0);z-=5;}
for(i=0,z=-20;i<4;i++){personas(3,1.6,z,0);z-=4;}
for(i=0,z=-32.5;i<4;i++){personas(14,1.6,z,0);z-=3;}
for(i=0,z=45;i<4;i++){personas(-3,1.6,z,0);z-=3;}
//operadores de los paneles de control
personas(39,1.6,-100,1);
personas(9,1.6,-105,1);
personas(-25,1.6,-80,1);
personas(-25,1.6,-10,1);
personas(0,1.6,-20,1);
personas(12.5,1.6,-32.5,1);
personas(0,1.6,45,1);
//JUEGOS:
tren();
xtremfall();
cuncuna();
carrusel();
Rueda();
ovni();
Boomerang();
kamikaze();
c_voladores();
PosicionPC();
glutSwapBuffers();
luz+=0.66;
glPopMatrix();
glutSwapBuffers();
}
void PosicionPC()
{
Panel_control(39,-100,90);
Panel_control(10,-112.5,90);
Panel_control(-25,-80,0);
Panel_control(-25,-10,-90);
Panel_control(0,-20,0);
Panel_control(12.5,-32.5,90);
Panel_control(0,45,0);
}
void Panel_control(float a,float b,float alfa){
glPushMatrix();
glTranslated(a,1,b);
glRotated(alfa,0,1,0);
glRotated(-90,1,0,0);
glScalef(0.8,0.5,0.5);
glutSolidCube(3.0);
glColor3d(sin(luz),0,0);
glTranslated(1,1,1.5);
glutSolidSphere(0.25,slices,stacks);
glColor3d(cos(luz/2),cos(luz),0);
glTranslated(-1,0,0);
glutSolidSphere(0.25,slices,stacks);
glColor3d(0,0,sin(luz));
glTranslated(-1,0,0);
glutSolidSphere(0.25,slices,stacks);
glPopMatrix();
glColor3d(1,0,0);
}
void Postes(int a,int b){
glPushMatrix();
glTranslated(a,0,b);
glScalef(2,3,2);
glRotated(-90,1,0,0);
glColor3f(0.75,0.75,0.75);
glutSolidCone(0.15,4.0,slices,stacks);
glTranslated(0,0,3.8);
glutSolidSphere(0.12,slices,stacks);
for(i=0;i<4;i++)
{
glPushMatrix();
glColor3f(0.75,0.75,0.75);
glRotated(-90,1,0,0);
glRotated(90*i,0,1,0);
glutSolidCone(0.1,1.0,3,3);
glTranslated(0,0,1);
glColor3d(sin(luz/2),sin(luz/2),0);
glutSolidSphere(0.1,3,3);
glPopMatrix();
}
glPopMatrix();
}
void arbol(int a,int b)
{
glPushMatrix();
glTranslated(a,5,b);
GLUquadricObj *obj;
obj = gluNewQuadric();
gluQuadricDrawStyle(obj,GLU_FILL);
glPushMatrix();
glColor3f(0.60,0.40,0.12);
glRotated(90,1,0,0);
glScalef(0.3,0.8,0.8);
gluCylinder(obj,3,3,6,20,20);
glRotated(180,0,1,0);
for(i=0;(12-i/2)>=0;i+=1)
{
glColor3d(0,1,0);
glPushMatrix();
glTranslated(0,0,-3);
glRotated(0,0,1,0);
glTranslated(0,0,0.5*i);
glutSolidTorus(0.5,12-i/2,slices,stacks);
glPopMatrix();
}
glPopMatrix();
glPopMatrix();
}
void personas(float a,float b,float c,int d){
glPushMatrix();
glTranslated(a,b,c);
glScalef(0.5,0.5,0.5);
glPushMatrix();
glColor3d(1,1,0);
glTranslated(0,1,-8);
glRotated(60,1,0,0);
glutSolidSphere(0.7,slices,stacks);
glPopMatrix();
glPushMatrix();
if(d==0)glColor3d(0,0.8,0);
else if(d==1)glColor3d(0,1,1);
glTranslated(0,-2,-8);
glRotated(270,1,0,0);
glutSolidCone(1,3,slices,stacks);
glPopMatrix();
GLUquadricObj *obj;
obj = gluNewQuadric();
glPushMatrix();
glColor3d(0,0.8,0);
glTranslated(-1,0,-8);
glRotated(90,0,1,0);
gluCylinder(obj,0.2,0.2,2,10.0,10.0);
glPopMatrix();
glPushMatrix();
glColor3d(0.8,0.8,0);
glTranslated(-1.2,0,-8);
glutSolidSphere(0.3,slices,stacks);
glPopMatrix();
glPushMatrix();
glTranslated(1.2,0,-8);
glutSolidSphere(0.3,slices,stacks);
glPopMatrix();
glPushMatrix();
glColor3d(0.8,0,0);
glTranslated(0.5,-2,-8);
glRotated(90,1,0,0);
gluCylinder(obj,0.2,0.2,1,10.0,10.0);
glPopMatrix();
glPushMatrix();
glColor3d(0.8,0,0);
glTranslated(-0.5,-2,-8);
glRotated(90,1,0,0);
gluCylinder(obj,0.2,0.2,1,10.0,10.0);
glPopMatrix();
glPushMatrix();
glColor3d(1,0,0);
glTranslated(-0.5,-3,-8);
glutSolidCube(0.5);
glPopMatrix();
glPushMatrix();
glColor3d(1,0,0);
glTranslated(0.5,-3,-8);
glutSolidCube(0.5);
glPopMatrix();
glPopMatrix();
}
void Boomerang()
{
glColor3d(1,0,0);
for(i=0,c=0;i<5;i++)
{glPushMatrix();
if(c==0){glColor3d(0,0,sin(luz*(i+1))); c=1;}
else if(c==1){glColor3d(0,sin(luz*(i+1)),sin(luz*(i+1))); c=0;}
glTranslated(45,0,-106+(25*i)); glRotated(-90,1,0,0); glutSolidCone(0.5,2.0,slices,stacks);
glTranslated(0,0,2); glutSolidSphere(0.2,slices,stacks);
glTranslated(-5,0,-2); glutSolidCone(0.5,2.0,slices,stacks);
glTranslated(0,0,2); glutSolidSphere(0.2,slices,stacks);
glPopMatrix();
}
glPushMatrix();
glColor3d(1,1,1);
glTranslated(45,0,40); glRotated(-90,1,0,0); glutSolidCone(1,37,slices,stacks);
glTranslated(-5,0,0); glutSolidCone(1,37,slices,stacks);
glColor3d(sin(luz),sin(luz),0);
glTranslated(0,0,37);
glutSolidSphere(1.5,slices,stacks);
glTranslated(5,0,0);
glutSolidSphere(1.5,slices,stacks);
glPopMatrix();
glColor3d(1,1,1);
glPushMatrix();
glTranslated(45,3,0);
glRotated(-90,0,1,0);
glRotated(270,0,0,1);
GLint circle_points = 100;
glLineWidth(4);
glBegin(GL_LINE_STRIP);
glVertex2f(0.999,-106);
for (i=0; i < 16; i++)
{angle=2*PI*i/circle_points; glVertex2f(cos(angle),sin(angle));}
glVertex2f(-33.5,40);
glEnd();
glPopMatrix();
glPushMatrix();
glTranslated(40,3,0);
glRotated(-90,0,1,0);
glRotated(270,0,0,1);
glBegin(GL_LINE_STRIP);
glVertex2f(0.999,-106);
for (i=0; i < 16; i++)
{angle=2*PI*i/circle_points; glVertex2f(cos(angle),sin(angle));}
glVertex2f(-33.5,40);
glEnd();
glPopMatrix();
glPushMatrix();
glTranslated(42.5,2.0,-106);
if(eb==0){ vbz+=1; glTranslated(0,0,vbz); if(vbz>106){eb=1; rotar=1;}}
else if(eb==1){ vbz+=1; vby+=0.89; glTranslated(0,vby,vbz); if(vby>=35){eb=2;}}
else if(eb==2){ vbz-=1*8; vby-=0.89*8; glTranslated(0,vby,vbz); if(vby<1.5){eb=3; rotar=-1;} }
else if(eb==3){ vbz-=4; glTranslated(0,0,vbz); if(vbz<0){eb=0;}}
if(rotar==1)glRotated(-30,1,0,0); if(rotar==-1)glRotated(0,1,0,0);
glPushMatrix();
glColor3d(1,1,0);
glScalef(2.5,2.5,8);
glutSolidSphere(0.5,slices,stacks);
glRotated(90,0,1,0); glutSolidCone(0.1,1.2,slices,stacks);
glRotated(-180,0,1,0); glutSolidCone(0.1,1.2,slices,stacks);
glPopMatrix();
glPopMatrix();
glLineWidth(1);
}
void cuncuna(){
glPushMatrix();
glTranslated(15,0,-10);
glScalef(0.6,0.6,0.6);
int i,j;
glPushMatrix();
glColor3d(0,0,0);
glTranslated(36,3,139.50);
glRotated(angulo,1,0,0);
glutSolidTorus(0.65,3,slices,stacks);
glPopMatrix();
glPushMatrix();
glColor4f(0.60,0.40,0.12,0);
glTranslated(36,5,141);
glutSolidSphere(6,slices,stacks);
glTranslated(3,0,-4);
glColor3d(1,1,1);
glutSolidSphere(3,slices,stacks);
glTranslated(0,0,-2.5);
glColor3d(0,0,0);
glutSolidSphere(1,slices,stacks);
glPopMatrix();
glPushMatrix();
glColor3d(1,1,1);
glTranslated(36,5,141);
glTranslated(-3,0,-4);
glutSolidSphere(3,slices,stacks);
glColor3d(0.75,0.75,0.75);
glTranslated(0,0,-0.98);
glutSolidSphere(2.25,slices,stacks);
glTranslated(0,0,-1.4);
glColor3d(0,0,0);
glutSolidSphere(1.1,slices,stacks);
glPopMatrix();
glPushMatrix();
glColor4f(0.60,0.40,0.12,0);
float b=0;
glTranslated(36,4,150);
glutSolidSphere(5.5,slices,stacks);
for(x=6.5,i=0;i<14;x-=1.5,i++)
{ if (i<=6)glTranslated(-5.5,x,0);
if(i>6){b+=0.65;glTranslated(-(5.5-b),-(5.5-b),0);}
glutSolidSphere(5.5-b,slices,stacks);
}
glPopMatrix();
glPopMatrix();
}//end cuncuna
void carrusel(){
int j;
vcs+=1;
glPushMatrix();
glTranslated(0,0,80);
glScalef(2,3,2);
glPushMatrix();
glColor3d(sin(luz),0,0.5);
glTranslated(-15,4.5,-40);
glRotated(vcs,0,1,0);
glutSolidSphere(0.5,slices,stacks);
glRotated(-90,1,0,0);
glTranslated(0,0,-0.7);
glColor3d(0,0.5,1);
glutSolidCone(3.0,1.0,slices,stacks);
glRotated(180,0,1,0);
glutSolidCone(3.0,0,slices,stacks);
for(i=0,c=0,x=0,j=-1;i<8;i++,j*=-1)
{
glPushMatrix();
glRotated(-90,1,0,0);
glRotated(45*i,0,1,0);
glRotated(vcs,0,1,0);
glTranslated(0,0,3.0);
if(x==0){ glColor3d(0,sin(luz),0); x=1;}
else if(x==1){ glColor3d(sin(luz),sin(luz),0); x=0;}
glutSolidSphere(0.1,slices,stacks);
glRotated(90,1,0,0);
glutWireCone(0,3,2,1);
glTranslated(0,0,3);
glutSolidSphere(0.1,slices,stacks);
glPushMatrix();
if(c==0){glColor3d(1,0,1); c=1;}
else if(c==1){glColor3d(0,1,0); c=2;}
else if(c==2){glColor3d(1,1,0); c=0;}
glTranslated(0,0,-1);
glTranslated(0,0,sin(vcs*(j*0.1))/3);
glutSolidSphere(0.3,slices,stacks);
glTranslated(0.3,0,-0.3);
glutSolidSphere(0.2,slices,stacks);
glTranslated(-0.3,0,0.5);
glRotated(-135,0,1,0);
glutSolidCone(0.1,0.7,slices,stacks);
glTranslated(0,-0.2,0);
glutSolidSphere(0.1,slices,stacks);
glTranslated(0,0.4,0);
glutSolidSphere(0.1,slices,stacks);
glPopMatrix();
glPopMatrix();
}
glColor3d(0,0.5,1);
glTranslated(0,0,3);
glRotated(-180,0,1,0);
glutSolidCone(3.0,0,slices,stacks);
glTranslated(0,0,-0.5);
glColor3d(1,1,1);
glutSolidCone(0.5,5.3,slices,stacks);
glPopMatrix();
glPopMatrix();
}//end carrusel
void ovni(){
int y;
vo+=0.073;
glPushMatrix();
glTranslated(0,25,-3);
glColor3f(0.75,0.75,0.75);
glRotated((vo*2),0,1,0);
glTranslated(0,sin(vo),-50);
glRotated(vo*9,0,1,0);
glScalef(3.0f, 2.0f, 3.0f);
glutSolidSphere(0.9,slices,stacks);
glTranslated(0,-0.3,0);
glRotated(-90,1,0,0);
glutSolidCone(2.0,1.0,slices,stacks);
glutSolidTorus(0.2,2.0,slices,stacks);
glRotated(-180,1,0,0);
glutSolidCone(2.0,0.6,slices,stacks);
for(i=0,y=0;i<18;i++)
{glPushMatrix();
glRotated(90,1,0,0);
glRotated(20*i,0,1,0);
glTranslated(0,0,2.05);
if(y==0){glColor3d(sin(luz),0,0);y=1;}
else if(y==1){glColor3d(0,sin(luz),0);y=2;}
else if(y==2){glColor3d(0,0,sin(luz));y=0;}
glutSolidSphere(0.2,slices,stacks);
glPopMatrix();
}
glPopMatrix();
}//end ovni
void Rueda(){
if(er==1)vr-=1;
else vr+=1;
if(vr>180)er=1;
else if(vr<-180) er=2;
glColor3d(1,1,0);
glPushMatrix();
glTranslated(-25,0,0);
glScalef(4,4,4);
glPushMatrix();
glTranslated(10,4,-8.3);
glRotated(vr,0,0,1);
glColor3d(sin(luz/9),1,0); c=1;
glutWireTorus(0.3,2.2,6,stacks);
glColor3d(1,0,0);
for(i=0;i<30;i++)//30
{
glPushMatrix();
glRotated(90,0,1,0);
glRotated(12*i,1,0,0);
glutWireCone(0,1.89,2,1);
glPopMatrix();
}
for(i=0;i<=12;i++)
{
glPushMatrix();
glColor3d(0,1,1);
glRotated(90,0,1,0);
glRotated(30*i,1,0,0);
glTranslated(0,2.4,0);
glTranslated(-0.2,0,0);
glRotated(270,1,0,0);
glutSolidCone(0.05,0.5,slices,stacks);
glTranslated(0.4,0,0);
glutSolidCone(0.05,0.5,slices,stacks);
glTranslated(-0.2,0,0.5);
glRotated(vr,1,0,0);
glutSolidCube(0.2);
glTranslated(0,0.1,0);
glutSolidCube(0.1);
glPopMatrix();
}
glutSolidCone(0.2,0.7,slices,stacks);
glRotated(180,1,0,0);
glutSolidCone(0.2,0.7,slices,stacks);
glPopMatrix();
glPushMatrix();
glColor3d(1,1,1);
glTranslated(10,4,-9);
glRotated(90,0,1,0);
glutSolidSphere(0.1,slices,stacks);
glTranslated(-1.4,0,0);
glutSolidSphere(0.1,slices,stacks);
glTranslated(0,-3.4,0);
glRotated(180,0,1,1);
glutSolidCone(0.2,3.4,slices,stacks);
glColor3d(0,0,1);
glutSolidCube(0.8);
glTranslated(-1.4,0,0);
glColor3d(1,1,1);
glutSolidCone(0.2,3.4,slices,stacks);
glColor3d(0,0,1);
glutSolidCube(0.8);
glPopMatrix();
glPopMatrix();
}//end Rueda
void kamikaze(){
if(ek==1)vk-=9*tiempok;
else vk+=9*tiempok;
if(vk>topek){topek+=25; ek=1;}
if(vk<-topek){topek+=25; ek=2;}
if(topek<600)tiempok+=0.002;
if(topek>600 && topek<750){ tiempok-=0.0041;}
if(topek==750){tiempok=0;topek=25; vk=0;}
glPushMatrix();
glTranslated(0,0,-75);
glRotated(90,0,1,0);
glScalef(3,5,3);
glPushMatrix();
glColor3d(1,1,1);
glTranslated(-0.4,4.4,-9);
glRotated(angulo*2,0,1,0);
glutSolidCone(0.3,1.5,slices,stacks);
glTranslated(0,0,-0.65);
glColor3d(1,1,0);
glutSolidSphere(0.1,slices,stacks);
glRotated(-angulo*2,1,0,0);
glTranslated(0,0,-3.9);
glutSolidCone(0.35,4.0,slices,stacks);
glColor3d(1,0,0);
glutSolidCube(0.8);
glPopMatrix();
glPushMatrix();
glColor3d(1,1,1);
glTranslated(0.4,4.4,-9);
glRotated(angulo*-2,0,1,0);
glutSolidCone(0.3,1.5,slices,stacks);
glTranslated(0,0,-0.65);
glColor3d(1,1,0);
glutSolidSphere(0.1,slices,stacks);
glRotated(-angulo*2,1,0,0);
glTranslated(0,0,-3.9);
glutSolidCone(0.35,4.0,slices,stacks);
glColor3d(1,0,0);
glutSolidCube(0.8);
glPopMatrix();
glColor3d(0,1,1);
glPushMatrix();
glTranslated(0.35,4.4,-9);
glRotated(-vk/2,1,0,0);
glutSolidSphere(0.33,slices,stacks);
glRotated(angulo*2,1,0,0);
glutSolidCone(0.3,3,slices,stacks);
glTranslated(0,0,3);
glRotated(25.5,1,0,0);
glutSolidSphere(0.3,slices,stacks);
glRotated(angulo*2,1,0,0);
glutSolidCone(0.3,3,slices,stacks);
glRotated(angulo*3,1,0,0);
glutSolidCone(0.3,3,slices,stacks);
glPopMatrix();
glPushMatrix();
glTranslated(-0.35,4.4,-9);
glRotated(vk/2,1,0,0);
glutSolidSphere(0.33,slices,stacks);
glRotated(angulo*2,1,0,0);
glutSolidCone(0.3,3,slices,stacks);
glTranslated(0,0,3);
glRotated(25.5,1,0,0);
glutSolidSphere(0.3,slices,stacks);
glRotated(angulo*2,1,0,0);
glutSolidCone(0.3,3,slices,stacks);
glRotated(angulo*3,1,0,0);
glutSolidCone(0.3,3,slices,stacks);
glPopMatrix();
glPopMatrix();
}//end kamikaze
void c_voladores(){
if(ecv1==1)vcv-=2;
else vcv+=2;
if(ecv2==1)ccv-=3;
else ccv+=3;
if(vcv<0) ecv1=2;
else if(vcv>220) ecv1=1;
if(ccv<-180) ecv2=2;
else if(ccv>180) ecv2=1;
glPushMatrix();
glTranslated(-15,0,35);
glScalef(3,4,3);
glPushMatrix();
glTranslated(10,4,-50);
glRotated(angulo*2,1,0,0);
glColor3d(1,1,1);
glutSolidSphere(0.6,slices,stacks);
glColor3d(1,1,1);
glutSolidCone(0.35,4.0,slices,stacks);
glTranslated(0,0,3.5);
glRotated(180,1,0,0);
glutSolidCone(0.35,4.0,slices,stacks);
glutSolidCube(0.8);
glPopMatrix();
glPushMatrix();
glColor3d(0,0,1);
glTranslated(10,4,-50);
glRotated(angulo*2,1,0,0);
glRotated(-ccv,0,0,1);
glutSolidTorus(0.28,0.7,slices,stacks);
glPopMatrix();
for(i=0;i<8;i++)
{
glPushMatrix();
glColor3d(1,1,1);
glTranslated(10,4,-50);
glRotated(ccv,0,1,0);
glRotated(angulo*i,0,1,0);
glutSolidCone(0.3,3.0,slices,stacks);
glTranslated(0,0,-3);
glColor3d(0,0,1);
glutSolidSphere(0.2,3,3);
glRotated(angulo*2,1,0,0);
glColor3d(1,0,0);
glRotated(vcv/3,1,0,0);
glutWireCone(0.0,2,2,1);
glTranslated(0,0,2.1);
glutSolidSphere(0.2,9,9);
glPopMatrix();
}
glPopMatrix();
}//end c_voladores
void tren(){
int i;
const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
const double a = t*90.0;
GLUquadricObj *obj;
obj = gluNewQuadric();
glPushMatrix();
glPushMatrix();
glTranslated(0,0,80);
glScalef(0.5,0.5,0.5);
glPushMatrix();
glTranslated(0,3,3);
glRotated(a/9,0,1,0);
glColor3d(1,0,0); //vagon principal
glTranslated(-10,2,-50);
glRotated(90,0,1,0);
glTranslated(0,0,0);
gluCylinder(obj,3.0,3.0,15.0,20.0,20.0);
glRotated(90,1,0,0); //chimenea
glColor3d(0,1,1);
glTranslated(0,3,-6);
gluCylinder(obj,1.0,1.0,3.0,10.0,10.0);
glRotated(90,1,0,0);
glColor3d(1,1,0);
glTranslated(0,6,3);
gluCylinder(obj,2.5,1.6,2.0,10.0,10.0);
glTranslated(0,-0.7,-22);
glColor3d(1,1,0);
glutSolidCube(7);
glTranslated(0,0,-10);
glutSolidCube(7);
glColor3d(0,1,1);
glTranslated(0,-3.7,19);
glutSolidCube(3);
glPopMatrix();
glPushMatrix();
glColor3d(1,1,0);
glTranslated(0,3,3);
glRotated(a/9,0,1,0);
glTranslated(-8,1.7,-50);
glutSolidSphere(2.8,16,16);
glPopMatrix();
glPushMatrix();
glColor3d(1,1,0);
glTranslated(0,3,3);
glRotated(a/9,0,1,0);
glTranslated(3,1.7,-50);
glutSolidSphere(2.8,16,16);
glPopMatrix();
glColor3d(1,1,1);
glPushMatrix();
glTranslated(0,3,3);
glRotated(a/9,0,1,0);
glTranslated(-8,-1,-47); //rueda 1 vagon principal
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(1.2,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3);
glRotated(a/9,0,1,0);
glTranslated(-3,-1,-47); //rueda 2 vagon principal
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(1.2,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3);
glRotated(a/9,0,1,0);
glTranslated(2,-1,-47); //rueda 3 vagon principal
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(1.2,0.8,2,16);
glPopMatrix();
glColor3d(1,1,1);
glPushMatrix();
//ruedas chicas de vagones de carga
glTranslated(0,3,3); //rueda 1 chica vagon de carga 1 lado A
glRotated(a/9,0,1,0);
glTranslated(10.3,-1.6,-46);
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(0.5,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3); //rueda 1 chica vagon de carga 1 lado B
glRotated(a/9,0,1,0);
glTranslated(10.3,-1.6,-54);
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(0.5,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3); //rueda 2 chica vagon de carga 1 lado A
glRotated(a/9,0,1,0);
glTranslated(13.3,-1.6,-46);
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(0.5,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3); //rueda 2 chica vagon de carga 1 lado B
glRotated(a/9,0,1,0);
glTranslated(13.3,-1.6,-54);
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(0.5,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3); //rueda 1 chica vagon de carga 2 lado A
glRotated(a/9,0,1,0);
glTranslated(20.3,-1.6,-46);
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(0.5,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3); //rueda 1 chica vagon de carga 2 lado B
glRotated(a/9,0,1,0);
glTranslated(20.3,-1.6,-54);
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(0.5,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3); //rueda 2 chica vagon de carga 2 lado A
glRotated(a/9,0,1,0);
glTranslated(23.3,-1.6,-46);
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(0.5,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3); //rueda 2 chica vagon de carga 2 lado B
glRotated(a/9,0,1,0);
glTranslated(23.3,-1.6,-54);
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(0.5,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3);
glRotated(a/9,0,1,0);
glLineWidth(2);
glBegin(GL_LINE_STRIP); //linea que une ruedas del vagon 2 de carga lado A
glVertex3d(20.3,-1.6,-46);
glVertex3d(23.3,-1.6,-46);
glEnd();
glBegin(GL_LINE_STRIP); //linea que une ruedas del vagon 2 de carga lado B
glVertex3d(20.3,-1.6,-54);
glVertex3d(23.3,-1.6,-54);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3d(10.3,-1.6,-46); //linea que une ruedas del vagon 1 de carga lado A
glVertex3d(13.3,-1.6,-46);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3d(10.3,-1.6,-54); //linea que une ruedas del vagon 1 de carga lado B
glVertex3d(13.3,-1.6,-54);
glEnd();
glColor3d(1,1,1);
glBegin(GL_LINE_STRIP); //adorno vagon principal
glVertex3d(-8,2,-47);
glVertex3d(2,2,-47);
glEnd();
glBegin(GL_LINE_STRIP); //linea que une los vagones
glVertex3d(0,-0.5,-50);
glVertex3d(25,-0.5,-50);
glEnd();
glBegin(GL_LINE_STRIP); //linea desde rueda 1 a rueda 3 lado B
glVertex3d(-8,-1,-53);
glVertex3d(2,-1,-53);
glEnd();
glBegin(GL_LINE_STRIP); //linea desde rueda 1 a rueda 3 lado A
glVertex3d(-8,-1,-47);
glVertex3d(2,-1,-47);
glEnd();
glPopMatrix();
glColor3d(1,1,1);
glPushMatrix();
glTranslated(0,3,3);
glRotated(a/9,0,1,0);
glTranslated(-8,-1,-53); //rueda 4
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(1.2,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3);
glRotated(a/9,0,1,0);
glTranslated(-3,-1,-53); //rueda 5
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(1.2,0.8,2,16);
glPopMatrix();
glPushMatrix();
glTranslated(0,3,3);
glRotated(a/9,0,1,0);
glTranslated(2,-1,-53); //rueda 6
glRotated(180,1,0,0);
glRotated(-a/2,0,0,1);
glutWireTorus(1.2,0.8,2,16);
glPopMatrix();
glPopMatrix();
glPopMatrix();
}//end tren
void xtremfall(){
const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
const double a = t*90.0;
glColor3d(1,0,0);
GLUquadricObj *obj;
obj = gluNewQuadric();
glPushMatrix();
glTranslated(20,0,45);
glScalef(2,4,2);
glPushMatrix();
glColor3d(1,1,1);
glTranslated(-10,12,-30);
glRotated(90,1,0,0);
gluCylinder(obj,0.6,0.6,12.0,20,20);
glPopMatrix();
glPushMatrix();
glColor3d(1,1,0);
glTranslated(-10,donay,-30);
glRotated(90,90,0,0);
glutSolidTorus(0.5,1.0,slices,stacks);
glPopMatrix();
if(donay>10){
flag1=1;
flag2=0;
}
else{
if(donay<=1){
flag1=0;
flag2=1;
}
}
if(flag1==1&&flag2==0)
donay=donay-0.8;
if(flag2==1&&flag1==0)
donay=donay+0.1;
glPushMatrix();
glColor3d(sin(luz*4),sin(luz),cos(luz/2));
glTranslated(-10,11,-30);
glutSolidSphere(1.3,slices,stacks);
glPopMatrix();
glPopMatrix();
}
static void idle(void){
glutPostRedisplay();
}
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(1024,768);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow(" <<>> ");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutSpecialFunc( specialFunc );
glutIdleFunc(idle);
glutMainLoop();
return EXIT_SUCCESS;
}
miércoles, noviembre 15, 2006
Ejemplo GLUT : Dibujado de Primitivas utilizando GLUT

Este ejercicio consta de dibujar primitivas al estilo de paint de Windows, pero con menos opciones obviamente, la tarea integra a través de GLUT la captura del mouse para el posterior dibujado de las figuras geométricas.
#include windows.h //agregar < >
#include GL/glut.h //agregar < >
void mouse(int btn, int state , int x, int y);
void key(unsigned char k, int, int);
void desplegar(void);
void inicio(void); // funcion de inicialización
void crear_cuadros(int x, int y, int s); // crea los cuadros del menu
int seleccion(int x, int y); //selecciona figura a dibujar
void menu_derecho(int id); //opciones de menu con boton derecho del mouse
void menu_line(int id);
void menu_sizepunto(int id);
void menu_relleno(int id);
GLsizei alto_default=480, ancho_default=640; // tamaño inicial de la ventana
int fill=0; // flag de relleno
int figura=0; // seleccion de primitivas
int contar_click=0; // variable de conteo de vertices
GLfloat tamano_punto=4.0, grosor_linea=2.0;// tamaño de puntos y lineas
GLfloat bgcolor[4]={0.0,0.0,0.0,0.0}; // color de fondo
int main(int argc, char **argv){
int c_menu, menu_punto, menu_linea, f_menu; // variables para trabajar con los menus
glutInit(&argc,argv); // inicio de ventanas GLUT
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); // especifica tipo de display GLUT
glutCreateWindow(" Ejemplo - Dibujado de Primitivas utilizando GLUT "); // nombre de la ventana
glutDisplayFunc(desplegar); // funcion de despliegue
menu_punto = glutCreateMenu(menu_sizepunto);// menu de tamaño de punto
glutAddMenuEntry("Aumentar", 1); // aumentar tamaño de punto
glutAddMenuEntry("Disminuir", 2); // disminuir tamaño de punto
menu_linea = glutCreateMenu(menu_line); // menu de grosor de linea
glutAddMenuEntry("Aumentar", 1); // aumentar grosor de linea
glutAddMenuEntry("Disminuir", 2); // disminuir grosor de linea
f_menu = glutCreateMenu(menu_relleno); // menu de relleno
glutAddMenuEntry("Si", 1); // activar relleno
glutAddMenuEntry("No", 2); // desactivar relleno
glutCreateMenu(menu_derecho); // menu del boton derecho del mouse
glutAddSubMenu("Tamaño Punto", menu_punto);// asignar a menu de tamaño de punto
glutAddSubMenu("Grosor Linea", menu_linea); // asignar a menu de grosor de linea
glutAddSubMenu("Relleno", f_menu); // asignar a menu de relleno
glutAddMenuEntry("Borrar",1); // borrar la pantalla
glutAddMenuEntry("Salir",2); // salir del programa
glutAttachMenu(GLUT_RIGHT_BUTTON); // relacionar menu al boton derecho del mouse
inicio(); // inicializar programa
glutMouseFunc(mouse); // especificar callback de mouse
glutMainLoop(); // iniciar ciclo principal de GLUT
}
/* funcion de inicializacion */
void inicio(void)
{
glMatrixMode(GL_PROJECTION); // especificar matriz de projeccion
glLoadIdentity(); // cargar identidad
glOrtho(0.0, (GLdouble) ancho_default , 0.0, (GLdouble) alto_default , -1.0, 1.0);
// ajustar perspectiva ortogonal al tamaño establecido de la ventana
glClear(GL_COLOR_BUFFER_BIT); // limpiar pantalla
glColor3f(1.0,1.0,1.0); // color de dibujo blanco
glPointSize(3.0); // tamaño predeterminado de punto = 3
glEnable(GL_LINE_STIPPLE); // tipo de linea
glLineStipple(1,0xFFFF); // linea continua
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //especificar que solo se dibujen lineas
glutReshapeWindow(ancho_default,alto_default); //tamaño de ventana establecido 480x640
glFlush(); // enviar al servidor grafico
}
void menu_derecho(int id){ //boton derecho del mouse
if(id==1) glutPostRedisplay(); // limpiar la pantalla
if(id==2) exit(1); //salir del programa
}
void menu_sizepunto(int id){ // menu de tamaño de punto
if(contar_click==0){
if(id==1) tamano_punto=tamano_punto+1; //aumentar tamaño a punto
else if(tamano_punto > 1) tamano_punto=tamano_punto-1;//disminuir tamaño a punto
glPointSize(tamano_punto); // guardar cambios del tamaño del punto
}
}
void menu_line(int id){ //grosor de linea
if(contar_click==0){
if(id==1) grosor_linea=grosor_linea+1; //aumentar grosor de la linea
else if(tamano_punto > 1) grosor_linea=grosor_linea-1;//disminuir grosor de linea
glLineWidth(grosor_linea); // cambiar el grosor de linea
}
}
void menu_relleno(int id){ //menu de relleno
if(contar_click==0){
if(id==1) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);// activar relleno
else glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // desactivar relleno
}
}
int seleccion(int x, int y){ //seleccionar la opcion requerida del menu
y=alto_default-y;
if(y>64)return 0; //si se encuentra en el cuadro para dibujar
else if(y <>448 &&amp;amp;amp; x<640> 320 && x < btn="=" state="=" opcion="seleccion(x,y);"> 0 &&amp;amp; opcion <6) figura="opcion;" opcion ="=" contar_click ="=" opcion="=" opcion="=" opcion="=" opcion ="=" figura ="=" figura ="=" contar_click ="=" contar_click="contar_click+1;" contar_click ="=" contar_click="0;" figura="=" contar_click ="=" contar_click="contar_click+1;" contar_click ="=" contar_click="contar_click+1;" contar_click ="=" contar_click="0;" figura ="=" contar_click ="=" contar_click="contar_click+1;" contar_click ="=" contar_click="contar_click+1;" contar_click ="=" contar_click="contar_click+1;" contar_click ="=" contar_click="0;" figura ="=" contar_click ="=" contar_click="contar_click+1;"> 0){
contar_click=contar_click+1;
glVertex2i(x,alto_default-y);
if(glutGetModifiers() == GLUT_ACTIVE_CTRL){ // unir el ultimo punto al primero con Ctrl presionado
glEnd();
contar_click=0;
}
}
}
}
glFlush(); // enviar al servidor grafico
}
}//fin mouse
/* Funcion que dibuja los cradrados del menu */
void crear_cuadros(int x, int y, int s ){
glBegin(GL_LINE_LOOP);
glVertex2i(x, y);
glVertex2i(x+s,y);
glVertex2i(x+s,y+s);
glVertex2i(x, y+s);
glEnd();
}//fin crear_cuadros
/* Funcion de despliegue */
void desplegar(void){
glPushAttrib(GL_ALL_ATTRIB_BITS); // guardar los atributos
glClearColor(bgcolor[0], bgcolor[1], bgcolor[2], bgcolor[3]); // color de fondo
glClear(GL_COLOR_BUFFER_BIT); // limpiar pantalla
glLineWidth(1.0); // lineas de grosor 1
glPointSize(3.0); // puntos de tamaño 3
glLineStipple(1, 0xFFFF);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);// dibujar los poligonos con relleno
glBegin(GL_QUADS);
glColor3f(1.0,0.0,0.0); //rojo
glVertex2i(448,64);
glVertex2i(472,64);
glVertex2i(472,48);
glVertex2i(448,48);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,1.0,0.0); //verde
glVertex2i(472,64);
glVertex2i(496,64);
glVertex2i(496,48);
glVertex2i(472,48);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.0,1.0); //azul
glVertex2i(496,64);
glVertex2i(520,64);
glVertex2i(520,48);
glVertex2i(496,48);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,1.0,1.0); //celeste
glVertex2i(520,64);
glVertex2i(544,64);
glVertex2i(544,48);
glVertex2i(520,48);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,0.0,1.0); //rosado
glVertex2i(544,64);
glVertex2i(568,64);
glVertex2i(568,48);
glVertex2i(544,48);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,0.5,0.0); //naranjo
glVertex2i(568,64);
glVertex2i(592,64);
glVertex2i(592,48);
glVertex2i(568,48);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,1.0,0.0); //amarillo
glVertex2i(592,64);
glVertex2i(616,64);
glVertex2i(616,48);
glVertex2i(592,48);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,1.0,1.0); //blanco
glVertex2i(616,64);
glVertex2i(640,64);
glVertex2i(640,48);
glVertex2i(616,48);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.7,0.0,0.0); //derivado del rojo
glVertex2i(448,48);
glVertex2i(472,48);
glVertex2i(472,32);
glVertex2i(448,32);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.7,0.0); //derivado del verde
glVertex2i(472,48);
glVertex2i(496,48);
glVertex2i(496,32);
glVertex2i(472,32);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.0,0.7); //derivado del azul
glVertex2i(496,48);
glVertex2i(520,48);
glVertex2i(520,32);
glVertex2i(496,32);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.7,0.7); //celeste oscuro
glVertex2i(520,48);
glVertex2i(544,48);
glVertex2i(544,32);
glVertex2i(520,32);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.7,0.0,0.7); //rosado oscuro
glVertex2i(544,48);
glVertex2i(568,48);
glVertex2i(568,32);
glVertex2i(544,32);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.7,0.3,0.0); //naranjo oscuro
glVertex2i(568,48);
glVertex2i(592,48);
glVertex2i(592,32);
glVertex2i(568,32);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.7,0.7,0.0); //amarillo oscuro
glVertex2i(592,48);
glVertex2i(616,48);
glVertex2i(616,32);
glVertex2i(592,32);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.7,0.7,0.7); //plomo
glVertex2i(616,48);
glVertex2i(640,48);
glVertex2i(640,32);
glVertex2i(616,32);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.5,0.0,0.0);
glVertex2i(448,32);
glVertex2i(472,32);
glVertex2i(472,16);
glVertex2i(448,16);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.5,0.0);
glVertex2i(472,32);
glVertex2i(496,32);
glVertex2i(496,16);
glVertex2i(472,16);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.0,0.5);
glVertex2i(496,32);
glVertex2i(520,32);
glVertex2i(520,16);
glVertex2i(496,16);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.5,0.5);
glVertex2i(520,32);
glVertex2i(544,32);
glVertex2i(544,16);
glVertex2i(520,16);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.5,0.0,0.5);
glVertex2i(544,32);
glVertex2i(568,32);
glVertex2i(568,16);
glVertex2i(544,16);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.5,0.3,0.0);
glVertex2i(568,32);
glVertex2i(592,32);
glVertex2i(592,16);
glVertex2i(568,16);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.5,0.5,0.0);
glVertex2i(592,32);
glVertex2i(616,32);
glVertex2i(616,16);
glVertex2i(592,16);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.4,0.4,0.4); //plomo oscuro
glVertex2i(616,32);
glVertex2i(640,32);
glVertex2i(640,16);
glVertex2i(616,16);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.3,0.0,0.0);
glVertex2i(448,16);
glVertex2i(472,16);
glVertex2i(472,0);
glVertex2i(448,0);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.3,0.0);
glVertex2i(472,16);
glVertex2i(496,16);
glVertex2i(496,0);
glVertex2i(472,0);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.0,0.3);
glVertex2i(496,16);
glVertex2i(520,16);
glVertex2i(520,0);
glVertex2i(496,0);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.3,0.3);
glVertex2i(520,16);
glVertex2i(544,16);
glVertex2i(544,0);
glVertex2i(520,0);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.3,0.0,0.3);
glVertex2i(544,16);
glVertex2i(568,16);
glVertex2i(568,0);
glVertex2i(544,0);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.4,0.3,0.0);
glVertex2i(568,16);
glVertex2i(592,16);
glVertex2i(592,0);
glVertex2i(568,0);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.3,0.3,0.0);
glVertex2i(592,16);
glVertex2i(616,16);
glVertex2i(616,0);
glVertex2i(592,0);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.1,0.1,0.1);
glVertex2i(616,16);
glVertex2i(640,16);
glVertex2i(640,0);
glVertex2i(616,0);
glEnd();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);// dibujar solo las lineas de los poligonos
glColor4f(1,1,1,1); // color inverso al del fondo de la pantalla
glBegin(GL_QUADS); // marco de los colores
glVertex2i(448,64);
glVertex2i(640,64);
glVertex2i(640,0);
glVertex2i(448,0);
glEnd();
crear_cuadros(0,0,64);
glBegin(GL_POINTS);
glVertex2i(32,32);
glEnd();
crear_cuadros(64,0,64);
glBegin(GL_LINES);
glVertex2i(120,54);
glVertex2i(77,11);
glEnd();
crear_cuadros(128,0,64); //3era. caja de menu
glBegin(GL_TRIANGLES);
glVertex2i(160,54);
glVertex2i(184,10);
glVertex2i(136,10);
glEnd();
crear_cuadros(192,0,64); //4ta. caja de menu
glBegin(GL_QUADS);
glVertex2i(200,54);
glVertex2i(248,54);
glVertex2i(248,10);
glVertex2i(200,10);
glEnd();
crear_cuadros(256,0,64); //5ta. caja de menu
glBegin(GL_LINE_LOOP);
glVertex2i(264,32);
glVertex2i(288,56);
glVertex2i(312,32);
glVertex2i(304,8);
glVertex2i(272,8);
glEnd();
glBegin(GL_QUADS); // marcos de los tipos de lineas
glVertex2i(320,64);
glVertex2i(448,64);
glVertex2f(448.0,42.6);
glVertex2f(320.0,42.6);
glVertex2f(320.0,42.6);
glVertex2f(448.0,42.6);
glVertex2f(448.0,21.3);
glVertex2f(320.0,21.3);
glVertex2f(320.0,21.3);
glVertex2f(448.0,21.3);
glVertex2f(448.0,0);
glVertex2f(320.0,0);
glEnd(); // fin marcos de los tipos de lineas
glEnable(GL_LINE_STIPPLE); // tipos de lineas
glLineStipple(1, 0xFFFF);
glBegin(GL_LINES);
glVertex2i(328,53);
glVertex2i(440,53);
glEnd();
glLineStipple(1, 0xF0F0);
glBegin(GL_LINES);
glVertex2i(328,32);
glVertex2i(440,32);
glEnd();
glLineStipple(1, 0xAAAA);
glBegin(GL_LINES);
glVertex2i(328,10);
glVertex2i(440,10);
glEnd();
glDisable(GL_LINE_STIPPLE); // fin tipos de lineas
glFlush(); // enviar al servidor grafico
//glPopAttrib(); // recuperar atributos previamente guardados
}
domingo, noviembre 12, 2006
Capítulo 7: Texture Mapping
• El mapeo de texturas permite cubrir objetos (polígonos) con imágenes (texturas).
• Esto entrega una visualización más real en objetos de “menor” complejidad.
• Por ejemplo, se puede construir una muralla de ladrillo utilizando un simple polígono recubierto por una textura de un ladrillo.
• Una textura puede ser unidimensional, bidimensional o tridimensional.
• Puede ser aplicada sobre una superficie de diferentes formas:
– Cubrir directamente una superficie (modo DECAL).
– Modular el color de la superficie pintada.
– Mezclar (blend) el color de la textura con el color de la superficie.
• Una textura es un arreglo rectangular de datos: color y valor alpha. Cada elemento se denomina texel.
• En el proceso de mapping una textura es asociada a un polígono.
1. Crear un objeto de textura y especificar una textura para el objeto.
2. Indicar cómo la textura se aplicará a cada píxel.
3. Habilitar mapeo de texturas.
4. Dibujar la escena, suministrando coordenadas geométricas y de texturas.
• Para especificar una textura 2D se utiliza el comando glTexImage2D.
void glTexImage2D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
– target: GL_TEXTURE_2D or GL_PROXY_TEXTURE_2D.
– level: define múltiples niveles de resoluciones de texturas (para mip mapping).
– internalFormat: formato en que se almacena internamente la textura:
• GL_ALPHA, GL_RGB, GL_RGB8, GL_RGBA8, etc.
– width: ancho de la textura.
– height: alto de la textura.
– border: ancho del borde la textura (0 = sin borde).
– format: formato de los datos de la imagen:
GL_COLOR_INDEX, GL_RGB, GL_RGBA, GL_RED, GL_GREEN, GL_BLUE,
GL_ALPHA, GL_LUMINANCE, or GL_LUMINANCE_ALPHA.
– type: tipo de datos de la imagen:
GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT,
GL_UNSIGNED_INT, GL_FLOAT, or GL_BITMAP.
– pixels: puntero a los datos de la imagen.
• Para escalar el tamaño de una imagen:
– intgluScaleImage( ... );
• Se puede usar información del framebuffer para generar una textura:
– voidglCopyTexImage2D( ... );
• Para reemplazar parte o completamente la actual textura:
– voidglTexSubImage2D( ... );
• Para reemplazar parte o completamente la actual textura utilizando datos de la imagen del framebuffer:
– voidglCopyTexSubImage2D( ... );
• Objetos texturizados pueden estar en movimiento, alejándose y/o acercándose hacia observador. Esto implica que el mapeo de la textura en el objeto debe cambiar de tamaño.
• Especialmente cuando un objeto se aleja, las texturas tienen que ser filtrada para reducir el tamaño y no producir actifacts visuales.
• Para evitar actifacts se pueden generar una serie de mapas de texturas prefiltradas en tamaño decreciente, llamada mipmaps.
• Con mipmapping, OpenGL automáticamente determina qué mapa usar basado el tamaño del objeto que está siendo mapeado (ver ejemplo mipmap.c).
Filtros
• Si bien las texturas son rectangulares, es improbable que exista una correspondencia 1:1 entre texels y píxeles.
• Dependiendo de las transformaciones un píxel puede ser una porción de un texel (magnificación) o puede ser un conjunto de varias texels (minificación).
• void glTexParameteri(GLenum target, GLenum pname, GLint param);
• target: GL_TEXTURE_2D or GL_TEXTURE_1D.
• pname: especifica el nombre del parámetro:
GL_TEXTURE_MIN_FILTER,
GL_TEXTURE_MAG_FILTER,
GL_TEXTURE_WRAP_S,
GL_TEXTURE_WRAP_T.
• param: especifica el valor de pname (ver tabla).
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
• A partir de OpenGL 1.1 es posible almacenar un conjunto de objetos de texturas y reutilizarlos cuando sea necesario.
• Pasos a seguir:
1. Generar nombres de texturas.
2. Vincular (crear) objetos de texturas a datos de texturas, incluyendo arreglo de imágenes y propiedades.
3. Si la implementación lo permite, definir un conjunto de texturas de alto-desempeño.
4. Vincular o revincular objetos de texturas, dejándolas disponibles para el rendering de modelos.
• Para generar uno mas nombre de texturas se utiliza:
void glGenTextures(GLsizei N, GLuint *textureNames);
N : cantidad de nombres solicitados.
textureNames : puntero a los valores entregados.
• Ejemplo:
static GLuint texName[2];
glGenTextures(2, texName);
Creación y Uso de Objetos de Texturas
• Para crear o seleccionar un objeto de textura se utiliza:
void glBindTexture(GLenum target, GLuint textureName);
target: GL_TEXTURE_1D or GL_TEXTURE_2D.
textureName: identificador de la textura.
• Ejemplo (ver texbind.c):
glGenTextures(2, texName);
glBindTexture(GL_TEXTURE_2D, texName[0]);
...
glBindTexture(GL_TEXTURE_2D, texName[0]);
• Para liberar recursos de objetos de texturas se utiliza:
void glDeleteTextures(GLsizei n, const GLuint
n : cantidad de objetos de texturas.
textureNames: puntero a los nombres de texturas.
• Ejemplo:
glDeleteTextures( 2, texName );
• Para definir las propiedades de cómo interactúa una textura en el proceso de rendering se utiliza la siguiente función:
void glTexEnv{if}(GLenum target, GLenum pname, TYPE param);
void glTexEnv{if}v(GLenum target, GLenum pname, TYPE *param);
target: GL_TEXTURE_ENV
pname:
Si es igual a GL_TEXTURE_ENV_MODE:
param: GL_DECAL, GL_REPLACE, GL_MODULATE or
Si es igual a GL_TEXTURE_ENV_COLOR:
param: es un arreglo de 4 flotantes R,G,B,A. Estos valores se usan si también se ha especificado la función de textura GL_BLEND.
Asignación de Coordenadas de Texturas
• Es el proceso en el que se asignan coordenadas de texturas a los vértices de un objeto.
• Las coordenadas de texturas pueden comprometer 1, 2, 3 o 4 componentes ( s, t, r, q ).
• Usualmente estos valores van entre
• Para definir las coordenadas de texturas se utiliza:
void glTexCoord{1234}{sifd}(TYPEcoords);
void glTexCoord{1234}{sifd}v(TYPE *coords);
• Para un rectángulo 2D las C.T. son (0,0), (1,0), (1,1), (0,1).
• Ejemplo:
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(5.0, 0.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(5.0, 5.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(0.0, 5.0, 0.0);
glEnd();
• Es posible repetir una textura cambiando el rango de las coordenadas de texturas y definiendo las propiedades adecuadas.
• Por ejemplo:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
....
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(0.0, 3.0); glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(3.0, 3.0); glVertex3f(2.41421, 1.0, -1.41421);
glTexCoord2f(3.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);
glEnd();
• También es posible fijar una textura cambiando en la propiedades e GL_REPEAT por GL_CLAMP.
sábado, noviembre 11, 2006
Capítulo 6: Blending, Antialiasing, Fog y Polygon Offset
• Blending: se utiliza para crear efectos de transparencia. Esto se hace por medio de la especificación de un función de mezcla que combina valores de colores entre un fuente y un destino.
• Antialiasing: es una técnica que altera los colores de objetos (puntos, líneas y polígonos) para que los bordes se vean más suaves (o menos dentados).
• Fog: corresponde al efecto de niebla en que los objetos más lejanos desaparecen. Esta ilusión de profundidad se crea calculando los colores de un objeto basado en la distancia que existe entre el objeto y el punto de vista.
• Polygon Offset: permite eliminar imperfecciones que se producen cuando un objeto sombreado y su wireframe utilizan los mismos vértices.
Blending
• Cuando el blending es activado, el valor alpha puede ser utilizado para combinar el valor del color del fragmento que está siendo procesado, con el pixel que ya está almacenado en el framebuffer.
• Con blending se puede controlar cuanto del color del actual pixel puede ser combinado con el nuevo fragmento.
• Blending ocurre después que la escena ha sido renderizada y convertida a fragmentos, pero antes que el pixel sea almacenado en el framebuffer.
• El valor alpha también puede ser usado para aceptar a rechazar un fragmento basado en su valor alpha (ver capítulo 10 del redbook).
• Blending no funciona en modo color index.
• Las operaciones blending se puede pensar en términos de que la componentes RGB son el color de un fragmento, y el alpha representa el nivel de opacidad de ese fragmento.
• Fuente (source): valor del color del fragmento que está siendo procesado.
• Destino (destination): valor del color del píxel almacenado.
• Durante el blending fuente y destino son combinados en 2 etapas:
– Primero se especifica cómo los factores fuente y destino van a ser calculados. Estos factores (R,G,B,A) multiplican a cada componente R, G, B, A del fuente y destino respectivamente.
– Luego se suman fuente y destino, y se obtiene el resultado.
• Factor Fuente: (Sr, Sg, Sb, Sa).
• Factor Destino: (Dr, Dg, Db, Da)
• Valor Final: (RsSr+RdDr, GsSg+GdDg, BsSb+BdDb, AsSa+AdDa)
• El valor final de cada componente es limitado a: 0-1.
Blending en OpenGL
• Habilitar blending: glEnable(GL_BLEND);
• Definir cómo se calcularán factores Fuente y Destino:
glBlendFunc(GLenum sfactor, Glenum dfactor);
sfactor: factor fuente.
dfactor: factor destino.
Factores de Blending Fuente y Destino
• No todas las combinaciones tienen sentido.
– Primera Imagen:
• Factor Fuente: GL_ONE (1,1,1,1)
• Factor Destino: GL_ZERO (0,0,0,0)
• (Rs*1 + Rd*0, Gs*1 + Gd*0, Bs*1 + Bd*0) = (Rs,Gs,Bs)
– Segunda Imagen:
• Factor Fuente: GL_SRC_ALPHA (As,As,As,As)
• Factor Destino: GL_ONE_MINUS_SRC_ALPHA
(1-As, 1-As,1-As,1-As)
• ( RsAs + Rd(1-As), GsAs + Gd(1-As), BsAs + Bd(1-As) )
– Factor Fuente: GL_SRC_ALPHA
– Factor Destino: GL_ONE
– Dibujar cada imagen con Factor Alpha: 0.333333
– (Rs*0.3 + (Rd=0)*1,
– (Rs*0.3 + (Rs*0.3)*1,
– (Rs*0.3 + (Rs*0.3 + Rs*0.3)*1,
– Factor Fuente: GL_SRC_ALPHA
– Factor Destino: GL_ONE_MINUS_SRC_ALPHA
– Dibujar cada imagen con Factor Alpha = % (0.1)
– ( RsAs + Rd(1-As), …
– ( RsAs + ( RsAs + Rd(1-A) )*(1-As), …
– ( RsAs + ( ...)* ( 1-As), …
– Factor Fuente: GL_DST_COLOR (Rd, Gd, Bd, Ad)
– Factor Destino: GL_SRC_COLOR (Rs, Gs, Bs, As)
– ( RsRd + RdRs,…
– Es una especie de filtro.
– Objeto 1 (más lejano): Transp: 80%
– Objeto 2 (intermedio: Transp: 40%
– Objeto 3 (más cercano): Transp: 90%
• Dibujar Fondo:
– Factor Fuente: GL_ONE
– Factor Destino: GL_ZERO
• Cambiar Factores blending:
– Factor Fuente: GL_SRC_ALPHA
– Factor Destino: GL_ONE_MINUS_SRC_ALPHA
• Dibujar objeto 1, Alpha = 0.2.
• Dibujar objeto 2, Alpha = 0.6.
• Dibujar objeto 3, Alpha = 0.1.
/* Initialize alpha blending function. */
static void init(void){
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glShadeModel (GL_FLAT);
glClearColor (0.0, 0.0, 0.0, 0.0);
}
glClear(GL_COLOR_BUFFER_BIT);
if (leftFirst) {
drawLeftTriangle();
drawRightTriangle();
}
else {
drawRightTriangle();
drawLeftTriangle();
}
glFlush();
}
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix ();
glCallList (sphereList);
glPopMatrix ();
glPushMatrix ();
glEnable (GL_BLEND);
glDepthMask (GL_FALSE);
glBlendFunc (GL_SRC_ALPHA, GL_ONE);
glCallList (cubeList);
glDepthMask (GL_TRUE);
glDisable (GL_BLEND);
glPopMatrix ();
Antialiasing (o graduación)
void glHint(GLenum target, GLenum hint);
target: comportamiento a controlar (ver tabla)
hint: GL_FASTEST, GL_NICEST, GL_DONT_CARE
Antialiasing Puntos, Lineas
Puntos:
• glEnable( GL_POINT_SMOOTH )
• glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
Líneas:
• glEnable( GL_LINE_SMOOTH );
• glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
• En modo RGBA, antialiasing debe tener blending habilitado.
Ejemplo aarbg.c
void init(void){
GLfloat values[2];
glGetFloatv (GL_LINE_WIDTH_GRANULARITY, values);
printf ("GL_LINE_WIDTH_GRANULARITY value is %3.1f\n",
values[0]);
glGetFloatv (GL_LINE_WIDTH_RANGE, values);
printf ("GL_LINE_WIDTH_RANGE values are %3.1f %3.1f\n",
values[0], values[1]);
glEnable (GL_LINE_SMOOTH);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glLineWidth (1.5);
glClearColor(0.0, 0.0, 0.0, 0.0);
}
• Es un Término general que describe formas similares de efectos atmosféricos: niebla, humo, polución.
• Limita la visibilidad.
• Para habilitar Fog:
– glEnable(GL_FOG);
– Elegir el color de fog.
– Determinar la función de densidad de fog con: glFog*();.
void glFog{if}v(GLenum pname, TYPE *params);
entonces param = GL_EXP, GL_EXP2 o GL_LINEAR.
Si pname = GL_FOG_DENSITY, GL_FOG_START o GL_FOG_END,
entonces param es el valor correspondiente.
entonces param = valor RGBA.
El color de final C = f Ci + (1 – f) Cf
Ci: color del fragmento.
Cf : color de fog.
GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1.0};
glEnable(GL_FOG);
fogMode = GL_EXP;
glFogi (GL_FOG_MODE, fogMode);
glFogfv (GL_FOG_COLOR, fogColor);
glFogf (GL_FOG_DENSITY, 0.35);
glHint (GL_FOG_HINT, GL_DONT_CARE);
glFogf (GL_FOG_START, 1.0);
glFogf (GL_FOG_END, 5.0);
glClearColor(0.5, 0.5, 0.5, 1.0); /* fog color */
viernes, noviembre 10, 2006
Capítulo 6 : Shading
• 6.1 Luz y Materia
• 6.2 Fuentes de Luces
• 6.3 Modelo de Reflexión Phong
• 6.5 Shading Poligonal
• 6.10 Rendering Global
• Objetos reales aparecen iluminados con diferentes tonos de colores.
• Esta graduación le da a las imágenes la apariencia dimensionalidad.
• Desde el punto de vista físico, una superficie puede emitir o reflejar luz.
• El color de un punto en un objeto, está dado por la interacción múltiple entre fuentes de luces y superficies reflectantes.
• La reflexión es un proceso recursivo complejo.
• Deriva en una ecuación integral: Ecuación de Rendering.
• Aproximaciones: radiosity, ray tracing (costosas).
• Un modelo simple basado en: Phong shading.
• Fuentes de luz = Emisores de luz.
• Se modela la interacción de los rayos con las superficies reflectantes.
• Interacción simple: una interacción única entre luces y superficies.
• 2 problemas:
– Modelamiento de las fuentes de luz en la escena.
– Modelamiento de la reflexión en las superficies.
• Sólo una parte de los rayos contribuye a la creación de la imagen.
Clasificación de Superficies según
(a) Superficie Especular (reluciente)
(b) Superficie Difusa
(c) Superficie Translúcida
6.2 Fuentes de Luz
• En una fuente de luz, cada punto emisor de la superficie puede ser caracterizada por:
– Posición: coordenadas x, y, z
– Dirección: ángulos θy φ
– Intensidad de longitud de onda: λ
• Función de Iluminación: n: I( x, y, z, I( x, y, z, θ, φ, λ)
• Contribución total: Integración sobre la superficie para considerando ángulos incidentes y la distancia entre la superficie y la fuente de luz.
• El color de una fuente de luz se puede modelar usando la teoría de tres colores.
• Una fuente puede tener tres componentes:
– rojo, verde, azul (RGB).
• Cada componente de color se puede usar para obtener la correspondiente componente de color que verá el observador.
• Intensidad o función luminancia de Fuente de luz:
– I = [ I I = [ Ir, I , Ig, I , Ib ]
• Corresponde a una iluminación uniforme.
• Se produce por grandes fuentes de luz, con difusores que esparcen los rayos de luz en todas direcciones.
• La iluminación en el ambiente se caracteriza por una intensidad igual en cada punto:
– Ia = [ = [ Iar ar, Iag ag, Iab ab ]
• Un punto fuente emite luz en todas las direcciones.
• Un punto fuente p0 se caracteriza por:
– I(p0) = [ Ir(p0), Ig(p0), Ib(p0) ]
• La intensidad recibida es inversamente proporcional al cuadrado de la distancia entre la fuente y la superficie:
– I(p, p0) = ( 1/ | p - p0 |2 ) * I(p0)
• En la realidad las sombras generan escenas más suaves.
• Existen áreas complemente iluminadas, completamente sombreadas y área intermedias (penumbra).
• Fuente con un ángulo reducido de emisión.
• La intensidad no es pareja en el cono; es más fuerte en el centro.
• Si la luz está lo suficientemente lejos a la superficie, el vector de incidencia no cambia.
• Es equivalente a una fuente de luz con rayos paralelos.
• Modelo desarrollado por Phong.
• Buena aproximación computacional del modelo físico.
• El modelo usa 4 vectores para calcular el color de un punto P:
– n: n: normal en P,
– v: v: dirección de P hacia el observador (COP),
– l: l: dirección de P hacia fuente de luz,
– r: r: dirección de un rayo perfectamente reflejado
• El modelo de Phong utiliza 3 tipos de reflexión:
– ambiental
– difusa
– especular
• Cada fuente de luz tiene estas 3 componentes para cada color primario (RGB).
• Matriz de Iluminación de fuente i:
• El modelo busca calcular el porcentaje de luz reflejada en un punto.
• Esto depende de las propiedades de reflexión del punto.
• Matriz de reflexión para el punto i:
• La intensidad de una fuente de luz en el punto i:
• Contribución de varias fuentes:
• La intensidad de
• Parte de la luz se refleja y parte se absorbe.
• Coeficiente de reflexión de la superficie:
– Ra = ka, 0 ≤ ka ≤ 1
• Intensidad:
– Ia = kaLa
• La luz reflejada se esparce en todas las direcciones.
• No depende del punto de vista del observador.
• Depende de la posición de la luz y la superficie del material.
• Superficies ásperas proveen reflexión difusa.
• Superficies difusas también se les llama Superficies de Lambert.
• Pueden ser modeladas por las leyes de Lambert:
– Reflexión difusa: Rd α cos θ
– cos θ = l • n
• Considerando coeficiente de reflexión kd, y vectores normalizados:
• Considerando atenuación cuadrática de la luz por la distancia d que viaja desde la fuente a la superficie:
• La reflexión especular le agrega brillo a los objetos.
• Usualmente es de un color diferente que el de la luz ambiente y difusa reflejada.
• Una superficie especular es lisa.
• Se considera que la luz que ve el observador depende de:
– ángulo φ entre r y v,
– r: la dirección de reflexión, y
– v: la dirección del observador.
• El modelo Phong usa la siguiente ecuación:
– α: coeficiente de brillantes (shininess)
• Considerando vectores r y v normalizados:
• Para cada fuente de luz y color primario:
• El modelo Phong puede ser aplicado a superficies compuestas de polígonos.
• En estos objetos se pueden reducir la cantidad de trabajo requerido para shading.
• Cada polígono debe ser tratado aparte, a través de uno de los siguiente algoritmos:
– Flat shading
– Interpolative or Gouraud shading
– Phong shading
• En cada polígono el vector n es constante.
• Los vectores l, n y v pueden variar entre polígonos.
• En OpenGL:
– glShadeModel( GL_FLAT);
Interpolativo o Gouraud Shading
• En gouraud shading se considera la normal en cada vértice para el cálculo del color del pixel.
• El color de cada pixel se obtiene como la interpolación de las intensidades obtenidas entre vértices.
• En OpenGL:
– glShadeModel( GL_SMOOTH );
• Cálculo de las normales:
Phong Shading
• Phong propone que en vez de interpolar la intensidad del color, se interpolen las normales entre polígonos.
• Cálculo de normales de los bordes:
• Existen limitaciones en el modelo de lighting local.
• La iluminación se realiza independientemente en cada objeto.
• Métodos de iluminación global:
– Ray Tracing
– Radiosity
• Es una extensión del modelo visto.
• Es ideal para objetos altamente reflexivos y transparentes.
• Los rayos pueden entrar a la cámara:
– Directamente de la fuente.
– Después de una interacción con una superficie visible.
– Después de múltiples reflexiones de superficies.
– Después de transmisión a través de una o más superficies.
• Se considera sólo los rayos que parten desde el centro de proyección.
• Los rayos lanzados son los que contribuyen a la imagen.
• Se inicia un proceso de trazado de rayos.
Radiosity
• Es ideal para superficies difusas.
• Considera un balance de energía global que determina el color de cada superficie poligonal.
• Incluye interacción difusa-difusa.
• El método básico de radiosidad divide una escena en pequeños polígonos planos (patches), cada uno se asume perfectamente difuso.
• El cálculo de sombreado se realiza en dos pasos:
– Primero se considera la interacción entre parejas de patches, para determinar los “factores de forma” que describen cómo la energía que sale de un patch, afecta a otro.
– Luego, la ecuación de rendering (integral), se reduce a un conjunto lineal de ecuaciones de radiosidad.
– La solución entrega la radiosidad de cada path, lo que se utiliza en el rendering de la escena.