OpenGL ES 2 Проекционная и фоновая коммутация - PullRequest
2 голосов
/ 29 марта 2020

У меня есть массив, содержащий высоту вершин карты местности. Когда я впервые рисую ландшафт, он выглядит хорошо:

enter image description here

Но когда я поворачиваю его по оси z, кажется, что части фигуры проецируются за вершинами сзади:

Поворот на 90 градусов (ось Z):

90 degreee rotation

~ Поворот на 180 градусов (ось Z ):

enter image description here

Помимо моей реализации карты, мой код довольно прост:

Vertex Shader:

attribute vec4 position;
attribute vec4 color;

uniform mat4 matrix;
varying vec4 interpolated_color;

void main() {
    gl_Position = matrix * position;
    interpolated_color = color;
}

Fragment_shader:

precision mediump float;

varying vec4 interpolated_color;

void main(){
   gl_FragColor = interpolated_color;
}

Renderer:

public class MapRenderer implements GLSurfaceView.Renderer {

    ...

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(1.0f, 0.0f,0.0f, 1.0f);
        map = mapGen.composeMap(); //gets array with vertices heights
        mapView = new MapView(context, map, mapGen);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
        float aspect_ratio = (float) width/height;
        Matrix.perspectiveM(projectionMatrix, 0, 45, aspect_ratio, 1f, 10f);
    }


    @Override
    public void onDrawFrame(GL10 gl) {
        float[] scratch = new float[16];

        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        Matrix.setIdentityM(modelMatrix, 0);

        Matrix.translateM(modelMatrix, 0, 0, 0, -4);
        Matrix.rotateM(modelMatrix, 0, -cameraAngle, 1, 0, 0); //cameraAngle initialized at 0 changes with user input
        Matrix.rotateM(modelMatrix, 0, mapAngle, 0, 0, 1); //mapAngle initialized at 0 changes with user input

        Matrix.multiplyMM(scratch, 0, projectionMatrix, 0, modelMatrix, 0);

        mapView.draw(scratch);
    }
}

Класс MapView:

    public void draw(float[] mvpMatrix){
        int matrix = GLES20.glGetUniformLocation(program, "matrix");

        GLES20.glUniformMatrix4fv(matrix, 1, false, mvpMatrix, 0);

        //nFaces and facesBuffer are class variables
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, nFaces*3, GLES20.GL_UNSIGNED_SHORT, facesBuffer);
    }

Я попытался включить или выключить выборку лица, чтобы увидеть, если возникли какие-либо различия, но никто не сделал. Изменение матрицы проекции также, по-видимому, не оказало никакого влияния, кроме изменения угла, при котором начинает появляться ошибка. Кажется, это происходит при ~ 90 градусов и до ~ 270 градусов при использовании Matrix.perspectiveM и точно при 90 и 270 при использовании Matrix.orthoM.

Я также проверил, возвращал ли OpenGL какие-либо ошибки glGetErrors() метод и ничего не получил.

Мои вершины сортируются в буфере последовательно от той, которая расположена в (-1, 1, 0), до последней, расположенной в (1, -1, 0). Я не знаю, могло ли это вызвать эту проблему или, даже если бы это было так, как я мог бы решить эту проблему в OpenGL ES 2, чтобы поддерживать вращение вокруг оси z.

1 Ответ

2 голосов
/ 29 марта 2020

Проверка глубины должна быть включена, чтобы OpenGL учитывал расстояние.

На рендере:

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(1.0f, 0.0f,0.0f, 1.0f);

        GLES20.glEnable(GLES20.GL_DEPTH_TEST);

        map = mapGen.composeMap(); //gets array with vertices heights
        mapView = new MapView(context, map, mapGen);
    }
...