В среде 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. Треугольник отображается с применением проекции и камеры.
Теперь, когда у вас есть приложение, которое отображает ваши фигуры в правильных пропорциях, пора добавить движение для ваших фигур.