Перезагрузить текстуры opengl после onResume () в GLSurfaceView - PullRequest
6 голосов
/ 06 марта 2011

У меня есть приложение для Android с двумя действиями, A и B. Приложение запускается с A, затем я нажимаю на экран, чтобы переключиться на B. Правильно отображается B, затем я нажимаю кнопку возврата на телефоне, чтобы вернуться к A Теперь действие выполняется правильно, за исключением того, что я не вижу свои текстуры. Метод onResume действия вызывает метод onResume GLSurfaceView, вызывает onSurfaceCreated моего рендерера, затем onSurfaceChanged. После этого onDrawFrame вызывается на каждом кадре, но очищает экран только с заданным цветом. Я знаю, что onSause GLSurfaceView уничтожает его содержимое, и 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) {

    }
}

Структура моего приложения: Каждое действие имеет один GLSurfaceView, и каждый GLSurfaceView содержит пользовательскую сцену. Сначала действие создает сцену, которая вызывает конструктор спрайтов. Затем действие создает GLSurfaceView, который вызывает метод LoadTextures сцены (из onSurfaceChagned), где она загружает растровое изображение для спрайтов на сцене с помощью loadGLTexture. Затем средство визуализации GlSurfaceView вызывает метод Draw сцены в onDrawFrame, а метод Draw сцены вызывает метод Draw Sprite.

// Извините за мой плохой английский

1 Ответ

6 голосов
/ 09 марта 2011

Я наконец-то понял, что эти строки в meStd рендерера onSurfaceChanged вышли из строя:

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

Если я изменю их порядок, все будет отлично работать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...