2012-05-29 47 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