在GLSurfaceView中的onResume()之后重新加载opengl纹理

时间:2011-03-06 20:24:51

标签: android opengl-es

我有一个带有2个活动的Android应用程序,A和B.应用程序以A开头,然后我点击屏幕切换到B. B正确显示,然后我按下手机上的后退按钮切换回A现在活动正常运行,除了我看不到我的纹理。活动的onResume方法调用GLSurfaceView的onResume方法,它在onSurfaceCreated上调用我的渲染器,然后调用onSurfaceChanged。在每个帧上调用onDrawFrame之后,它只会清除具有给定颜色的屏幕。我知道GLSurfaceView的onPause会破坏它的内容,onResume应该重建它,但它对我不起作用:(

我的代码:

渲染器:

public class GlRenderer implements Renderer {

private Context     context;
private CScene      scene;
long mLastTime;

public GlRenderer(Context context, CScene scene) {
    this.context = context;
    this.scene=scene;
}

@Override
public void onDrawFrame(GL10 gl) {
    long now = System.currentTimeMillis();

    if (mLastTime > now) return;
    float dt = (float) ((now - mLastTime) / 1000.0);
    mLastTime = now;
    scene.Update(dt);
    scene.Draw(gl);
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    if(height == 0) {                       //Prevent A Divide By Zero By
        height = 1;                         //Making Height Equal One
    }
    gl.glViewport(0, 0, width, height);     //Reset The Current Viewport
    gl.glLoadIdentity();                    //Reset The Projection Matrix
    gl.glMatrixMode(GL10.GL_PROJECTION);    //Select The Projection Matrix

    GLU.gluOrtho2D(gl, 0, width, height, 0);

    gl.glMatrixMode(GL10.GL_MODELVIEW);     //Select The Modelview Matrix
    gl.glLoadIdentity();    //Reset The Modelview Matrix

    scene.LoadTextures(gl);
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glEnable(GL10.GL_TEXTURE_2D);            //Enable Texture Mapping ( NEW )
    gl.glShadeModel(GL10.GL_SMOOTH);            //Enable Smooth Shading
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);    //Black Background
    gl.glClearDepthf(1.0f);                     //Depth Buffer Setup
    gl.glEnable(GL10.GL_DEPTH_TEST);            //Enables Depth Testing
    gl.glDepthFunc(GL10.GL_LEQUAL);             //The Type Of Depth Testing To Do

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
    gl.glEnable(GL10.GL_BLEND); 
    gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA); 
}

}

我的精灵课程:

public class Sprite {

private FloatBuffer vertexBuffer;   // buffer holding the vertices

private FloatBuffer textureBuffer;  // buffer holding the texture coordinates
private float texture[] = new float[8]; 
/** The texture pointer */
private int[] textures = new int[1];

private float width;
private float height;
private float x;
private float y;

public Sprite(float _width, float _height, float xpos, float ypos){
    this(_width,_height,xpos,ypos,1.0f,1.0f);
}

public Sprite(float _width, float _height, float xpos, float ypos, float tex_width, float tex_height) {
    //.......
}

public void loadGLTexture(GL10 gl, Context c, Bitmap bitmap) {
    // generate one texture pointer
    gl.glGenTextures(1, textures, 0);
    // ...and bind it to our array
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    // create nearest filtered texture
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    // Use Android GLUtils to specify a two-dimensional texture image from our bitmap 
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

    // Clean up
    bitmap.recycle();
}

public void draw(GL10 gl) {
    // bind the previously generated texture
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

    // Point to our buffers
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

    // Set the face rotation
    gl.glFrontFace(GL10.GL_CW);
    // Point to our vertex buffer
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

    gl.glLoadIdentity();
    gl.glTranslatef((float)x, (float)y, 0);

    // Draw the vertices as triangle strip
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0,4);

    //Disable the client state before leaving
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}   

}

我的场景课程:

public class CScene{
Context context;
public String name;

    protected Activity activity;

    public CScene(Context _context, Activity activity, String name){
        context=_context;
        this.name=name;
        this.activity=activity;
    }


    public void Update(float dt){

    }
    public void Draw(GL10 gl){
    }

    public boolean TapControl(MotionEvent  event)
    {
        return true;
    }

    public void LoadTextures(GL10 gl) {

    }
}

我的申请结构: 每个活动都有一个GLSurfaceView,每个GLSurfaceView都包含一个自定义场景。活动首先创建Scene,它调用sprite的构造函数。然后活动创建GLSurfaceView,它调用场景的LoadTextures方法(来自onSurfaceChagned),其中使用loadGLTexture加载场景中精灵的位图。然后GlSurfaceView的渲染器在onDrawFrame中调用场景的Draw方法,场景的Draw方法调用Sprite的Draw方法。

//抱歉我的英语不好

1 个答案:

答案 0 :(得分:6)

我终于想通了,渲染器onSurfaceChanged方法中的这些行都是乱序的:

gl.glLoadIdentity();                    //Reset The Projection Matrix
gl.glMatrixMode(GL10.GL_PROJECTION);    //Select The Projection Matrix

如果我改变他们的订单,一切都很好。