我有一个包含 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/