Primitivas OpenGL

Primitivas en OpenGL mat-610 Primitivas geométricas en OpenGL v1 v0 v2 v1 v2 v4 v7 v3 v5 v6 GL_POINTS v0 v2

Views 141 Downloads 0 File size 1MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Primitivas en OpenGL mat-610

Primitivas geométricas en OpenGL

v1 v0

v2 v1

v2

v4

v7 v3

v5

v6 GL_POINTS

v0

v2

v4

v2

v1 GL_LINE_STRIP

v3

v4

v0

v3

v0 v 2

v4

GL_TRIANGLES

v1

v3 GL_TRIANGLE_STRIP

v0 v1 GL_TRIANGLE_FAN

v0

v0

v6

v2 v5

v4

v1

v2 v4 v1 GL_QUADS

v5

v4

v1

GL_LINE_LOOP

v6

v7

v3

v2 v3

v4

GL_LINES

v5

v1

v3

v5

v4

v2

v3

v4

v0

v0

v0

v2 v1

v5 v3 GL_QUAD_STRIP

v7

v3 GL_POLYGON

Limpiar la ventana •

La memoria de despliegue almacena generalmente datos antes de dibujar.



¿Por qué no solo dibujar un rectángulo del tamaño y color de la imágen? •

porque el comando de limpieza está optimizado,



la forma del área de despliegue puede ser diferente a un rectángulo.

glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT );

Documentación OpenGL

void glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha );

Sets the current clearing color for use in clearing color buffers in RGBA mode. The red, green, blue and alpha values are clamped if necessary to the range [0,1]. The default clearing color is (0, 0, 0, 0), which is black.

Especificar un color en OpenGL set_current_color( red ); draw_object( A ); draw_object( B ); set_current_color( green ); set_current_color( blue ); draw_object( C );

glColor3f( glColor3f( glColor3f( glColor3f( glColor3f( glColor3f( glColor3f( glColor3f(

0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0,

0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0,

0.0 0.0 0.0 1.0 0.0 1.0 1.0 1.0

); ); ); ); ); ); ); );

// // // // // // // //

black red green blue yellow magenta cyan white

OpenGL como máquina de estados void glEnable( GLenum capability ); void glDisable( GLenum capability ); ej. GL_BLEND, GL_DEPTH_TEST, GL_FOG, GL_LIGHTING...

GLboolean glIsEnabled( GLenum capability ); regresa GL_TRUE o GL_FALSE.

void void void void void

glGetBooleanv( GLenum pname, GLBoolean *params ); glGetIntegerv( GLenum pname, GLint *params ); glGetFloatv( GLenum pname, GLfloat *params ); glGetDoublev( GLenum pname, GLdouble *params ); glGetPointerv( GLenum pname, GLvoid **params );

Tamaño del punto (default es 1.0) void glPointSize( GLfloat size );

Ancho de la línea (default es 1.0) void glLineWidth( GLfloat width );

Patrón de líneas punteadas void glLineStipple( GLint factor, GLushort pattern ); glLineStipple( 1, 0x00FF ); glEnable( GL_LINE_STIPPLE );

0 0 1 1 1 1 1 1 0 0 0 0 0 1 1 1

PATTERN

FACTOR

0x3F07

1

0x00FF

1

0x00FF

2

0x0C0F

1

0x0C0F

3 7

0x3F07

Ejemplo libro rojo 2-5 (en la página web)

Polígonos como puntos, contornos o sólidos •

Un polígono tiene dos lados, frente y atrás: puede dibujarse diferente dependiendo qué lado mira el usuario.



Por default se dibujan igual.

void glPolygonMode( GLenum face, GLenum mode ); face: GL_FRONT_AND_BACK, GL_FRONT, GL_BACK mode: GL_POINT, GL_LINE, GL_FILL glPolygonMode( GL_FRONT, GL_FILL ); glPolygonMode( GL_BACK, GL_LINE );

Polígonos en OpenGL •

Por convención los polígonos cuyos vértices aparecen en orden contrario a las manecillas del reloj (CCW) en la pantalla se dicen orientados hacia el frente (front-facing).



La mayoría de los sólidos pueden representarse con polígonos de orientación consistente (orientable manifolds) - esfera, toros, teteras, conejos, etc...



no orientados - botella de klein, banda de Möbius...

Polígonos en OpenGL void glFrontFace( GLenum mode ); mode: GL_CCW, GL_CW.



Culling - operación que evita desplegar ciertas caras del polígono, las de adentro o las de afuera, dependiendo de la posición de la cámara.

void glCullFace( GLenum mode ); mode: GL_FRONT, GL_BACK, GL_FRONT_AND_BACK glEnable( GL_CULL_FACE ); glDisable( GL_CULL_FACE );

Polígonos en OpenGL •

Un polígono puede dibujarse con un patrón de 32x32 bits.



El argumento es una máscara de 0s y 1s. Cuando aparece 1 se dibuja el pixel, si es 0 no dibuja.

void glPolygonStipple( GLubyte * mask ); glEnable( GL_POLYGON_STIPPLE ); glDisable( GL_POLYGON_STIPPLE );

0x06 0x03 0x00 0x00 128

64

32

16

8

4

2

1

* para cada byte el bit más significativo va primero

Ejemplo libro rojo 2-6 (en la página web)

13

Polígonos no-convexos en OpenGL •

Se dividen los polígonos no-convexos en partes convexas. v2

v1 v0

void glEdgeFlag( GLboolean flag );

glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); glBegin( GL_POLYGON ); glEdgeFlag( GL_TRUE ); glVertex3fv( v0 ); glEdgeFlag( GL_FALSE ); glVertex3fv( v1 ); glEdgeFlag( GL_TRUE ); glVertex3fv( v2 ); glEnd();

Vectores normales •

Vector que apunta en la dirección perpendicular a una superficie (plana).



Si la superficie es curva la dirección normal puede ser diferente en cada punto.



En OpenGL se puede especificar una normal por polígono o por vértice.



Los vectores normales a un objeto definen la orientación de su superficie, en particular relativamente a las fuentes de luz. (capítulo 5) •

se usan para determinar cuánta luz recibe en cada vértice. (apéndice E)

glBegin( GL_POLYGON ); glNormal3fv( n0 ); glVertex3fv( v0 ); glNormal3fv( n1 ); glVertex3fv( v1 ); glNormal3fv( n2 ); glVertex3fv( v2 ); glNormal3fv( n3 ); glVertex3fv( v3 ); glEnd();

glEnable( GL_NORMALIZE );

Algunos tutoriales

http://user.xmission.com/~nate/tutors.html

int main(int argc, char** argv) { glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowSize(512+GAP*3, 512+GAP*3); glutInitWindowPosition(50, 50); glutInit(&argc, argv); window = glutCreateWindow("Fog"); glutReshapeFunc(main_reshape); glutDisplayFunc(main_display); glutKeyboardFunc(main_keyboard); world = glutCreateSubWindow(window, GAP, GAP, 256, 256); glutReshapeFunc(world_reshape); glutDisplayFunc(world_display); glutKeyboardFunc(main_keyboard); screen = glutCreateSubWindow(window, GAP+256+GAP, GAP, 256, 256); glutReshapeFunc(screen_reshape); glutDisplayFunc(screen_display); glutKeyboardFunc(main_keyboard); glutCreateMenu(screen_menu); glutAddMenuEntry("Models", 0); glutAddMenuEntry("", 0); glutAddMenuEntry("Soccerball", 's'); glutAddMenuEntry("Al Capone", 'a'); glutAddMenuEntry("F-16 Jet", 'j'); glutAddMenuEntry("Dolphins", 'd'); glutAddMenuEntry("Flowers", 'f'); glutAddMenuEntry("Porsche", 'p'); glutAddMenuEntry("Rose", 'r'); glutAttachMenu(GLUT_RIGHT_BUTTON);

command = glutCreateSubWindow(window, GAP+256+GAP, GAP+256+GAP, 256, 256); glutReshapeFunc(command_reshape); glutDisplayFunc(command_display); glutMotionFunc(command_motion); glutMouseFunc(command_mouse); glutKeyboardFunc(main_keyboard); glutCreateMenu(command_menu); glutAddMenuEntry("Fog", 0); glutAddMenuEntry("", 0); glutAddMenuEntry("[l] GL_LINEAR", 'l'); glutAddMenuEntry("[e] GL_EXP", 'e'); glutAddMenuEntry("[x] GL_EXP2", 'x'); glutAddMenuEntry("[c] Clear color toggle", 'c'); glutAddMenuEntry("[r] Reset parameters", 'r'); glutAddMenuEntry("", 0); glutAddMenuEntry("Quit", 27); glutAttachMenu(GLUT_RIGHT_BUTTON); redisplay_all(); glutMainLoop(); return 0; }

Algoritmos de conversión de primitivas geométricas (raster conversion) mat-610

Algoritmos básicos

Un software de raster aproxima los primitivos descritos (líneas, puntos, polígonos) en una malla Cartesiana, con pixels de la intensidad de gris o color apropiado. Los pixels se almacenan como un bitmap o pixmap en memoria del CPU o en un frame buffer. Examinaremos algoritmos en términos de una grilla Cartesiana de enteros, pero se pueden extender a algoritmos con punto flotante o a 3 dimensiones.

Pipeline de salida Cada primitiva se convierte en pixels que se escriben en el cuadro que corresponde con los atributos especificados. La primitiva es ajustada o cortada (clipped) al rectángulo especificado: los pixels fuera del rectángulo no se despliegan. cortar la primitiva antes de ser dibujada calculando analíticamente sus intersecciones con el rectángulo. ¿ventajas? solo hay que trabajar con la primitiva cortada, la original puede ser mucho más grande. para cortar se usan principalmente líneas, rectángulos y polígonos.

Conversión de segmentos de recta

B = (xb , yb )

B P

A = (xa , ya )

Punto en una recta:

A

dy

dx = xb

xa

dy = yb

ya

m=

dy dx

xa )

dx(y

dx

F (x, y) = 0, con F (x, y) = dy(x

ya )

Punto a la izquierda o a la derecha de la recta: F (xm , ym ) < 0, izquierda del segmento [A, B] dirigido de A a B F (xm , ym ) > 0, derecha del segmento [A, B] dirigido de A a B

Conversión de segmentos de recta B P

A

dx = xb

xa

dy = yb

ya

dy

dx

F (x, y) = 0, con F (x, y) = dy(x

dy m= dx

xa )

dx(y

Sea un punto P = (xp,yp) de la recta R y que tenga por abcisa: xp = xa +

x

Sustituyendo para verificar en la ecuación de arriba tenemos: 0 = F (xp , yp ) = dy (xp = dy (xa +

De donde obtenemos:

ya )

dy. x = dx(yp ya ) dy yp = ya + . x dx yp = ya + m x

xa ) x

dx (yp xa )

ya ) dx (yp

ya )

Conversión de segmentos de recta Los objetos geométricos en una imágen son aproximaciones discretas de ideales continuos. Se necesitan métodos eficaces para pasar de los objetos ideales a la discretización con la que será representada la imágen. Suponemos contar con una primitiva: void QImage::setPixel ( int x, int y, uint index_or_rgb )

que permite dibujar el pixel (x,y) del color rgb y por el momento queremos dibujar solamente segmentos de recta. Nos limitaremos a dibujar segmentos de grosor 1. Tomaremos solo pendientes entre -1 y 1, las demás las calcularemos por simetría.

Conversión de segmentos de recta La secuencia de pixels debe estar lo más cerca posible de la línea “ideal” Consideramos una línea de 1 pixel de ancho: si la pendiente está entre -1 y 1, 1 pixel debe estar iluminado en cada columna. si la pendiente está fuera de este rango 1 pixel debe estar iluminado en cada renglón. todas las líneas deben dibujarse con brillo constante, independientemente de su largo y orientación y lo más rápido posible. preveer otros anchos, tipos de pluma, tipo de puntos extremos, etc.