OpenGL立方体着色

时间:2016-06-06 22:52:38

标签: android opengl-es

我使用OpenGL2.0创建了一个多维数据集。我希望它的每张脸都有六种不同的颜色。我按照一些例子画了一个立方体。除了立方体的颜色外,一切顺利。每个面的颜色混合在一起,只显示红色和绿色。它看起来很有线,我没有看到任何人有这个问题和我一样。有人可以帮我一把吗?下面是我的代码和多维数据集。非常感谢你!

enter image description here

public class MyCube {
private FloatBuffer vertexBuffer;
private ShortBuffer drawListBuffer;
private ShortBuffer[] ArrayDrawListBuffer;
private FloatBuffer colorBuffer;

private int mProgram;

//For Projection and Camera Transformations
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;" +
                "attribute vec4 vPosition;" +
                "attribute vec4 vColor;" +
                "varying vec4 vColorVarying;" +
                "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;" +
                "vColorVarying = vColor;"+
                "}";

// Use to access and set the view transformation
private int mMVPMatrixHandle;

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

// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
float cubeCoords[] = {
        -0.5f, 0.5f, 0.5f,   // front top left 0
        -0.5f, -0.5f, 0.5f,   // front bottom left 1
        0.5f, -0.5f, 0.5f,   // front bottom right 2
        0.5f, 0.5f, 0.5f,  // front top right 3
        -0.5f, 0.5f, -0.5f,   // back top left 4
        0.5f, 0.5f, -0.5f,   // back top right 5
        -0.5f, -0.5f, -0.5f,   // back bottom left 6
        0.5f, -0.5f, -0.5f,  // back bottom right 7
        };


// Set color with red, green, blue and alpha (opacity) values
float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
float red[] = { 1.0f, 0.0f, 0.0f, 1.0f };
float blue[] = { 0.0f, 0.0f, 1.0f, 1.0f };

private short drawOrder[] = {
                                0, 1, 2, 0, 2, 3,//front
                                0, 4, 5, 0, 5, 3, //Top
                                0, 1, 6, 0, 6, 4, //left
                                3, 2, 7, 3, 7 ,5, //right
                                1, 2, 7, 1, 7, 6, //bottom
                                4, 6, 7, 4, 7, 5 //back
                                }; //(order to draw vertices)

final float cubeColor[] =
        {
                // Front face (red)
                        1.0f, 0.0f, 0.0f, 1.0f,
                        1.0f, 0.0f, 0.0f, 1.0f,
                        1.0f, 0.0f, 0.0f, 1.0f,
                        1.0f, 0.0f, 0.0f, 1.0f,
                        1.0f, 0.0f, 0.0f, 1.0f,
                        1.0f, 0.0f, 0.0f, 1.0f,

                // Top face (green)
                        0.0f, 1.0f, 0.0f, 1.0f,
                        0.0f, 1.0f, 0.0f, 1.0f,
                        0.0f, 1.0f, 0.0f, 1.0f,
                        0.0f, 1.0f, 0.0f, 1.0f,
                        0.0f, 1.0f, 0.0f, 1.0f,
                        0.0f, 1.0f, 0.0f, 1.0f,

                // Left face (blue)
                       0.0f, 0.0f, 1.0f, 1.0f,
                        0.0f, 0.0f, 1.0f, 1.0f,
                        0.0f, 0.0f, 1.0f, 1.0f,
                        0.0f, 0.0f, 1.0f, 1.0f,
                        0.0f, 0.0f, 1.0f, 1.0f,
                        0.0f, 0.0f, 1.0f, 1.0f,

                // Right face (yellow)
                       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, 1.0f, 0.0f, 1.0f,
                        1.0f, 1.0f, 0.0f, 1.0f,
                        1.0f, 1.0f, 0.0f, 1.0f,

                // Bottom face (cyan)
                       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, 1.0f,
                        0.0f, 1.0f, 1.0f, 1.0f,
                        0.0f, 1.0f, 1.0f, 1.0f,

                // Back face (magenta)
                       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,
                        1.0f, 0.0f, 1.0f, 1.0f,
                        1.0f, 0.0f, 1.0f, 1.0f
        };


public MyCube() {
    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(
            // (# of coordinate values * 4 bytes per float)
            cubeCoords.length * 4);
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(cubeCoords);
    vertexBuffer.position(0);

    // 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);

    // initialize byte buffer for the color list
    ByteBuffer cb = ByteBuffer.allocateDirect(
            // (# of coordinate values * 2 bytes per short)
            cubeColor.length * 4);
    cb.order(ByteOrder.nativeOrder());
    colorBuffer = cb.asFloatBuffer();
    colorBuffer.put(cubeColor);
    colorBuffer.position(0);


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

    // create empty OpenGL ES Program
    mProgram = GLES20.glCreateProgram();

    // add the vertex shader to program
    GLES20.glAttachShader(mProgram, vertexShader);

    // add the fragment shader to program
    GLES20.glAttachShader(mProgram, fragmentShader);

    // creates OpenGL ES program executables
    GLES20.glLinkProgram(mProgram);
}

private int mPositionHandle;
private int mColorHandle;

private final int vertexCount = cubeCoords.length / COORDS_PER_VERTEX;
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
    // Add program to OpenGL ES environment
    GLES20.glUseProgram(mProgram);

    // get handle to vertex shader's vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
    // get handle to fragment shader's vColor member
    mColorHandle = GLES20.glGetAttribLocation(mProgram, "vColor");


    // Enable a handle to the cube vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    // Prepare the cube coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
            GLES20.GL_FLOAT, false,
            vertexStride, vertexBuffer);


    // Set color for drawing the triangle
    //mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
    // Enable a handle to the cube colors
    GLES20.glEnableVertexAttribArray(mColorHandle);
    // Prepare the cube color data
    GLES20.glVertexAttribPointer(mColorHandle, 4, GLES20.GL_FLOAT, false, 16, colorBuffer);

    // get handle to shape's transformation matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

    // Pass the projection and view transformation to the shader
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);


    // Draw the cube
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
    //GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);


    // Disable vertex array
    GLES20.glDisableVertexAttribArray(mPositionHandle);
    GLES20.glDisableVertexAttribArray(mColorHandle);
    GLES20.glDisableVertexAttribArray(mMVPMatrixHandle);
}

}

1 个答案:

答案 0 :(得分:2)

索引缓冲区用于使用与用于索引colorBuffer的索引相同的索引来索引vertexBuffer,因此每个中的相应元素需要匹配。索引缓冲区中的索引范围为0-7,因此您只能索引colorBuffer的前8个条目,这些条目为绿色和红色。

您需要为顶点位置和颜色的每个唯一组合设置单独的索引。对于每个面,有4种独特的顶点颜色组合,因此您的cubeCoords数组中需要6 * 4 = 24个条目,cubeColor数组中需要24个匹配条目。

像这样:

float cubeCoords[] = {

    // front face
    -0.5f, 0.5f, 0.5f,   // front top left 0
    -0.5f, -0.5f, 0.5f,   // front bottom left 1
    0.5f, -0.5f, 0.5f,   // front bottom right 2
    0.5f, 0.5f, 0.5f,  // front top right 3

    // top face
    -0.5f, 0.5f, -0.5f,   // back top left 4
    -0.5f, 0.5f, 0.5f,   // front top left 5
    0.5f, 0.5f, 0.5f,  // front top right 6
    0.5f, 0.5f, -0.5f,   // back top right 7

    // other faces...
}

final float cubeColor[] =
{
        // Front face (red)
                1.0f, 0.0f, 0.0f, 1.0f,
                1.0f, 0.0f, 0.0f, 1.0f,
                1.0f, 0.0f, 0.0f, 1.0f,
                1.0f, 0.0f, 0.0f, 1.0f,

        // Top face (green)
                0.0f, 1.0f, 0.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,
                0.0f, 1.0f, 0.0f, 1.0f,

            // other faces...
}

private short drawOrder[] = {
                            0, 1, 2, 0, 2, 3,//front
                            4, 5, 6, 4, 6, 7, //Top
                            // other faces...
}