• No se han encontrado resultados

Laboratorio 2: Viewports e Interacción con el Mouse (en 2D) Seleccionar un área de la figura para hacer zoom.

N/A
N/A
Protected

Academic year: 2021

Share "Laboratorio 2: Viewports e Interacción con el Mouse (en 2D) Seleccionar un área de la figura para hacer zoom."

Copied!
31
0
0

Texto completo

(1)

Laboratorio 2: Viewports e

Interacción con el Mouse

(en 2D)

Seleccionar un área de la figura para

hacer zoom.

(2)

Introducción

Los vértices sufren transformaciones para pasar del mundo a la pantalla.

Estas transformaciones, las especificamos mediante matrices.

(3)

Ventana del mundo 2D

● Luego de modelar los objetos y la escena 2D (mediante transformaciones, con más matrices!!)

● Debemos seleccionar qué área de este

mundo 2D queremos mostrar.

● Esto lo hacemos especificando una matriz de proyección.

(4)

En OpenGL

● Para especificar esa matriz de proyección, se utiliza(ba):

gluOrtho2D(left, right, bottom, top);

● Ahora, nosotros debemos ocuparnos de crear la matriz. :(

● Pero OpenTK provee clases y estructuras para trabajar con matrices y vectores.

○ Estas clases poseen operadores sobrecargados

para que podamos utilizarlos más fácilmente. (+, -, *, /)

(5)

En OpenTK

Matrix4 projMat;

projMat = Matrix4.CreateOrthographicOffCenter(

left, right, bottom, top, zNear, zFar);

Con esto creamos una matriz. Resta hacer que nuestro shader (de vértices) las utilice. (Lo

vemos luego). ● Usar:

○ zNear = -1.0f; ○ zFar = 1.0f;

(6)
(7)

Viewport

● La última de las transformaciones es la de

Viewport.

● La transformación de viewport especifica en qué región de la pantalla será dibujada la escena. (en nuestro caso, en qué región del GLControl)

● Al trabajar sobre la pantalla, las

coordenadas son números enteros (pixels). (A diferencia de las coordenadas de la

(8)

En OpenGL

En OpenGL especificamos la información del viewport mediante:

glViewport(x, y, width, height);

OpenTK sobrecarga este método:

GL.Viewport(x, y, width, height); GL.Viewport(rectangle);

GL.Viewport(point, size); GL.Viewport(size);

(9)

Viewport

Coordenadas de la ventana (mi glControl), según OpenGL x y (x,y) h w

(10)

Relación de aspecto

● Relación de aspecto = ancho / alto

○ Si la región del mundo que queremos dibujar tiene una relación de aspecto distinta a la del viewport, veremos nuestra escena deformada.

○ Debemos preocuparnos por definir el viewport con la misma relación de aspecto que la ventana 2D.

(11)
(12)

¿Cómo lo logramos?

Tenemos que dibujar la misma figura 2 veces: Primero:

● Una ventana 2D que abarque a toda la figura.

● Un viewport a la izquierda. Segundo:

● Una ventana que abarque sólo una parte de la figura.

(13)

Pseudocódigo

void On_Paint(){ ... SetearViewport(viewport1); SetearVentana(projMatrix1); figura.Dibujar(); SetearViewport(viewport2); SetearVentana(projMatrix2); figura.Dibujar(); ... }

(14)

Pseudocódigo

● Podemos utilizar dos variables de tipo

Rectangle (System.Drawing) para guardar información de los viewports.

● Y dos variables de tipo OpenTK.Matrix4 para las matrices de proyección.

Rectangle viewport1 = new ...; Rectangle viewport2 = new ...;

Matrix4 projMat1 = Matrix4.CreateOrthog..; Matrix4 projMat2 = Matrix4.CreateOrthog...;

(15)

Pseudocódigo

¿Dónde actualizamos los valores de los viewports?

void glControl1_Resize(..){

//Sacar las cuentas en función de glControl1.Width //glControl1.Height y el aspectRatio de la ventana viewport1.X = ...; // 2D viewport1.Y = ...; viewport1.Width = ...; viewport1.Height = ...; viewport2.X = ...; ... glControl1.Invalidate(); };

(16)

Shaders

Las matrices que utilicemos para aplicarle transformaciones a nuestros datos, se las tenemos que enviar a nuestro shader (de vértices).

En este caso, le vamos a asignar dos matrices:

○ La matriz de ModelView; ○ La matriz de Proyeccion;

La transformación del Viewport la realiza OpenGL (esa es fácil).

(17)

Shaders (vértices)

in vec2 vPosition; //Una posicion en 2D

uniform mat4 mViewMatrix;

uniform mat4 projMatrix; void main(){

vec4 vPos = vec4(vPosition, 0.0, 1.0);

gl_Position = projMatrix * mViewMatrix * vPos; }

La posición ahora se ve afectada por las transformaciones de ModelView y de Proyección.

Aparecen variables uniformes.

(18)

Shaders

Cuando se linkea el programa de shader, se crean (entre otras cosas) dos tablas con

índices (location) para las variables de entrada.

● Indices para las variables in (llamadas atributos de vértice)

● Indices para las variables uniform.

(vertex Attributes) (Uniform variables) Location Name Location Name

0 vPosition 0 mViewMatrix 1 projMatrix

(19)

Shaders

Sólo podemos asignar valor a las variables de un shader a través de su location.

Podemos obtener estos índices con:

int GL.GetAttribLocation(program, attrName);

int GL.GetUniformLocation(program, uniformName);

En nuestro caso:

int mvmLoc; int pLoc;

mvmLoc = GL.GetUniformLocation(prog, "vViewMatrix"); pLoc = GL.GetUniformLocation(prog, "projMatrix");

(20)

Shaders

Para asignarle valores a las variables uniform del shader existen varias funciones de la

forma:

GL.Uniform*(location, value);

En nuestro caso usamos:

GL.UniformMatrix4(mvmLoc, Matrix4.Identity); GL.UniformMatrix4(pLoc, projMatrix1);

● Para la matriz ModelView usamos la identidad. (Todavía no utilizamos

(21)

Pseudocódigo

void On_Paint(){ ... GL.Viewport(viewport1); GL.UniformMatrix4(mvmLoc, Matrix4.Identity); GL.UniformMatrix4(pLoc, projMatrix1); figura.Dibujar(); GL.Viewport(viewport2); GL.UniformMatrix4(pLoc, projMatrix2); figura.Dibujar(); ... }

(22)

Interacción con el Mouse

● Ya tenemos medio laboratorio.. ;)

● Falta hacer que el área de zoom se pueda elegir interactivamente con el mouse.

● El componente GLControl (al igual que

todos los componentes de Windows) tiene el evento Click(...) que se dispara cuando se

realiza un click de mouse sobre el componente.

● Peeero, las coordenadas que reporta, ¿en que espacio están?

(23)

OpenGL vs Windows

x

y x

y

(24)

Unproject

● Los vértices se fueron transformando, hasta llegar a coordenadas de pantalla.

● Ahora quiero el camino inverso, es decir, a partir de una posición en pantalla,

determinar a qué posición en el mundo corresponde.

(25)

Unproject

● De eso se encarga(ba) la función

gluUnproject(...);

● Esta función no está disponible en OpenTK. La tenemos que implementar!

● Consultar la documentación de esta

función, para comprender bien el significado de los parámetros.

(26)

Unproject

Vector3 UnProject(Vector3 win,

Matrix4 mViewMat, Matrix4 projMat,

Rectangle viewport) {

Vector3 resul = Vector3.Zero; Vector4 _in = Vector4.Zero; Vector4 _out = Vector4.Zero; Matrix4 oneMatrix;

//Combinamos las dos matrices y las invertimos. oneMatrix = Matrix4.Multiply(mViewMat, projMat); oneMatrix.Invert();

(27)

Unproject (cont.)

_in.X = win.X; _in.Y = win.Y; _in.Z = win.Z; _in.W = 1.0f;

//Map x and y from window coordinates.

_in.X = (_in.X - viewport.X) / viewport.Width;

_in.Y = (_in.Y - viewport.Y) / viewport.Height; //Map to range -1 to 1.

_in.X = _in.X * 2 - 1; _in.Y = _in.Y * 2 - 1; _in.Z = _in.Z * 2 - 1;

(28)

Unproject (cont.)

//Antitransformamos.

_out = Vector4.Transform(_in, finalMatrix); if ((_out.W > float.Epsilon) ||

(_out.W < -float.Epsilon)) {

_out.X = _out.X / _out.W; _out.Y = _out.Y / _out.W; _out.Z = _out.Z / _out.W; }else{

throw new Exception("UnProject: No pudo antitransformar.");

(29)

Unproject (cont.)

resul.X = _out.X; resul.Y = _out.Y; resul.Z = _out.Z; return resul; };

Este método lo vamos a utilizar en el manejador del evento Click();

(30)

Metodo On_Click

void glControl1_Click(EventArgs e){

MouseEventArgs mea = (MouseEventArgs)e; int x = mea.X;

int y = glControl1.Height - mea.Y;

Vector3 winPos = new Vector3(x, y, 0.0f); Vector3 worldPos;

worldPos = UnProject(winPos, mViewMat, projMat1, viewport1);

//Modificar projMat2 usando worldPos (...) glControl1.Invalidate();

(31)

Pseudocódigo - Método Paint()

void glControl1_Paint(){ GL.Clear(...);

Activar el programa de shader;

Asignarle valor a la matriz ModelView del shader Asignarle valor a la matriz Projection del shader SetearViewport(viewport1);

figura.Dibujar();

Asignarle valor a la matriz Projection del shader SetearViewport(viewport2);

figura.Dibujar();

Referencias

Documento similar

Ciaurriz quien, durante su primer arlo de estancia en Loyola 40 , catalogó sus fondos siguiendo la división previa a la que nos hemos referido; y si esta labor fue de

Volviendo a la jurisprudencia del Tribunal de Justicia, conviene recor- dar que, con el tiempo, este órgano se vio en la necesidad de determinar si los actos de los Estados

(29) Cfr. MUÑOZ MACHADO: Derecho público de las Comunidades Autóno- mas, cit., vol. Es necesario advertir que en la doctrina clásica este tipo de competencias suele reconducirse

Una nueva decisión del Tribunal Europeo de Dere- chos Humanos va a permitir a ese Tribunal con- tinuar por el camino iniciado en el Caso Pretty c. Suiza en dar contenido al derecho

el de 1991 (LOGSE) el alumno podía cursar hasta 5 materias científicas: entre las 6 de modalidad (Física, Matemáticas y Dibujo Técnico o Química, Biología y Cien- cias de la Tierra

El núcleo de la estrategia de la UE esbozada en la sección 2 —que es el apoyo al fortalecimiento de los sistemas nacionales de salud en los PMA— podría lograrse esencialmente

b) El Tribunal Constitucional se encuadra dentro de una organiza- ción jurídico constitucional que asume la supremacía de los dere- chos fundamentales y que reconoce la separación

La recuperación histórica de la terciaria dominica sor María de Santo Domingo en los últimos años viene dada, principalmente, por causa de su posible influjo sobre personajes