[Tutorial] III.5 - Punteado de lineas: glLineStipple()

Ver el tema anterior Ver el tema siguiente Ir abajo

[Tutorial] III.5 - Punteado de lineas: glLineStipple()

Mensaje  HarZe el Jue Jul 30, 2009 9:29 pm

III.5 Punteado de lineas: glLineStipple()
Novedades:
  • glEnable() / glDisable()
  • glLineStipple()


Lo más complejo de este tutorial no es la función para el punteado, si cómo se hace el punteado.
Primero explicaré el código sin centrarme en el patrón que sigue el punteado, ya que en el código apenas hay nada nuevo. Con las flechas arriba y abajo, cambias el factor de aumento o disminución del patrón, con la flecha derecha cambias el patrón.

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

#define F_UP 0
#define F_DOWN 1

#define PATRON_COMPLETO 0xffff
#define PATRON_POCO_ESPACIADO 0xeeee
#define PATRON_ESPACIADO 0x5555
#define PATRON_MUY_ESPACIADO 0x1111

int flechas[2];
GLint factor = 1;
GLushort patron = 0x5555;
/*    Es un número de 16 bits (4 bytes) y el punteado se define por ceros y unos
*   0 - no se pinta
*   1 - se pinta
*   En el caso de 0x5555 en binario es:
*   5 en binario es 0101    0,1, 10 es 2 ,11 es 3, 100 es 4, 101 es 5
*   Pero lo que importa es el dibujo que crea:
*   0101 0101 0101 0101
*   Que significa: punteado puro.
*   Para obtener otro tipo de dibujo primero haz en binario, algo como esto:
*   1110 1110 1110 1110
*   Que da una sepación más debil, 1110 es 14, en hexadecimal 14 es E
*   El patrón que sale es 0xeeee                                 */

void IniciarGLUT() {
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  glutInitWindowSize(600,600);
  glutInitWindowPosition(100,100);
  glutCreateWindow("Practica III,5 de OpenGL");
 
  glEnable(GL_LINE_STIPPLE); //Activar el punteado de líneas
}
   
void PintarEscena() {
   glMatrixMode(GL_MODELVIEW);
   glClear(GL_COLOR_BUFFER_BIT);
   glLoadIdentity();
   
   glColor3f(0,0,0);
   glRectf(-10,-10,10,10);
   
   glColor3f(1,1,1);
   glLineStipple(factor,patron);
   
   glBegin(GL_LINE_STRIP); // G
      glVertex3i(-1,5,0);
      glVertex3i(-4,5,0);
      glVertex3i(-4,-5,0);
      glVertex3i(-1,-5,0);
      glVertex3i(-1,-2,0);
      glVertex3i(-2,-2,0);
   glEnd();
   
   glBegin(GL_LINE_STRIP); // L
      glVertex3i(2,5,0);
      glVertex3i(2,-5,0);
      glVertex3i(5,-5,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) {
   if (key==GLUT_KEY_UP) flechas[F_UP]=1;
   if (key==GLUT_KEY_DOWN) flechas[F_DOWN]=1;
   if (key==GLUT_KEY_RIGHT) {
      switch (patron) {
         case PATRON_ESPACIADO: patron = PATRON_POCO_ESPACIADO; break;
         case PATRON_POCO_ESPACIADO: patron = PATRON_COMPLETO; break;
         case PATRON_COMPLETO: patron = PATRON_MUY_ESPACIADO; break;
         case PATRON_MUY_ESPACIADO: patron = PATRON_ESPACIADO; break;
      }
   }
}

void FlechasUp(int key, int x, int y) {
   if (key==GLUT_KEY_UP) flechas[F_UP]=0;
   if (key==GLUT_KEY_DOWN) flechas[F_DOWN]=0;
}

void CambiarLineas(int value) {
    if (flechas[F_UP]) if ((factor + 1)<=25) factor++;
   if (flechas[F_DOWN]) if ((factor - 1)>=1) factor--;
   
   glutTimerFunc(33,CambiarLineas,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(33,CambiarLineas,1);
 
  glutMainLoop();
    return 0;
}

En cuanto al código, no es difícil, primero hay que activar el punteado, al iniciar el programa (aunque podemos activar/desactivar ésta y otras características en cualquier momento) con glEnable(GL_LINE_STIPPLE);. Y para usar el punteado, usamos la función: glLineStipple(factor,patron);, aquí nos paramos. El primer argumento es el factor de escalado del patrón, cuanto más alto, más se alarga el patrón, para esto hay que entender cómo es un patrón, aquí viene lo importante del tutorial, cómo son los patrones.
Un patrón es un fragmento de punteado de línea que se repite, esto se hace a través del sistema binario (viene un poco comentado en el código, pero igualmente lee esto): donde 0 es no pintar y 1 es pintar. En grupo de 16 bits (4 bytes), que es un entero largo (en OpenGL es GLushort,y representa el patrón.
Cojo un ejemplo del código, escrito en hexadecimal, puesto así pues cada dos letras hexadecimales es un bytes, analicemos: 0xeeee
Hexadecimal: 0xeeee
En binario es: 1110 1110 1110 1110
El programa lee el número binario, del revés, primero el final, con lo cual este patrón es así:

Para hacer los patrones, tendrás que hacerlo a mano en binaro, pensar en que se dará la vuelta al aplicar, y pasarlo a hexadecimal es mi consejo, pero vale cualquier número, ya que se pasará a binario de todas formas.
El factor, si es 1, cada dato binario ocupará un pixel, si el factor es 5, ocupará 5 y en total 16*5 = 80. Es algo a tener en cuenta.

HarZe
WebMaster & Desarrollador

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

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.