首页 > 解决方案 > 如何在 OpenGL ES 中应用投影和相机视图?

问题描述

我尝试根据官方文档(https://developer.android.com/training/graphics/opengl/projection#kotlin)应用投影和相机视图。不幸的是,我得到了一个空屏幕而不是常规三角形。以下是我的onSurfaceCreatedonDrawFrame功能。我填充了一个不在onSurfaceChanged函数中的投影变换矩阵(如文档中所示),因为我从未在我的应用程序中调用过它(在这种情况下结果是相同的)。

override fun onSurfaceCreated(unused: GL10, config: EGLConfig) {
   mTriangle = Triangle()
   GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
   Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)
}

override fun onDrawFrame(unused: GL10) {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)

    // 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
    mTriangle.draw(vPMatrix)
}

然后我想出了重写我的绘图功能。首先,我vertexShaderCode按照文档中的说明进行设置。

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;" +
                "}"

其次,我改变了函数本身:

fun draw(mvpMatrix: FloatArray) { // pass in the calculated transformation matrix

    // get handle to shape's transformation matrix
    vPMatrixHandle = GLES20.glGetUniformLocation(program, "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)

}

我有一个空屏幕...然后我尝试将上面的代码和它的工作版本结合起来。我有:

 fun draw(mvpMatrix: FloatArray) {
    // 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)
        }

        // 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(it)
    }
}

这也没有用。我怎样才能画出我的三角形?

附言

  1. 将 3f->2f->1f 更改为“near”值Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f)无任何作用
  2. 在绘图函数的第二个(大)版本中使用gl_Position = vPosition;而不是给出三角形。问题似乎与矩阵有关。gl_Position = uMVPMatrix * vPosition;vertexShaderCode

标签: androidkotlinopengl-esopengl-es-2.0vertex-shader

解决方案


好的,终于成功了!

用过 Matrix.frustumM(projectionMatrix, 0, -1.5f, 1.5f, -1f, 1f, 1f, 7f)的,也许一切都和上面一样。


推荐阅读