Layout Problems with Open GL SurfaceView after phone is locked
I am running an app with a SurfaceView. When the Surface view is visible and I press the 'power' button to lock the phone then return to the app the perspective is off. It appears to be rendering a "tall and skinny" view on the left side of my "short and wide" view.
When I look at onSurfaceChanged it is being called once when the phone is powered on with 'width=480 height=800' then again when after the phone is unlocked with 'width=800 height=480'. I am calling gl.glFrustumf() each frame with the correct new width/height data collected from onSurfaceChanged but something is still making my window appear skinny and tall, any ideas?
Edit: Perhaps it has something to do with my view structure.
The Activities contentView is called MainView..
MainView
/ \
UIView SurfaceView (I look wrong)
/
UI Elements
(These all look correct)
Edit #2:
Screenshot:
The globe and the 'Download More' button are drawn in 3d. The Square in is a child of the UI view (other children of UIView also show up correctly). It appears as if the SurfaceView thinks the width is the height and the height is the width. I did more printing of the Surface View's Width and height and get this output:
--Phone On Unlock Screen
--Activity onWindowFocusChanged called
I/System.out( 8817): ***********UI Width: 480 UI Height: 800
I/System.out( 8817): ***********Main Width: 480 Main Height: 800
I/System.out( 8817): ***********GL Width: 480 GL Height: 800
--App continues to run. These are triggered in GLSurfaceView onLayout
I/System.out( 8061): ***********UI Width: 800 UI Height: 480
I/Syste开发者_JAVA百科m.out( 8061): ***********Main Width: 800 Main Height: 480
I/System.out( 8061): ***********GL Width: 800 GL Height: 480
I/System.out( 8061): ***********UI Width: 800 UI Height: 480
I/System.out( 8061): ***********Main Width: 800 Main Height: 480
I/System.out( 8061): ***********GL Width: 800 GL Height: 480
So the Width and Height appear to fix themselves sometime after onWindowFocusChanged but graphically it never looks correct.
Edit #3:
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
:)
public void onSurfaceChanged(GL10 gl, int width, int height) {
mWidth = width;
mHeight = height;
mAspectRatio = (float) width / height;
mSurfaceChangedID++;
}
Then I since I have something ideas rendered in 3d and others as 2d UI elements I setup the projection each frame in the onDraw
public void onDrawFrame(GL10 gl) {
gl.glClearColor( mClearColorR, mClearColorG, mClearColorB, 1.0f );
gl.glClear( GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT );
for( each item ) {
if( item.Is3d() ) {
//For 3d Elements:
gl.glMatrixMode( GL10.GL_PROJECTION );
gl.glLoadIdentity();
gl.glFrustumf( mAspectRatio*-mHalfViewAngleTan, mAspectRatio*mHalfViewAngleTan, -mHalfViewAngleTan, mHalfViewAngleTan, mNearZClip, mFarZClip );
//Enable Lighting, Setup fog
...
} else {
//For UI Elements:
gl.glMatrixMode( GL10.GL_PROJECTION );
gl.glLoadIdentity();
gl.glOrthof( -0.5f*mAspectRatio, 0.5f*mAspectRatio, -0.5f, 0.5f, -1, 1 );
//Disable Lighting, Disable fog, Setup blending
...
}
//Setup client state and vertex buffers
...
gl.glDrawArrays( GL10.GL_TRIANGLES, 0, mdl.getVtxCount() );
}
}
Edit #4:
Turns out it did have to do with View, I changed how the SurfaceView was added to its parent...
It was...
getMainView().addView( m3DView );
It is now...
// add to parent view
{
Display display = getWindow().getWindowManager().getDefaultDisplay();
android.widget.AbsoluteLayout absLayout = new android.widget.AbsoluteLayout(this);
absLayout.setLayoutParams(new android.view.ViewGroup.LayoutParams(display.getWidth(), display.getHeight()));
absLayout.addView( m3DView, new android.view.ViewGroup.LayoutParams(display.getWidth(), display.getHeight()) );
getMainView().addView( absLayout );
}
A GLSurfaceView must be notified when the activity is paused and resumed. GLSurfaceView clients are required to call onPause() when the activity pauses and onResume() when the activity resumes. These calls allow GLSurfaceView to pause and resume the rendering thread, and also allow GLSurfaceView to release and recreate the OpenGL display.
This should solve your problem.
精彩评论