Laboratorio de Computación Gráfica

martes, noviembre 14, 2006

Práctica #5 - Martes 14 de noviembre de 2006- Ambos grupos

Laboratorio de Computación Gráfica
Practica 5 Martes, 14 de Noviembre de 2006
- Texturas y superficies paramétricas -
Entrega: Martes 21 de noviembre de 2006

Observe el siguiente código fuente:

/* Programa en OpenGL, usando GLUT, para dibujar una superficie generada por NURBS y se hace ondear aplicándo una función senoidal.
Las teclas t,T sirven para cambiar el modo de despliegue de modo poligonal a sombreado.

Creado: Mayo de 2003 Última actualización: 28 de Noviembre de 2005

Santiago Igor Valiente Gomez
igor@servidor.unam.mx
*/

# include <gl/glut.h>
// # include <stdlib.h>
# include <stdio.h>
# define _USE_MATH_DEFINES
# include <math.h>
# define PI 3.1415926535
GLfloat ctlpoints1[4][4][3]; GLfloat ctlpoints2[4][4][3];
GLfloat *grid1=&ctlpoints1[0][0][0];
GLfloat *grid2=&ctlpoints2[0][0][0];
GLfloat modo=GLU_FILL;
GLfloat luz_ambiental[4]={1.0,1.0,1.0,1.0};
static float tex[2][2][2] = { { {0, 0}, {1, 0} }, { {0, 1}, {1, 1} } };
GLfloat amplitud = 2.0;
static float iteracion = 0;
static float fase = 0.0;
static float time = 0.0;
int window; int showPoints=0;
int winWidth, winHeight;
int uSize = 4;
int vSize = 4;
int textura = 0;
static int angx = -20;
static int angy=0;
static int angz=0;
static GLfloat x=0.0;
static GLfloat y=0.0;
static GLfloat z=0.0;
static float ang=0.0;
GLUnurbsObj *objNurb1;
GLUnurbsObj *objNurb2;

void init_surface(void){
int u,v;
glPushAttrib(GL_ENABLE_BIT GL_EVAL_BIT);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_MAP2_TEXTURE_COORD_2);
for (u=0;u<uSize;u++)
{
for (v=0;v<vSize;v++)
{
ctlpoints1[u][v][0] = 2.0*((GLfloat)u) - 6.0;
ctlpoints1[u][v][1] = 2.0*((GLfloat)v) - 3.0;
ctlpoints1[u][v][2] = 0.0;
ctlpoints2[u][v][0] = 2.0*((GLfloat)u);
ctlpoints2[u][v][1] = 2.0*((GLfloat)v) - 3.0;
ctlpoints2[u][v][2] = 0.0;
}
}
glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, &tex[0][0][0]);
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &ctlpoints1[0][0][0]);
glMapGrid2f(14, 0.0, 1.0, 14, 0.0, 1.0);
glEvalMesh2(GL_FILL, 0, 14, 0, 14);
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &ctlpoints2[3][0][0]);
glEvalMesh2(GL_FILL, 0, 14, 0, 14);
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &ctlpoints2[3][3][0]);
glEvalMesh2(GL_FILL, 0, 14, 0, 14);
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &ctlpoints1[0][3][0]);
glEvalMesh2(GL_FILL, 0, 14, 0, 14);
}

void init(void)
{
GLfloat mat_diffuse[] = {0.7,0.7,0.7,1.0};
GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};
GLfloat mat_shininess[] = {100.0};
glClearColor(0.0,1.0,0.0,0.0);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0,GL_AMBIENT,luz_ambiental);
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
init_surface();
objNurb1=gluNewNurbsRenderer();
objNurb2=gluNewNurbsRenderer();
gluNurbsProperty(objNurb1, GLU_SAMPLING_TOLERANCE, 25.0);
gluNurbsProperty(objNurb1, GLU_DISPLAY_MODE, modo);
gluNurbsProperty(objNurb2, GLU_SAMPLING_TOLERANCE, 25.0);
gluNurbsProperty(objNurb2, GLU_DISPLAY_MODE, modo);
}

void showcontrolpoints(void)
{
int i;
glPointSize(5.0);
glDisable(GL_LIGHTING);
glColor3f(1.0,1.0,0.0);
for(i=0;i<uSize*vSize;i++)
{
glBegin(GL_POINTS);
if (i == 0)
glTexCoord2f(0.0,0.0);
if (i == 12)
glTexCoord2f(1.0,0.0);
glVertex3fv(&grid1[i*3]);
if (i == 3) glTexCoord2f(0.0,1.0);
if (i == 15) glTexCoord2f(1.0,1.0);
glVertex3fv(&grid2[i*3]); glEnd();
}
glEnable(GL_LIGHTING);
}

void senoidal(void)
{
int u, v;
for (u = 0; u < uSize; u++)
{
for (v = 0; v < vSize; v++)
{
ctlpoints1[u][v][2] = amplitud * sin(u*(2*PI/8) + iteracion + v);
ctlpoints2[u][v][2] = amplitud * sin((u+3)*(2*PI/8) + iteracion + v);
}
}
}

void display(void)
{
GLfloat knots1[8] = {0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0};
GLfloat knots2[8] = {0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0};
senoidal();
glClear(GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT);
gluNurbsProperty(objNurb1, GLU_DISPLAY_MODE, modo);
gluNurbsProperty(objNurb2, GLU_DISPLAY_MODE, modo);
glPushMatrix();
glRotatef((GLfloat)angx,1.0,0.0,0.0);
glRotatef((GLfloat)angy,0.0,1.0,0.0);
glRotatef((GLfloat)angz,0.0,0.0,1.0);
glTranslatef(x,0.0,0.0);
glTranslatef(0.0,y,0.0);
glTranslatef(0.0,0.0,z);
gluBeginSurface(objNurb1);
gluNurbsSurface(objNurb1, 8,knots1,8,knots1,4*3,3,grid1,4,4,GL_MAP2_VERTEX_3);
gluEndSurface(objNurb1);
gluBeginSurface(objNurb2);
gluNurbsSurface(objNurb2, 8,knots2,8,knots2,4*3,3,grid2,4,4,GL_MAP2_VERTEX_3);
gluEndSurface(objNurb2);
showcontrolpoints();
glPopMatrix();
glFlush();
glutSwapBuffers();
}

void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 't': case 'T':
if(modo==GLU_OUTLINE_POLYGON)
modo=GLU_FILL;
else
modo=GLU_OUTLINE_POLYGON;
glutPostRedisplay();
break;
case 'm': case 'M':
if (textura==0)
{
textura = 1;
glEnable(GL_TEXTURE_2D);
}
else
{
textura = 0;
glDisable(GL_TEXTURE_2D);
}
case 'c': case 'C':
z=z+0.5;
glutPostRedisplay();
break;
case 'l': case 'L':
z=z-0.5;
glutPostRedisplay();
break;
case 's': case 'S':
y=y+0.5;
glutPostRedisplay();
break;
case 'b': case 'B':
y=y-0.5;
glutPostRedisplay();
break;
case 'i': case 'I':
x=x-0.5;
glutPostRedisplay();
break;
case 'd': case 'D':
x=x+0.5;
glutPostRedisplay();
break;
case 'x':
angx=(angx+10)%360;
glutPostRedisplay();
break;
case 'X':
angx=(angx-10)%360;
glutPostRedisplay();
break;
case 'y':
angy=(angy+10)%360;
glutPostRedisplay();
break;
case 'Y':
angy=(angy-10)%360;
glutPostRedisplay();
break;
case 'z':
angz=(angz+10)%360;
glutPostRedisplay();
break;
case 'Z':
angz=(angz-10)%360;
glutPostRedisplay();
break;
case 'r': case 'R':
angx=0;
angy=0;
angz=0;
x=y=z=0.0;
glutPostRedisplay();
break;
case 27:
exit(0);
break;
default:
break;
}
}
void ortho(void)
{
if (winWidth <= winHeight)
glOrtho(-10.0,10.0,-10.0*(GLfloat)winHeight/(GLfloat)winWidth,10.0*(GLfloat)winHeight/(GLfloat)winWidth,-10.0,10.0);
else
glOrtho(-10.0*(GLfloat)winWidth/(GLfloat)winHeight,10.0*(GLfloat)winWidth/(GLfloat)winHeight,-10.0,10.0,-10.0,10.0);
}

void reshape (int w, int h)
{
glViewport(0, 0, w, h);
winWidth = w;
winHeight = h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); ortho();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void idle(void)
{
iteracion += 0.1;
glutSetWindow(window);
glutPostRedisplay();
}

void visible(int vis)
{
if (vis == GLUT_VISIBLE)
glutIdleFunc(idle);
else
glutIdleFunc(NULL);
}

void mouse(int button, int state, int x, int y)
{
if(button == GLUT_LEFT_BUTTON)
{
}
}

void motion(int x, int y)
{
}

int main(int argc,char** argv)
{
GLubyte image[64][64][3];
int i, j, c;
for(i=0;i<64;i++)
{
for(j=0;j<64;j++)
{
c = (((((i&0x8)==0)^((j&0x8)))==0))*255;
image[i][j][0]= (GLubyte) c;
image[i][j][1]= (GLubyte) c;
image[i][j][2]= (GLubyte) c;
}
}
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE GLUT_RGB GLUT_DEPTH);
glutInitWindowSize(500,500);
window = glutCreateWindow("flag");
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutVisibilityFunc(visible);
glEnable(GL_DEPTH_TEST);
glTexImage2D(GL_TEXTURE_2D,0,3,64,64,0,GL_RGB,GL_UNSIGNED_BYTE, image);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glutMainLoop();
return 0;
}



Ahora realice las siguientes actividades y conteste lo que se vaya preguntando:

1. Explique en detalle el funcionamiento del programa y el por qué del uso de cada uno de los comandos de OpenGL, GLU y GLUT aquí mostrados.
2. Modifique el programa para cargar una textura de mapa de bits de 64 x 64 pixeles con una profundidad de color de 8 bits.
3. Modifique el programa para que con un evento de timer se cambie el mapa de bits que se aplica como textura cada 30 segundos. Utilizar un mínimo de 5 mapas de bits.
4. Modifique el programa para que con el botón izquierdo del ratón cambie la frecuencia y con el botón derecho la amplitud de las senoidales aplicadas para deformar la superficie.