绘制基本三角形时的拼图效果

问题描述

我一直在https://developer.android.com/training/graphics/opengl上关注Android的培训资料,但是我翻阅了指南并对其进行了两次重新制作,并且在各处进行了更改,但似乎看不到我在做什么错?在我看来,mTriangle被创建了多次,或者它的数据在重绘之前没有被删除,因此旋转时会产生拼图的效果。我的代码

class GameRenderer : GLSurfaceView.Renderer {
    private lateinit var mTriangle: Triangle
    private val vPMatrix: FloatArray = FloatArray(16)
    private val projectionMatrix: FloatArray = FloatArray(16)
    private val viewMatrix: FloatArray = FloatArray(16)
    private val rotationMatrix: FloatArray = FloatArray(16)

    override fun onSurfaceCreated(unused: GL10,config: EGLConfig) {
        GLES20.glClearColor(0.0f,0.0f,1.0f)
        mTriangle = Triangle()
    }

    override fun onDrawFrame(unused: GL10) {
        GLES20.glClearColor(0.0f,1.0f)
        val scratch = FloatArray(16)
        val time = SystemClock.uptimeMillis() % 4000L
        val angle = 0.090f * time.toInt()
        Matrix.setLookAtM(viewMatrix,0f,-3f,1.0f,0.0f)
        Matrix.multiplyMM(vPMatrix,projectionMatrix,viewMatrix,0)
        Matrix.setRotateM(rotationMatrix,angle,-1.0f)
        Matrix.multiplyMM(scratch,vPMatrix,rotationMatrix,0)
        mTriangle.draw(scratch)
    }

    override fun onSurfaceChanged(unused: GL10,width: Int,height: Int) {
        GLES20.glViewport(0,width,height)
        val ratio: Float = width.toFloat() / height.toFloat()
        Matrix.frustumM(projectionMatrix,-ratio,ratio,-1f,1f,3f,7f)
    }
}

那是渲染器的代码,三角形本身是:

class Triangle {
    private var mProgram: Int
    private val fragmentshadercode: String =
        "precision mediump float;\n" +
        "uniform vec4 vColor;\n" +
        "void main() {\n" +
            "\tgl_FragColor = vColor;\n" +
        "}"
    private val vertexshadercode: String =
        "uniform mat4 uMVPMatrix;\n" +
        "attribute vec4 vPosition;\n" +
        "void main() {\n" +
            "\tgl_Position = uMVPMatrix * vPosition;\n" +
        "}"

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

    private val COORDS_PER_VERTEX: Int = 3
    private var triangleCoords: FloatArray = floatArrayOf(     // in counterclockwise order:
        0.0f,0.622008459f,// top
        -0.5f,-0.311004243f,// bottom left
        0.5f,0.0f      // bottom right
    )
    private val color: FloatArray = floatArrayOf(0.63671875f,0.76953125f,0.22265625f,1.0f)

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

    private var vertexBuffer: FloatBuffer =
        ByteBuffer.allocateDirect(triangleCoords.size * 4).run {
            order(ByteOrder.nativeOrder())
            asFloatBuffer().apply {
                put(triangleCoords)
                position(0)
            }
        }

    init {
        val vertexShader: Int = loadShader(GLES20.GL_VERTEX_SHADER,vertexshadercode)
        val fragmentShader: Int = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentshadercode)
        mProgram = GLES20.glCreateProgram().also {
            GLES20.glAttachShader(it,vertexShader)
            GLES20.glAttachShader(it,fragmentShader)
            GLES20.glLinkProgram(it)
        }
    }

    fun loadShader(type: Int,shadercode: String): Int {
        return GLES20.glCreateShader(type).also { shader ->
            GLES20.glShaderSource(shader,shadercode)
            GLES20.glCompileShader(shader)
        }
    }

    fun draw(mvpMatrix: FloatArray) {
        GLES20.gluseProgram(mProgram)
        positionHandle = GLES20.glGetAttribLocation(mProgram,"vPosition").also {
            GLES20.glEnabLevertexAttribArray(it)
            GLES20.glVertexAttribPointer(
                it,COORDS_PER_VERTEX,GLES20.GL_FLOAT,false,vertexStride,vertexBuffer
            )
            mColorHandle = GLES20.glGetUniformlocation(mProgram,"vColor").also { colorHandle ->
                GLES20.gluniform4fv(colorHandle,1,color,0)
            }
            vPMatrixHandle = GLES20.glGetUniformlocation(mProgram,"uMVPMatrix")
            GLES20.gluniformMatrix4fv(vPMatrixHandle,mvpMatrix,0)
            GLES20.glDrawArrays(GLES20.GL_TRIANGLES,vertexCount)
            GLES20.gldisabLevertexAttribArray(it)
        }
    }
}

解决方法

您错过了清除帧缓冲区的操作。注意glClearColor为颜色缓冲区指定清晰的值。但是您必须调用glClear来设置缓冲区的值:

GLES20.glClearColor(0.0f,0.0f,1.0f)
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)