4

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.

Cœur
  • 37,241
  • 25
  • 195
  • 267
1FpGLLjZSZMx6k
  • 947
  • 1
  • 8
  • 26
  • When orientation changes activity is recreated by default. If you want stop reloading activity you need to specify "configChanges" attribute in manifest.xml file – Biraj Zalavadia Sep 28 '13 at 12:50

2 Answers2

5

DO this way

<activity
            android:name=".MainActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            />
Biraj Zalavadia
  • 28,348
  • 10
  • 61
  • 77
1

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">
Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225
  • Thanks for the quick response. When I add the `glViewport` in the `onSurfaceChanged` section, I get the same problem. What does the manifest.xml modification do? – 1FpGLLjZSZMx6k Sep 28 '13 at 14:02
  • take a look on example I posted, last row.... If you want to disable screen change on rotation add to your Activity `android:configChanges="screenSize|orientation` – Maxim Shoustin Sep 28 '13 at 14:29
  • The changes to the Manifest.xml were enough to make the magic happen: It works now! What would be the correct interpretation of why this works? Does the config change tell the application that I want to listen to orientation changes, which otherwise wouldn't be correctly handled? – 1FpGLLjZSZMx6k Sep 28 '13 at 14:46
  • after your Manifest change you do not get `onSurfaceChanged` call, right? http://developer.android.com/guide/topics/manifest/activity-element.html – Maxim Shoustin Sep 28 '13 at 14:51
  • You probably mean `onSurfaceCreated`? Your changes to the Manifest were the ones who made me solve the problem. Now I only get a `onSurfaceChanged` when chaning the orientation (which is the expected behaviour). I will accept your answer, as it correctly solves my problem. To dig deeper: As far as I understand, Android picks a config that matches to the device. And everytime this config changes, a call to `onSurfaceCreated` will be triggered. Note that orientation change was working before I added the Manifest change. It was just triggering an unnecessary call to `onSurfaceCreated` – 1FpGLLjZSZMx6k Sep 28 '13 at 14:59