OpenGL ES Android 2D 视图似乎被缩小到无穷大

OpenGL ES Android 2D view appears to be zoomed out to infinity

我有一个 Kotlin 沙盒应用程序可以在 Android Studio 中试验 OpenGL ES。我按照教程进行操作,成功创建了具有适当长宽比的三角形、直线和点。我正在为 Android 使用 OpenGL ES 2 这本书,并转换为 Kotlin。 Source code is available here.

我与本书不同,试图创建用于平移和缩放的 2D 可变换视图(目前我对 3D 功能不是很感兴趣)所以我引用了 Android Dev docs 和某处在混杂的代码中,我创建了一个错误。出现的是中心的一个点,尽管缩放并将点移动到不同的位置。这些点渲染是因为着色器是 10 像素,我怀疑三角形在那里但太小了。也许在管道的某个地方应用了 0 的比例?我尝试手动缩放 orthoM 视图,但它在非常极端的数字下没有效果。我将这些点从原点移开,所有的点在孤立时仍然出现在原点。所以我认为 0 缩放可能正在发生。

我的预期结果是看到点出现在 1.0f 和 -1.0f 之间,当 setLookAtM 和点顶点被这样定义时。

渲染器:

package com.e

import android.content.Context
import android.opengl.GLES20.*
import android.opengl.GLSurfaceView.Renderer
import android.opengl.Matrix
import android.opengl.Matrix.*
import com.e.mysandboxapplication.R
import util.LoggerConfig
import util.ShaderHelper
import util.TextResourceReaderService
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10


class Open2DMapGLRenderer (
        private var context: Context
    ) : Renderer  {

    private val U_Matrix = "u_Matrix"
    private var projectionMatrix = FloatArray(16)
    private var viewMatrix = FloatArray(16)
    private val vPMatrix = FloatArray(16)
    private var vPMatrixHandle = 0
    private var uMatrixLocation = 0
    private val BYTES_PER_FLOAT = 4
    private lateinit var vertexData : FloatBuffer
    private var program = 0
    private val u_Color = "u_Color"
    private var uColorLocation = 0
    private var a_Position = "a_Position"
    private var aPositionLocation = 0
    private var POSITION_COMPONENT_COUNT = 2

    init{
        val vertices = PopulateVertices()
        vertexData = ByteBuffer.allocateDirect(vertices.count() * BYTES_PER_FLOAT)
            .order(ByteOrder.nativeOrder())
            .asFloatBuffer()
        vertexData.put(vertices)
    }

    private fun PopulateVertices(): FloatArray {
        val vertices = floatArrayOf(
            // Triangle 1
            -0.5f, -0.5f,
            0.5f, 0.5f,
            -0.5f, 0.5f,

            // Triangle 2
            -0.5f, -0.5f,
            0.5f, -0.5f,
            0.5f, 0.5f,

            // Line 1
            -0.5f, 0f,
            0.5f, 0f,

            // Points
            0.5f, 0.5f,
            -0.5f, -0.5f,
            0.0f, 0.0f
        )
        return vertices
    }

    override fun onDrawFrame(gl: GL10?) {
        glClear(GL_COLOR_BUFFER_BIT)
        setLookAtM(viewMatrix, 0, 0f, 0f, 1.0f, 0f, 0f, 0f, 0f, 1.0f, 0f)
        multiplyMM(vPMatrix, 0, projectionMatrix, 0, viewMatrix, 0)
        vPMatrixHandle = glGetUniformLocation(program, "uMVPMatrix")
        glUniformMatrix4fv(vPMatrixHandle, 1, false, vPMatrix, 0)
        DrawTriangles()
        DrawPoints()
        DrawLines()
    }

    private fun DrawPoints() {
        glUniform4f(uColorLocation, 1.0f, 1.0f, 1.0f, 1.0f)
        glDrawArrays(GL_POINTS, 8, 3)
    }

    private fun DrawLines() {
        glUniform4f(uColorLocation, 0f, 0f, 1.0f, 1.0f)
        glDrawArrays(GL_LINES, 6, 2)
    }

    private fun DrawTriangles() {
        glUniform4f(uColorLocation, 1.0f, 1.0f, 1.0f, 1.0f)
        glDrawArrays(GL_TRIANGLES, 0, 6)
    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        var isPortrait = width > height
        glViewport(0, 0, width, height)
        var scale = 1.0f // added this for diagnostics. No apparent effect.
        var aspectRatio = if ( isPortrait ) { width / height.toFloat() } else { height / width.toFloat() }
        if (isPortrait) {
            // Portrait
            orthoM(projectionMatrix, 0, -aspectRatio * scale , aspectRatio * scale, -scale, scale, -2.0f, 2.0f)
        }else{
            // Landscape
            orthoM(projectionMatrix, 0 , -scale, scale, -aspectRatio * scale , aspectRatio * scale, -2.0f, 2.0f)
        }
    }

    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        glClearColor(0.75f,0.75f,0.75f,1.0f)
        val vertexShaderSource : String = TextResourceReaderService()
            .readTextFileFromResource(context, R.raw.simple_vertex_shader)
        val fragmentShaderSource : String = TextResourceReaderService()
            .readTextFileFromResource(context, R.raw.simple_fragment_shader)

        val vertexShader : Int = ShaderHelper().compileVertexShader(vertexShaderSource)
        val fragmentShader : Int = ShaderHelper().compileFragmentShader(fragmentShaderSource)

        program = ShaderHelper().linkProgram(vertexShader, fragmentShader)

        if(LoggerConfig.ON) {
            ShaderHelper().validateProgram(program)
        }

        glUseProgram(program)

        uColorLocation = glGetUniformLocation(program, u_Color)
        aPositionLocation = glGetAttribLocation(program, a_Position)
        vertexData.position(0)
        glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, 0, vertexData)
        glEnableVertexAttribArray(aPositionLocation)
        uMatrixLocation = glGetUniformLocation(program, U_Matrix)
    }
}

ShaderHelper 实用程序Class:

import android.opengl.GLES20.*
import android.util.Log

public class ShaderHelper{
    private val TAG : String = "ShaderHelper"

    public fun compileVertexShader (shaderCode : String): Int{
        return compileShader(GL_VERTEX_SHADER, shaderCode)
    }

    public fun compileFragmentShader (shaderCode : String): Int{
        return compileShader(GL_FRAGMENT_SHADER, shaderCode)
    }

    private fun compileShader(type: Int , shaderCode: String) : Int{
        val shaderObjectId : Int = glCreateShader(type)

        if(shaderObjectId == 0){
            if (LoggerConfig.ON){
                Log.w(TAG, "Could not create new Shader.")
            }
            return 0
        }
        glShaderSource(shaderObjectId, shaderCode)
        glCompileShader(shaderObjectId)

        val compileStatus : IntArray = IntArray(1)
        glGetShaderiv(shaderObjectId, GL_COMPILE_STATUS, compileStatus, 0 )

        if(LoggerConfig.ON){
            Log.v(TAG, "Results of compiling source: " + "\n" + shaderCode + "\n"
            + glGetShaderInfoLog(shaderObjectId))
        }
        if(compileStatus[0] == 0){
            glDeleteShader(shaderObjectId)
            Log.v(TAG, "Compilation of shader failed.")
            return 0
        }
        return shaderObjectId
    }

    public fun linkProgram (vertexShaderId : Int, fragmentShaderId : Int) : Int {
        val programObjectId : Int = glCreateProgram()

        if(programObjectId == 0) {
            if (LoggerConfig.ON) {
                Log.v(TAG, "Could not create GL Program.")
            }
            return 0
        }

        glAttachShader(programObjectId, vertexShaderId)
        glAttachShader(programObjectId, fragmentShaderId)
        glLinkProgram(programObjectId)

        val linkStatus : IntArray = IntArray(1)
        glGetProgramiv(programObjectId, GL_LINK_STATUS, linkStatus, 0)

        if (LoggerConfig.ON) {
            // Print the program info log to the Android log output.
            Log.v(TAG, "Results of linking program:\n"
                    + glGetProgramInfoLog(programObjectId));
        }

        if(linkStatus[0] == 0) {
            glDeleteProgram(programObjectId)
            if(LoggerConfig.ON){
                Log.v(TAG, "Linking of program failed.\n")
            }
            return 0
        }
        return programObjectId
    }

    public fun validateProgram(programObjectId : Int) : Boolean{
        glValidateProgram(programObjectId)
        val validateStatus = IntArray(1)
        glGetProgramiv(programObjectId, GL_VALIDATE_STATUS, validateStatus, 0);
        Log.v(TAG, "Results of validating program: " + validateStatus[0]
                + "\nLog:" + glGetProgramInfoLog(programObjectId));

        return validateStatus[0] != 0;  
    }
}

顶点着色器:

uniform mat4 uMVPMatrix;

attribute vec4 v_Position;

void main()
{
    gl_Position = uMVPMatrix * v_Position;
    gl_PointSize = 10.0;
}

片段着色器:

precision mediump float;

uniform vec4 u_Color;

void main()
{
    gl_FragColor = u_Color;
}

问题是顶点着色器位置的变量包含拼写错误。

private var a_Position = "a_Position"

不匹配着色器:

attribute vec4 v_Position;

导致包含在 0,0,0 的所有内容。