Android OpenGL ES: ¿Cómo se selecciona un objeto 2D?

He estado buscando una introducción a la selección 2D en OpenGL ES en el desbordamiento de pila. En general, veo preguntas sobre 3D.

Estoy diseñando un editor de nivel basado en mosaico 2D en Android 4.0.3, usando OpenGL ES. En el editor de niveles, hay un objeto 2D, amarillo, cuadrado colocado en el centro de la pantalla. Todo lo que quería era detectar si el objeto había sido tocado por un usuario.

Introduzca aquí la descripción de la imagen

En el editor de niveles, no hay ninguna superposición de mosaicos. En su lugar, se colocan lado a lado, al igual que dos píxeles cercanos en una imagen de mapa de bits en MS Paint. Mi propósito es detectar individualmente un evento táctil para cada objeto cuadrado en el editor de niveles.

El objeto se crea con una matriz de vértices simple, y utilizando GL_TRIANGLES para dibujar 2 triángulos rectos planos. No hay manipulaciones ni carga desde un archivo ni nada. Lo único que sé es que si un usuario toca cualquiera de los triángulos amarillos, entonces ambos triángulos amarillos deben ser seleccionados.

¿Podría alguien dar una pista de cómo tengo que hacer esto? Gracias por adelantado.

EDITAR:

Esta es la función draw() :

 public void draw(GL10 gl) { gl.glPushMatrix(); gl.glTranslatef(-(deltaX - translateX), (deltaY - translateY), 1f); gl.glColor4f(1f, 1f, 0f, 1f); //TODO: Move ClientState and MatrixStack outside of draw(). gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 6); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glPopMatrix(); } 

EDIT 2:

Todavía me falta algo de información. ¿Estás usando una cámara? O empujar otras matrices antes de la representación del modelo ?. Por ejemplo, si está usando una cámara ortográfica, puede desproteger fácilmente sus coordenadas de pantalla [x_screen, y_screen] de esta manera (y es análogo):

No estoy usando una cámara, pero estoy usando probablemente una proyección ortográfica. Una vez más, no sé, como sólo estoy usando una función común de OpenGL. Hago empujar y hacer estallar matrices, porque pienso en integrar muchos azulejos (los objetos cuadrados 2D) con diversas matrices de la traducción. No hay dos baldosas que tengan la misma matriz de traducción M.

¿Es una proyección de perspectiva lo mismo que la proyección ortográfica cuando se trata de 2D? No veo ninguna diferencia entre los dos.

Esta es la configuración inicial cuando se crea la superficie (una clase que extiende GLSurfaceView y que implementa GLSurfaceView.Renderer ):

 public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); } public void onSurfaceCreated(GL10 gl, EGLConfig arg1) { reset(); } public void onDrawFrame(GL10 gl) { clearScreen(gl); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrthof(0f, super.getWidth(), 0f, super.getHeight(), 1, -1); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); canvas.draw(gl); } private void clearScreen(GL10 gl) { gl.glClearColor(0.5f, 1f, 1f, 1f); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); } 

Un enfoque básico sería el siguiente:

  1. Defina una caja delimitadora para cada objeto "táctil". Esto podría ser sólo un rectángulo (x, y, ancho, altura).
  2. Cuando actualiza un mosaico en el mundo, actualiza su cuadro delimitador (completamente en coordenadas mundiales).
  3. Cuando el usuario toca la pantalla, tiene que desprotejar las coordenadas de la pantalla a las coordenadas mundiales
  4. Compruebe si el punto no proyectado se superpone con cualquier cuadro delimitador.

Algunas indirectas en artículos previos. [Editado]

  • 1 y 2. Usted debe tener que hacer un seguimiento de donde está procesando sus fichas. Almacene su posición y tamaño. Un rectángulo es una estructura conveniente. En su ejemplo podría calcularse de esta manera. Y usted tiene que recalcularlo cuando el modelo cambia. Vamos a llamar Rectángulo r:

     rx = yourTile.position.x -(deltaX - translateX) ry = yourTile.position.y -(deltaY - translateY) r.width= yourTile.width //as there is no model scaling r.height = yourTile.height// 
  • 3 – si está usando una cámara ortográfica, puede desproteger fácilmente sus coordenadas de pantalla [x_screen, y_screen] de esta manera (y es análogo):

     x_model = ((x_screen/GL_viewport_width) -0.5 )*camera.WIDTH + Camera.position.x 
  • 4 – Para cada uno de sus rectángulos, compruebe si [x_model; Y_model] está dentro de él.

[2nd Edit] Por la forma en que está actualizando sus matrices, puede considerar que está utilizando una cámara con la superficie de la pregunta surfaceView.width () / 2, surfaceView.height () / 2. Usted está emparejando 1 pixel en pantalla a 1 unidad en mundo, así que usted no necesita desproporcionar cualquier cosa. Puedes reemplazar esos valores en mi fórmula y obtener x_screen = x_model – (Tendrás que voltear el componente Y del evento táctil debido a que Y crece hacia abajo en Java y hacia arriba en GL).

Ultimas palabras. Si el usuario toca el punto [x, y], compruebe si [x, screenHeight-y] * toca algunos de sus rectángulos y ya está. Hacer un poco de depuración, registro de los puntos de contacto y ver si son como se esperaba. Generar sus rectángulos y ver si coinciden con lo que ves en la pantalla, entonces es una cuestión de comprobar si un punto está dentro de un rectángulo.

Debo decirle que usted no debe fijar la cámara a las dimensiones de la pantalla, porque su app parecerá drástico diferente en diversos dispositivos. Este es un tema por sí solo así que no voy más lejos, pero considere la definición de su modelo en términos de unidades del mundo – independiente del tamaño de la pantalla. Esto es tan fuera de tema, pero espero que haya obtenido una buena visión de lo que usted necesita saber!

* El volteo te lo dije. PS: palo con la proyección ortográfica (la perspectiva sería más compleja de usar).

Por favor, permítanme que publique una segunda respuesta a su pregunta. Esto es completamente más de alto nivel / filosófico. Puede ser una respuesta tonta e inútil, pero, espero que ayude a alguien nuevo a los gráficos de computadora a cambiar su mente a "modo gráfico".

Realmente no se puede seleccionar un triángulo en la pantalla. Ese cuadrado no es 2 triángulos. Ese cuadrado es sólo un montón de píxeles amarillos. OpenGL toma algunos vértices, los conecta, los procesa y colorea algunos píxeles en la pantalla. En una etapa en la tubería gráfica incluso la información geométrica se pierde, y sólo tiene píxeles aislados. Eso es análogo a una carta impresa por una impresora en un papel. Por lo general no procesar la información de un documento (ok, tal vez un lector de código de barras hace: D)

Si necesita procesar más sus dibujos, tiene que modelarlos y procesarlos usted mismo con estructuras de datos auxiliares. Por eso te sugerí que creas un rectángulo para modelar tus fichas. Usted crea su "mundo" imaginario de los objetos, y después los vuelve a la pantalla. El usuario del evento táctil no pertenece al mismo mundo, por lo que tiene que "traducir" coordenadas de la pantalla en sus coordenadas del mundo. Entonces usted cambia algo en su mundo (puede ser que el usuario arrastre su dedo y usted tiene que mover un objeto), y de nuevo le dice a OpenGL que su mundo a la pantalla.

Debes operar en tu modelo, no en la vista. Las mallas son más de una cosa de la visión, así que usted no debe mezclarlas con la información del modelo, es una buena práctica separar ambas cosas. (Por favor, un experto me corrija, soy un aficionado a los gráficos)

¿Ha comprobado LibGDX ?

Hace la vida mucho más fácil cuando se trabaja con OpenGL ES.

  • Android cuál es la diferencia entre getAction () y getActionMasked () en MotionEvent
  • Android: ¿Cómo permitir sólo un toque?
  • La propiedad webkitForce del evento táctil: Feedback de presión de los dedos. Buscando documentación
  • Superposición de Android para tomar todo el tacto, y pasarlos?
  • Umbral de ACTION_MOVE de Android
  • Desactivar el disparo de touchcancel en el navegador de Android
  • Cómo determinar lo que tocó la pantalla de mi dispositivo Android?
  • Cómo detener otras imágenes para moverse mientras arrastra una imagen
  • Resplandor cuando toque la pantalla en android?
  • ¿Cómo crear un imagebutton de forma irregular donde la parte transparente de la imagen no se puede hacer clic?
  • Vista de desplazamiento de Android en evento táctil
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.