onSurfaceCreated() called every time orientation c

2019-04-09 21:01发布

问题:

I'm implementing the GLSurfaceView.Renderer like so:

public class GL20Renderer implements GLSurfaceView.Renderer {
    private static GL20Renderer mInstance = new GL20Renderer();
    private GL20Renderer() {}
    public static GL20Renderer getInstance() {
        return mInstance;
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        Log.e("App", "onDrawFrame()");
    }
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        Log.e("App", "onSurfaceChanged()");
    }
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        Log.e("App", "onSurfaceCreated()");
    }

}

This class is implemented in the MainActivity:

public class MainActivity extends Activity {
    private GLSurfaceView mGLView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        // Create a GLSurfaceView instance and set it as the ContentView for this Activity
        mGLView = new GL20SurfaceView(this);
        setContentView(mGLView);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mGLView.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mGLView.onResume();
    }

}

GL20SurfaceView is:

public class GL20SurfaceView extends GLSurfaceView {
    public GL20SurfaceView(Context context) {
        super(context);

        // Create an OpenGL ES 2.0 context.
        setEGLContextClientVersion(2);

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(GL20Renderer.getInstance());
    }
}

Very simple as you can see. When I now start the App, the onSurfaceCreated() method is correctly called, follow by one call of onSurfaceChanged().

Problem now is: Whenever the device orientation changes, I get another call of onSurfaceCreated() followed by onSurfaceChanged().

In my understanding, the onSurfaceCreated() method is called whenever a new surface needs to be created. My question is: Why does it do that whenever I change just the device orientation? Shouldn't it be sufficient that only a onSurfaceChanged() call is triggered in order to adjust the viewport?

Note that I don't put my device to sleep when changing the orientation.

回答1:

DO this way

<activity
            android:name=".MainActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            />


回答2:

The one of advantages of OpenGL that you draw regards to screen size. It gives you ability to handle all Android resolutions.

I'm not sure how it works with GL20 (sure the same like GL10).

As I know in onSurfaceChanged provides several configurations for OpenGL based on length/width of your screen.

For example glViewport

It is necessary to call glViewport handler when GL view dimensions are modified.

Only if you have width = height is unnecessary but its other story.

as exampe

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {

    // prevent 0 divide
    if(height == 0) {
        height=1;
    }

    screenWidth = width;
    screenHeight = height;
    ratio = (float) width/height;
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    gl.glOrthof(0, width, 0, height, -10f, 10f);
    gl.glViewport(0, 0, screenWidth, screenHeight);

If you want to avoid that, add to Manifest.xml:

<activity android:name="Activity"
  android:configChanges="screenSize|orientation">