Dans l'environnement OpenGL ES, la projection et les vues de caméra vous permettent d'afficher les objets dessinés dans un qui ressemble davantage à la façon dont vous voyez des objets physiques avec vos yeux. Cette simulation de l'affichage physique se fait par le biais de transformations mathématiques des coordonnées des objets dessinés:
- Projection : cette transformation ajuste les coordonnées des objets dessinés en fonction de
la largeur et la hauteur du
GLSurfaceView
où elles sont affichées ; Sans ce calcul, les objets dessinés par OpenGL ES sont faussés par les proportions inégales de la vue fenêtre. En général, une transformation de projection ne doit être calculée que lorsque les proportions des La vue OpenGL est établie ou modifiée dans la méthodeonSurfaceChanged()
de votre moteur de rendu. Pour en savoir plus sur les projections OpenGL ES et la cartographie des coordonnées, consultez Cartographie des coordonnées Objets. - Camera View (Vue de la caméra) : cette transformation ajuste les coordonnées des objets dessinés en fonction d'un
la position de la caméra virtuelle. Il est important de noter qu'OpenGL ES ne définit pas de caméra
mais fournit à la place des méthodes utilitaires qui simulent un appareil photo en transformant l'affichage
des objets dessinés. Une transformation de vue de caméra peut être calculée une seule fois lorsque vous établissez votre
GLSurfaceView
, ou changer de façon dynamique en fonction des actions des utilisateurs ou de vos la fonction d'application.
Cette leçon explique comment créer une projection et une vue de caméra, et comment les appliquer aux formes dessinées dans
votre GLSurfaceView
.
Définir une projection
Les données d'une transformation de projection sont calculées dans onSurfaceChanged()
de la classe GLSurfaceView.Renderer
. L'exemple de code suivant
prend la hauteur et la largeur de l'élément GLSurfaceView
et l'utilise pour remplir une
transformation de projection Matrix
à l'aide de la méthode Matrix.frustumM()
:
Kotlin
// vPMatrix is an abbreviation for "Model View Projection Matrix" private val vPMatrix = FloatArray(16) private val projectionMatrix = FloatArray(16) private val viewMatrix = FloatArray(16) override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) { GLES20.glViewport(0, 0, width, height) val ratio: Float = width.toFloat() / height.toFloat() // this projection matrix is applied to object coordinates // in the onDrawFrame() method Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f) }
Java
// vPMatrix is an abbreviation for "Model View Projection Matrix" private final float[] vPMatrix = new float[16]; private final float[] projectionMatrix = new float[16]; private final float[] viewMatrix = new float[16]; @Override public void onSurfaceChanged(GL10 unused, int width, int height) { 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(projectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7); }
Ce code renseigne une matrice de projection, mProjectionMatrix
, que vous pouvez ensuite combiner
avec une transformation de vue de caméra dans la méthode onDrawFrame()
, comme illustré dans la section suivante.
Remarque:Il suffit d'appliquer une transformation de projection à vos d'objets dessinent généralement un affichage très vide. En règle générale, vous devez aussi installer la transformation d'affichage pour que tout soit affiché à l'écran.
Définir une vue de caméra
Terminez le processus de transformation de vos objets dessinés en ajoutant une transformation de vue de caméra en tant que
du processus de dessin dans votre moteur de rendu. Dans l'exemple de code suivant, la vue de la caméra
est calculée à l'aide de la méthode Matrix.setLookAtM()
.
puis combinés à la matrice de projection calculée précédemment. La combinaison
les matrices de transformation sont ensuite transmises à la forme tracée.
Kotlin
override fun onDrawFrame(unused: GL10) { ... // Set the camera position (View matrix) Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, 3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f) // Calculate the projection and view transformation Matrix.multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0) // Draw shape triangle.draw(vPMatrix)
Java
@Override public void onDrawFrame(GL10 unused) { ... // Set the camera position (View matrix) Matrix.setLookAtM(viewMatrix, 0, 0, 0, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); // Calculate the projection and view transformation Matrix.multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0); // Draw shape triangle.draw(vPMatrix); }
Appliquer des transformations de caméra et de projection
Pour utiliser la matrice de transformation combinée de la projection et de la vue de caméra présentée dans le
affiche un aperçu des sections, commencez par ajouter une variable de matrice au nuanceur de sommets défini précédemment
dans la classe Triangle
:
Kotlin
class Triangle { private val 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 // Note that the uMVPMatrix factor *must be first* in order // for the matrix multiplication product to be correct. " gl_Position = uMVPMatrix * vPosition;" + "}" // Use to access and set the view transformation private var vPMatrixHandle: Int = 0 ... }
Java
public class Triangle { 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 // Note that the uMVPMatrix factor *must be first* in order // for the matrix multiplication product to be correct. " gl_Position = uMVPMatrix * vPosition;" + "}"; // Use to access and set the view transformation private int vPMatrixHandle; ... }
Ensuite, modifiez la méthode draw()
de vos objets graphiques pour accepter la combinaison
et appliquez-la à la forme:
Kotlin
fun draw(mvpMatrix: FloatArray) { // pass in the calculated transformation matrix ... // get handle to shape's transformation matrix vPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix") // Pass the projection and view transformation to the shader GLES20.glUniformMatrix4fv(vPMatrixHandle, 1, false, mvpMatrix, 0) // Draw the triangle GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount) // Disable vertex array GLES20.glDisableVertexAttribArray(positionHandle) }
Java
public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix ... // get handle to shape's transformation matrix vPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); // Pass the projection and view transformation to the shader GLES20.glUniformMatrix4fv(vPMatrixHandle, 1, false, mvpMatrix, 0); // Draw the triangle GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount); // Disable vertex array GLES20.glDisableVertexAttribArray(positionHandle); }
Une fois que vous avez correctement calculé et appliqué les transformations de projection et de vue de caméra, vos objets graphiques sont dessinés dans des proportions correctes et doivent se présenter comme suit:
Maintenant que vous disposez d'une application qui affiche vos formes dans des proportions correctes, il est temps de ajouter du mouvement à vos formes.