[Tutorial] III.8 - Polígonos, circunferencias, mapas de bits y cadenas de QUAD

Ver el tema anterior Ver el tema siguiente Ir abajo

[Tutorial] III.8 - Polígonos, circunferencias, mapas de bits y cadenas de QUAD

Mensaje  HarZe el Lun Ago 03, 2009 7:32 pm

III.8 - Polígonos, circunferencias, mapas de bits y cadenas de QUAD
Novedades:
  • Uso de GL_QUAD_STRIP en glBegin()
  • Uso de GL_POLYGON en glBegin()
  • Uso de GL_POLYGON_STIPPLE en glEnable()
  • glPolygonStipple()


Lo primero de todo es que con este tutorial (más sencillo que los dos anteriores) acaba de exponer todos los primitivos posibles para dibujar (puntos, lineas, triangulos, cuadrilateros y polígonos). Y analizamos en punteo de polígonos, que es en realidad aplicarle un mapa de bits. La salida de este programa recuerda a los canales cuando por la noche no emitian. La pantalla clásica de un circulo blanquinegro y bandas arcoiris arriba y abajo. Con las flechas aumentas o disminuyes la precisión de la circunferencia central.

Código:
#include <GL/glut.h>
#include <math.h>

#define GL_PI 3.14159f

float i;
int precision = 20;
unsigned char flechas[2];
GLubyte patron[] = {
   0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00,
   0x0f, 0xff, 0xff, 0xf0,
   0x0f, 0xff, 0xff, 0xf0,
   0x0f, 0xff, 0xff, 0xf0,
   0x0f, 0xff, 0xff, 0xf0,
   0x0f, 0xf0, 0x0f, 0xf0,
   0x0f, 0xf0, 0x0f, 0xf0,
   0x0f, 0xf0, 0x0f, 0xf0,
   0x0f, 0xf0, 0x0f, 0xf0,
   0x0f, 0xf3, 0xcf, 0xf0,
   0x0f, 0xf3, 0xcf, 0xf0,
   0x0f, 0xf3, 0xcf, 0xf0,
   0x0f, 0xf3, 0xcf, 0xf0,
   0x0f, 0xf3, 0xcf, 0xf0,
   0x0f, 0xf3, 0xcf, 0xf0,
   0x0f, 0xf3, 0xcf, 0xf0,
   0x0f, 0xf3, 0xcf, 0xf0,
   0x0f, 0xf0, 0x0f, 0xf0,
   0x0f, 0xf0, 0x0f, 0xf0,
   0x0f, 0xf0, 0x0f, 0xf0,
   0x0f, 0xf0, 0x0f, 0xf0,
   0x0f, 0xff, 0xff, 0xf0,
   0x0f, 0xff, 0xff, 0xf0,
   0x0f, 0xff, 0xff, 0xf0,
   0x0f, 0xff, 0xff, 0xf0,
   0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00 };

void IniciarGLUT() {
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  glutInitWindowSize(600,600);
  glutInitWindowPosition(100,100);
  glutCreateWindow("Practica III,8 de OpenGL");
}

void PintarEscena() {
  glMatrixMode(GL_MODELVIEW);
  glClear(GL_COLOR_BUFFER_BIT);
  glLoadIdentity();
 
  glColor3f(1,1,1);

  glEnable(GL_POLYGON_STIPPLE);
  glPolygonStipple(patron);
  glBegin(GL_POLYGON);
   for (i=0; i< GL_PI*2; i = i + (GL_PI/precision)) {
      float x,y;
      x = 8.0f*cosf(i);
      y = 8.0f*sinf(i);
      glVertex3f(x,y,0);
   }
  glEnd();
  glDisable(GL_POLYGON_STIPPLE);

  glBegin(GL_QUAD_STRIP);
   for (i=-10; i < 11; i++) {
      float color = (i + 10)/7;
      if (color<=1.0f) glColor3f(0,0,color);
      else if ((color-1)<=1.0f) glColor3f(0,color,0);
      else glColor3f(color,0,0);

      glVertex3i(i,10,0);
      glVertex3i(i,9,0);
   }
   for (i=10; i > -11; i--) {
      float color = (i + 10)/7;
      if (color<=1.0f) glColor3f(color,0,0);
      else if ((color-1)<=1.0f) glColor3f(0,color,0);
      else glColor3f(0,0,color);

      glVertex3i(i,-10,0);
      glVertex3i(i,-9,0);
   }
  glEnd();
 
  glutSwapBuffers();
}

void ReProyectar(int w, int h) {
  GLfloat formato;

  if(h == 0) h = 1;
     
    glViewport(0, 0, w, h);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  formato = (GLfloat)w / (GLfloat)h;
    if (w <= h) glOrtho (-10.0f, 10.0f, -10.0f / formato, 10.0f / formato, -1.0f, 1.0f);
    else glOrtho (-10.0f * formato, 10.0f * formato, -10.0f, 10.0f, -1.0f, 1.0f);
}

void Flechas(int key, int x, int y) {
   switch (key) {
      case GLUT_KEY_UP: flechas[0] = 1; break;
      case GLUT_KEY_DOWN: flechas[1] = 1; break;
   }
}

void FlechasUp(int key, int x, int y) {
   switch (key) {
      case GLUT_KEY_UP: flechas[0] = 0; break;
      case GLUT_KEY_DOWN: flechas[1] = 0; break;
   }
}

void Cambiar(int value) {
   if (flechas[0]) {
      if ((precision + 1)<= 20) precision++;
   }
   if (flechas[1]) {
      if ((precision - 1)>= 2) precision--;
   }
   glutTimerFunc(200,Cambiar,1);
   glutPostRedisplay();
}

int main(int argc, char **argv) {
  glutInit(&argc,argv); //Solo necesario en Linux
  IniciarGLUT();
 
  glutReshapeFunc(ReProyectar);
  glutDisplayFunc(PintarEscena);
  glutIdleFunc(PintarEscena);
  glutSpecialFunc(Flechas);
  glutSpecialUpFunc(FlechasUp);
  glutTimerFunc(200,Cambiar,1);
 
  glutMainLoop();
    return 0;
}


Primero explicaré lo más fácil:
Código:
  glBegin(GL_QUAD_STRIP);
   for (i=-10; i < 11; i++) {
      float color = (i + 10)/7;
      if (color<=1.0f) glColor3f(0,0,color);
      else if ((color-1)<=1.0f) glColor3f(0,color,0);
      else glColor3f(color,0,0);

      glVertex3i(i,10,0);
      glVertex3i(i,9,0);
   }
   for (i=10; i > -11; i--) {
      float color = (i + 10)/7;
      if (color<=1.0f) glColor3f(color,0,0);
      else if ((color-1)<=1.0f) glColor3f(0,color,0);
      else glColor3f(0,0,color);

      glVertex3i(i,-10,0);
      glVertex3i(i,-9,0);
   }
  glEnd();
Sin tener en cuenta lo del color, para que tome esa apariencia, lo único que hay que indicar es que con GL_QUAD_STRIP, los cuatro primeros vértices forman y un nuevo cuadrilátero y cada dos nuevos que se añaden forman un nuevo cuadrilátero con los dos anteriores. Formando una "cadena" de cuadriláteros.
Lo siguiente es el polígono: GL_POLYGON.
Código:
  glEnable(GL_POLYGON_STIPPLE);
  glPolygonStipple(patron);
  glBegin(GL_POLYGON);
   for (i=0; i< GL_PI*2; i = i + (GL_PI/precision)) {
      float x,y;
      x = 8.0f*cosf(i);
      y = 8.0f*sinf(i);
      glVertex3f(x,y,0);
   }
  glEnd();
  glDisable(GL_POLYGON_STIPPLE);
Lo primero que debo explicar es que el polígono forma una sola figura con tantos vértices como indiques. Debe cumplir una regla, para que se dibuje bien su interior en el modo GL_FILL por defecto, y es que cualquier punto interno del polígono debe poder formar una linea recta con cualquier otro punto del polígono sin que esta línea se salga del polígono.
Teniendo eso en cuenta, he hecho un bucle que provoca más vértices de un círculo cuanto más aumente la variable precision.
Ahora entro en el punteado, o mapeado de pixeles. Primero, debe ser activado, al igual que el punteado de líneas, con: GL_POLYGON_STIPPLE. Al igual que el punteado de líneas, solo se dibujará en donde el patrón indique un 1, si pone 0 no se pinta.
EL patrón se indica con esta función: glPolygonStipple(patron);.
El patrón de las líneas, se repetía, aquí pasa igual, la única diferencia es que aquí cada patrón no es de 16 bits, sino de 32 bits de ancho por 32 bits de alto, indicado en hexadecimal (eso es igual que las líneas). Hay que tener en cuenta, que el patrón se lee primero desde abajo, es decir, si el patrón es este:
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x0f, 0xff, 0xff, 0xf0,
0x0f, 0xff, 0xff, 0xf0,
0x0f, 0xff, 0xff, 0xf0,
0x0f, 0xff, 0xff, 0xf0,
0x0f, 0xf0, 0x0f, 0xf0,
0x0f, 0xf0, 0x0f, 0xf0,
0x0f, 0xf0, 0x0f, 0xf0,
0x0f, 0xf0, 0x0f, 0xf0,
0x0f, 0xf3, 0xcf, 0xf0,
0x0f, 0xf3, 0xcf, 0xf0,
0x0f, 0xf3, 0xcf, 0xf0,
0x0f, 0xf3, 0xcf, 0xf0,
0x0f, 0xf3, 0xcf, 0xf0,
0x0f, 0xf3, 0xcf, 0xf0,
0x0f, 0xf3, 0xcf, 0xf0,
0x0f, 0xf3, 0xcf, 0xf0,
0x0f, 0xf0, 0x0f, 0xf0,
0x0f, 0xf0, 0x0f, 0xf0,
0x0f, 0xf0, 0x0f, 0xf0,
0x0f, 0xf0, 0x0f, 0xf0,
0x0f, 0xff, 0xff, 0xf0,
0x0f, 0xff, 0xff, 0xf0,
0x0f, 0xff, 0xff, 0xf0,
0x0f, 0xff, 0xff, 0xf0,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00

Es una especie de cuadrado que contiene a otro. La línea que se corresponde con la de más abajo es aquí la de más arriba. Esto tiene un motivo, en el eje X, se avanza hacia la derecha, y en el eje Y hacia arriba. Pero estamos acostumbrados a que la imagenes empiezan arriba a la izquierda, y en realidad empiezan desde abajo, por eso, la primera línea horizontal que escribamos es en realidad la de más abajo.
Los tamaños de estos punteados deben ser mútlpilos de 4: 16x16, 32x32, 64x64, 128,x128, 256x256...

Por último, no olvides que son píxeles, si reduces o aumentas la ventana, aparecerán más o menos patrones repetidos, pero tienen siempre el mismo tamaño.

HarZe
WebMaster & Desarrollador

Cantidad de envíos : 58
Fecha de inscripción : 21/06/2009
Edad : 24

Ver perfil de usuario http://opengl-esp.superforo.net

Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.