2016-11-09 6 views
0

Ich habe eine Punktklasse, die einen Puffer verwendet, um einige Punkte zu zeichnen. Ich möchte den Inhalt des Gezeichneten ändern können (aktualisiere die Szene mit neuen Punkten). Das Erstellen eines völlig neuen Objekts klingt nicht wirklich gut, also habe ich versucht, den Inhalt des Puffers zu ändern. Kürzlich habe ich über glBufferSubData() herausgefunden, aber ich weiß nicht, wie man es benutzt.Vertex-Pufferdaten dynamisch ändern opengl

Hier ist mein Punkt Klasse:

public class Point { 
    private int mProgram, mPositionHandle, mColorHandle, mMVPMatrixHandle; 
    private FloatBuffer vertexBuffer,colorBuffer; 
    private static final int COORDS_PER_VERTEX = 3; 
    private static final int COORDS_PER_COLOR = 3; 
    private int vertexCount,colorCount; 


    private final String vertexShaderCode = 
      "uniform mat4 uMVPMatrix;" + 
        "attribute vec4 vPosition;" + 
        "attribute mediump vec4 vColor;" + 
        "varying mediump vec4 vaColor;" + 
        "void main() {" + 
        " vaColor = vColor;" + 
        " gl_Position = uMVPMatrix * vPosition;" + 
        " gl_PointSize = 20.0;" + 
        "}"; 

    private final String fragmentShaderCode = 
      "precision mediump float;" + 
        "varying mediump vec4 vaColor;" + 
        "void main() {" + 
        " gl_FragColor = vaColor;" + 
        "}"; 


    private static int vertexStride = COORDS_PER_VERTEX * 4; 
    private final int colorStride = COORDS_PER_COLOR * 4; 


    public Point(float pointCoords[],float colorCoords[]){ 
     this.vertexCount = pointCoords.length/COORDS_PER_VERTEX; 
     this.colorCount = colorCoords.length/COORDS_PER_COLOR; 

     ByteBuffer vbb = ByteBuffer.allocateDirect(pointCoords.length * 4); 
     vbb.order(ByteOrder.nativeOrder()); 
     vertexBuffer = vbb.asFloatBuffer(); 
     vertexBuffer.put(pointCoords); 
     vertexBuffer.position(0); 



     ByteBuffer cbb = ByteBuffer.allocateDirect(colorCoords.length * 4); 
     cbb.order(ByteOrder.nativeOrder()); 
     colorBuffer = cbb.asFloatBuffer(); 
     colorBuffer.put(colorCoords); 
     colorBuffer.position(0); 


     int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, 
       vertexShaderCode); 
     int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, 
       fragmentShaderCode); 

     // create empty OpenGL ES Program 
     mProgram = GLES20.glCreateProgram(); 

     // create empty OpenGL ES Program 
     mProgram = GLES20.glCreateProgram(); 

     // add the vertex shader to program 
     GLES20.glAttachShader(mProgram, vertexShader); 

     // add the fragment shader to program 
     GLES20.glAttachShader(mProgram, fragmentShader); 

     // creates OpenGL ES program executables 
     GLES20.glLinkProgram(mProgram); 
    } 

    public void draw(float[] mvpMatrix) { 
     // Add program to OpenGL ES environment 
     GLES20.glUseProgram(mProgram); 

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

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

     // Prepare the point coordinate data 
     GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, 
       GLES20.GL_FLOAT, false, 
       vertexStride, vertexBuffer); 


     mColorHandle = GLES20.glGetAttribLocation(mProgram,"vColor"); 

     GLES20.glEnableVertexAttribArray(mColorHandle); 
     // Set color for drawing the triangle 
     GLES20.glVertexAttribPointer(mColorHandle, COORDS_PER_COLOR, GLES20.GL_FLOAT, false, 
       colorStride, colorBuffer); 

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

     //TRANSLATION 
     float[] transMatrix = new float[16]; 

     Matrix.setIdentityM(transMatrix,0); 
     Matrix.translateM(transMatrix,0,0.5f,0,0); 
     Matrix.multiplyMM(transMatrix,0,mvpMatrix,0,transMatrix,0); 


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

     GLES20.glDrawArrays(GLES20.GL_POINTS, 0, vertexCount); 

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

    /** 
    * Change content of buffer 
    */ 
    public void changeBufferData(float[] newBufferInfo) { 
     GLES20.glBufferSubData(?,0,newBufferInfo.length*4,vertexBuffer); 
    } 

    } 

Antwort

0

Sie sind zur Zeit clientseitige Vertex Arrays mit Daten pro Ziehung mit glVertexAttribPointer hochgeladen werden. Das dynamische Aktualisieren wird nicht teurer als das, was Sie bereits tun, da Sie bereits für jeden Zeichenvorgang Daten in den treibereigenen Speicher zuteilen und kopieren müssen.

jedoch, wie Sie sagen, ist Puffer neu zu teuer, so vermeidet clientseitige Vertex-Upload ist sehr zu empfehlen ...

Der Teil, den Sie fehlt, ist die Notwendigkeit, einen Vertex Buffer Objekt zu erstellen (glGenBuffers, etc) , die Sie dann anstelle von clientseitigen Attributen verwenden können. glBufferData und glSubBufferData werden verwendet, um den Inhalt eines dieser Pufferobjekte zu patchen.

+0

Ich bin ziemlich neu zu öffnen gl. Ich verstehe, was du sagst, ich werde versuchen zu sehen, ob ich das umsetzen kann. –

+0

Dies könnte helfen: http://www.learnopengles.com/android-lesson-seven-an-introduction-to-vertex-buffer-objects-vbos/ – solidpixel