2012-05-29 2 views
0

OpenGLES 2.0에서 FloatBuffer 대신 Android에서 float 배열을 사용하려고하지만 glDrawArrays가 0x502 또는 GL_INVALID_OPERATION 오류를 발생시킵니다.안드로이드에서 vertex로 float []을 사용하면 OpenGL 오류가 발생합니다. 0x502

이 오류가 발생하지 않고 모든 것이 FloatBuffers를 사용할 때 제대로 작동합니다.

나는이 오류가 일반적으로 프로그램이 설정되지 않아 발생했다고 읽었습니다. 나는 하나의 쉐이더 프로그램만을 사용하고 모든 것이 초기화 될 때 그것을 설정한다. 여기

이 코드는 내가 FloatBuffers을 사용하지 않으

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

관련 GraphicsEngine 코드가 여기에있다

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

오류없이 잘 작동

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

내 코드입니다 그들은 수레의 배열보다 변화하기 때문에 느립니다.

답변

3

이 코드에는 FloatBuffers를 사용할 수밖에 없습니다.

float[]을 사용하는 사용자의 setVertices4d 메서드는 고장났습니다. 그런 식으로 glVertexAttrib4fv를 사용할 수 없습니다. glVertexAttrib4는 단일 정점 만 지정하고 v 버전은 속성 값을 해당 단일 정점에 배열로 전달하기 만하면 포인터 기능과 유사한 정점 배열을 설정하지 않습니다.

+0

glUniform4fv를 사용하여 유니폼의 길이가 1보다 큰 float []을 전달할 수 있습니까? 내 코드의 다른 섹션에서 그렇게하고 있으며 작동하고 있습니다. 당신이 할 수 없도록하는 꼭지점 속성에 대해 독특한 것이 있습니까? http://www.khronos.org/opengles/sdk/docs/man/xhtml/glVertexAttrib.xml에서 알 수 있듯이 _ 일반 정점 속성에 사용할 값 배열에 대한 포인터를 지정합니다 ._ 이렇게하면 하나 이상의 가치를 전달할 수있는 것 같은 소리. – EmbMicro

+1

유니폼 및 속성은 완전히 다릅니다. 유니폼은 항상 일정한 단일 값입니다. 속성을 지정할 때, 당신은 하나의 꼭지점 당 하나의 속성 목록을 생성합니다. glVertexAttrib는 한 번에 하나의 꼭지점에 대한 속성을 지정합니다. 정점의 배열을 정의하려면, glVertexAttribPointer를 FloatBuffers와 함께 사용해야합니다. – Tim

+0

이 모든 것에 관한 문서를 어디에서 찾을 수 있는지 알고 계십니까? – EmbMicro