2013-10-25 1 views
3

Android 개발자! 문제가 있습니다. 내 안드로이드 애플 리케이션 OpenGL을 사용하여 몇 줄을 그려야합니다. 예를 들어 으로 시작하여 다시 작성했습니다. 그것은 IllegalArgumentException을 던집니다 : GLES20.glVertexAttribPointer를 호출 할 때 네이티브 오더 직접 버퍼를 사용해야합니다. 나는 내가 사용했던 예에서와 같이, 왜 그것을 nativeorder로 설정했는지 이해하지 못한다. 여기 내 전체 OpenGLRenderer 클래스는 다음과 같습니다 (I는 플로트 [] 매개 변수와 함께 두 번째 생성자를 사용하여이 클래스의 인스턴스를 생성 할 때),Android OpenGL : IllegalArgumentException 기본 순서 직접 버퍼 사용

public class OpenGLRenderer implements GLSurfaceView.Renderer { 

     final int COORDS_PER_VERTEX = 3; 
     final int NR_OF_LINES; 
     final int NR_OF_VERTECES; 
     final int VertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex 
     final int NR_OF_VERTECES_PER_LINE = 2; 
     final int BYTES_PER_VERTEX = 4; 


    private FloatBuffer bufferVertecesLines; 
    private float[] arrayVertecesLines; 
    //private FloatBuffer ColorBuffer;  
    // Set color with red, green, blue and alpha (opacity) values 
    float color[] = { 0.3f, 0.7f, 0.2f, 1.0f }; 

    private int GlProgram; 
    private int PositionHandle; 
    private int ColorHandle; 


    //SHADERS---------------------------------------------------------------------------------------------------------------------------- 
    private final String VertexShaderCode = 
      // This matrix member variable provides a hook to manipulate 
     // the coordinates of the objects that use this vertex shader 
     "uniform mat4 uMVPMatrix;" + 

     "attribute vec4 vPosition;" + 
     "void main() {" + 
     // the matrix must be included as a modifier of gl_Position 
     " gl_Position = uMVPMatrix * vPosition;" + 
     "}"; 

    private final String FragmentShaderCode = 
      "precision mediump float;" + 
     "uniform vec4 vColor;" + 
     "void main() {" + 
     " gl_FragColor = vColor;" + 
     "}"; 


    //CONSTRUCTOR---------------------------------------------------------------------------------------------------------------------------- 
    public OpenGLRenderer(FloatBuffer thisLineVertexBuffer, int numberoflines) 
    { 

     bufferVertecesLines = thisLineVertexBuffer; 
     NR_OF_VERTECES = numberoflines * 2; 
     NR_OF_LINES = numberoflines; 
     Log.v("Leen","mijn eigen logje - OpenGLRenderer - Constructor"); 
    } 

    public OpenGLRenderer(float[] thisLineVertexArray) 
    { 
     arrayVertecesLines = thisLineVertexArray; 
     NR_OF_VERTECES = thisLineVertexArray.length/COORDS_PER_VERTEX; 
     NR_OF_LINES = thisLineVertexArray.length/COORDS_PER_VERTEX/NR_OF_VERTECES_PER_LINE; 
    } 

    private void convertArrayToBuffer() 
    { 
     int NrOfBytes = NR_OF_LINES * NR_OF_VERTECES_PER_LINE * COORDS_PER_VERTEX * BYTES_PER_VERTEX; 
     // in voorbeeld: 
     // NrOfBytes =   2 *   2   *   3   *  4  = 48     

     ByteBuffer bb = ByteBuffer.allocate(NrOfBytes); 
     bb.order(ByteOrder.nativeOrder()); 
     bufferVertecesLines = bb.asFloatBuffer(); 
     bufferVertecesLines.put(arrayVertecesLines); 

    } 

    //--------------------------------------------------------------------------------------------------------------------------------------- 
    @Override 
    public void onSurfaceChanged(GL10 unused, int width, int height) 
    { 
     // Adjust the viewport based on geometry changes, 
     // such as screen rotation 
     GLES20.glViewport(0, 0, width, height); 
    } 

    //--------------------------------------------------------------------------------------------------------------------------------------- 
    @Override 
    public void onDrawFrame(GL10 arg0) 
    { 
     int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, VertexShaderCode); 
     int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, FragmentShaderCode); 

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

     this.drawAllLines(); 
    } 

    //--------------------------------------------------------------------------------------------------------------------------------------- 
    @Override 
    public void onSurfaceCreated(GL10 unused, EGLConfig config) 
    { 
     GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    } 


    //--------------------------------------------------------------------------------------------------------------------------------------- 
    public static int loadShader(int type, String shaderCode){ 

     // create a vertex shader type (GLES20.GL_VERTEX_SHADER) 
     // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) 
     int shader = GLES20.glCreateShader(type); 

     // add the source code to the shader and compile it 
     GLES20.glShaderSource(shader, shaderCode); 
     GLES20.glCompileShader(shader); 

     return shader; 

    } 

    //--------------------------------------------------------------------------------------------------------------------------------------- 
    public void drawAllLines() 
    { 
     // Add program to OpenGL ES environment 
     GLES20.glUseProgram(GlProgram); 

     // get handle to vertex shader's vPosition member 
     PositionHandle = GLES20.glGetAttribLocation(GlProgram, "vPosition"); 

     // Enable a handle to the triangle vertices 
     GLES20.glEnableVertexAttribArray(PositionHandle); 

     // Prepare the Line coordinate data 
     // vertexstride = offset. 3 coordinaten per vertex * 4 bytes per vertex = 12 

     this.convertArrayToBuffer(); 

     GLES20.glVertexAttribPointer(PositionHandle, COORDS_PER_VERTEX, 
              GLES20.GL_FLOAT, false, 
              VertexStride, bufferVertecesLines); 

     // get handle to fragment shader's vColor member 
     ColorHandle = GLES20.glGetUniformLocation(GlProgram, "vColor"); 

     // Set color for drawing the triangle 
     GLES20.glUniform4fv(ColorHandle, 1, color, 0); 

     // Draw the triangle 
     GLES20.glDrawArrays(GLES20.GL_LINES, 0, NR_OF_VERTECES); 

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

    } 

} 

답변

1
private void convertArrayToBuffer() 
{ 
    int NrOfBytes = NR_OF_LINES * NR_OF_VERTECES_PER_LINE * COORDS_PER_VERTEX * BYTES_PER_VERTEX; 
    // in voorbeeld: 
    // NrOfBytes =   2 *   2   *   3   *  4  = 48     

    ByteBuffer bb = ByteBuffer.allocate(NrOfBytes); 
    bb.order(ByteOrder.nativeOrder()); 
    bufferVertecesLines = bb.asFloatBuffer(); 
    bufferVertecesLines.put(arrayVertecesLines); 
    bb.position(0);     //!!!!!!!!!!!!! 
    bufferVertecesLines.position(0);//!!!!!!!!!!!!! 
} 
+0

노력에 감사하지만 그것을 고치지 않았습니다. 나는 당신이 말했던 것처럼 변수 bb에 대해'position (0)'메소드를 사용했고 변수'bufferVertecesLines'에 대해서도 사용했고 (GLES20.glVertexAttribPointer 명령문 바로 앞에있는 다른 곳에서) 사용하려고했습니다. 다른 방법으로는 flip() 메서드를 사용했지만 성공하지 못했습니다. 다른 아이디어는 무엇입니까? – blubbiedevis

+0

한편, 내 의견과 편집 내용은 서로 엇갈 렸지만 위의 내 의견은 여전히 ​​중요합니다 ... – blubbiedevis

15

확인을 발견했다. 나는 ByteBuffer.allocate() 메서드를 사용하지 않았지만 ByteBuffer.allocateDirect() 메서드를 사용했습니다. 이 조각은 예외를 던지지 않고 있습니다 :

private void convertArrayToBuffer() 
{ 
    int NrOfBytes = NR_OF_LINES * NR_OF_VERTECES_PER_LINE * COORDS_PER_VERTEX * BYTES_PER_VERTEX; 
    // in voorbeeld: 
    // NrOfBytes =   2 *   2   *   3   *  4  = 48     

    ByteBuffer bb = ByteBuffer.allocateDirect(NrOfBytes);  //!!!!!!!!!! 
    bb.order(ByteOrder.nativeOrder()); 
    bufferVertecesLines = bb.asFloatBuffer(); 
    bufferVertecesLines.put(arrayVertecesLines); 
    bb.position(0);     
    bufferVertecesLines.position(0); 
}