【问题标题】:Android OpenGL ES 2.0 colour buffer not workingAndroid OpenGL ES 2.0 颜色缓冲区不起作用
【发布时间】:2015-04-30 14:21:12
【问题描述】:

我一直在关注本教程:http://developer.android.com/training/graphics/opengl/index.html,并且一切正常。目前我有一个用于顶点位置的缓冲区,一个用于绘制顶点的顺序。我想为每个顶点的颜色添加一个,但是当我这样做时,我在 GLES20.glUseProgram() 中收到错误 1282。

任何帮助都会很棒,因为我有点 GL 菜鸟。

这是我的着色器代码:

    static public final String vertexShaderCode =
        "uniform mat4 uMVPMatrix;" +
                "attribute vec4 aPosition;" +
                "attribute vec4 aColor;" + 
                "varying vec4 vColor;" + 
                "void main() {" +
                "  gl_Position = uMVPMatrix * aPosition;" +
                "  vColor = aColor;" +
                "}";

static public final String fragmentShaderCode =
        "varying vec4 vColor;" +
                "void main() {" +
                "  gl_FragColor = vColor;" +
                "}";

我加载的内容:

    int shaderV = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
    GLES20.glShaderSource(shaderV, vertexShaderCode);
    GLES20.glCompileShader(shaderV);

    int shaderF = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
    GLES20.glShaderSource(shaderF, fragmentShaderCode);
    GLES20.glCompileShader(shaderF);

我是这样设置程序的:

    int vertexShader = ShaderInfo.GetVertexShader();
    int fragmentShader = ShaderInfo.GetFragmentShader();

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

在每个时间步长/循环/迭代/我称之为:

    GLES20.glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    MyGLRenderer.checkGlError("glClearColor");

    // Redraw background color
    //GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    MyGLRenderer.checkGlError("glClear");

    // Set the camera position (View matrix)
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
    MyGLRenderer.checkGlError("setLookAtM");

    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
    MyGLRenderer.checkGlError("multiplyMM");

    // Draw shape
    rect.Draw(mMVPMatrix);

在哪里 rect.Draw();由:

    MyGLRenderer.checkGlError("BEFOREglUseProgram");
    GLES20.glUseProgram(mProgram);
    MyGLRenderer.checkGlError("glUseProgram");

    // get handle to vertex shader's vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
    MyGLRenderer.checkGlError("glGetAttribLocationPosition");
    // Enable a handle to the triangle vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);

    // get handle to fragment shader's aColor member
    mColorHandle = GLES20.glGetUniformLocation(mProgram, "aColor");
    // Set color for drawing the triangle
    GLES20.glUniform4fv(mColorHandle, 1, color, 0);

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

    // Apply the projection and view transformation
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
    MyGLRenderer.checkGlError("glUniformMatrix4fv");

    GLES20.glDrawElements(
            GLES20.GL_TRIANGLES, drawOrder.length,
            GLES20.GL_UNSIGNED_SHORT, drawListBuffer);

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

最后,我像这样创建缓冲区:

private short drawOrder[] = { };
private void SetDrawOrder()
{
    if(drawOrder.length != elements.size()*3)
        drawOrder = new short[elements.size()*3];
    for(int i = 0; i< elements.size(); i++)
    {
        drawOrder[i*3 + 0] = (short)elements.get(i).nodes.get(0).indexInMesh;
        drawOrder[i*3 + 1] = (short)elements.get(i).nodes.get(1).indexInMesh;
        drawOrder[i*3 + 2] = (short)elements.get(i).nodes.get(2).indexInMesh;
    }

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

private void AddNodesToArray()
{

    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(
            // (number of coordinate values * 4 bytes per float)
            vertexCount * COORDS_PER_VERTEX * 4);
    // use the device hardware's native byte order
    bb.order(ByteOrder.nativeOrder());

    // create a floating point buffer from the ByteBuffer
    vertexBuffer = bb.asFloatBuffer();
    // add the coordinates to the FloatBuffer
    for(int i = 0; i< nodes.size(); i++)
        vertexBuffer.put(nodes.get(i).position);
    // set the buffer to read the first coordinate
    vertexBuffer.position(0);
}

private void AddColoursToArray()
{

    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(
            // (number of coordinate values * 4 bytes per float)
            vertexCount * 4 * 4);
    // use the device hardware's native byte order
    bb.order(ByteOrder.nativeOrder());

    // create a floating point buffer from the ByteBuffer
    colourBuffer = bb.asFloatBuffer();
    // add the coordinates to the FloatBuffer
    for(int i = 0; i< nodes.size(); i++)
        colourBuffer.put(nodes.get(i).colour);
    // set the buffer to read the first coordinate
    colourBuffer.position(0);
}

【问题讨论】:

  • 上述问题的任何解决方案..?我也遇到了同样的问题
  • 很遗憾没有,抱歉。

标签: android opengl-es opengl-es-2.0


【解决方案1】:

这段代码

// get handle to fragment shader's aColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "aColor");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, color, 0);

不会工作。 aColor 在着色器中不是统一的,而是顶点属性。您永远不会为您的属性设置顶点属性指针。

【讨论】:

  • 感谢您的回复!我有“属性 vec4 aColor;”在我的顶点着色器代码中,您是说我应该将其更改为“”uniform vec4 aColor;”吗?这仍然给我同样的错误(在 glUseProgram 中)。
  • 没有。你想要一个每个顶点的属性。所以你必须将它保留为attribute,但也要在客户端代码中处理它。基本上,您必须执行与 aPosition 相同的操作:qyeri 位置,启用属性数组,设置属性指针。
  • 我已将其更改为:mColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor"); MyGLRenderer.checkGlError("glGetAttribLocationColor"); GLES20.glEnableVertexAttribArray(mColorHandle); GLES20.glVertexAttribPointer(mColorHandle, 4, GLES20.GL_FLOAT, false, colourStride, colourBuffer);但是我仍然在 glUseProgram 遇到错误,对此有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-27
  • 1970-01-01
  • 2011-02-05
  • 2014-12-18
  • 1970-01-01
相关资源
最近更新 更多