防止OpenGL清除

时间:2014-02-06 18:11:19

标签: android opengl-es

我在Android中有一个OpenGL WallpaperService,我想要实现的是在不丢失我已经绘制的内容的情况下添加(绘制)某些内容。目前我只使用三角形等基元,但仍然无法实现我的目标。这是我的代码:

渲染器:

@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°旋转后创建一个圆圈。

1 个答案:

答案 0 :(得分:0)

OpenGL ES(或实际上是EGL)的工作方式是在“交换”帧之后,帧的内容是未定义的。如果您只想进行更新,则需要将交换行为设置为EGL_BUFFER_PRESERVED。我认为在onSurfaceCreated中调用下面的代码应该启用它(未测试):

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