Primitivas Básicas Dibujo en 3D • Las librerías gráficas antiguas permiten trabajar con puntos 2D (pixels) • OpenGL no trabaja con coordenadas de pantalla, sino con coordenadas posicionales dentro del volumen de visualización • El trasladar toda la escena 3D a la pantalla se realiza automáticamente y (0,100,0) (-100,0,0) (100,0,0) x (0,-100,0) z glOrtho(-100,100,-100,100,100,-100) Dibujo de puntos glBegin(GL_POINTS); glVertex3s (0, 0, 50); glVertex2f (-50.0, 50.0); glEnd(); y (-50,50,0) (0,0,50) z x Ajuste del tamaño del punto • El tamaño por defecto de un punto es 1 pixel • Podemos cambiarlo usando: void glPointSize (Glfloat tamaño) • Para conocer qué tamaños soporta nuestra distribución: Glfloat dimen[2]; // almacena el rango de tamaños Glfloat paso; // almacena los incrementos de tamaño glGetFloatv(GL_POINT_SIZE_GRANULARITY, &paso); glGetFloatv(GL_POINT_SIZE_RANGE, dimen); • Para mejorar la calidad de los puntos: void glEnable (GL_POINT_SMOOTH) Dibujo de líneas sueltas glBegin(GL_LINES); glVertex3s (0, 0, 50); glVertex2f (-50.0, 50.0); glVertex3s (0, 100, 0); glVertex3s (-100, 100, -100); glEnd(); y (-100,100,-100) (0,100,0) (-50,50,0) (0,0,50) z x Dibujo de polilíneas glBegin(GL_LINES_STRIP); glVertex3s (0, 0, 50); glVertex2f (-50.0, 50.0); glVertex3s (0, 100, 0); glVertex3s (-100, 100, -100); glEnd(); y (-100,100,-100) (0,100,0) (-50,50,0) (0,0,50) x • Para cerrar la polilínea: glBegin(GL_LINE_LOOP); ... glEnd(); z Ajuste del grosor de línea • El grosor por defecto es 1 pixel • Podemos cambiarlo usando: void glLineWidth (Glfloat ancho) • Para conocer qué tamaños soporta nuestra distribución: Glfloat dimen[2]; // almacena el rango de anchos posibles Glfloat paso; // almacena los incrementos de ancho glGetFloatv(GL_LINE_WIDTH_GRANULARITY, &paso); glGetFloatv(GL_LINE_WIDTH_RANGE, dimen); Patrones de líneas • Para dibujar líneas discontinuas primero hay que activar el modo: void glEnable (GL_LINE_STIPPLE) • Luego se indica el patrón: void glLineStipple (GLint factor, GLushort patron) patron = 0x 5 5 5 5 0101010101010101 factor = 3 Dibujo de triángulos • A partir de ahora, las líneas representan polígonos --> áreas • La mayoría del hardware 3D está optimizado para triángulos glBegin(GL_TRIANGLES); glVertex2f (-50.0, 50.0); glVertex3s (0, 100, 0); glVertex3s (-100,100,-100); ... glEnd(); (-100,100,-100) y (0,100,0) (-50,50,0) x z Caras frontales y posteriores • El sentido anti-horario indica cuál es la cara frontal • Cada cara puede tener propiedades diferentes V2 glBegin(GL_TRIANGLES); glVertex3s (); // vértice V0 glVertex3s (); // vértice V1 glVertex3s (); // vértice V2 glVertex3s (); glVertex3s (); glVertex3s (); ... glEnd(); • // vértice V3 // vértice V4 // vértice V5 Sentido antihorario V1 V0 V4 Sentido horario Para que el sentido sea al revés: void glFrontFace (GL_CW) V3 V5 Modos de dibujo • Por defecto, los polígonos se dibujan sólidos (sin aristas) • Otras opciones son: hueco con aristas o sólo mostrando los vértices • Cada cara puede mostrarse de forma diferente void glPolygonMode (GLenum cara, GLenum modo) GL_BACK GL_FRONT_AND_BACK GL_FRONT glPolygonMode (GL_FRONT, GL_FILL) GL_FILL GL_LINE GL_POINT glPolygonMode (GL_BACK, GL_LINE) V2 Mallas de triángulos • Para dibujar tiras de triángulos: glBegin(GL_TRIANGLE_STRIP); glVertex3s (); // vértice glVertex3s (); // vértice glVertex3s (); // vértice glVertex3s (); // vértice glVertex3s (); // vértice ... glEnd(); • V1 V0 V0 V1 V2 V3 V4 V2 V3 V1 V0 V4 Ventajas: V3 V2 – sólo se especifica un vértice por triángulo – mejores efectos de iluminación al sombrear la superficie total V0 V1 V2 Abanicos de triángulos • Para dibujar abanicos de triángulos: glBegin(GL_TRIANGLE_FAN); glVertex3s (); // vértice glVertex3s (); // vértice glVertex3s (); // vértice glVertex3s (); // vértice glVertex3s (); // vértice ... glEnd(); • V0 V1 V2 V3 V4 V1 V0 V3 V2 V1 V0 V3 El vértice V0 es común a todos los triángulos V4 V2 V0 V1 Cuadriláteros • y Existe hardware de aceleración para polígonos de más de 3 lados glBegin(GL_QUADS); glVertex2s (-50, 50); glVertex2s (100, 0); glVertex2s (100,100); glVertex2s (0,100); ... glEnd(); (100, 100,0) (0,100,0) (-50,50,0) (100, 0,0) //V0 //V1 //V2 //V3 z V3 • Las caras frontales siguen siendo en el sentido anti-horario V0 V2 V1 x V3 Mallas de cuadriláteros • Para dibujar tiras de cuadriláteros: V0 V2 glBegin(GL_QUAD_STRIP); glVertex3s (); // vértice glVertex3s (); // vértice glVertex3s (); // vértice glVertex3s (); // vértice glVertex3s (); // vértice glVertex3s (); // vértice ... glEnd(); V0 V1 V2 V3 V4 V5 V1 V4 V2 V5 • Ventajas: – sólo se especifican dos vértices por polígono V0 V3 – mejores efectos de iluminación al sombrear la superficie total V1 Polígonos generales • y Para cualquier número de lados (0,100,0) (100, 100,0) (0,0,0) (100, 0,0) (-50,50,0) glBegin(GL_POLYGON); glVertex2s (-50, 50); glVertex2s (0, 0); glVertex2s (100,0); glVertex2s (100,100); glVertex2s (0,100); ... glEnd(); //V0 //V1 //V2 //V3 //V4 z V4 • Las caras frontales siguen siendo en el sentido anti-horario V0 V3 V1 V2 x Relleno de polígonos • Para rellenar con un patrón primero hay que activar el modo: void glEnable (GL_POLYGON_STIPPLE) • Luego se indica el patrón de relleno: void glPolygonStipple (GLubyte bitmap[32x4]) = 0x0A 0x94 Reglas para los polígonos • Debido a la optimización de los algoritmos internos de OpenGL, existen tres restricciones para los polígonos: – Todos los polígonos deben ser planares – Las aristas no deben intersectarse – Los polígonos deben ser convexos Polígonos válidos Polígonos no válidos Subdivisión y bordes • Un polígono cóncavo puede representarse como varios convexos • Si se dibuja relleno, los bordes no se apreciarán • Si se dibuja en alambre, podemos indicar qué aristas no queremos ver: glEdgeFlag(TRUE); // a partir de aquí, las aristas son visibles glVertex3s(); ... glEdgeFlag(FALSE); // a partir de aquí, las aristas no se ven glVertex3s(); ... Visualización de objetos 3D • Las superficies de los objetos estarán formados por varias primitivas • Para resolver el problema de visibilidad glEnable (GL_DEPTH_TEST) glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) • Para acelera el proceso, podemos indicar que no se visualizen las caras traseras de los polígonos glEnable (GL_CULL_FACE) • Para desactivar una opción activada con glEnable se usa: glDisable (GL_CULL_FACE)