CONCEPTO DE PILA
Una pila (stack en inglés) es una lista ordenada o
estructura de datos en la que el modo de acceso a sus elementos es de tipo LIFO
(del inglés Last In First Out, último en entrar, primero en salir).
Las pilas suelen emplearse en los siguientes contextos:
Evaluación de expresiones
en notación postfija (notación polaca inversa).
Reconocedores
sintácticos de lenguajes independientes del contexto
Implementación de
recursividad.
PARA QUE NOS SIRVEN?
Permite almacenar y recuperar datos. Esta estructura se
aplica en multitud de ocasiones en el área de informática debido a su
simplicidad y ordenación implícita de la propia estructura.
Para el manejo de los datos se cuenta con dos operaciones
básicas: apilar (push), que coloca un objeto en la pila, y su operación
inversa, retirar (o desapilar, pop), que retira el último elemento apilado.
En cada momento sólo se tiene acceso a la parte superior de
la pila, es decir, al último objeto apilado (denominado TOS, Top of Stack en
inglés). La operación retirar permite la obtención de este elemento, que es
retirado de la pila permitiendo el acceso al siguiente (apilado con
anterioridad), que pasa a ser el nuevo TOS.
Por analogía con objetos cotidianos, una operación apilar
equivaldría a colocar un plato sobre una pila de platos, y una operación
retirar a retirarlo.
MANEJO DE PILAS EN OPENGL
PILA DE MATRICES
En algunos casos nos puede interesar guardar la transformación que tenemos en la matriz activa para posteriormente recuperarla, por ejemplo si deseamos renderizar un coche formado por la carroceria y cuatro ruedas. El coche entero tendra una transformación para colocarlo en el lugar (translacion + rotacion) y cada una de las ruedas tendra una transformación de rotación y transformación adicional que la colocara en relación al sistema de coordenadas del coche, para no tener que aplicar la misma transformación del coche a cada rueda podemos almacenarla en una pila y posteriormente recuperarla. Ejemplo:
Disponemos de una pila de matrices para cada una de las matrices existentes: MODELVIEW, PROJECTION y TEXTURE.
En algunos casos nos puede interesar guardar la transformación que tenemos en la matriz activa para posteriormente recuperarla, por ejemplo si deseamos renderizar un coche formado por la carroceria y cuatro ruedas. El coche entero tendra una transformación para colocarlo en el lugar (translacion + rotacion) y cada una de las ruedas tendra una transformación de rotación y transformación adicional que la colocara en relación al sistema de coordenadas del coche, para no tener que aplicar la misma transformación del coche a cada rueda podemos almacenarla en una pila y posteriormente recuperarla. Ejemplo:
glPushMatrix(); // Guardamos la transformacion del mundo
glTranslatef(cocheX, cocheY, cocheZ);
glRotatef(angulo, ejeX, ejeY, ejeZ);
RenderCarroceria();
glPushMatrix(); // Guardamos la transformacion del cocheglPushMatrix();
glTranslatef(rueda1X, rueda1Y, rueda1Z);glRotatef(anguloRueda1, eje1X, eje1Y, eje1Z);
RenderRueda();
glPopMatrix(); // Recuperamos la transformacion del coche
glPushMatrix();
glTranslatef(rueda2X, rueda2Y, rueda2Z);glRotatef(anguloRueda2, eje2X, eje2Y, eje2Z);
RenderRueda();
glPopMatrix();
glPushMatrix();
glTranslatef(rueda3X, rueda3Y, rueda3Z);glRotatef(anguloRueda3, eje3X, eje4Y, eje3Z);
RenderRueda();
glPopMatrix();
glTranslatef(rueda4X, rueda4Y, rueda4Z);glRotatef(anguloRueda4, eje4X, eje4Y, eje4Z);
RenderRueda();
glPopMatrix();
glPopMatrix(); // Recuperamos la transformacion del mundo
Disponemos de una pila de matrices para cada una de las matrices existentes: MODELVIEW, PROJECTION y TEXTURE.
PROGRAMAS ROTACION
#include "stdafx.h"
#include <stdlib.h>
#include <GL/glut.h>
GLfloat anguloCuboX = 0.0f;
GLfloat anguloCuboY = 0.0f;
GLfloat anguloEsfera = 0.0f;
GLint ancho=400;
GLint alto=400;
int hazPerspectiva = 0;
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(Perspectiva)
gluPerspective(60.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f);
else
glOrtho(-4,4, -4, 4, 1, 10);
glMatrixMode(GL_MODELVIEW);
ancho = width;
alto = height;
}
void drawCube(void)
{
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
glColor3f(0.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glEnd();
glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glVertex3f(-1.0f,-1.0f, -1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glColor3f(1.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glEnd();
glColor3f(0.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glColor3f(1.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glVertex3f( 1.0f,-1.0f, -1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, -1.0f);
glEnd();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5.0f);
glRotatef(anguloCuboX, 1.0f, 0.0f, 0.0f);
glRotatef(anguloCuboY, 0.0f, 1.0f, 0.0f);
drawCube();
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5.0f);
glRotatef(anguloEsfera, 0.0f, 1.0f, 0.0f);
glTranslatef(3.0f, 0.0f, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glutWireSphere(0.5f, 8, 8);
glFlush();
glutSwapBuffers();
anguloCuboX+=0.1f;
anguloCuboY-=0.1f;
anguloEsfera+=0.2f;
}
void init()
{
glClearColor(0,0,0,0);
glEnable(GL_DEPTH_TEST);
ancho = 400;
alto = 400;
}
void idle()
{
display();
}
void keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case 'p':
case 'P':
Perspectiva=1;
reshape(ancho,alto);
break;
case 'o':
case 'O':
Perspectiva=0;
reshape(ancho,alto);
break;
case 27: // escape
exit(0);
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(ancho, alto);
glutCreateWindow("Cubo 1");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
#include "GL/gl.h"
#include "gpu940.h"
#include <math.h> //necesario para la función gluPerspective
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
void draw();
Nuestra función principal, main()
Aquí inicializamos OpenGL y configuramos algunos parámetros, así como la matriz de proyección
int main()
{
glOpen(DEPTH_BUFFER); // Inicializa el OpenGL
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Especifica el color que se usará para borrar la pantalla (rojo, verde, azul, alpha)
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST); // Activamos el test de profundidad
glShadeModel(GL_SMOOTH); // Sombreado suave
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // Correción de perspectiva
glMatrixMode(GL_PROJECTION); //Cambiamos a la matriz de proyección...
glLoadIdentity(); //Y la reseteamos
gluPerspective(45.0f,(GLfloat)320/(GLfloat)240,0.1f,100.0f); // Esta función la definiremos más adelante
glMatrixMode(GL_MODELVIEW); //Cambiamos a la matriz de modelado
while(true) // Este bucle se ejecutara indefinidamente, por lo que no podremos terminar la aplicación sin matarla
{
draw(); // Función definida por nosotros para dibujar
glSwapBuffers(); // Intercambia los buffers y muestra uno en pantalla. Esto es así porque usamos double buffer
};
glClose();
return 0;
}
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar){
GLdouble top, bottom, left, right;
top = zNear * tan(pi180*fovy/2);
bottom = -top;
right = aspect*top;
left = -right;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(left, right, bottom, top, zNear, zFar);
glMatrixMode(GL_MODELVIEW);
}
void draw()
{
static GLfloat xrot=0; //variables estáticas para guardar la rotación del cubo
static GLfloat yrot=0;
static GLfloat zrot=0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //limpiamos la pantalla
glLoadIdentity(); // reseteamos
glTranslatef(0.0f,0.0f,-5.0f); // Nos desplazamos un poco
glRotatef(xrot,1.0f,0.0f,0.0f); //
glRotatef(yrot,0.0f,1.0f,0.0f); // Rotamos en cada eje según nuestras variables de rotación
glRotatef(zrot,0.0f,0.0f,1.0f); //
glBegin(GL_QUADS); // Comenzamos a dibujar polígonos de cuatro vértices
glVertex3f(-1.0f, -1.0f, 1.0f); //Primer vértice del primer polígono
glVertex3f( 1.0f, -1.0f, 1.0f); //Segundo vértice
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f); //Primer vértice del segundo polígono
glVertex3f(-1.0f, 1.0f, -1.0f); //Segundo vértice
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd(); // Terminamos con los polígonos de cuatro vértices
xrot+=1.3f; // Modificamos las variables de rotación
yrot+=1.2f;
zrot+=1.4f;
}
#include "GL/gl.h"
#include "gpu940.h"
#include <math.h> //necesario para la función gluPerspective
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
void draw();
Nuestra función principal, main()
Aquí inicializamos OpenGL y configuramos algunos parámetros, así como la matriz de proyección
int main()
{
glOpen(DEPTH_BUFFER); // Inicializa el OpenGL
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Especifica el color que se usará para borrar la pantalla (rojo, verde, azul, alpha)
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST); // Activamos el test de profundidad
glShadeModel(GL_SMOOTH); // Sombreado suave
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // Correción de perspectiva
glMatrixMode(GL_PROJECTION); //Cambiamos a la matriz de proyección...
glLoadIdentity(); //Y la reseteamos
gluPerspective(45.0f,(GLfloat)320/(GLfloat)240,0.1f,100.0f); // Esta función la definiremos más adelante
glMatrixMode(GL_MODELVIEW); //Cambiamos a la matriz de modelado
while(true) // Este bucle se ejecutara indefinidamente, por lo que no podremos terminar la aplicación sin matarla
{
draw(); // Función definida por nosotros para dibujar
glSwapBuffers(); // Intercambia los buffers y muestra uno en pantalla. Esto es así porque usamos double buffer
};
glClose();
return 0;
}
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar){
GLdouble top, bottom, left, right;
top = zNear * tan(pi180*fovy/2);
bottom = -top;
right = aspect*top;
left = -right;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(left, right, bottom, top, zNear, zFar);
glMatrixMode(GL_MODELVIEW);
}
void draw()
{
static GLfloat xrot=0; //variables estáticas para guardar la rotación del cubo
static GLfloat yrot=0;
static GLfloat zrot=0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //limpiamos la pantalla
glLoadIdentity(); // reseteamos
glTranslatef(0.0f,0.0f,-5.0f); // Nos desplazamos un poco
glRotatef(xrot,1.0f,0.0f,0.0f); //
glRotatef(yrot,0.0f,1.0f,0.0f); // Rotamos en cada eje según nuestras variables de rotación
glRotatef(zrot,0.0f,0.0f,1.0f); //
glBegin(GL_QUADS); // Comenzamos a dibujar polígonos de cuatro vértices
glVertex3f(-1.0f, -1.0f, 1.0f); //Primer vértice del primer polígono
glVertex3f( 1.0f, -1.0f, 1.0f); //Segundo vértice
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f); //Primer vértice del segundo polígono
glVertex3f(-1.0f, 1.0f, -1.0f); //Segundo vértice
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd(); // Terminamos con los polígonos de cuatro vértices
xrot+=1.3f; // Modificamos las variables de rotación
yrot+=1.2f;
zrot+=1.4f;
}
No hay comentarios.:
Publicar un comentario