OpenGL ES 2颜色缓冲区不起作用

时间:2016-10-26 11:56:24

标签: android opengl-es

我最近开始使用OpenGL ES 2 for android。我按照他们的例子绘制了形状,然后我进一步创建了一个立方体。我现在正试图获得漂亮的色彩效果(每个人都面对不同的颜色)。我已经定义了一个colorBuffer,它有一个每个顶点的颜色,但是当我绘制形状时,图像是黑色的。

如果我只使用一种颜色,而不是缓冲区,则形状很好。

我尝试从positionBuffer调整我的colorBuffer,但我做错了。

这是我的代码:

 public class Cube {


    private FloatBuffer vertexBuffer;  // Buffer for vertex-array
    private final FloatBuffer colorsBuffer;

    private static final int COORDS_PER_VERTEX = 3;

    private static final int COORDS_PER_COLOR = 4;

    private ShortBuffer drawListBuffer;

    private int mColorHandle;

//    float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };


    private float colors[] ={
            // FRONT
            1.0f, 0.5f, 0.0f, 1.0f,
            1.0f, 0.5f, 0.0f, 1.0f,
            1.0f, 0.5f, 0.0f, 1.0f,
            1.0f, 0.5f, 0.0f, 1.0f,

            //RIGHT
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,

            //RIGHT
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            //RIGHT
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            //RIGHT
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            //RIGHT
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f, 1.0f,
    };

    short[] drawOrder = {
            0, 1, 2, 0, 2, 3,
            4, 5, 6, 4, 6, 7,
            8, 9, 10, 8, 10, 11,
            12, 13, 14, 12, 14, 15,
            16, 17, 18, 16, 18, 19,
            20, 21, 22, 20, 22, 23,
    };

    private float cubeCoords[] = {
            // FRONT
            -1.0f, 1.0f,  1.0f,  // 0. top-left-front
            -1.0f, -1.0f,  1.0f,  // 1. bottom-left-front
            1.0f,  -1.0f,  1.0f,  // 2. bottom-right-front
            1.0f,  1.0f,  1.0f,  // 3. top-right-front

            // RIGHT
            1.0f,  1.0f,  1.0f,  // 3. top-right-front
            1.0f,  -1.0f,  1.0f,  // 2. bottom-right-front
            1.0f,  -1.0f,  -1.0f,  // 4. right-top-front
            1.0f,  1.0f, -1.0f,  // 5. right-top-back

            // BACK
            1.0f,  1.0f, -1.0f,  // 5. right-top-back
            1.0f,  -1.0f,  -1.0f,  // 4. right-top-front
            -1.0f,  -1.0f, -1.0f,  // 6. right-top-back
            -1.0f,  1.0f, -1.0f,  // 7. left-top-back

            // LEFT
            -1.0f,  1.0f, -1.0f,  // 7. left-top-back
            -1.0f,  -1.0f, -1.0f,  // 6. right-top-back
            -1.0f, -1.0f,  1.0f,  // 1. bottom-left-front
            -1.0f, 1.0f,  1.0f,  // 0. top-left-front

            // BOTTOM
            -1.0f, -1.0f,  1.0f,  // 1. bottom-left-front
            1.0f,  -1.0f,  1.0f,  // 2. bottom-right-front
            1.0f,  -1.0f,  -1.0f,  // 4. right-top-front
            -1.0f,  -1.0f, -1.0f,  // 6. right-top-back

            // TOP
            -1.0f, 1.0f,  1.0f,  // 0. top-left-front
            1.0f,  1.0f,  1.0f,  // 3. top-right-front
            1.0f,  1.0f, -1.0f,  // 5. right-top-back
            -1.0f,  1.0f, -1.0f,  // 7. left-top-back
    };




    private final String vertexShaderCode =
            "uniform mat4 uMVPMatrix;" +
                    "attribute vec4 vPosition;" +
                    "void main() {" +
                    "  gl_Position = uMVPMatrix * vPosition;" +
                    "}";

    private final String fragmentShaderCode =
            "precision mediump float;" +
                    "uniform vec4 vColor;" +
                    "void main() {" +
                    "  gl_FragColor = vColor;" +
                    "}";
    private int MVPMatrixHandle;
    private int mPositionHandle;

    private int colorHandle;
    private final int mProgram;

    private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

    private final int colorStride = COORDS_PER_COLOR * 4;

    private final int vertexCount = cubeCoords.length / COORDS_PER_VERTEX;

    // Constructor - Set up the buffers
    public Cube() {
        Log.d("TAG","vertexCount: "+vertexCount);
        // Setup vertex-array buffer. Vertices in float. An float has 4 bytes
        ByteBuffer vbb = ByteBuffer.allocateDirect(cubeCoords.length * 4);

        vbb.order(ByteOrder.nativeOrder()); // Use native byte order
        vertexBuffer = vbb.asFloatBuffer(); // Convert from byte to float
        vertexBuffer.put(cubeCoords);         // Copy data into buffer
        vertexBuffer.position(0);           // Rewind


        // initialize byte buffer for the draw list
        ByteBuffer dlb = ByteBuffer.allocateDirect(
                // (# of coordinate values * 2 bytes per short)
                drawOrder.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        drawListBuffer = dlb.asShortBuffer();
        drawListBuffer.put(drawOrder);
        drawListBuffer.position(0);


        colorsBuffer = ByteBuffer.allocateDirect(colors.length * 4).order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        colorsBuffer.put(colors);
        colorsBuffer.position(0);



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

        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram, vertexShader);
        GLES20.glAttachShader(mProgram, fragmentShader);
        GLES20.glLinkProgram(mProgram);
    }

    // Draw the shape
    public void draw(float[] mvpMatrix) {
        GLES20.glUseProgram(mProgram);

        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);

        MVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        // get handle to fragment shader's vColor member

        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

        // Set color for drawing the triangle
//        GLES20.glUniform4fv(mColorHandle, 1, color, 0);

        GLES20.glEnableVertexAttribArray(mColorHandle);

        GLES20.glVertexAttribPointer(mColorHandle, COORDS_PER_COLOR, GLES20.GL_FLOAT, false,
                colorStride, colorsBuffer);

        GLES20.glUniformMatrix4fv(MVPMatrixHandle, 1, false, mvpMatrix, 0);

        GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);

        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
}

1 个答案:

答案 0 :(得分:0)

您没有对着色器程序中的颜色数据执行任何操作,因此您上传的数据并没有对其执行任何操作。

您需要将新顶点属性的处理代码添加到着色器;像这样的东西:

private final String vertexShaderCode =
         "uniform mat4 uMVPMatrix;" +
         "attribute vec4 vPosition;" +
         "attribute mediump vec4 vColor;" +
         "varying mediump vec4 vaColor;" +
         "void main() {" +
         "  vaColor = vColor;" +
         "  gl_Position = uMVPMatrix * vPosition;" +
         "}";

private final String fragmentShaderCode =
        "precision mediump float;" +
        "varying mediump vec4 vaColor;" +
        "void main() {" +
        "  gl_FragColor = vaColor;" +
        "}";