安卓OpenGL ES教程似乎无法正常工作

9
我一直在跟随Android上OpenGL ES2.0的教程。我已经进入到“应用投影和相机视图”的部分,但是我总是得到一个空白屏幕且没有三角形显示,前面的部分却能正常工作。我尝试将整个教程复制粘贴到我的代码中,但得到了相同的结果。更改以下行:
gl_Position = uMVPMatrix * vPosition;

to:

gl_Position = vPosition;

将应用程序放回到第一部分(三角形会根据屏幕方向而伸展)。有什么问题吗?这是我目前的代码,以防我遗漏了什么:

public class GLTest20Renderer implements Renderer {
    private final String vertexShaderCode = 
        // This matrix member variable provides a hook to manipulate
        // the coordinates of the objects that use this vertex shader
        "uniform mat4 uMVPMatrix;   \n" +

        "attribute vec4 vPosition;  \n" +
        "void main(){               \n" +

        // the matrix must be included as a modifier of gl_Position
        " gl_Position = uMVPMatrix * vPosition; \n" +

        "}  \n";

    private final String fragmentShaderCode = 
        "precision mediump float;  \n" +
        "void main(){              \n" +
        " gl_FragColor = vec4 (0.63671875, 0.76953125, 0.22265625, 1.0); \n" +
        "}                         \n";


    private FloatBuffer triangleVB;

    private int mProgram;
    private int maPositionHandle;

    private int muMVPMatrixHandle;
    private float[] mMVPMatrix = new float[16];
    private float[] mMMatrix = new float[16];
    private float[] mVMatrix = new float[16];
    private float[] mProjMatrix = new float[16];

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

        initShapes();

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

        mProgram = GLES20.glCreateProgram();             // create empty OpenGL Program
        GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
        GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
        GLES20.glLinkProgram(mProgram);                  // creates OpenGL program executables

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

    public void onDrawFrame(GL10 unused) {
        GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT );

        // Add program to OpenGL environment
        GLES20.glUseProgram(mProgram);

        // Prepare the triangle data
        GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 12, triangleVB);
        GLES20.glEnableVertexAttribArray(maPositionHandle);

        // Apply a ModelView Projection transformation
        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);

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

    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);

        float ratio = (float) width / height;

        Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

        muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
    }

    private void initShapes() {
        float triangleCoords[] = {
            // X, Y, Z
            -0.5f, -0.25f, 0,
             0.5f, -0.25f, 0,
             0.0f,  0.559016994f, 0
        }; 

        // initialize vertex Buffer for triangle  
        ByteBuffer vbb = ByteBuffer.allocateDirect(
                // (# of coordinate values * 4 bytes per float)
                triangleCoords.length * 4); 
        vbb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order
        triangleVB = vbb.asFloatBuffer();  // create a floating point buffer from the ByteBuffer
        triangleVB.put(triangleCoords);    // add the coordinates to the FloatBuffer
        triangleVB.position(0);            // set the buffer to read the first coordinate
    }

    private 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;
    }
}

我在三星Galaxy S2上运行所有这些内容。

1
好的,我通过将look at中的近点更改为2来修复了它:Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 2, 7); 而不是3,不确定这是否是他们的错误还是我仍然错过了什么。 - sler
这个API 15的SDK示例对我很有用。也许你可以比较一下代码,看看发生了什么。 - Jacob Phillips
1
在这个例子中,似乎他们直接将三角形放在近裁剪平面上。也许你的设备实现了裁剪阶段,直接将物体裁剪在平面上,而不是让它停留。尝试将近裁剪平面设置为2.98或2.99,看看会发生什么。 - MyReliableSchreck
我认为你是正确的,这对我来说似乎有效。 - sler
似乎不是常见问题。也许这是设备特定的问题? - Vetle
显示剩余2条评论
1个回答

13

已修复,只需将lookat中的近点更改为小于3:

Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 2, 7);

谢谢,这真的为我节省了很多时间。 - Lei Guo
1
但为什么会这样呢?我已经在Galaxy Note 3 / Galaxy S3 / Galaxy S Advance上进行了测试。只有在Note 3上,示例才能正常运行,而不需要进行修改。有任何想法吗? - Abhishek Bansal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接