viernes, noviembre 17, 2006

Screenshots Parque de diversiones OpenGL










Ejemplo OpenGL - PARQUE DE DIVERSIONES

Este ejemplo implementó una parque de diversiones en 3 dimensiones, utilizando opengl. Además tiene implementado una cámara que permite adentrarse en el parque y ver de mejor forma los diversos juegos o atracciones desarrolladas con múltiples figuras geométricas. A continuación el código , para que lo prueben:


/********************************************/
/* */
/* 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;amp; x<640> 320 &&amp; x < btn="=" state="=" opcion="seleccion(x,y);"> 0 &&amp;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

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.

Texture Mapping
• 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.

Proceso de Mapeo de Texturas
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.

Especificación de una Textura
• 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.

Especificación de una Textura
– 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.

Otras Funciones

• 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( ... );

Múltiples Niveles de Detalle (LOD)
• 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).
• Para especificar los métodos de magnificación y minificación se utiliza:
• 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).

• Ejemplo:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

Objetos de Texturas
• 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.

Nombres de Objetos de Textura
• 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]);

Borrado de Objetos de Texturas
• Para liberar recursos de objetos de texturas se utiliza:
void glDeleteTextures(GLsizei n, const GLuint *textureNames);
n : cantidad de objetos de texturas.
textureNames: puntero a los nombres de texturas.
• Ejemplo:
glDeleteTextures( 2, texName );

Funciones de Texturas
• 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 GL_BLEND.
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 0 a 1.
• 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();

Repetición y Fijación de Texturas
• 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();

Repetición y Fijación de Texturas
• 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

Efectos

• 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.

Factores Fuente y Destino
• 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

Ejemplos de Blending

• No todas las combinaciones tienen sentido.
• Mezcla de dos imágenes:
– 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) )

• Mezcla de tres imágenes equivalentemente:
– 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,

• Mezcla gradual:
– 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), …

• Modulación de colores:
– 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.

• Tres objetos, uno detrás de otro, sobre un fondo sólido:
– 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.

Ejemplo alpha.c
/* 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);
}

void display(void){
glClear(GL_COLOR_BUFFER_BIT);
if (leftFirst) {
drawLeftTriangle();
drawRightTriangle();
}
else {
drawRightTriangle();
drawLeftTriangle();
}
glFlush();
}

Ejemplo alpha3d.c
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)

• Para controlar el comportamiento OpenGL:
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);
}

Fog
• 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*();.

Fog

void glFog{if}(GLenum pname, TYPE param);
void glFog{if}v(GLenum pname, TYPE *params);

Si pname = GL_FOG_MODE,
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.

En modo RGBA si pname = GL_FOG_COLOR,
entonces param = valor RGBA.
El color de final C = f Ci + (1 – f) Cf
Ci: color del fragmento.
Cf : color de fog.

Ejemplo fog.c
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

Contenido

• 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

6 Shading

• Objetos reales aparecen iluminados con diferentes tonos de colores.
• Esta graduación le da a las imágenes la apariencia dimensionalidad.

6.1 Luz y Materia
• 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).
Luz y Superficies
• 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.

Luz y Superficies

• Sólo una parte de los rayos contribuye a la creación de la imagen.

Clasificación de Superficies según la Interacción Luz-Material
(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.

Colores en Fuentes 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 ]

Fuente de Luz Ambiental
• 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 ]

Fuente de Luz Puntual
• 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)

• Fuentes con forma de punto generan un alto contraste.
• En la realidad las sombras generan escenas más suaves.
• Existen áreas complemente iluminadas, completamente sombreadas y área intermedias (penumbra).


Fuente de Luz Faro (Spotlight)

• Fuente con un ángulo reducido de emisión.

Fuente de Luz Faro (Spotlight)
• La intensidad no es pareja en el cono; es más fuerte en el centro.

Fuente de Luz Distante
• 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.

6.3 Modelo de Iluminación de Phong
• 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

6.3 Modelo de Iluminación de Phong

• 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:

6.3 Modelo de Iluminación de Phong
• 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:

6.3 Modelo de Iluminación de Phong
• La intensidad de una fuente de luz en el punto i:
• Contribución de varias fuentes:
• Contribución total:

Reflexión Ambiental
• La intensidad de la Luz La es igual en cada punto.
• 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

Reflexión Difusa
• 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.

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

Reflexión Difusa
• 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:

Reflexión Especular
• 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.

Reflexión Especular
• El modelo Phong usa la siguiente ecuación:
– 0 ≤ ks ≤ 1, constante de reflexión.
– α: coeficiente de brillantes (shininess)

• Considerando vectores r y v normalizados:

Fórmula Final del modelo Phong
• Para cada fuente de luz y color primario:

6.6 Shading Poligonal
• 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


Flat 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 );

Interpolativo o Gouraud Shading
• 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:
• Cálculo de normales intermedias:

Phong Shading

6.10 Rendering Global
• 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

Ray Tracing
• 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.
• Para hacer tratable el problema, se invierte la dirección de los rayos.
• 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.

jueves, noviembre 09, 2006

Capítulo 5: Lighting

Efecto de la Iluminación

• El realismo de una escena depende de la iluminación.

Lighting en OpenGL
• OpenGL aproxima la iluminación, descomponiendo la luz en tres componentes: R, G, B.

• El color de una fuente de luz se caracteriza por la cantidad de rojo, verde y azul que puede emitir.
• Las propiedades de los materiales se caracterizan por la cantidad de luz roja, verde y azul que pueden reflejar en distintas direcciones.
• OpenGL utiliza una aproximación “liviana” para realizar el proceso en tiempo real.
• El modelo de lighting está dividido en cuatro componentes:
– Ambiente
– Difusa
– Especular
– Emisivo

Modelo de Lighting
• Componente Ambiente:
– Es luz que a sido esparcida por todo el ambiente y es imposible de determinar su origen.
– Cuando golpea una superficie se esparce igualmente en todas direcciones.
– Una sala iluminada tiene una gran componente ambiente.
• Componente Difusa:
– La luz viene de una dirección, pero cuando golpea una superficie se esparce igualmente en todas las direcciones.
– Una luz que proviene de una posición particular tiene una componente difusa.
• Componente Especular:
– La luz viene de una dirección, y cuando golpea una superficie se refleja en una dirección en particular.
– Un láser bien enfocado que choca con un espejo produce casi un 100% de reflexión especular.
– Ejemplos de materiales: metales pulidos y plásticos.

Colores de Materiales
• El color de los materiales depende de luz RGB que llega y de la cantidad que se refleja.
• A un material se le asignan diferentes valores de reflexión para cada componente: ambiente, difusa y especular.
• Además dispone de una propiedad de color de emisión, la cual crea la sensación de que un objeto emite luz.

Cálculo de Valores RGB
• Para una fuente de luz y materiales se definen valores RGB.
• Para una fuente de luz corresponden a la intensidad emitida de cada componente.
• Para los materiales corresponde a la capacidad de reflexión del de cada componente.
• Si una luz tiene componentes (LR, LG, LB), y un material (MR, MG, MB), sin considerar los efectos de reflectividad, el color resultante es:
– (LR*MR, LG*MG, LB*MB)

Ejemplo: Esfera Iluminada
• Definición de normales para cada vértice.
• Creación, posicionamiento y habilitación de una o más luces.
• Selección del modelo de lighting.
• Definición de las propiedades de los materiales.

Creación de Fuentes de Luz
void glLight{if}(GLenum light, GLenum pname, TYPEparam);
void glLight{if}v(GLenum light, GLenum pname, TYPE *param);

• Crea una fuente de luz: GL_LIGHT0, ... , GL_LIGHT7.
• Las características se definen por pname (ver tabla).
• param indica los valores asignados, dada la característica pname.

Valores por defecto para pname
Ejemplo de Definición y Posicionamiento de una Fuente de Luz
GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
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);

Posición de la Fuente de Luz
• OpenGL permite ubicar una luz en el infinito o localmente:
– Direccional: está en el infinito, los rayos son paralelos. Se puede variar la dirección (x,y,z).
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

– Posicional: tiene en un posición (x,y,z) que especifica su posición en coordenadas del objeto. Luego es transformada por la matriz ModelView y almacenada en coordenadas del observador.

GLfloat light_position[] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

Atenuación de la Luz
• Para luz posicional OpenGL permite atenuación de la luz:

• Ejemplo:
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.0);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 1.0);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.5);

Spotlights

• Cut_Off:
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);

• Dirección:
GLfloat spot_direction[] = { -1.0, -1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);

• Concentración de la Luz:
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2.0);

Controlando la Posición y Dirección
• OpenGL trata la posición y dirección de una fuente de luz tal cual como lo hace para la posición de una primitiva geométrica.
• Cuando se llama a glLight*(), la posición y dirección es transformada por la actual matriz de ModelView y se almacena en coordenadas del observador.
• Ejemplos:
– Luz en una posición fija.
– Luz en movimiento en torno a un objeto estacionario.
– Luz moviéndose junto con el punto de vista.

Luz en una Posición Fija
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho (-1.5, 1.5, -1.5*h/w, 1.5*h/w, -10.0, 10.0);
else
glOrtho (-1.5*w/h, 1.5*w/h, -1.5, 1.5, -10.0, 10.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
/* later in init() */
GLfloat light_position[] = { 1.0, 1.0, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, position);

Luz Moviéndose Independientemente
static GLdouble spin;
void display() {
GLfloat light_position[] = { 0.0, 0.0, 1.5, 1.0 };
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
glRotated(spin, 1.0, 0.0, 0.0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glPopMatrix();
glutSolidTorus (0.275, 0.85, 8, 15);
glPopMatrix();
glFlush();
}

Ver Ejemplo movelight.c

Luz Moviéndose con el Punto de Vista
GLfloat light_position() = { 0.0, 0.0, 0.0, 1.0 };
glViewport(0, 0, (GLint) w, (GLint) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
static GLdouble ex, ey, ez, upx, upy, upz;
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
gluLookAt (ex, ey, ez, 0.0, 0.0, 0.0, upx, upy, upz);
glutSolidTorus (0.275, 0.85, 8, 15);
glPopMatrix();
glFlush();
}


Seleccionando un Modelo de Lighting
• Para seleccionar las propiedades del modelo:
void glLightModel{if}(GLenum pname, TYPEparam);
void glLightModel{if}v(GLenum pname, TYPE *param);

– pname define la característica (ver tabla).
– param especifica el valor.

Parámetros del Modelo de Lighting
• Luz Ambiente Global:
– Adicionalmente, se puede definir una luz ambiente que no viene de ningún lado:
GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

• Punto de Vista Local o Infinito:
– OpenGL permite definir un punto de vista local o infinito.
– Es importante en el cálculo de la reflexión especular.
– Para habilitar modelo local:
– glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

• Lighting en los dos lados:
– OpenGL permite activar cálculo de lighting para la cara Front y Back de cada polígono:
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

Definición de las Propiedades de los Materiales
• voidglMaterial{if}(GLenum face, GLenum pname, TYPEparam);
• voidglMaterial{if}v(GLenum face, GLenum pname, TYPE *param);
– face: GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK.
– pname: propiedad (ver tabla).
– Param: valor.

miércoles, noviembre 08, 2006

Capítulo 5: Viewing

Contenido
5.1 Clasificación de Proyecciones.
5.2 Posicionamiento de la Cámara.
5.3 Proyecciones Simples.
5.4 Eliminación de Superficies Ocultas.

Viewing

• En el modelo de la cámara sintética se distinguen 2 partes:
– definición de los objetos a observar.
– definición de la cámara para observar.

• Se debe considerar:
– posición de la cámara.
– tipo de proyección.
– volumen de visión (window 3D, clipping volume).

• Elementos: Objeto, observador, proyectores y plano de proyección.

• COP = Center of Projection (posición de cámara)

Centro de Proyección en Infinito
• Si se mueve el COP al infinito se obtiene una proyección paralela con DOP (direction of projection).

5.1 Clasificación de Proyecciones
• Proyecciones Geométricas Planas

Proyección Ortográfica
• Los proyectores son perpendicular al plano de proyección.

Proyecciones Ortográficas
Perfil, Planta y Elevación
• El plano de proyección es paralelo a una cara del objeto.
• Preservación de distancias y ángulos.
• Se utilizan en el dibujo técnico.

Proyección Axonométrica
• Los proyectores siguen perpendiculares sobre el plano de proyección, pero el plano de proyección no está paralelo a una cara del objeto.

Vistas Axonométricas
• Isométrica: plano está simétrico a las 3 principales caras. Los ángulos entre las proyecciones de los tres ejes son iguales.
• Dimétrica: plano está simétrico a 2 caras. Los ángulos entre dos de los ejes son iguales.
• Trimétrica: caso general. Los ángulos entre los tres ejes son diferentes.

Vista Oblicua
• Proyectores no son perpendiculares al plano de proyecciones

Vista Perspectiva
• Perspectiva clásica: observador se encuentra simétricamente con respecto al objeto.
• Se utiliza para obtener una impresión realista en 3 dimensiones del espacio (arquitectura y animación).

Proyecciones Perspectivas con cero, uno y dos Puntos
• A: 0 direcciones principales son paralelas al plano.
• B: 1 dirección principal es paralela al plano.
• C: 2 direcciones principales son paralelas al plano.

5.2 Posicionamiento de la Cámara

• Cámara en el Origen y Traslación de matriz Model-View.
– glTranslatef(0.0, 0.0, -5.0);
– mueve por defecto la cámara en dirección de +Z.

Posicionamiento de la Cámara
• glMatrixMode(GL_MODELVIEW);
• glLoadIdentity();
• glTranslatef(0.0, 0.0, -5.0);
• glRotatef(-90.0, 0.0, 1.0, 0.0);

Definir la Posición a través de la Función gluLookAt()
gluLookAt(eyex,eyey,eyez,atx,aty,atz,upx,upy,upz)

Otras formas de Viewing (1/2)
Roll, Pitch y Yaw

5.3 Proyecciones Simples

• Cámara
a. Fondo de la cámara perpendicular a la dirección Z.
b. Caso general, fondo de la cámara con cualquier orientación.

Proyección Perspectiva
• zp = -d
• x/z = -xp / d xp = -x /(z/d) x / (z/d)
• yp = -y / (z/d) y / (z/d)
• Nonuniform foreshortening.
• Transformación irreversible.

Proyección Perspectiva
• Coordenadas Homogéneas:
– (x, y, z) 􀃆 (x, y, z, 1)
• Suponer:
– (x,y,z) (wx, wy, wz, w), w != 0
- Para recobrar (x,y,z) dividimos por w.

Pipeline de Proyección

Etapas en la Transformación de Vértices
v’ = Mv
con v = ( x, y, z, w), vector columna.

En la Proyección Ortogonal toman valores x e y, z = 0.

5.4 Eliminación de Superficies Ocultas
• Algoritmos “hidden surface removal”.
• Algoritmos “visible surface”

Hidden Surface Removal
• Los algoritmos se dividen en 2 clases:
– Object-Space: ordena las superficies del objeto.
– Image-Space: trabaja en conjunto con la proyección para determinar la relación entre los puntos del objeto.
• Algoritmo Z-Buffer (Image-Space).

Hidden Surface Removal

Algoritmo Z-Buffer
• OpenGL:
– glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
– glEnable(GL_DEPTH_TEST);
– glClear(GL_DEPTH_BUFFER_BIT);