android - OpenGL立方体着色

标签 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);
}

最佳答案

索引缓冲区用于索引到 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...
}

关于android - OpenGL立方体着色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37668017/

相关文章:

android - Android 4.2 离线语音识别API

Android循环显示动画太快

android - keytool 不适用于签署 android 应用程序

android - 如何在 Android 中滚动 "infinitely"宽 View ?

iphone - OpenGL ES 2D - z 顺序、深度缓冲区与按顺序绘制

iphone - 在 iPhone 上拖动 UIScrollView 时,OpenGL ES View 中的动画卡住

android - FLAG_ACTIVITY_CLEAR_TOP 调用 onCreate() 而不是 onResume()

java - 屏幕左侧 glTranslatef

android - 将 int 数组转换为 Android OpenGL ES 1.0 的 intbuffer?

c++ - 使用 Emscripten 将 OpenGL ES 转换反馈数据返回给主机