OpenGL ES Android Transformations de Matrice
J'ai un convertisseur de mise en œuvre de GLSurfaceView.Convertisseur d'interface; une sous-classe de GLSurfaceView et certaines classes représentant mes objets, je tiens à attirer. J'ai le code de http://developer.android.com/training/graphics/opengl/motion.html
Je veux élargir cette et ajouter un peu de mouvement le long des axes et ne pouvez pas le gérer. L'objet n'est que de la rotation.
et voici mon code:
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);
}
}
Mes attentes sont que sur chaque redessiner l'objet est mis en rotation par la mutilation et traslated le long de l'Axe Y par 1f. Je ne peux voir qu'en rotation (un peu projeté trop) bien.
J'ai effectivement eu quelques questions concernant:
comment puis-je demander ma traduction de la matrice et
quelle est la meilleure pratique de la division de la fonctionnalité opengl? Ne faudrait-il pas modelMatrix être stockés dans l'objet lui-même plutôt que dans le moteur de rendu? Si la matrice opérations exécutées dans le moteur de rendu de classe?
J'ai regroupés comme je suppose qu'ils sont tous liés.
Voici un dernier conseil: essayez de reproduire étape par étape les leçons de learningwebgl.com/blog/?page_id=1217 . Elle ne couvre que le javascript, mais les différences sont à côté des minimes. L'API est la même et la matrice de calcul est le même. Bonne chance!
Dans un autre thread les gens suggéré (pour le même code de la même tutoriel) à l'aide de
gl_Position = uMVPMatrix * vPosition;
au lieu de gl_Position = vPosition * uMVPMatrix;
. Si j'ai suivi la suggestion, je ne peux pas voir mon triangle à tousVous devez également calculer le MVP de la matrice dans l'ordre de M,V,P. Vous devez calculer actuellement dans l'ordre de P,V,M
cela ne résout absolument pas le problème. Je ne peux pas voir mon triangle avec M*V*P) à tous
OriginalL'auteur Michael T | 2012-11-20
Vous devez vous connecter pour publier un commentaire.
Ive été de travailler avec l'exemple de l'Android à la Formation, l'approche suivante, enfin, fonctionne pour moi. (Basé sur L'affichage Graphique avec OpenGL ES > Ajout d'une trajectoire">Android de Formation > Affichage Graphique avec OpenGL ES > Ajout d'une trajectoire)
Utiliser le bon vertex shader:
Dans la classe de rendu:
Appliquer des transformations dans onDrawFrame, commencer avec traduction:
Puis rotation:
Combiner la rotation et la translation, éviter d'utiliser mModelMatrix
Combiner le modèle de la matrice de la projection et de la vue de la caméra; encore éviter l'utilisation de mModelMatrix
Dessiner la forme
Merci à vous tous, pour toutes les contributions utiles que je pouvais en tirer de ce fil.
Dans le cas où il aide à quelqu'un d'autre qui vient à travers cette réponse, la partie qui n'était pas évident pour moi, c'était que la Matrice.multiplyMM modifie la destination de la matrice pendant calcul, pas après. Donc, si vous voulez multiplier mvp par rotation, et mettre le résultat dans mvp, allant de la Matrice.multiplyMM(mMVPMatrix, 0, mMVPMatrix, 0, mModelMatrix, 0) sera mutation mMVPMatrix à la volée, résultant dans un étrange calcul. C'est pourquoi le clone travaux ci-dessus. Pour ma part, j'ai été en mesure de calculs en "chaîne" en basculant entre les deux "zéro" matrices, par exemple: pastebin.com/h7c9Ktg9
OriginalL'auteur escalator
Si vous voulez voir de mouvement, vous devez mettre à jour mTriangle.marquer chaque image (de préférence en fonction du temps pour lutter contre les différences de vitesse ou des retards causés par d'autres procédés...).
Remarque que la Matrice.setIdentityM(mModelMatrix, 0); restaure tous le cumul des rotations et des translations à "zéro" ou fait à la Matrice Identité...
De la même convention s'applique btw à tous ensemble fonctions.
Pour accumuler toutes les transformations, on doit
Aussi il convient de garder les valeurs de l'objet vecteur de translation [ox,oy,oz] entre chaque appel et de les nourrir à la Matrice.translateM(mModelMatrix, ox, oy, oz, 0);
Généralement on concatène tous " translation, rotation, échelle, etc. les matrices dès que possible et de les mettre en cache par objet, ou de façon hiérarchique par un complexe récipient avec de multiples objets et d'avoir une zone de délimitation, de sorte que plusieurs objets peuvent être sélectionnées lors de la derrière la caméra (ou plus généralement à l'extérieur de l'affichage frustum).
Aussi généralement on garde d'un mouvement de caméra dans une matrice et par image se multiplie avec la matrice de projection.
Vous pouvez commencer avec quelque chose comme:
Comme Tim remarqué, il n'existe pas de matrice de projection impliqués, ce qui signifie que toutes les valeurs z de se comporter dans ce code exactement, même si le changement de x & y aurait une différence.
Je serais tenté de dire, que le MVP de la matrice signifierait multipliant
afin de M * V * P = (M*V) * P = M * V*P).
C'est parce qu'il y est ce setRotate à la place de la Matrice.rotateM. (ou ce qu'il est en Android GLES de l'API)
J'ai maintenant
Matrix.setIdentityM(mModelMatrix, 0); Matrix.setIdentityM(mMVPMatrix, 0); Matrix.translateM(mModelMatrix, 0, 1f, 0f, 0); Matrix.rotateM(mModelMatrix, 0, mTriangle.mAngle, 0, 0, -1.0f); Matrix.multiplyMM(tempMatrix, 0, mVMatrix, 0, mModelMatrix, 0); Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, tempMatrix, 0);
et encore voir de rotation autour de l'Axe Z uniquement et pas de n'importe quel autre mouvement. Merci pour l'astuce de traduire les objets à l'origine. Je vais aborder ce problème, après je gère pour déplacer l'objet dans l'origine.Je ne vois pas pourquoi la traduction ne fonctionne pas (à moins que votre appareil photo = mVMatrix suit le triangle...) Qu'avez-vous à mProjMatrix?
j'ai mis à jour mon exemple de code dans la question. Vous pourriez peut-être prendre un coup d'oeil.
OriginalL'auteur Aki Suihkonen
Remarque que vous n'avez pas l'application de votre matrice de projection pour le triangle vous êtes le dessin, qui pourraient causer des problèmes.
Devrait probablement être:
Matrix.multiplyMM(mVMatrix, 0, mVMatrix, 0, mModelMatrix, 0)
? Si oui, je peut encore voir la rotation seulement. Pas de traduction.Autant que je sache, Vous ne pouvez pas avoir la même matrice sur le côté droit et gauche de la multiplyMM: Cependant, les valeurs des éléments ne sont pas définis si le résultat de la superposition d'éléments soit de gauche ou de rhs éléments.. J'ai défini une nouvelle matrice, le "ModelView' de la matrice, pour tenir le résultat temporaire de la vue*modèle de multiplication.
fait la même chose que vous avez défini une matrice temporaire. Toujours le même problème, comme prévu.
OriginalL'auteur Tim