Применение проекции и положения камеры

В среде OpenGL ES, проекция и положение камеры позволяют отображать объекты таким образом, чтобы больше напоминать то, как вы видите физические объекты собственными глазами. Такое моделирование физического просмотра осуществляется на основе математических преобразований координат объектов:

  • Проекция - Это преобразование корректирует координаты рисуемых объектов на основе ширины и высоты GLSurfaceView , где они отображаются. Без этих расчетов, объекты отображаемые на OpenGL ES будут искажены из-за неравных пропорций окна просмотра. Преобразование проекции обычно необходимо рассчитывать только тогда, когда пропорции OpenGL представления установлены или изменены в onSurfaceChanged() методе вашего визуализатора. Дополнительные сведения о OpenGL ES проекциях и системе координат, см. Система координат при рисовании объектов.
  • Положение камеры - Это преобразование корректирует координаты рисуемых объектов, основанных на положении виртуальной камеры. Важно отметить, что OpenGL ES не определяет фактический объект камеры, а вместо этого предоставляет служебные методы, которые имитируют камеру путем преобразования отображения рисуемых объектов. Преобразование положения камеры может быть вычислено один раз, когда вы устанавливаете ваш GLSurfaceView, или может изменяться динамически на основе действий пользователя или функциональности вашего приложения.

Этот урок описывает, как создать проекцию, задать положение камеры и применить их к фигурам, отображаемых в вашем GLSurfaceView.

Определение проекции

Данные для преобразования проекции рассчитываются в onSurfaceChanged() методе вашего GLSurfaceView.Renderer класса. Следующий пример кода принимает высоту и ширину GLSurfaceView и использует их для преобразования проекции при заполнении Matrix с помощью Matrix.frustumM() метода:

@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
    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(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}

Этот код заполняет матрицу проекции, mProjectionMatrix которую затем можно объединить с преобразованием положения камеры в onDrawFrame() методе, который показан в следующем разделе.

Примечание: Простое применение преобразование проекции для ваших графических объектов, как правило, приводит к очень пустому экрану. В общем, необходимо также применить преобразование положения камеры для того, чтобы что-нибудь отобразилось на экране.

Определение положения камеры

Завершите процесс трансформации ваших объектов, добавив преобразование положение камеры как часть процесса рисования. В следующем примере кода, преобразование положение камеры вычисляется с помощью Matrix.setLookAtM() метода, а затем объединяется с ранее рассчитанной матрицы проекции. Объединенные матрицы преобразования затем передаются в рисуемую фигуру.

@Override
public void onDrawFrame(GL10 unused) {
    ...
    // Set the camera position (View matrix)
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

    // Draw shape
    mTriangle.draw(mMVPMatrix);
}

Применение преобразований проекции и камеры

Чтобы объединить матрицы преобразования проекции и положения камеры, показанные в предыдущих разделах, измените draw() метод ваших графических объектов, что бы они принимали комбинированную матрицу преобразований и применяли её к фигуре:

public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
    ...

    // get handle to shape's transformation matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

    // Pass the projection and view transformation to the shader
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

    // Draw the triangle
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
    ...
}

После того как вы правильно рассчитаете и примените преобразования проекции и положения камеры, ваши графические объекты начнут отображаться в правильных пропорциях, и это должно будет выглядеть следующим образом:

Рисунок 1. Треугольник отображается с применением проекции и камеры.

Теперь, когда у вас есть приложение, которое отображает ваши фигуры в правильных пропорциях, пора добавить движение для ваших фигур.