2011-04-25 16 views
7

많은 다른 사람들과 마찬가지로, GLSurfaceView를 사용하여 3D 미리보기에서 SurfaceView를 사용하여 3D 객체를 그리는 중입니다. 일부 버튼은 맨 위에 배치됩니다. 실제로 프로토 타입이 작동하지만 onResume이 제대로 작동하지 않습니다. 이력서가 끝난 후, GLSurfaceView는 더 이상 보이지 않게됩니다. 레이아웃에서 SurfaceView를 제거하면 도면을 잘 볼 수 있기 때문에 작동 중임을 알고 있습니다.Android에서 setZOrderMediaOverlay를 올바르게 사용하는 방법은 무엇입니까?

대상은 Nexus One, 실행중인 2.3.3 ROM입니다.

다음은 레이아웃 XML의 :이 모든이 <merge> 블록에 싸여

<com.example.cameratest.GLPreview 
     android:id="@+id/cubes" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"/> 

<com.example.cameratest.Preview 
     android:id="@+id/camera" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"/> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/buttongroup" 
    android:orientation="vertical" 
    android:layout_width="wrap_content" 
    android:layout_height="fill_parent" 
    android:layout_gravity="right" android:gravity="center"> 

    <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/buttonClose"></Button> 
    <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/buttonMode"></Button>  
    <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/buttonCameraInfo"></Button> 
</LinearLayout> 

하지만, 어떤 이유로, 위 <code> 목록에 포함 할 수 없었다. PreviewSurfaceView을 확장하고 카메라 미리보기 논리를 구현하는 클래스입니다.

활동이 시작될 때 제대로 작동합니다. 다른 활동 (예 : 단추 중 하나를 누름)을 실행하고 해당 활동을 마치면 기본 활동이 재개되지만 3D 오브젝트가 더 이상 표시되지 않습니다.

내가 찾은 this discussion 여기에 setZOrderMediaOverlay()이 z- 순서 문제를 해결하는 데 도움이 될 것이라고 언급되어 있습니다. 또한 Android document for setZOrderMediaOverlay()은 "표면 뷰를 포함하는 윈도우가 윈도우 매니저에 부착되기 전에"이 함수를 호출해야한다고 말합니다. 그 문을 어떻게 해석해야할지 모르겠다. 따라서 코드에 디버그 문을 넣어 이벤트 시퀀스를 확인한다.

 
GLPreview: OnResume 
GLPreview: onAttachedToWindow 
GLPreview: onWindowVisibilityChanged -> VISIBLE 
GLPreview: surfaceCreated 
GLPreview: surfaceChanged, format=1, w=800, h=480 

그래서 내가 setZOrderMediaOverlay() 요구 사항 중 하나 onResume() 또는 생성자에서 호출 할 수 있다고 가정 : 나는 응용 프로그램을 시작할 때


public class GLPreview extends GLSurfaceView 
{ 
    private static final String TAG = "GLPreview"; 

    public GLPreview(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
     // this.setZOrderMediaOverlay(true);   
    } 

    public void onPause() 
    { 
     super.onPause(); 
     Log.d(TAG, "GLPreview: OnPause"); 
    } 

    public void onResume() 
    { 
     // this.setZOrderMediaOverlay(true);   
     super.onResume(); 
     Log.d(TAG, "GLPreview: OnResume"); 
    } 

    public void surfaceCreated(SurfaceHolder holder) 
    { 
     Log.d(TAG, "GLPreview: surfaceCreated"); 
     super.surfaceCreated(holder); 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) 
    { 
     Log.d(TAG, String.format("GLPreview: surfaceChanged, format=%d, w=%d, h=%d", format, w, h)); 
     super.surfaceChanged(holder, format, w, h); 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) 
    { 
     Log.d(TAG, "GLPreview: surfaceDestroyed"); 
     super.surfaceDestroyed(holder); 
    } 

    protected void onAttachedToWindow() 
    { 
     Log.d(TAG, "GLPreview: onAttachedToWindow"); 
     super.onAttachedToWindow(); 
    } 

    protected void onDetachedFromWindow() 
    { 
     Log.d(TAG, "GLPreview: onDetachedFromWindow"); 
     super.onDetachedFromWindow(); 
    } 

    protected void onWindowVisibilityChanged (int vis) 
    { 
     String newVisibility; 
     switch (vis) 
     { 
      case View.GONE: 
       newVisibility = "GONE"; 
       break; 
      case View.INVISIBLE: 
       newVisibility = "INVISIBLE"; 
       break; 
      case View.VISIBLE: 
       newVisibility = "VISIBLE"; 
       break; 
      default: 
       newVisibility = String.format("Unknown constant %d", vis); 
     } 

     Log.d(TAG, String.format("GLPreview: onWindowVisibilityChanged -> %s", newVisibility)); 
     super.onWindowVisibilityChanged(vis); 
    } 
} 
 

여기 이벤트의 순서입니다 : 여기처럼 GLSurfaceView 코드가 보이는 방법입니다. 그러나 setZOrderMediaOverlay()true 또는 false, GLSurfaceView 또는 SurfaceView 클래스의 다양한 조합을 시도했지만 그 중 아무 것도 문제를 해결하지 못했습니다.

안드로이드 프로그래밍에 관해서는 상대적으로 새로운 편입니다. 나는 지금까지 왔지만이 시점에서 나는 도움이 필요하다. 이 시나리오에서 setZOrderMediaOverlay()을 성공적으로 사용하고 onResume()과 함께 작업 한 사람이 어떻게해야하는지 알려주세요.

미리 감사드립니다.

+1

FWIW을 SurfaceViews 중복에 대한 몇 가지 노트 http://stackoverflow.com/questions/5648221/fighting-with-surfaceview-camera-and-opengl/25020225#25020225를 참조하십시오

을 요약합니다. – fadden

답변

14

저는 같은 문제로 당분간 어려움을 겪었지만 지금 아래 코드가 작동한다고 생각합니다. (카메라 켜기/끄기 여부와 관계없이 일시 정지/잠금 후 계속 작동합니다).

첫째, 레이아웃 파일에 정의 된보기 등이 없습니다. 코드로 작성되었습니다. 다음은 주 onCreate() 메소드에서 호출됩니다. augScreen에서 setZOrderMediaOverlay()에 유의하십시오.

onPause() 및 onResume()을 augScreen에 전달하는 것 외에는 특별한 것이 없습니다.

 // 1 - Camera Preview 
     camScreen = new CameraPreview(this); 
     setContentView(camScreen, new LayoutParams(
       LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 

    // 2 - 3D object display 
     augScreen = new AR_SurfaceView(this, getViewRange()); 
     addContentView(augScreen, new LayoutParams(
       LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 
     augScreen.setZOrderMediaOverlay(true); 

    // 3 - Permanent overlay 
    RelativeLayout overlayScreen = new OverlayView(this); 
    addContentView(overlayScreen, new LayoutParams(
      LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
    overlayScreen.setVisibility(View.VISIBLE); 

    // 4 - UI buttons (toggleable) 
     uiScreen = new UserInterfaceView(this); 
     addContentView(uiScreen, new LayoutParams(
       LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
+1

감사합니다. onCreate()에서'setZOrderMediaOverlay()'를 호출하면이 문제가 해결됩니다. BTW, 나는 여전히 XML 레이아웃 파일을 가지고있다. 코드에서 뷰를 빌드하기 위해 앱을 변환하지 않았습니다. 나는이 질문에 언급하지 않았다는 것을 알고 있지만 동일한 응용 프로그램에는 카메라 미리보기 화면 (fps를 보여주는 간단한 DrawText)에서 그려 사용되는 코드가 있습니다. 이제'setZOrderMediaOverlay()'변경을 구현 한 후 왜이 코드가 작동을 멈췄는지 알아야합니다. – alokoko

+0

"작동하지 않는다"는 말은 코드가 호출되고 카메라 미리보기와 3D 객체가 표시되지만 fps 텍스트가 더 이상 카메라 미리보기 화면에 그려지지 않는다는 의미입니다. 흠. – alokoko

0

Awila_Tech의 대답도 저에게 도움이되었습니다.GLSurfaceView를 사용하고 onPause 및 onResume을 Activity의 onPause 및 onResume에서 깔끔하게 호출했지만 실제 onDrawFrame이 호출되는 동안 내 화면은 5 번 중 1 번 검은 색으로 표시되었습니다. ,

public class OpenGLApp extends Activity implements GLSurfaceView.Renderer { 
    private GLSurfaceView mGLSurfaceView; 

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

     mGLSurfaceView = new GLSurfaceView(this); 
     mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 8); 
     mGLSurfaceView.setRenderer(this); 
     mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); 
     mGLSurfaceView.setKeepScreenOn(true); 
     mGLSurfaceView.setDrawingCacheEnabled(true); 
     mGLSurfaceView.setZOrderOnTop(true); 

     setContentView(mGLSurfaceView); 
     //... 
    } 

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

    @Override 
    protected void onResume() { 
     mGLSurfaceView.onResume(); 
     //... 
     super.onResume(); 
    } 
} 
+0

피트, mGLSurfaceView 전에 super.onPause() 및 super.onResume()을 호출하지 않아도됩니까? –

관련 문제