Mapeo Ventana-Puerto de Visión
Sistema de Coordenadas Sistema de Coordenadas Globales (datos abstractos) Sistema de Coordenadas Locales (datos abstractos) Sistema de Coordenadas de la Pantalla (pixeles) Ventana (Window), Puerto de Vision(Viewport) Mapeo Ventana-Puerto de Visión (Window to viewport Mapping )
Screen Coordinate System Glut OpenGL (0,0)
Sistema de Coordenadas de la Pantalla (Screen Coordinate System) Malla Cartesiana en 2D Origen (0,0) en esquina inferior izquierda(OpenGL) Horizontal – x Vertical – y Los Pixeles estan definidos en las Intersecciones de la malla El sistema de coordenadas esta definido con respecto al origen de la ventana (OpenGL:la esquina inferior izquierda de la ventana ) y (0,0) x (2,2)
Sistema de Coordenadas Global Las coordenadas dependen de la aplicación(mts, in, cm, etc) – es dificil trabajar directamente en la pantalla (mapear) 10 feet 20 feet
Sistema de Coordenadas Globales Otro ejemplo: graficar la función sinc: sinc(x) = sin(PI*x)/PI*x x = -4 .. +4
Sistema de Coordenadas Globales (World Coordinate System) Esta muy bien si podemos utilizar las coordenadas en el world coordinate system ( no de la pantalla) glBegin(GL_LINE_STRIP); for (x = -4.0; x <4.0; x+=0.1){ GLfloat y = sin(3.14 * x) / (3.14 * x); glVertex2f (x,y); } glEnd();
Definir una ventana en el Espacio Global (world window)
Ventana (World Window) World window – una region rectangular en el espacio global que define lo que se va a desplegar W_B W_T Definido por W_L, W_R, W_B, W_T W_L W_R Usar en OpenGL el comando: gluOrtho2D(left,right,bottom, top)
Puerto deVision (Viewport) La region rectangular en la pantalla para desplegar los objetos graficos definidos por la ventana (World window) Definido en el sistema de coordenadas de la pantalla (valores enteros) glViewport(int left, int bottom, int (right-left), int (top-bottom)); llamar esta función antes de desplegar (definir glBegin() y glEnd() ) V_L V_R V_B V_T
Para dibujar lo definido en el Espacio Global Se necesita hacer dos tareas Definir un rectangulo (ventana) en el espacio global (llamar la función de OpenGL ) Definir un viewport (llamar una función de OpenGL ) Realizar el mapeo ( window to viewport mapping) (OpenGL internamente hara esto por uno)
Ejemplo DrawQuad() { glViewport(0,0,300,200); (300,200) glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-1,1,-1,1); glBegin(GL_QUADS); glColor3f(1,1,0); glVertex2f(-0.5,-0.5); glVertex2f(+0.5,-0.5); glVertex2f(+0.5,+0.5); glVertex2f(-0.5,+0.5); glEnd(); } (300,200) (0,0) viewport
Mapeo Ventana- Puerto de Visión Los objetos en el espacio global definidos por la Ventana seran dibujados en el Puerto de Visión viewport (x,y) World window (Sx, Sy)
Mapeo Window-Viewport Como calcular (sx, sy) ? (x,y) (Sx, Sy)
Mapeo Ventana-Puerto de Visión Primera cosa para recordar – no se necesita calcular. OpenGL lo hará por uno Solo se necesita definir el viewport (con glViewport()), y la ventna el el espacio abstracto (con gluOrtho2D()) Pero veremos lo que hay detras del mapeo.
Tambien, una cosa para recordar … Un aspecto practico de OpenGL Antes de llamar a gluOrtho2D(), se necesitará dos lineas de código glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(Left, Right, Bottom, Top);
Ventana a Puerto de Vision Aspectos que estan definidos: Ventana (W_L, W_R, W_B, W_T) Puerto de Vision (V_L, V_R, V_B, V_T) (x,y) en sistema de coordenadas globales Calcular el correspondiente (sx, sy) en el sistema de coordenadas de la pantalla
Ventana a Puerto de Vision Principios basicos: el mapeo debe ser proporcional (x,y) (sx,sy) (x – W_L) / (W_R – W_L) = (sx – V_L) / (V_R – V_L) (y - W_B) / (W_T – W_B) = (sy – V_B) / (V_T – V_B)
Mapeo Ventana-Puerto de Vision (x,y) (sx,sy) (x – W_L) / (W_R – W_L) = (sx – V_L) / (V_R – V_L) (y - W_B) / (W_T – W_B) = (sy – V_B) / (V_T – V_B) sx = x * (V_R-V_L)/(W_R-W_L) - W_L * (V_R – V_L)/(W_R-W_L) + V_L sy = y * (V_T-V_B)/(W_T-W_B) – W_B * (V_T-V_B)/(W_T-W_B) + V_B
Algunos aspectos basicos Como calcular una ventana apropiada de manera automatica? Como realiza un zoom sobre la imagen? Como calcular un viewport de manera adecuada, de tal manera que no se vea distorsionada?
Calculo de la Ventana La idea básica es ver todos los objetos en el espacio del objeto Se puede tener una vista inicial y el usuario puede cambiar la vista Como obtenerlo?
Definición de la Ventana Encontrar las coordenadas extendidas en el espacio que cubra toda la escena min X max X min Y max Y
Zoom sobre la escena Viewport Definir la ventana – llamar a gluOrtho2D() con un nuevo rango Puede ser definida de manera interactiva Viewport
Viewport sin distorsión La deformación sucede cuando… La ventana en el espacio global y la ventana sobre la pantalla tienen diferentes proporciones (aspect ratios) Aspect ratio? R = W / H
Aspect Ratio: Comparacion entre el ancho y la altura de una imagen o región W Ventana Aspect Ratio = R Espacio sobre la pantalla Aspect Ratio = W / H R > W / H
Hay que conservar el aspect ratio para que no se deforme la imagen ? W Ventana Aspect Ratio = R Espacio sobre la pantalla Aspect Ratio = W / H R > W / H hay que escalar
R R > W / H glViewport(0, 0, W, W/R) W/R H W Ventana Aspect Ratio = R Espacio sobre la pantalla Aspect Ratio = W / H R > W / H glViewport(0, 0, W, W/R)
Compare aspect ratios R < W / H H W Ventana Aspect Ratio = R Espacio sobre la pantalla Aspect Ratio = W / H R < W / H
R < W / H ? H W Ventana Espacio sobre la pantalla Aspect Ratio = R Aspect Ratio = W / H R < W / H
Asociacion aspect ratios H * R H W Ventana Aspect Ratio = R Espacio sobre la Pantalla Aspect Ratio = W / H R < W / H glViewport(0, 0, H*R, H)
Cuando llamar a glViewport() ? Dos lugares: Inicialización Default: el mismo que el tamaño de la ventanas Cuando el usuario redimensiona la ventana de la pantalla
Resize (Reshape) window Void main(int argc, char** argv) { … glutDisplayFunc(display); glutReshapeFunc(resize); glutKeyboardFunc(key); } void resize () – Se llamara cuando la ventana se redimensione
Resize (reshape) window Void resize(int W, int H) { glViewport(0,0,W, H); } Esto es realizado por default por GLUT
Colocando todo junto DrawQuad() { glViewport(0,0,300,200); (300,200) glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-1,1,-1,1); glBegin(GL_QUADS); glColor3f(1,1,0); glVertex2f(-0.5,-0.5); glVertex2f(+0.5,-0.5); glVertex2f(+0.5,+0.5); glVertex2f(-0.5,+0.5); glEnd(); } (300,200) (0,0) viewport
Tambien funciona… main() OpenGL Default: { … glViewport: tan grande Como la ventana de la pantalla gluOrtho2D: gluOrtho2D(-1,1,-1,1); Cada vez que se aprende una nueva OpenGLfunction, hay que tratar de conocer sus argumentos default main() { … glBegin(GL_QUADS); glColor3f(1,1,0); glVertex2f(-0.5,-0.5); glVertex2f(+0.5,0); glVertex2f(+0.5,+0.5); glVertex2f(-0.5,+0.5); glEnd(); }