OpenGL ES 환경에서 투영 및 카메라 보기를 사용하면 육안으로 실제 객체를 보는 것과 더 비슷한 방식으로 그린 객체를 표시할 수 있습니다. 이 실제 보기 시뮬레이션은 그린 객체의 좌표를 수학적으로 변환하여 실행됩니다.
- 투영 - 이 변환은 그린 객체가 표시되는
GLSurfaceView
의 너비와 높이를 기준으로 그린 객체의 좌표를 조정합니다. 이 계산이 없으면 뷰 창의 비율이 같지 않으면 OpenGL ES에서 그린 객체가 기울어집니다. 일반적으로 투영 변환은 OpenGL 뷰의 비율이 설정되거나 렌더기의onSurfaceChanged()
메서드에서 변경될 때만 계산해야 합니다. OpenGL ES 투영 및 좌표 매핑에 관한 자세한 내용은 그린 객체의 좌표 매핑을 참고하세요. - 카메라 뷰 - 이 변환에서는 가상 카메라 위치를 기반으로 그린 객체의 좌표를 조정합니다. OpenGL ES는 실제 카메라 객체를 정의하는 것이 아니라 그린 객체의 표시를 변환하여 카메라를 시뮬레이션하는 유틸리티 메서드를 제공한다는 점에 유의해야 합니다. 카메라 뷰 변환은
GLSurfaceView
를 설정할 때 한 번만 계산되거나 사용자 작업 또는 애플리케이션의 함수에 따라 동적으로 변경될 수 있습니다.
이 과정에서는 투영과 카메라 뷰를 만들어 GLSurfaceView
에 그린 도형에 적용하는 방법을 설명합니다.
프로젝션 정의
투영 변환 데이터는 GLSurfaceView.Renderer
클래스의 onSurfaceChanged()
메서드에서 계산됩니다. 다음 코드 예에서는 GLSurfaceView
의 높이와 너비를 가져와 Matrix.frustumM()
메서드로 투영 변환 Matrix
을 채웁니다.
Kotlin
// vPMatrix is an abbreviation for "Model View Projection Matrix" private val vPMatrix = FloatArray(16) private val projectionMatrix = FloatArray(16) private val viewMatrix = FloatArray(16) override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) { GLES20.glViewport(0, 0, width, height) val ratio: Float = width.toFloat() / height.toFloat() // this projection matrix is applied to object coordinates // in the onDrawFrame() method Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f) }
Java
// vPMatrix is an abbreviation for "Model View Projection Matrix" private final float[] vPMatrix = new float[16]; private final float[] projectionMatrix = new float[16]; private final float[] viewMatrix = new float[16]; @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(projectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7); }
이 코드는 투영 행렬인 mProjectionMatrix
를 채웁니다. 그러면 다음 섹션에 나오는 onDrawFrame()
메서드에서 이 행렬을 카메라 뷰 변환과 결합할 수 있습니다.
참고: 그리기 객체에 투영 변환을 적용하기만 하면 일반적으로 빈 화면이 표시됩니다. 일반적으로 화면에 무엇이든 표시하려면 카메라 뷰 변환도 적용해야 합니다.
카메라 보기 정의
렌더기에서 그리기 프로세스의 일부로 카메라 뷰 변환을 추가하여 그린 객체의 변환 프로세스를 완료합니다. 다음 코드 예에서 카메라 뷰 변환은 Matrix.setLookAtM()
메서드를 사용하여 계산된 다음 이전에 계산된 투영 행렬과 결합됩니다. 그런 다음 결합된 변환 행렬이 그려진 도형에 전달됩니다.
Kotlin
override fun onDrawFrame(unused: GL10) { ... // Set the camera position (View matrix) Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, 3f, 0f, 0f, 0f, 0f, 1.0f, 0.0f) // Calculate the projection and view transformation Matrix.multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0) // Draw shape triangle.draw(vPMatrix)
Java
@Override public void onDrawFrame(GL10 unused) { ... // Set the camera position (View matrix) Matrix.setLookAtM(viewMatrix, 0, 0, 0, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); // Calculate the projection and view transformation Matrix.multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0); // Draw shape triangle.draw(vPMatrix); }
투영 및 카메라 변환 적용
미리보기 섹션에 표시된 결합된 투영과 카메라 보기 변환 행렬을 사용하려면 먼저 이전에 Triangle
클래스에서 정의한 꼭짓점 셰이더에 행렬 변수를 추가합니다.
Kotlin
class Triangle { private val vertexShaderCode = // This matrix member variable provides a hook to manipulate // the coordinates of the objects that use this vertex shader "uniform mat4 uMVPMatrix;" + "attribute vec4 vPosition;" + "void main() {" + // the matrix must be included as a modifier of gl_Position // Note that the uMVPMatrix factor *must be first* in order // for the matrix multiplication product to be correct. " gl_Position = uMVPMatrix * vPosition;" + "}" // Use to access and set the view transformation private var vPMatrixHandle: Int = 0 ... }
Java
public class Triangle { private final String vertexShaderCode = // This matrix member variable provides a hook to manipulate // the coordinates of the objects that use this vertex shader "uniform mat4 uMVPMatrix;" + "attribute vec4 vPosition;" + "void main() {" + // the matrix must be included as a modifier of gl_Position // Note that the uMVPMatrix factor *must be first* in order // for the matrix multiplication product to be correct. " gl_Position = uMVPMatrix * vPosition;" + "}"; // Use to access and set the view transformation private int vPMatrixHandle; ... }
그런 다음 그래픽 객체의 draw()
메서드를 수정하여 결합된 변환 행렬을 허용하고 도형에 적용합니다.
Kotlin
fun draw(mvpMatrix: FloatArray) { // pass in the calculated transformation matrix // get handle to shape's transformation matrix vPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix") // Pass the projection and view transformation to the shader GLES20.glUniformMatrix4fv(vPMatrixHandle, 1, false, mvpMatrix, 0) // Draw the triangle GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount) // Disable vertex array GLES20.glDisableVertexAttribArray(positionHandle) }
Java
public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix ... // get handle to shape's transformation matrix vPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); // Pass the projection and view transformation to the shader GLES20.glUniformMatrix4fv(vPMatrixHandle, 1, false, mvpMatrix, 0); // Draw the triangle GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount); // Disable vertex array GLES20.glDisableVertexAttribArray(positionHandle); }
투영 및 카메라 뷰 변환을 올바르게 계산하고 적용하면 그래픽 객체가 올바른 비율로 그려지고 다음과 같이 표시됩니다.
올바른 비율로 도형을 표시하는 애플리케이션이 있으므로 도형에 모션을 추가해 보겠습니다.