[Tutorial] III.8 - Polígonos, circunferencias, mapas de bits y cadenas de QUAD
Página 1 de 1.
[Tutorial] III.8 - Polígonos, circunferencias, mapas de bits y cadenas de QUAD
III.8 - Polígonos, circunferencias, mapas de bits y cadenas de QUAD
Novedades:
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.
Primero explicaré lo más fácil:
Lo siguiente es el polígono: GL_POLYGON.
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:
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.
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();
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);
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
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.
Temas similares
» [Tutorial] II.3 - glutTimerFunc()
» [Tutorial] II.4 - glutKeyboardFunc()
» [Tutorial] II.2 - glutReshapeFunc()
» [Tutorial] II.5 - glutSpecialFunc()
» [Tutorial] II.6 - glutMouseFunc()
» [Tutorial] II.4 - glutKeyboardFunc()
» [Tutorial] II.2 - glutReshapeFunc()
» [Tutorial] II.5 - glutSpecialFunc()
» [Tutorial] II.6 - glutMouseFunc()
Página 1 de 1.
Permisos de este foro:
No puedes responder a temas en este foro.
|
|