Проблемы макета с Open GL SurfaceView после блокировки телефона - PullRequest
0 голосов
/ 17 марта 2011

Я запускаю приложение с SurfaceView. Когда вид Поверхность виден, и я нажимаю кнопку «Питание», чтобы заблокировать телефон, затем возвращаюсь в приложение, перспектива выключена. Похоже, что он отображает «высокий и худой» вид слева от моего «короткого и широкого» вида.

Когда я смотрю на onSurfaceChanged, он вызывается один раз, когда телефон включен с 'width = 480 height = 800', затем снова, когда после разблокировки телефона с 'width = 800 height = 480'. Я вызываю gl.glFrustumf () каждый кадр с правильными новыми данными ширины / высоты, собранными из onSurfaceChanged, но что-то все еще заставляет мое окно выглядеть стройным и высоким, есть идеи?

Edit: Возможно, это как-то связано с моей структурой представления.

Вид содержимого операций называется MainView ..

         MainView
        /        \
     UIView     SurfaceView (I look wrong)
     /
UI Elements
(These all look correct)

Правка № 2:

Скриншот:

LockScreenFail

Глобус и кнопка «Загрузить еще» нарисованы в 3d. Квадрат в является дочерним элементом представления UI (другие дети UIView также отображаются правильно). Похоже, что SurfaceView думает, что ширина - это высота, а высота - это ширина. Я сделал больше печати ширины и высоты вида поверхности и получил следующий вывод:

--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/System.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

Таким образом, ширина и высота, кажется, исправляются через некоторое время после onWindowFocusChanged, но графически они никогда не выглядят правильными.

Редактировать № 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++;
}

Тогда я, поскольку у меня есть кое-какие идеи, представленные в 3D и других как элементы 2d UI, я устанавливаю проекцию каждого кадра в 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() );  
    }
}           

Редактировать # 4:

Оказывается, это было связано с View, я изменил способ добавления SurfaceView к своему родителю ...

Это было ...

getMainView().addView( m3DView );

Это сейчас ...

    // 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 );
    }

1 Ответ

2 голосов
/ 18 марта 2011

GLSurfaceView должен быть уведомлен, когда действие приостановлено и возобновлено.Клиенты GLSurfaceView обязаны вызывать onPause (), когда действие приостанавливается, и onResume (), когда действие возобновляется.Эти вызовы позволяют GLSurfaceView приостанавливать и возобновлять поток рендеринга, а также позволяют GLSurfaceView освобождать и воссоздавать отображение OpenGL.

Это должно решить вашу проблему.

...