2016-08-16 3 views
0

Ich versuche, ein 3D-Android-Spiel mit der OpenGL-Bibliothek zu erstellen. Soweit ich das beurteilen kann, stellt die Android-Plattform (oder OpenGL) kein Kamera-Objekt zur Verfügung, also habe ich mein eigenes gemacht. Ich habe es geschafft, ein Quadrat zu erstellen, das auf dem Bildschirm gezeichnet wird. Es gelang mir auch, die Kamera ohne Probleme in alle drei Richtungen zu bewegen. Das Problem, das ich habe, ist, wenn ich die Kamera entweder in der X- oder Y-Achse drehe, wird das Quadrat auf eine sehr seltsame Weise angezeigt. Es scheint ihre Perspektive stark verzerrt zu sein. Hier einige BilderÄndern der Kamera Vorwärtsvektor hat seltsame Ergebnisse in Android OpenGL

Kamera am Ursprung nach vorn suchen: Position [0,0,0.55f], Vorwärts [0,0, -1], Bis [0,1,0]

No transformations on the camera, at the origin

Kamera nach rechts bewegt: Position [3,0,0.55f], Vorwärts [0,0, -1], bis [0,1,0]

Camera moved to the right, so object to the left

Kamera drehte sich leicht nach rechts: Position [0,0,0,55f], Vorwärts [0,05f, 0, -1], Hoch [0,1,0]

Camera turned to the right, while at the origin

Ich bin nicht sicher, wo das Problem generiert wird. Hier sind die Ecken des Platzes:

static float vertices[] = { 
     // Front face (CC order) 
     -1.0f, 1.0f, 1.0f, // top left 
     -1.0f, -1.0f, 1.0f, // bottom left 
     1.0f, -1.0f, 1.0f, // bottom right 
     1.0f, 1.0f, 1.0f, // top right 
}; 

Von dem, was ich gelesen habe, meine Matrix-Multiplikationen in der richtigen Reihenfolge sind. Ich gehe die Matrices an den Vertex-Shader und tun die Multiplikationen dort:

private final String vertexShaderCode = 
     "uniform mat4 uVMatrix;" + 
     "uniform mat4 uMMatrix;" + 
     "uniform mat4 uPMatrix;" + 
     "attribute vec4 aVertexPosition;" +  // passed in 
     "attribute vec4 aVertexColor;" + 
     "varying vec4 vColor;" + 
     "void main() {" + 
     " gl_Position = uPMatrix * uVMatrix * uMMatrix * aVertexPosition;" + 
     " vColor = aVertexColor;" + // pass the vertex's color to the pixel shader 
     "}"; 

Das Modell Matrix bewegt er sich nur auf den Ursprung und macht es Maßstab 1:

Matrix.setIdentityM(ModelMatrix, 0); 
Matrix.translateM(ModelMatrix, 0, 0, 0, 0); 
Matrix.scaleM(ModelMatrix, 0, 1, 1, 1); 

ich meine Kamera-Objekt verwenden, zu aktualisieren die Ansicht Matrix:

Matrix.setLookAtM(ViewMatrix, 0, 
      position.x, position.y, position.z, 
      position.x + forward.x, position.y + forward.y, position.z + forward.z, 
      up.x, up.y, up.z); 

Hier ist meine ProjectionMatrix:

float ratio = width/(float) height; 

Matrix.frustumM(ProjectionMatrix, 0, -ratio, ratio, -1, 1, 0.01f, 10000f); 

Was fehlt mir?

Antwort

1

Mit den Parametern Sie frustrumM() passieren:

Matrix.frustumM(ProjectionMatrix, 0, -ratio, ratio, -1, 1, 0.01f, 10000f); 

Sie haben eine extrem starke Perspektive. Dies ist der Grund, warum die Geometrie sehr verzerrt aussieht, sobald Sie sie nur leicht drehen.

Die links, rechts, unten und oben Werte sind Abstände in der Tiefe von der nahen Abschneideebene gemessen.B. für Ihren oberen Wert Wert von 1.0, mit dem Wert 0.bei 0.01, die obere Ebene des Ansichtsvolumens bewegt sich in einem Abstand von 1,0 entfernt von der Blickrichtung in einer Vorwärtsentfernung von 0,01.

Bei der Berechnung erhalten Sie atan (oben/nahe) = atan (1,0/0,01) = atan (100,0) = 89,42 Grad für den halben vertikalen Blickwinkel oder 178,85 Grad für den gesamten Blickwinkel, was entspricht eine extreme Fischaugenlinse auf einer Kamera, die fast den gesamten Raum vor der Kamera abdeckt.

Um eine vernünftigere Perspektive zu verwenden, können Sie die Werte basierend auf dem gewünschten Ansichtswinkel berechnen. Mit alpha wobei der vertikalen Betrachtungswinkel:

float near = 0.01f; 
float top = tan(0.5f * alpha) * near; 
float right = top * ratio; 
Matrix.frustumM(ProjectionMatrix, 0, -right, right, -top, top, near, 10000f); 

Beginne mit Sichtwinkeln im Bereich von 45 bis 60 Grad für eine allgemein ansprechende Menge der Perspektive. Und denken Sie daran, dass die oben verwendete Funktion tan() Winkel im Bogenmaß verwendet, also müssen Sie sie zuerst konvertieren, wenn der ursprüngliche Winkel in Grad ist. Wenn Sie Angst vor Mathe haben, können Sie stattdessen immer perspectiveM() verwenden. ;)

1

Je nach Setup ist der Vertex-Puffer möglicherweise falsch. Ihr Vertices-Array ist ein vec3. Und die Attributposition in Ihrem Shader ist ein vec4.

Auch Sie Projektion Matrix ist seltsam, je nach dem Seitenverhältnis, das Sie wollen, werden Sie bizarre Ergebnisse bekommen.

Sie sollten stattdessen perspectiveM verwenden.

+0

In Bezug auf Vertices Array ist ein vec3 und der Shader ist ein vec4, ich folgte den Android-Tutorials und wenn ich die Form in 3D drehen funktioniert es gut, so glaube ich nicht, es ist das Quadrat selbst, das ist das Problem – robev

+0

As Nun, die Tutorials sagen frustumM zu verwenden, wenn Sie ein 3D-Spiel machen, und dies sind die Parameter, um es zu geben, ich werde perspectiveM testen, aber ich denke nicht, dass das etwas ändern wird – robev

+0

perspectiveM funktioniert..Die Frage ist, warum doesn ' t Kegelstumpf? https://developer.android.com/training/graphics/opengl/projection.html sagt, es zu verwenden ... – robev