Transformaciones de matrices Android de OpenGL ES

Tengo un procesador que pone en práctica la interfaz de GLSurfaceView.Renderer; Una subclase de GLSurfaceView y algunas clases que representan mis objetos que quiero dibujar. Tengo el código de http://developer.android.com/training/graphics/opengl/motion.html Quiero ampliar esto y añadir algunos moviendo a lo largo de los ejes y no puede manejarlo. El objeto sólo se gira. Y aquí está mi código:

public class NotMyCoolRenderer implements GLSurfaceView.Renderer { public GLShip mTriangle; private GLBackgroundStar mSquare; private final float[] mMVPMatrix = new float[16]; private final float[] mProjMatrix = new float[16]; private final float[] mVMatrix = new float[16]; private final float[] mModelMatrix = new float[16]; private final float[] tempMatrix = new float[16]; public void onDrawFrame(GL10 unused) { // Draw background color GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); // Set the camera position (View matrix) Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); // Calculate the projection and view transformation Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0); // Draw square mSquare.draw(mMVPMatrix); // Now moving on to triangle aka ship Matrix.setIdentityM(mModelMatrix, 0); Matrix.translateM(mModelMatrix, 0, 0.1f, 0f, 0); Matrix.rotateM(mModelMatrix, 0, mTriangle.mAngle, 0, 0, -1.0f); Matrix.multiplyMM(tempMatrix, 0, mVMatrix, 0, mProjMatrix, 0); Matrix.multiplyMM(mMVPMatrix, 0, mModelMatrix , 0, tempMatrix , 0); // Draw triangle mTriangle.draw(mMVPMatrix); } public void onSurfaceChanged(GL10 unused, int width, int height) { // Adjust the viewport based on geometry changes, // such as screen rotation GLES20.glViewport(0, 0, width, height); float ratio = (float) width / height; // this projection matrix is applied to object coordinates // in the onDrawFrame() method Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7); } public class GLShip { public volatile float mAngle; private final String vertexShaderCode = // This matrix member variable provides a hook to manipulate // the coordinates of the objects that use this vertex shader "uniform mat4 uMVPMatrix;" + "attribute vec4 vPosition;" + "void main() {" + // the matrix must be included as a modifier of gl_Position " gl_Position = uMVPMatrix * vPosition;" + "}"; public void draw(float[] mvpMatrix) { // Add program to OpenGL environment GLES20.glUseProgram(mProgram); // get handle to vertex shader's vPosition member mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); // Enable a handle to the triangle vertices GLES20.glEnableVertexAttribArray(mPositionHandle); // Prepare the triangle coordinate data GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer); // get handle to fragment shader's vColor member mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); // Set color for drawing the triangle GLES20.glUniform4fv(mColorHandle, 1, color, 0); // get handle to shape's transformation matrix mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); NotMyCoolRenderer.checkGlError("glGetUniformLocation"); // Apply the projection and view transformation GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0); NotMyCoolRenderer.checkGlError("glUniformMatrix4fv"); // Draw the triangle GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount); // Disable vertex array GLES20.glDisableVertexAttribArray(mPositionHandle); } } 

Mis expectativas son que en cada redibujo el objeto sería girado por mAngle y traslated a lo largo de Y-Axis por 1f. Puedo ver sólo girar (un poco proyectado demasiado) sin embargo. En realidad tengo algunas preguntas con respecto a eso: ¿cómo aplico mi matriz de traducción y cuál es la mejor práctica de dividir la funcionalidad opengl? ¿No debería ser el modelMatrix almacenado en el propio objeto en lugar de renderer? ¿Deberían realizarse las operaciones matriciales en la clase render? Los he agrupado desde que adivino que están todos relacionados.

He estado trabajando con el ejemplo de la formación de Android, el siguiente enfoque finalmente funciona para mí. (Basado en Android Training> Visualización de gráficos con OpenGL ES> Adición de movimiento )

  1. Utilice el sombreado de vértices correcto:

     private final String vertexShaderCode = // This matrix member variable provides a hook to manipulate // the coordinates of the objects that use this vertex shader "uniform mat4 uMVPMatrix;" + "attribute vec4 vPosition;" + "void main() {" + // the matrix must be included as a modifier of gl_Position " gl_Position = uMVPMatrix * vPosition;" + "}"; 
  2. En la clase renderer:

     public class MyGL20Renderer implements GLSurfaceView.Renderer { [...] // create a model matrix for the triangle private final float[] mModelMatrix = new float[16]; // create a temporary matrix for calculation purposes, // to avoid the same matrix on the right and left side of multiplyMM later // see https://stackoverflow.com/questions/13480043/opengl-es-android-matrix-transformations#comment18443759_13480364 private float[] mTempMatrix = new float[16]; [...] 
  3. Aplicar transformaciones en onDrawFrame , comience con la traducción :

     public void onDrawFrame(GL10 unused) { [...] Matrix.setIdentityM(mModelMatrix, 0); // initialize to identity matrix Matrix.translateM(mModelMatrix, 0, -0.5f, 0, 0); // translation to the left 
  4. Luego rotación :

     // Create a rotation transformation for the triangle long time = SystemClock.uptimeMillis() % 4000L; float mAngle = 0.090f * ((int) time); Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f); 
  5. Combine la rotación y la traducción, evite usar mModelMatrix

    "Como la misma matriz en el lado derecho e izquierdo de multiplyMM" (véase 2 )

     // Combine Rotation and Translation matrices mTempMatrix = mModelMatrix.clone(); Matrix.multiplyMM(mModelMatrix, 0, mTempMatrix, 0, mRotationMatrix, 0); 
  6. Combine la matriz del modelo con la proyección y la vista de la cámara; De nuevo evite usar mModelMatrix

    "Como la misma matriz en el lado derecho e izquierdo de multiplyMM" (véase 2 )

     // Combine the model matrix with the projection and camera view mTempMatrix = mMVPMatrix.clone(); Matrix.multiplyMM(mMVPMatrix, 0, mTempMatrix, 0, mModelMatrix, 0); 
  7. Dibuja la forma

     // Draw shape mTriangle.draw(mMVPMatrix); 

Gracias a todos, por todo el útil aporte que podría sacar de este hilo.

Si desea ver el movimiento, debe actualizar mTriangle.mAngle cada trama (preferiblemente en función del tiempo para combatir las diferencias de velocidad o los retrasos causados ​​por otros procesos …).

Tenga en cuenta que Matrix.setIdentityM (mModelMatrix, 0); Restaura todas las rotaciones y traducciones acumuladas a "cero" o en realidad a Identity Matrix … La misma convención se aplica btw a todas las funciones establecidas . Para acumular todas las transformaciones, hay que

  • SetIdentity (modelo);
  • Traducir (trans); // para obtener el origen de la rotación
  • Girar (rotmatrix); // para acumular la rotación
  • Traducir (t2); // traducir de nuevo a alguna mejor posición …

También se deben mantener los valores del vector de traducción de objeto [buey, oy, oz] entre cada llamada y alimentarlos a Matrix.translateM (mModelMatrix, ox, oy, oz, 0);

Normalmente se concatena todas las matrices de "traducción, rotación, escala", etc. lo más pronto posible y las almacena en caché por objeto, o jerárquicamente por un contenedor complejo que tiene múltiples objetos y que tiene un cuadro delimitador, La cámara (o, en general, fuera del frusto de visualización).

También típicamente se mantiene una cámara en movimiento en una matriz y por cuadro se multiplica con la matriz de proyección.

Puede comenzar con algo como:

 float Time = System.currentTimeMillis() * 0.01f; // 10 radians / second == fast! Matrix.translateM(mModelMatrix, Math.sin(Time)*2.0f, 0, 1f, 0); ... 

Tal como Tim lo notó, no hay ninguna matriz de proyección implicada, lo que significa que todos los valores z se comportan exactamente en este código, a pesar de que cambiar los valores xyy haría una diferencia.

Me atrevería a decir que la matriz MVP significaría multiplicar en orden M * V * P = (M * V) * P = M * (V * P).

Tenga en cuenta que no está aplicando su matriz de proyección al triángulo que dibuja, lo que podría causar problemas.

Probablemente sea:

 Matrix.multiplyMM(mMVMatrix, 0, mVMatrix, 0, mModelMatrix, 0); Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVMatrix, 0); 
  • Cómo dibujar / hacer una colisión de física de bala cuerpo / forma?
  • Creación de shaders OpenGL en NativeActivity
  • ¿Es posible deformar la imagen subyacente con OpenGL ES 2.0?
  • GLSurfaceView que muestra negro en Nexus 7 con Android 4.2
  • Cómo renderizar vídeo a través de openGLES2 con Android NDK
  • Transparencia de OpenGL ES 2.0 mediante pruebas alfa en shader
  • Cómo dibujar una línea punteada dinámicamente utilizando OpenGL ES 2.0 en Android mediante programación?
  • Activación de Android en silencio
  • Tamaños de textura razonables en android
  • Android OpenGL ES 2.0: No obtengo resultados que quiero con Matrix.traslateM
  • Grabación de marcos generados por Open GL ES en android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.