使用glDrawArrays使用OpenGL ES绘制一个多维数据集

时间:2014-09-18 18:27:06

标签: android opengl-es-2.0

以前,我一直在使用glDrawElements绘制一些3D形状,但是当它以不同的方式着色时,最好是拥有独特的顶点。

我一直在尝试重写我以前工作的立方体类来使用glDrawArrays代替并提供每个顶点的颜色(和正常但我还没有使用它)数据,但现在我在屏幕上看不到任何内容。

流程非常多:编译着色器,创建程序和附加着色器,为模型数据创建缓冲区,设置程序,传递指向模型数据的指针,传递MVP矩阵,绘制。

我认为我已经为glDrawElements做了相同的事情,所以我想我会责怪我的着色器代码,但我真的不清楚是什么问题。任何帮助表示赞赏。

public class Cube {

private final String vertexShaderCode =
        "uniform mat4 uMVPMatrix;" +
        "attribute vec4 aPosition;" +   
        "attribute vec4 aColor; \n" 
        + "attribute vec3 aNormal; \n"  
        + "varying vec4 v_Color; \n"    
        + "void main() {" +
        "  gl_Position = uMVPMatrix * vPosition;" +
        "}";

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

// Store our data in float buffer.
private final FloatBuffer mCubePositions;
private final FloatBuffer mCubeColors;
private final FloatBuffer mCubeNormals;

// Bytes per float.
private final int mBytesPerFloat = 4;

/** Size of the position data in elements. */
private final int mPositionDataSize = 3;    
/** Size of the color data in elements. */
private final int mColorDataSize = 4;   
/** Size of the normal data in elements. */
private final int mNormalDataSize = 3;

private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
private int mNormalHandle;
private int mMVPMatrixHandle;

final float[] cubePositionData =
    {...
    };

    final float[] cubeColorData =
    {...
    };

    final float[] cubeNormalData =
    {...
    };

/**
 * Sets up the drawing object data for use in an OpenGL ES context.
 */
public Cube() {
    // prepare shaders and OpenGL program
    int vertexShader = MyGLRenderer.loadShader(
            GLES20.GL_VERTEX_SHADER,
            vertexShaderCode);
    int fragmentShader = MyGLRenderer.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);                  // create OpenGL program executables

    // Initialize the buffers.
    mCubePositions = ByteBuffer.allocateDirect(cubePositionData.length * mBytesPerFloat)
    .order(ByteOrder.nativeOrder()).asFloatBuffer();    
    mCubePositions.put(cubePositionData);
    mCubePositions.position(0);

    mCubeColors = ByteBuffer.allocateDirect(cubeColorData.length * mBytesPerFloat)
    .order(ByteOrder.nativeOrder()).asFloatBuffer();    
    mCubeColors.put(cubeColorData);
    mCubeColors.position(0);

    mCubeNormals = ByteBuffer.allocateDirect(cubeNormalData.length * mBytesPerFloat)
    .order(ByteOrder.nativeOrder()).asFloatBuffer();    
    mCubeNormals.put(cubeNormalData);
    mCubeNormals.position(0);
}

public void draw(float[] mMVPMatrix) {
    // Add program to OpenGL environment
    GLES20.glUseProgram(mProgram);

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

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

    mNormalHandle = GLES20.glGetAttribLocation(mProgram, "aNormal"); 

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

    // Apply the projection and view transformation
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);

    // Pass in the position information
    mCubePositions.position(0);
    GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize,
            GLES20.GL_FLOAT, false, 0, mCubePositions);
    GLES20.glEnableVertexAttribArray(mPositionHandle);

    // Pass in the color information
    mCubeColors.position(0);
    GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize,
            GLES20.GL_FLOAT, false, 0, mCubeColors);
    GLES20.glEnableVertexAttribArray(mColorHandle);

    // Pass in the normal information
    mCubeNormals.position(0);
    GLES20.glVertexAttribPointer(mNormalHandle, mNormalDataSize,
            GLES20.GL_FLOAT, false, 0, mCubeNormals);
    GLES20.glEnableVertexAttribArray(mNormalHandle);

    // Pass in the combined matrix.
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);

    // Draw the cube.
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 36);

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

1 个答案:

答案 0 :(得分:0)

您的顶点着色器代码未命中为v_Color变量变量赋值,这导致没有颜色从顶点着色器传递到片段着色器。您需要将其添加到顶点着色器代码中的main()函数:

v_Color = aColor;

aPosition的声明之间的名称也不匹配,然后使用名为vPosition的(未定义的)变量。

我强烈建议您检查着色器编辑的结果,并在失败时研究错误。 glGetShaderiv()glGetShaderInfoLog()是你的朋友。