Şekil çiz

OpenGL ile çizilecek şekilleri tanımladıktan sonra, muhtemelen bu şekilleri çizmek istersiniz. Şekil çizme her zaman düşünebileceğinizden biraz daha fazla kod gerekir; çünkü API, üzerinde çok fazla kontrole sahip değiliz.

Bu ders, önceki derste tanımladığınız şekillerin OpenGL kullanarak nasıl çizileceğini açıklar. ES 2.0 API.

Şekilleri ilk kullanıma hazırla

Herhangi bir çizim yapmadan önce, çizmeyi planladığınız şekilleri ilk kullanıma hazırlamanız ve yüklemeniz gerekir. Aksi takdirde programınızda kullandığınız şekillerin yapısı (orijinal koordinatlar) kurs sırasında değişir yoksa projenin yürütülmesi sırasında onSurfaceCreated() yönteminiz oluşturucusu ile birlikte çalışır.

Kotlin

class MyGLRenderer : GLSurfaceView.Renderer {
    ...
    private lateinit var mTriangle: Triangle
    private lateinit var mSquare: Square

    override fun onSurfaceCreated(unused: GL10, config: EGLConfig) {
        ...
        // initialize a triangle
        mTriangle = Triangle()
        // initialize a square
        mSquare = Square()
    }
    ...
}

Java

public class MyGLRenderer implements GLSurfaceView.Renderer {

    ...
    private Triangle mTriangle;
    private Square   mSquare;

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        ...
        // initialize a triangle
        mTriangle = new Triangle();
        // initialize a square
        mSquare = new Square();
    }
    ...
}

Şekil çizin

OpenGL ES 2.0 kullanarak tanımlı bir şekil çizmek önemli miktarda kod gerektirir çünkü grafik oluşturma ardışık düzenine çok fazla ayrıntı sağlaması gerekir. Özel olarak, takip etmek için:

  • Vertex Gölgelendirici - Bir şeklin köşelerini oluşturmak için OpenGL ES grafik kodu.
  • Parça Gölgelendirici - Bir şeklin yüzünü renklerle veya dokunun.
  • Program: Çizim için kullanmak istediğiniz gölgelendiricileri içeren bir OpenGL ES nesnesi bir veya daha fazla şekil.

Şekil çizmek için en az bir köşe gölgelendirici ve bu şekli renklendirmek için bir parça gölgelendiriciye ihtiyacınız vardır. Bu gölgelendiriciler derlenmeli ve ardından bir OpenGL ES programına eklenmelidir. Bu program daha sonra çizim yapmak için şekli. Burada, Triangle sınıf:

Kotlin

class Triangle {

    private val vertexShaderCode =
            "attribute vec4 vPosition;" +
            "void main() {" +
            "  gl_Position = vPosition;" +
            "}"

    private val fragmentShaderCode =
            "precision mediump float;" +
            "uniform vec4 vColor;" +
            "void main() {" +
            "  gl_FragColor = vColor;" +
            "}"

    ...
}

Java

public class Triangle {

    private final String vertexShaderCode =
        "attribute vec4 vPosition;" +
        "void main() {" +
        "  gl_Position = vPosition;" +
        "}";

    private final String fragmentShaderCode =
        "precision mediump float;" +
        "uniform vec4 vColor;" +
        "void main() {" +
        "  gl_FragColor = vColor;" +
        "}";

    ...
}

Gölgelendiriciler, OpenGL ES ortamını kapsıyor. Bu kodu derlemek için oluşturucu sınıfınızda bir yardımcı program yöntemi oluşturun:

Kotlin

fun loadShader(type: Int, shaderCode: String): Int {

    // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
    return GLES20.glCreateShader(type).also { shader ->

        // add the source code to the shader and compile it
        GLES20.glShaderSource(shader, shaderCode)
        GLES20.glCompileShader(shader)
    }
}

Java

public static int loadShader(int type, String shaderCode){

    // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
    int shader = GLES20.glCreateShader(type);

    // add the source code to the shader and compile it
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);

    return shader;
}

Şeklinizi çizmek için gölgelendirici kodunu derlemeniz, bir OpenGL ES programına eklemeniz gerekir nesnesini bulun ve programı bağlayın. Bunu, çizdiğiniz nesnenin oluşturucusunda yapın, böylece yalnızca biter bir kez.

Not: OpenGL ES gölgelendiricilerini derlemek ve programları bağlamak pahalıdır daha fazla dikkat etmeniz gerekir. Dolayısıyla, bunu birden fazla kez yapmaktan kaçınmalısınız. CANNOT TRANSLATE hakkında bilgi sahibi değilseniz, kodunuzu yalnızca kendilerine ait alan bir defa oluşturulur ve daha sonra kullanılmak üzere önbelleğe alınır.

Kotlin

class Triangle {
    ...

    private var mProgram: Int

    init {
        ...

        val vertexShader: Int = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
        val fragmentShader: Int = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)

        // create empty OpenGL ES Program
        mProgram = GLES20.glCreateProgram().also {

            // add the vertex shader to program
            GLES20.glAttachShader(it, vertexShader)

            // add the fragment shader to program
            GLES20.glAttachShader(it, fragmentShader)

            // creates OpenGL ES program executables
            GLES20.glLinkProgram(it)
        }
    }
}

Java

public class Triangle() {
    ...

    private final int mProgram;

    public Triangle() {
        ...

        int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
                                        vertexShaderCode);
        int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
                                        fragmentShaderCode);

        // create empty OpenGL ES Program
        mProgram = GLES20.glCreateProgram();

        // add the vertex shader to program
        GLES20.glAttachShader(mProgram, vertexShader);

        // add the fragment shader to program
        GLES20.glAttachShader(mProgram, fragmentShader);

        // creates OpenGL ES program executables
        GLES20.glLinkProgram(mProgram);
    }
}

Bu noktada, şeklinizi çizen gerçek çağrıları eklemeye hazırsınız. Şekil çizmek OpenGL ES, oluşturma ardışık düzenine ne istediğinizi bildirmek için birkaç parametre belirtmenizi gerektirir ve nasıl çizileceğini öğrendiniz. Çizim seçenekleri şekle göre değişiklik gösterebileceğinden şekil sınıflarının kendi çizim mantığını içerir.

Şekil çizmek için bir draw() yöntemi oluşturun. Bu kod, konumu ve renk değerlerini şeklin köşe gölgelendiricisine ve parça gölgelendiricisine ekler ve ardından çizimi yürütür işlevini kullanın.

Kotlin

private var positionHandle: Int = 0
private var mColorHandle: Int = 0

private val vertexCount: Int = triangleCoords.size / COORDS_PER_VERTEX
private val vertexStride: Int = COORDS_PER_VERTEX * 4 // 4 bytes per vertex

fun draw() {
    // Add program to OpenGL ES environment
    GLES20.glUseProgram(mProgram)

    // get handle to vertex shader's vPosition member
    positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition").also {

        // Enable a handle to the triangle vertices
        GLES20.glEnableVertexAttribArray(it)

        // Prepare the triangle coordinate data
        GLES20.glVertexAttribPointer(
                it,
                COORDS_PER_VERTEX,
                GLES20.GL_FLOAT,
                false,
                vertexStride,
                vertexBuffer
        )

        // get handle to fragment shader's vColor member
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor").also { colorHandle ->

            // Set color for drawing the triangle
            GLES20.glUniform4fv(colorHandle, 1, color, 0)
        }

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

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(it)
    }
}

Java

private int positionHandle;
private int colorHandle;

private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

public void draw() {
    // Add program to OpenGL ES environment
    GLES20.glUseProgram(mProgram);

    // get handle to vertex shader's vPosition member
    positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

    // Enable a handle to the triangle vertices
    GLES20.glEnableVertexAttribArray(positionHandle);

    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX,
                                 GLES20.GL_FLOAT, false,
                                 vertexStride, vertexBuffer);

    // get handle to fragment shader's vColor member
    colorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

    // Set color for drawing the triangle
    GLES20.glUniform4fv(colorHandle, 1, color, 0);

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

    // Disable vertex array
    GLES20.glDisableVertexAttribArray(positionHandle);
}

Tüm bu kodu yerleştirdikten sonra, bu nesneyi çizmek için yalnızca Oluşturucunuzun onDrawFrame() yönteminden draw() yöntemi:

Kotlin

override fun onDrawFrame(unused: GL10) {
    ...

    mTriangle.draw()
}

Java

public void onDrawFrame(GL10 unused) {
    ...

    mTriangle.draw();
}

Uygulamayı çalıştırdığınızda uygulama şu şekilde görünmelidir:

Şekil 1. Projeksiyon veya kamera görünümü olmadan çizilen üçgen.

Bu kod örneğinde birkaç sorun var. Her şeyden önce, bu herhangi bir arkadaş. İkincisi, üçgen biraz bastırılmış ve ekranı değiştirdiğinizde şekli değişir. cihazın yönünü değiştirebilirsiniz. Şeklin eğik olmasının nedeni nesnenin köşeler, kaplumbağanın kapladığı ekran alanının oranları için düzeltilmemiştir. GLSurfaceView gösteriliyor. Projeksiyon ve kamera kullanarak bu sorunu çözebilirsiniz ele alacağız.

Son olarak, üçgen sabit duruyor ve bu biraz sıkıcı. Hareket ekleme dersi, bu şekli siz oluşturuyorsunuz döndürecek ve OpenGL ES grafik ardışık düzenini daha ilginç bir şekilde kullanacak.