2013-03-17 10 views
6

Tak więc wygenerowałem sferę w OpenGL ES (konkretnie, OpenGL ES 2.0, w Javie, dla Androida). Kiedy ta kula jest umieszczona w tej samej pozycji, co środek używany do mojej matrycy widokowej, jest w porządku, ale gdy jest poza środkiem, kula jest bardzo źle wypaczona (patrz poniżej).(OpenGL ES) Obiekty z dala od centrum widoku są rozciągnięte

Dlaczego tak się dzieje i jak mogę to zatrzymać?

enter image description here

To ten sam kulę. Ten w prawym górnym rogu jest po prostu przetłumaczony na x i y (nie z).

Niektóre fragmenty kodu z mojego wykonania GLSurfaceView.renderer,

public void onSurfaceCreated(GL10 unused, EGLConfig config) { 
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    GLES20.glEnable(GLES20.GL_CULL_FACE); 
    GLES20.glEnable(GLES20.GL_DEPTH_TEST); 

    // Both centred on (0,0,0), of radius 1.0. 
    outerSphere = new Sphere(); 
    centreSphere = new Sphere(); 
} 

public void onSurfaceChanged(GL10 unused, int width, int height) { 
    GLES20.glViewport(0, 0, width, height); 

    ratio = (float) width/height; 

    final float left = -ratio; 
    final float right = ratio; 
    final float bottom = -1.0f; 
    final float top = 1.0f; 
    final float near = 1.0f; 
    final float far = 100.0f; 

    Matrix.frustumM(projMatrix, 0, left, right, bottom, top, near, far); 
} 

public void onDrawFrame(GL10 unused) { 
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); 

    float eyeX = 0.0f; 
    float eyeY = 0.0f; 
    float eyeZ = 10.0f; 

    final float lookX = 0.0f; 
    final float lookY = 0.0f; 
    final float lookZ = 0.0f; 

    final float upX = 0.0f; 
    final float upY = 1.0f; 
    final float upZ = 0.0f; 

    Matrix.setLookAtM(viewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, 
         upX, upY, upZ); 

    // Set identity matrix as input for translations. 
    Matrix.setIdentityM(outerModelMatrix, 0); 

    // Translate outer sphere by 5 in x and y. 
    Matrix.translateM(outerModelMatrix, 0, 5.0f, 5.0f, 0.0f); 

    // MVP matrix = Projection * View * Model. 
    Matrix.multiplyMM(centreMVPMatrix, 0, viewMatrix, 0, centreModelMatrix, 0); 
    Matrix.multiplyMM(centreMVPMatrix, 0, projectionMatrix, 0, centreMVPMatrix, 0); 
    Matrix.multiplyMM(outerMVPMatrix, 0, viewMatrix, 0, outerModelMatrix, 0); 
    Matrix.multiplyMM(outerMVPMatrix, 0, projectionMatrix, 0, outerMVPMatrix, 0); 

    outerSphere.draw(outerMVPMatrix); 
    centreSphere.draw(outerMVPMatrix); 

} 

A moi shadery są prosto,

private final static String vertexShaderCode = 
    "uniform mat4 u_MVPMatrix;" + 
    "attribute vec4 a_Position;" + 
    "uniform vec4 u_Color;" + 
    "void main() {" + 
    " gl_Position = u_MVPMatrix * a_Position;" + 
    "}"; 
private final static String fragmentShaderCode = 
    "precision mediump float;" + 
    "uniform vec4 u_Color;" + 
    "void main() {" + 
    " gl_FragColor = u_Color;" + 
    "}"; 

Zostawiłam się prawie cały kod z klasy kula, i inne rzeczy, które moim zdaniem nie są konieczne (?), ale jeśli są potrzebne, to je wymyślę.

Odpowiedz

5

Witamy w świecie perspective distortion!

Trochę więcej szczegółów: twoje pole widzenia jest zbyt wąskie, będziesz musiał kształtować stożek, aby był nieco większy.

+3

Aha! A teraz wiem, czego szukam, oczywiście informacje są łatwo dostępne (np. Podobne pytania na przepełnieniu stosu.) Dla każdego, kto się z tym spotka, zobacz np. Http://stackoverflow.com/a/8891510/927046 i http://stackoverflow.com/a/13270443/927046.) Dzięki. – Sam

+1

Wiedza o tym, co dla Google jest często najtrudniejsze :) Cieszę się, że mogę wskazać ci właściwy kierunek. –

+0

Należy również dodać, że moim zdaniem problemem było zbyt * szerokie * pole widzenia. Musiał być węższy (z aparatem umieszczonym na boku ojca, aby to zrekompensować). – Sam