[Tutorial] III.1 Dibujar figuras, los puntos

Ver el tema anterior Ver el tema siguiente Ir abajo

[Tutorial] III.1 Dibujar figuras, los puntos

Mensaje  HarZe el Miér Jul 29, 2009 4:43 pm

A partir de ahora, en el bloque III hablaremos de cómo dibujar figuras, 2D y 3D, hasta ahora, para no entrar en este tema, solo usaba rectángulos (glRectf()) con una función que los hace automáticos. Pero para no estar limitado, puedes hacer exactamente lo que te de la gana, pero eso si, punto a punto.

Para ir entendiendo el dibujado, debemos entender dónde dibujamos. Para ello, voy a explicar qué es un buffer. Un buffer es un espacio reservado para almacenar datos, cuando iniciamos nuestro programa con GLUT. Hasta ahora hemos usado un buffer, el de color, el más básico (GLUT_RGB), que guarda el color de cada pixel, que es el único buffer que nosotros vamos a ver. Es decir, cuando dibujamos, el programa calcula que pixeles se pintará, y de qué color. Y al final es lo que vemos. El resto de bufferes tiene otras funciones que ya veremos, y siempre recordar que es el buffer de color el que siempre vemos, el resto son para cálculos. El siguiente que veremos es el de profundidad, para el 3D. También añado que al poner GLUT_DOUBLE, habrá el doble de bufferes, uno para calcular, mientras el otro se muestra.

III.1 Dibujar puntos GL_POINTS
Novedades:
  • glBegin()
  • glEnd()
  • glColorXX()
  • glVertexXX()


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

float tamanno = 1.0f;
int up, down;
int alto, ancho;

void IniciarGLUT() {
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  glutInitWindowSize(600,600);
  glutInitWindowPosition(100,100);
  glutCreateWindow("Practica III,1 de OpenGL");
}
   
void PintarEscena() {
   glMatrixMode(GL_MODELVIEW);
   glClear(GL_COLOR_BUFFER_BIT);
   glLoadIdentity();

   glColor3f(1.0f,1.0f,1.0f);
   glRectf(-5.0f,-5.0f,5.0f, 7.0f);
   
   glBegin(GL_POINTS);
      glColor3f(0.5f,0.0f,0.0f);
      glVertex3f(-2.0f,5.0f,0.0f);
      glVertex3f(-2.0f,3.0f,0.0f);
      glVertex3f(-2.0f,1.0f,0.0f);
      glVertex3f(-2.0f,-1.0f,0.0f);
      glVertex3f(-2.0f,-3.0f,0.0f);
      glVertex3f(0.0f,1.0f,0.0f);
      glVertex3f(2.0f,5.0f,0.0f);
      glVertex3f(2.0f,3.0f,0.0f);
      glVertex3f(2.0f,1.0f,0.0f);
      glVertex3f(2.0f,-1.0f,0.0f);
      glVertex3f(2.0f,-3.0f,0.0f);
   glEnd();
   
   glutSwapBuffers();
}

void ReProyectar(int w, int h) {
   ancho = w;
   alto = 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*tamanno, 10.0f*tamanno, -10.0f*tamanno / formato, 10.0f*tamanno / formato, 1.0f, -1.0f);
    else glOrtho (-10.0f*tamanno * formato, 10.0f*tamanno * formato, -10.0f*tamanno, 10.0f*tamanno, 1.0f, -1.0f);
}

void Zoom(int value) {
   if (up) tamanno = tamanno * 1.01f;
   if (down) tamanno = tamanno / 1.01f;
   
   ReProyectar(ancho,alto);
    glutTimerFunc(33,Zoom,1);
    glutPostRedisplay();
}

void Flechas(int key, int x, int y) {
   if (key==GLUT_KEY_UP) up = 1;
   if (key==GLUT_KEY_DOWN) down = 1;
}

void FlechasUp(int key, int x, int y) {
   if (key==GLUT_KEY_UP) up = 0;
   if (key==GLUT_KEY_DOWN) down = 0;
}

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

A parte de enesñar como se dibujan puntos, hay otra cosa que quiero demostrar con este programa, que los puntos, son pixeles, da igual si están lejos o cerca, siempre tendrán el mismo tamaño. Unas capturas muestran de que hablo:

De cerca, los puntos son apenas visibles con respecto al rectángulo blanco.

Más lejos, parece una ficha de dominó, los puntos ahora se nota mucho más. De hecho si alejamos mucho más el rectángulo, veremos todo nergro.

El programa en sí, es sencillo, y tiene un sistema para controlar el tamaño del sistema de coordanadas. Es decir, el rectángulo es siempre igual, pero cada vez, el tamaño de la zona a mostrar es mas grande, y por lo tanto el rectángulo se hace cada vez más pequeño. Como no existe una función como glutPostRedisplay() para el "Reshape", dentro de la función controlada por tiempo glutTimerFunc(), obligo a que se cambie el tamaño si es necesario con ReProyectar(ancho,alto);. El ancho y alto, lo obtengo de la función asignada a glutReshapeFunc(), pues a través de las variables w y [h/i], es la única manera de saber las dimensiones actuales de la pantalla.

Ahora lo importante de este tutorial: los puntos. Examinemos la función asignada a [i]glutDisplayfunc()
, que es en la que nos vamos a fijar casi siempre desde ahora.
Código:
void PintarEscena() {
   glMatrixMode(GL_MODELVIEW);
   glClear(GL_COLOR_BUFFER_BIT);
   glLoadIdentity();

   glColor3f(1.0f,1.0f,1.0f);
   glRectf(-5.0f,-5.0f,5.0f, 7.0f);
   
   glBegin(GL_POINTS);
      glColor3f(0.5f,0.0f,0.0f);
      glVertex3f(-2.0f,5.0f,0.0f);
      glVertex3f(-2.0f,3.0f,0.0f);
      glVertex3f(-2.0f,1.0f,0.0f);
      glVertex3f(-2.0f,-1.0f,0.0f);
      glVertex3f(-2.0f,-3.0f,0.0f);
      glVertex3f(0.0f,1.0f,0.0f);
      glVertex3f(2.0f,5.0f,0.0f);
      glVertex3f(2.0f,3.0f,0.0f);
      glVertex3f(2.0f,1.0f,0.0f);
      glVertex3f(2.0f,-1.0f,0.0f);
      glVertex3f(2.0f,-3.0f,0.0f);
   glEnd();
   
   glutSwapBuffers();
}
Voy a profundizar un poco, glMatrixMode(GL_MODELVIEW); determina el modo de cálculo para las matrices (todo OpenGL funciona con matrices de 16 elementos, ya hablaremos de ello), en este caso MODELVIEW: modelado.
glClear(GL_COLOR_BUFFER_BIT); ordena limpiar el buffer de color, conviene hacerlo para que la anterior imagen no interfiera, en el caso de que no haya orden de pintar sobre toda la pantalla. Más tarde veremos la utilidad.
glLoadIdentity();, consideralo un RESET de la matriz, es decir, ubicarnos en la posición 0,0,0 en XYZ, sin rotar ni trasladar. Cuando veamos las transformaciones en el bloque IV, lo usaremos más de una vez. Por ahora, digamos que conviene resetear, porque sino los cambios de la vez anterior se acumulan y no resultaría todo como queremos. (Ya veremos que en OpenGL los cambios son acumulativos).
glColor3f(1.0f,1.0f,1.0f); El color que a partir de ahora, se aplicará a cualquier cosa que se dibuje (hasta que indiquemos otro color), es blanco (todos los colores al máximos son blanco).
glRectf(-5.0f,-5.0f,5.0f, 7.0f); El rectángulo blanco sobre el que irán los puntos.
glBegin(GL_POINTS); A partir de ahora, cada vez que vayamos a pintar puntos, lineas o polígonos en 2D o 3D. Necesitamos indicar que tipo de forma dibujamos, desde ahora, podremos dar vértices, que se leeran de uno en uno, cada uno un puntos. (En caso de lineas, se leen a pares; triángulos a trios, y así...). Hasta cerrarlo con glEnd().
glColor3f(0.5f,0.0f,0.0f); El color desde ahora será granate.
glVertex3f(-2.0f,5.0f,0.0f); Es uno de los puntos. Esta función, indica la posición XYZ, primero X, luego Y y Z en este caso es inútil en 2D.
glEnd(); Se acaba el dibujado de puntos, o de lo hubiese sido.
glutSwapBuffers() Intercambia los bufferes, desde ese momento, calcularemos en el otro y por fuerza, se mostrará el buffer de color que acabamos de calcular.

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.