2012-05-29 29 views
0

我想在OpenGLES 2.0中使用浮点数组来代替FloatBuffer,但是当我这样做时,我的glDrawArrays给出错误0x502或GL_INVALID_OPERATION。Android使用float []作为顶点导致OpenGL错误0x502

我没有得到这个错误,当我使用FloatBuffers时,一切正常。

我读过这个错误通常是由程序没有设置。我只使用一个着色器程序,并在一切初始化时设置它。

这里是我的代码

public class LineEngine { 
    private static final float[] IDENTIY = new float[16]; 
    private float[] mLinePoints; 
    private float[] mLineColors; 
    private int mCount; 

    public LineEngine(int maxLines) { 
     Matrix.setIdentityM(IDENTIY, 0); 

     mLinePoints = new float[maxLines * 2 * 4]; 
     mLineColors = new float[maxLines * 2 * 4]; 

     reset(); 
    } 

    public void addLine(float[] position, float[] color) { 
     int offset = mCount * 2 * 4; 
     System.arraycopy(position, 0, mLinePoints, offset, 8); 
     System.arraycopy(color, 0, mLineColors, offset, 4); 
     System.arraycopy(color, 0, mLineColors, offset + 4, 4); 

     mCount++; 
    } 

    public void reset() { 
     mCount = 0; 
    } 

    public void draw() { 
     if (mCount > 0) { 
      GraphicsEngine.setMMatrix(IDENTIY); 
      GraphicsEngine.setColors(mLineColors); 
      GraphicsEngine.setVertices4d(mLinePoints); 
      GraphicsEngine.disableTexture(); 
      GLES20.glDrawArrays(GLES20.GL_LINES, 0, mCount * 2); 

      int error = GLES20.glGetError(); 
      if (error != 0) 
       Log.e("OpenGL", "Draw " + error); // Prints error 1282 

      GraphicsEngine.disableColors(); 
      reset(); 
     } 
    } 
} 

此代码工作正常,没有错误

public class LineEngine { 
    private static final float[] IDENTIY = new float[16]; 
    private FloatBuffer mLinePoints; 
    private FloatBuffer mLineColors; 
    private int mCount; 

    public LineEngine(int maxLines) { 
     Matrix.setIdentityM(IDENTIY, 0); 

     ByteBuffer byteBuf = ByteBuffer.allocateDirect(maxLines * 2 * 4 * 4); 
     byteBuf.order(ByteOrder.nativeOrder()); 
     mLinePoints = byteBuf.asFloatBuffer(); 

     byteBuf = ByteBuffer.allocateDirect(maxLines * 2 * 4 * 4); 
     byteBuf.order(ByteOrder.nativeOrder()); 
     mLineColors = byteBuf.asFloatBuffer(); 

     reset(); 
    } 

    public void addLine(float[] position, float[] color) { 
     mLinePoints.put(position, 0, 8); 
     mLineColors.put(color, 0, 4); 
     mLineColors.put(color, 0, 4); 
     mCount++; 
    } 

    public void reset() { 
     mLinePoints.position(0); 
     mLineColors.position(0); 
     mCount = 0; 
    } 

    public void draw() { 
     if (mCount > 0) { 
      mLinePoints.position(0); 
      mLineColors.position(0); 
      GraphicsEngine.setMMatrix(IDENTIY); 
      GraphicsEngine.setColors(mLineColors); 
      GraphicsEngine.setVertices4d(mLinePoints); 
      GraphicsEngine.disableTexture(); 
      GLES20.glDrawArrays(GLES20.GL_LINES, 0, mCount * 2); 

      int error = GLES20.glGetError(); 
      if (error != 0) 
       Log.e("OpenGL", "Draw " + error); // no errors 

      GraphicsEngine.disableColors(); 
      reset(); 
     } 
    } 
} 

的相关GraphicsEngine代码是在这里

public static void setVertices4d(FloatBuffer vertices) { 
    GLES20.glVertexAttribPointer(aVertexHandle, 4, GLES20.GL_FLOAT, false, 
      16, vertices); 
    GLES20.glEnableVertexAttribArray(aVertexHandle); 
    mState.shape = -1; 
} 

public static void setVertices4d(float[] vertices) { 
    GLES20.glVertexAttrib4fv(aVertexHandle, vertices, 0); 
    GLES20.glEnableVertexAttribArray(aVertexHandle); 
    mState.shape = -1; 
} 

public static void setColors(FloatBuffer colors){ 
    GLES20.glVertexAttribPointer(aColor, 4, GLES20.GL_FLOAT, false, 
      16, colors); 
    GLES20.glEnableVertexAttribArray(aColor); 
    GLES20.glUniform1i(GraphicsEngine.uEnableColors, 1); 
} 

public static void setColors(float[] colors){ 
    GLES20.glVertexAttrib4fv(aColor, colors, 0); 
    GLES20.glEnableVertexAttribArray(aColor); 
    GLES20.glUniform1i(GraphicsEngine.uEnableColors, 1); 
} 

我不想使用FloatBuffers因为它们比浮点数组更慢。

回答

3

您没有选择,只能使用FloatBuffers代码。

您的setVertices4d方法需要float[]已损坏,您无法以此方式使用glVertexAttrib4fv。 glVertexAttrib4只指定单个顶点,并且使用版本仅将属性的值作为数组传递给该单个顶点,但不会设置类似于指针函数的顶点数组。

+0

你可以使用glUniform4fv传递一个长度大于1的float [],但是对于制服来说呢?我在我的代码的另一部分这样做,它的工作。顶点属性是否独一无二? 看看http://www.khronos.org/opengles/sdk/docs/man/xhtml/glVertexAttrib.xml它说_指定一个指向要用于通用顶点属性的值的数组的指针._这使得它听起来像你可以传递多个值。 – EmbMicro

+1

制服和属性完全不同。制服只是一个始终不变的单一值。当你指定属性时,你要创建一个大的属性列表,以便每个顶点有一个属性。 glVertexAttrib一次指定单个顶点的属性。如果你想定义一个顶点数组,那么你必须使用glVertexAttribPointer和FloatBuffers。 – Tim

+0

你知道我在哪里可以找到关于这一切的任何文档吗? – EmbMicro