OpenGL ES Android-Matrix-Transformationen
Ich habe einen renderer implementieren GLSurfaceView.Renderer-Schnittstelle; eine Unterklasse von GLSurfaceView und einige Klassen repräsentieren meine Objekte, die ich zeichnen will. Ich habe den code von http://developer.android.com/training/graphics/opengl/motion.html
Ich möchte zu erweitern, und fügen Sie einige Bewegung entlang der Achsen und können es nicht verwalten. Das Objekt wird nur gedreht.
und hier ist mein 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);
}
}
Meine Erwartungen sind, dass auf jedem Neuzeichnen wäre das Objekt gedreht werden, indem Sie zerfleischen und traslated entlang der Y-Achse von 1f. Ich sehe nur drehen (ein bisschen projiziert auch) wenn.
Ich habe tatsächlich einige Fragen zu:
wie kann ich meine übersetzung matrix und
was ist die beste Praxis der Aufteilung der opengl-Funktionalität? Sollte nicht die modelMatrix gespeichert werden, in das Objekt selbst eher als renderer? Sollten matrix-Operationen werden durchgeführt in der renderer-Klasse?
Ich habe gruppiert Sie zusammen, da ich vermute, dass Sie alle verwandt.
- Hmm. immer noch nichts, zu erklären, wie mProjMatrix initialisiert wird.
- Hier ist noch ein letzter Tipp: versuchen Sie zu replizieren, Schritt für Schritt die lehren aus der learningwebgl.com/blog/?page_id=1217 . Es deckt nur javascript, aber die Unterschiede sind neben minimal. Die API ist die gleiche und die matrix-Mathematik ist die gleiche. Viel Glück!
- In einem anderen thread Menschen vorgeschlagen (für den gleichen code für die gleiche übung) mit
gl_Position = uMVPMatrix * vPosition;
stattgl_Position = vPosition * uMVPMatrix;
. Wenn ich den Vorschlag Folgen, ich kann nicht sehen, mein Dreieck alle - Sie sollten auch die Berechnung der MVP-matrix in der Reihenfolge von M,V,P. berechnen Sie es derzeit in der Größenordnung von P,V,M
- auch dies das problem nicht lösen. Ich kann nicht sehen, mein Dreieck mit M*(V*P) an alle
- Ich habe einen Hinweis nicht auf Ihre Frage. Bitte verwenden Sie nicht
Matrix.rotateM()
imonDrawFrame()
- es weist extra 16 Schwimmern. Eine solche Zuweisung von Speicher auf jedem draw-frame-iteration hat einen erheblichen Einfluss auf die performance. Lesen Sie meine Hinweise zu diesem hier: androidworks-kea.blogspot.com/2012/05/... und code-Beispiele hier: groups.google.com/group/android-developers/browse_thread/thread/... - wie in der Frage genannten, habe ich den code von einem google-tutorial, aber danke.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ive arbeiten bei dem Beispiel aus dem Android-Ausbildung, wurde der folgende Ansatz funktioniert endlich bei mir. (Basierend auf Anzeige von Grafiken mit OpenGL ES > Hinzufügen Motion">Android-Ausbildung > Anzeige von Grafiken mit OpenGL ES > Hinzufügen von Bewegung)
Verwenden Sie das entsprechende vertex-shader:
In der renderer-Klasse:
Anwenden von Transformationen in onDrawFrame, beginnen Sie mit übersetzung:
Dann rotation:
Kombinieren rotation und translation, vermeiden Sie die Verwendung mModelMatrix
Kombinieren Sie die Modell-matrix mit den Projektions-und Kamera-Ansicht; wieder vermeiden Sie die Verwendung mModelMatrix
Zeichnen Sie die Form
Danke an Euch alle, für all die wertvollen Beiträge, die ich ziehen konnte aus diesem thread.
Wenn Sie sehen wollen Bewegung, Sie sollten aktualisieren mTriangle.zerfleischen jeden frame (vorzugsweise als eine Funktion der Zeit zur Bekämpfung von Geschwindigkeits-Unterschiede oder Verzögerungen, die durch andere Prozesse,...).
Beachten Sie, dass die Matrix.setIdentityM(mModelMatrix, 0); stellt alle angesammelten Drehungen und übersetzungen für "null" oder tatsächlich an Identity Matrix...
Die gleiche Konvention gilt btw für alle set Funktionen.
Sammeln Sie alle Transformationen, man muss
Außerdem sollte man immer die Werte des Objekt-übersetzung-Vektor [ox,oy,oz] zwischen den einzelnen rufen und füttern Sie an die Matrix.translateM(mModelMatrix, ox, oy, oz, 0);
Typischerweise verkettet alle 'verschieben, drehen, skalieren, etc. Matrizen so früh wie möglich und cache pro Objekt oder pro hierarchisch komplexe container mit mehreren Objekten und mit einer bounding-box, so dass mehrere Objekte können gekeult, wenn hinter der Kamera (oder in der Regel außerhalb der Betrachtung Pyramidenstumpf).
Auch in der Regel hält man eine bewegliche Kamera in einer matrix und pro Bild multipliziert mit der Projektions-matrix.
Können Sie beginnen, mit so etwas wie:
Als Tim bemerkt, es ist keine Projektion-matrix eingebunden, so dass alle z-Werte Verhalten sich in dieser code genau, obwohl ändern x & y-Werte würde einen Unterschied machen.
Ich würde geneigt sein, zu sagen, dass die MVP-matrix würde bedeuten multiplizieren
um M * V * P = (M*V) * P = M * (V*P).
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);
und sehe immer noch die Drehung um die Z-Achse nur die und keine andere Bewegung. Danke für den Tipp mit der übersetzung der Objekte um den Ursprung. Ich werde dieses problem anzugehen, nach dem ich es Schaffe, Sie um das Objekt zu bewegen aus dem Ursprung.Beachten Sie, dass Sie nicht die Anwendung Ihre Projektions-matrix auf das Dreieck, das Sie gerade zeichnen, das könnte zu Problemen führen.
Sollte wohl sein:
Matrix.multiplyMM(mVMatrix, 0, mVMatrix, 0, mModelMatrix, 0)
? Wenn ja, ich kann immer noch sehen, rotation nur. Keine übersetzung.