尝试有选择地重绘一个Android游戏的背景,但运动图像在屏幕上重复

时间:2011-04-09 16:40:19

标签: android opengl-es

如果我刚开始显示问题的图片,这是最简单的。这些图片显示了纹理的快照。

我的HTC Hero上的应用程序:

Image from my Hero

模拟器上的相同应用程序工作正常(忽略随机放置的剩余物,我知道它们的原因,这不是问题): Image from the emulator

现在,如果你看第一张图片,最上面的图片是“真实图片”,其他图片总是跟在下面,上面还有副本。我目前只是重新绘制了所访问的背景方块,并且由于某种原因它们被绘制在副本上方(你可以看到它们都被瓷砖部分地涂上了)。

你是否必须在Android手机的每一帧上重画整个屏幕?或者是否有可能摆脱这些奇怪的副本?

以下是用于绘制纹理的代码(我是opengl-es的新手,所以它很像复制岛):

第一

public static void beginDrawing(GL10 gl, float viewWidth, float viewHeight) {
    gl.glShadeModel(GL10.GL_FLAT);
    gl.glEnable(GL10.GL_BLEND);
    gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
    gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);

    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glPushMatrix();
    gl.glLoadIdentity();
    gl.glOrthof(0.0f, viewWidth, 0.0f, viewHeight, 0.0f, 1.0f);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glPushMatrix();
    gl.glLoadIdentity();

    gl.glEnable(GL10.GL_TEXTURE_2D);
}

然后对于每个纹理(我首先绘制背景,然后在这种情况下只有一个绿色纹理。我确定它只被绘制一次):

        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
        ((GL11Ext) gl).glDrawTexfOES(x, y, 0, (float) mWidth, (float) mHeight); 

最后:

public static void endDrawing(GL10 gl) {
    gl.glDisable(GL10.GL_BLEND);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glPopMatrix();
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glPopMatrix();
}

我用来加载纹理的代码:

private void loadGLTextures(GL10 gl) {
    int[] textures = new int[1];
    gl.glGenTextures(1, textures, 0);
    textureID = textures[0];

    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
            GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
            GL10.GL_LINEAR);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
            GL10.GL_CLAMP_TO_EDGE);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
            GL10.GL_CLAMP_TO_EDGE);
    gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
            GL10.GL_MODULATE);

    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
    int[] mCropWorkspace = new int[4];
    mCropWorkspace[0] = 0;
    mCropWorkspace[1] = bitmap.getHeight();
    mCropWorkspace[2] = bitmap.getWidth();
    mCropWorkspace[3] = -bitmap.getHeight();
    ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, 
            GL11Ext.GL_TEXTURE_CROP_RECT_OES, 
            mCropWorkspace,
            0);
    mCrop = mCropWorkspace;
    bitmap.recycle();
}

所有帮助都很受欢迎,如果有任何不清楚的地方请发表评论!

编辑:我应该补充一点,如果我每一帧重绘所有正方形,那么“额外”图像就会被隐藏,并且它会按照应有的方式工作。

2 个答案:

答案 0 :(得分:2)

  

你是否必须在Android手机的每一帧上重画整个画面?

是的,这就是使用双缓冲的原因。 在显示当前帧时准备下一帧。

答案 1 :(得分:1)

我可以知道你在哪里清楚了之前访问过的广场。绝对有可能只更新脏药水。但假设您使用android进行编码,它会维护两个内部交换的缓冲区。在这种情况下,您必须确保清除2帧后图像的区域。