2014-02-06 50 views
0

我在Android中有一個OpenGL WallpaperService,我想要實現的是向場景添加(繪製)某些內容,而不會丟失已經繪製的內容。目前,我只與三角形等原始圖形工作,但仍然無法實現我的目標。這裏是我的代碼:防止OpenGL清除

渲染:

@Override 
public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
    // Set the background color to black (rgba). 
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); 
    // Enable Smooth Shading, default not really needed. 
    gl.glShadeModel(GL10.GL_SMOOTH); 
    // Depth buffer setup. 
    gl.glClearDepthf(1.0f); 
    // Enables depth testing. 
    gl.glEnable(GL10.GL_DEPTH_TEST); 
    // The type of depth testing to do. 
    gl.glDepthFunc(GL10.GL_LEQUAL); 
    // Really nice perspective calculations. 
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, 
      GL10.GL_NICEST); 
} 

@Override 
public void onSurfaceChanged(GL10 gl, int width, int height) { 
    // Sets the current view port to the new size. 
    gl.glViewport(0, 0, width, height); 
    // Select the projection matrix 
    gl.glMatrixMode(GL10.GL_PROJECTION); 
    // Reset the projection matrix 
    gl.glLoadIdentity(); 
    // Calculate the aspect ratio of the window 
    GLU.gluPerspective(gl, 45.0f, 
      (float) width/(float) height, 
      0.1f, 100.0f); 
    // Select the modelview matrix 
    gl.glMatrixMode(GL10.GL_MODELVIEW); 
    // Reset the modelview matrix 
    gl.glLoadIdentity(); 
} 

@Override 
public void onDrawFrame(GL10 gl) { 
    // Clears the screen and depth buffer. 
    //gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
    // Replace the current matrix with the identity matrix 
    gl.glLoadIdentity(); 
    // Translates 10 units into the screen. 
    gl.glTranslatef(0, 0, -10); 

    // SQUARE A 
    // Save the current matrix. 
    gl.glPushMatrix(); 
    // Rotate square A counter-clockwise. 
    gl.glRotatef(angle, 0, 0, 1); 
    // Draw square A. 
    square.draw(gl); 
    // Restore the last matrix. 
    gl.glPopMatrix(); 

    // SQUARE B 
    // Save the current matrix 
    gl.glPushMatrix(); 
    // Rotate square B before moving it, making it rotate around A. 
    gl.glRotatef(-angle, 0, 0, 1); 
    // Move square B. 
    gl.glTranslatef(2, 0, 0); 
    // Scale it to 50% of square A 
    gl.glScalef(.5f, .5f, .5f); 
    // Draw square B. 
    square.draw(gl); 

    // SQUARE C 
    // Save the current matrix 
    gl.glPushMatrix(); 
    // Make the rotation around B 
    gl.glRotatef(-angle, 0, 0, 1); 
    gl.glTranslatef(2, 0, 0); 
    // Scale it to 50% of square B 
    gl.glScalef(.5f, .5f, .5f); 
    // Rotate around it's own center. 
    gl.glRotatef(angle*10, 0, 0, 1); 
    // Draw square C. 
    square.draw(gl); 

    // Restore to the matrix as it was before C. 
    gl.glPopMatrix(); 
    // Restore to the matrix as it was before B. 
    gl.glPopMatrix(); 

    // Increse the angle. 
    angle++; 
} 

廣場:

public Square() { 
    // a float is 4 bytes, therefore we multiply the number if 
    // vertices with 4. 
    ByteBuffer vbb = ByteBuffer.allocateDirect(mVertices.length * 4); 
    vbb.order(ByteOrder.nativeOrder()); 
    mVertexBuffer = vbb.asFloatBuffer(); 
    mVertexBuffer.put(mVertices); 
    mVertexBuffer.position(0); 

    // short is 2 bytes, therefore we multiply the number if 
    // vertices with 2. 
    ByteBuffer ibb = ByteBuffer.allocateDirect(mIndices.length * 2); 
    ibb.order(ByteOrder.nativeOrder()); 
    mIndexBuffer = ibb.asShortBuffer(); 
    mIndexBuffer.put(mIndices); 
    mIndexBuffer.position(0); 
} 

/** 
* This function draws our square on screen. 
* @param gl 
*/ 
public void draw(GL10 gl) { 
    // Counter-clockwise winding. 
    gl.glFrontFace(GL10.GL_CCW); 
    // Enable face culling. 
    gl.glEnable(GL10.GL_CULL_FACE); 
    // What faces to remove with the face culling. 
    gl.glCullFace(GL10.GL_BACK); 

    // Enabled the vertices buffer for writing and to be used during 
    // rendering. 
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
    // Specifies the location and data format of an array of vertex 
    // coordinates to use when rendering. 
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer); 

    gl.glDrawElements(GL10.GL_TRIANGLES, mIndices.length, 
      GL10.GL_UNSIGNED_SHORT, mIndexBuffer); 

    // Disable the vertices buffer. 
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
    // Disable face culling. 
    gl.glDisable(GL10.GL_CULL_FACE); 
} 

現在它顯示3個格在空間中旋轉各地的不同點。但是我不想清除它,所以它可以在360°旋轉後創建一個圓。

回答

0

OpenGL ES(或實際上是EGL)的工作原理是,在一個幀被「交換」之後,幀的內容是未定義的。如果只想執行更新,則需要將交換行爲設置爲EGL_BUFFER_PRESERVED。我想調用onSurfaceCreated下面的代碼應該啓用此(未測試):

eglSurfaceAttrib(eglGetCurrentDisplay(), eglGetCurrentSurface(), EGL_SWAP_BEHAVIOUR, EGL_BUFFER_PRESERVED); 
+0

我從javax.microedition.khronos.opengles包GL10類的工作。 GLSurfaceView有幾種類似於你提到的方法,但不是那個。即使谷歌不知道它可能在哪裏。你能指定更多嗎? – arenaq

+0

你可以在[android.opengl.EGL14](http://developer.android.com/reference/android/opengl/EGL14.html)找到這些函數。 –

+0

是的,首先它需要API lvl 17 ...在我看來,對於像防止清理這樣的小事來說真的很頑固......它應該像某個時間參數一樣......不要告訴我,另一種方式是記住我的對象所做的所有路徑並將它們繪製每一幀......必須有更簡單的方法 – arenaq