beokay
beokay

Reputation: 13

How do I apply projection and camera views in OpenGL ES?

I tried applying projection and camera views according to the official documentation (https://developer.android.com/training/graphics/opengl/projection#kotlin). Unfortunately I got an empty screen instead of regular triangle. Below are my onSurfaceCreated and onDrawFrame functions. I populate a projection transformation matrix not in the onSurfaceChanged function (as it is shown in the docs) because I have it never called in my app (in that case the result was the same).

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)
}

Then I came up with rewriting my draw function. Firstly I set vertexShaderCode as it was said in the docs.

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

Secondly I changed the function itself:

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)

}

I got an empty screen... Then I tried to combine code above and working version of it. I got:

 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)
    }
}

This didn't work too. How can I get my triangle drawn?

P.S.

  1. Changing 3f->2f->1f for "near" value at Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 7f) does nothing
  2. Using gl_Position = vPosition; instead of gl_Position = uMVPMatrix * vPosition; in the vertexShaderCode with second (big) version of draw function gives the triangle. Problem seems to be with matrices.

Upvotes: 0

Views: 731

Answers (1)

beokay
beokay

Reputation: 13

Okay, finally it works!

Used Matrix.frustumM(projectionMatrix, 0, -1.5f, 1.5f, -1f, 1f, 1f, 7f) and maybe everything the same as above is.

Upvotes: 1

Related Questions