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

标签 android opengl-es

我有一个包含 2 个 Activity 的 Android 应用程序,A 和 B。应用程序以 A 开头,然后我点击屏幕切换到 B。B 正确显示,然后我按手机上的后退按钮切换回 A . 现在 Activity 运行正常,除了我看不到我的纹理。 Activity 的 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); 
}

我的 Sprite 类:

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) {

    }
}

我的应用程序的结构: 每个 Activity 都有一个 GLSurfaceView,每个 GLSurfaceView 都包含一个自定义场景。 Activity 首先创建场景,它调用 Sprite 的构造函数。然后该 Activity 创建 GLSurfaceView,它调用场景的 LoadTextures 方法(来自 onSurfaceChagned),其中它使用 loadGLTexture 为场景中的 Sprite 加载位图。然后GlSurfaceView的renderer在onDrawFrame中调用场景的Draw方法,场景的Draw方法调用Sprite的Draw方法。

//抱歉我的英语不好

最佳答案

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

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

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

关于android - 在 GLSurfaceView 中的 onResume() 之后重新加载 opengl 纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5213145/

相关文章:

java - 为什么 Java native 缓冲区那么慢?

android - OpenGL ES : Bad performance when calculating vertex position in vertex shader

android - CCRenderTexture、GL11ExtensionPack、Libgdx 如何操作

android - 在当前项目中找不到前缀为 'android' 的插件

java - 从 backstack 中删除不在 backstack 顶部的特定 fragment

java - 随着 map 的移动在谷歌地图上获取标记

android - 不知道 Firebase 过滤器的异常

ios - OpenGL 游戏引擎能否创建它自己的 UIResponder 子类,类似于 Sprite Kit 为 SKNode 所做的?

opengl-es - OpenGL ES 2.0 着色器最佳实践

android - 深度测试在平移时有效,但在指定 z 坐标(2D 渲染)时无效