OpenGL ES ortamında, projeksiyon ve kamera görünümleri, çizilen nesneleri, fiziksel nesneleri gözlerinizle görme şeklinize daha çok benzeyen bir şekilde görüntülemenizi sağlar. Bu fiziksel görüntüleme simülasyonu, çizilen nesne koordinatlarının matematiksel dönüşümleriyle yapılır:
- Projeksiyon - Bu dönüştürme, çizilen nesnelerin koordinatlarını gösterildikleri
GLSurfaceView
genişliğine ve yüksekliğine göre ayarlar. Bu hesaplama yapılmadığında, OpenGL ES tarafından çizilen nesneler, görünüm penceresinin eşit olmayan oranlarıyla çarpıtılır. Bir projeksiyon dönüşümü genellikle yalnızca OpenGL görünümünün oranları oluşturucunuzunonSurfaceChanged()
yönteminde oluşturulduğunda veya değiştirildiğinde hesaplanmalıdır. OpenGL ES projeksiyonları ve koordinat eşlemesi hakkında daha fazla bilgi için Çizilen nesneler için koordinatları eşleme bölümüne bakın. - Kamera Görünümü - Bu dönüştürme, çizilen nesnelerin koordinatlarını sanal kamera konumuna göre ayarlar. OpenGL ES'nin gerçek bir kamera nesnesi tanımlamadığını, bunun yerine çizilen nesnelerin görüntüsünü dönüştürerek bir kamerayı simüle eden yardımcı yöntemler sunduğunu unutmamak önemlidir. Kamera görünümü dönüşümü,
GLSurfaceView
oluşturduğunuzda yalnızca bir kez hesaplanabilir veya kullanıcı işlemlerine ya da uygulamanızın işlevine bağlı olarak dinamik olarak değiştirilebilir.
Bu derste, nasıl projeksiyon ve kamera görünümü oluşturacağınız ve bunu GLSurfaceView
dosyanızda çizilen şekillere nasıl uygulayacağınız açıklanmaktadır.
Projeksiyon tanımlama
Projeksiyon dönüşümü verileri, GLSurfaceView.Renderer
sınıfınızın onSurfaceChanged()
yönteminde hesaplanır. Aşağıdaki örnek kod, GLSurfaceView
yüksekliğini ve genişliğini alır ve Matrix.frustumM()
yöntemini kullanarak Matrix
projeksiyon dönüşümünü doldurmak için kullanır:
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); }
Bu kod bir projeksiyon matrisini doldurur. mProjectionMatrix
daha sonra, bir sonraki bölümde gösterilen onDrawFrame()
yöntemindeki bir kamera görünümü dönüşümüyle birleştirebilirsiniz.
Not: Çizim nesnelerinize yalnızca bir projeksiyon dönüşümü uygulamak genellikle çok boş bir ekranla sonuçlanır. Genel olarak, bir şeyin ekranda görünmesi için kamera görünümü dönüşümü de uygulamanız gerekir.
Kamera görünümü tanımlama
Oluşturucunuzda çizim sürecinin bir parçası olarak kamera görünümü dönüşümü ekleyerek çizdiğiniz nesneleri dönüştürme işlemini tamamlayın. Aşağıdaki örnek kodda, kamera görünümü dönüşümü Matrix.setLookAtM()
yöntemi kullanılarak hesaplanır ve ardından daha önce hesaplanan projeksiyon matrisi ile birleştirilir. Daha sonra, birleştirilmiş dönüşüm matrisleri çizilen şekle geçirilir.
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); }
Projeksiyon ve kamera dönüşümleri uygulayın
Önizleme bölümlerinde gösterilen birleşik projeksiyon ve kamera görünümü dönüştürme matrisini kullanmak için önce, önceden Triangle
sınıfında tanımlanan tepe gölgelendiricisine bir matris değişkeni ekleyin:
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; ... }
Ardından, birleştirilmiş dönüşüm matrisini kabul etmek için grafik nesnelerinizin draw()
yöntemini değiştirin ve şekle uygulayın:
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); }
Projeksiyon ve kamera görünümü dönüşümlerini doğru bir şekilde hesaplayıp uyguladıktan sonra, grafik nesneleriniz doğru oranlarda çizilir ve şöyle görünmelidir:
![](https://developer.android.com/static/images/opengl/ogl-triangle-projected.png?authuser=5&hl=tr)
Şekil 1. Projeksiyon ve kamera görünümü uygulanmış üçgen.
Artık şekillerinizi doğru oranlarda görüntüleyen bir uygulamanıza sahip olduğunuza göre şekillerinize hareket eklemenin zamanı geldi.