2017-02-19 9 views
0

내 게임보기 안에 카메라 미리보기를 추가 할 수 있습니까? 이 오류가 나타나는 게임 뷰 내부에 카메라 미리보기를 추가하려고했습니다.게임 뷰 (표면보기) 내부에서 카메라 미리보기를 추가하는 방법

E/SurfaceHolder에 : 예외 잠금 표면 java.lang.IllegalArgumentException가

그것은 내 gameloop 에 뭔가 문제처럼 보일하지만 난 그것을 해결하는 방법을 모른다. 누구든지 문제를 해결하는 방법을 알고 있습니까?

내 GameLoop

public class MainThread extends Thread { 
public static final int MAX_FPS = 30; 
private double averageFPS; 
private SurfaceHolder surfaceHolder; 
private GamePanel gamePanel; 
private boolean running; 
public static Canvas canvas; 

public void setRunning(boolean running){ 
    this.running = running; 
} 

public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel){ 
    super(); 
    this.surfaceHolder = surfaceHolder; 
    this.gamePanel = gamePanel; 
} 

@Override 
public void run() { 
    long startTime; 
    long timeMillis = 1000/MAX_FPS; 
    long waitTime; 
    int frameCount = 0; 
    long totalTime = 0; 
    long targetTime = 1000/MAX_FPS; 

    while(running){ 
     startTime = System.nanoTime(); 
     canvas = null; 

     try{ 
      canvas = this.surfaceHolder.lockCanvas(); 
      synchronized (surfaceHolder){ 
       this.gamePanel.update(); 
       this.gamePanel.draw(canvas); 
      } 
     } catch (Exception e) {e.printStackTrace();} 
     finally { 
      if (canvas != null){ 
       try{ 
        surfaceHolder.unlockCanvasAndPost(canvas); 
       }catch (Exception e) {e.printStackTrace();} 
      } 
     } 
     timeMillis = (System.nanoTime() - startTime)/1000000; 
     waitTime = targetTime - timeMillis; 
     try{ 
      if(waitTime > 0) 
       this.sleep(waitTime); 
     }catch (Exception e) {e.printStackTrace();} 

     totalTime += System.nanoTime() - startTime; 
     frameCount++; 
     if(frameCount == MAX_FPS){ 
      averageFPS = 1000/((totalTime/frameCount)/1000000); 
      frameCount = 0; 
      totalTime = 0; 
      System.out.println(averageFPS); 
     } 
    } 
} 

}

내 GameView

public class GamePanel extends SurfaceView implements SurfaceHolder.Callback { 
private MainThread thread; 

private ObstacleManager obstacleManager; 

private SurfaceHolder mHolder; 
private Camera mCamera; 

public GamePanel(Context context, Camera camera) { 
    super(context); 
    mCamera = camera; 
    mCamera.setDisplayOrientation(90); 
    mHolder = getHolder(); 
    mHolder.addCallback(this); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    thread = new MainThread(mHolder, this); 

    obstacleManager = new ObstacleManager(100, 100, Color.BLACK); 
    setFocusable(true); 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 

    try{ 
     //when the surface is created, we can set the camera to draw images in this surfaceholder 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 

    } catch (IOException e) { 
     Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage()); 
    } 
    thread = new MainThread(holder, this); 
    thread.setRunning(true); 
    thread.start(); 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    //before changing the application orientation, you need to stop the preview, rotate and then start it again 
    if(mHolder.getSurface() == null)//check if the surface is ready to receive camera data 
     return; 

    try{ 
     mCamera.stopPreview(); 
    } catch (Exception e){ 
     //this will happen when you are trying the camera if it's not running 
    } 

    //now, recreate the camera preview 
    try{ 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage()); 
    } 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    boolean retry = false; 
    while(retry){ 
     try{ 
      thread.setRunning(false); 
      thread.join(); 
     }catch (Exception e) {e.printStackTrace(); } 
     retry = false; 
    } 
    mCamera.stopPreview(); 
    mCamera.release(); 
} 

public void update(){ 
    obstacleManager.update(); 
} 

@Override 
public void draw(Canvas canvas){ 
    super.draw(canvas); 
    //canvas.drawColor(Color.WHITE); 
    obstacleManager.draw(canvas); 
} 

}

내 MainActivity

public class Main2Activity extends Activity { 

//declaring gameview 
private GameView gameView; 
private Camera mCamera; 
private FrameLayout frameLayout; 
private GamePanel gamePanel; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.activity_main); 

    DisplayMetrics dm = new DisplayMetrics(); 
    getWindowManager().getDefaultDisplay().getMetrics(dm); 
    Constants.SCREEN_WIDTH = dm.widthPixels; 
    Constants.SCREEN_HEIGHT = dm.heightPixels; 


    try { 
     mCamera = Camera.open(0);//you can use open(int) to use different cameras 
    } catch (Exception e) { 
     Log.d("ERROR", "Failed to get camera: " + e.getMessage()); 
    } 

    if (mCamera != null) { 
     frameLayout = (FrameLayout) findViewById(R.id.gameView); 
     gamePanel = new GamePanel(this, mCamera); 
     frameLayout.addView(gamePanel); 
    } 

} 

답변

0

카메라 미리보기와 캔버스 그리기 모두 동일한 서페이스를 사용할 수 없습니다. 하나는 다른 하나의 옆에 두 개의 서페이스를 만들 수 있지만 하나를 다른 하나의 위에 놓으려고 시도하지 않습니다. 그러면 z 순서가 안정적으로 유지되지 않습니다. 가장 좋은 방법은 카메라 미리보기를 SurfaceTexture로 전환하고 게임 및 카메라 미리보기를 그리는 데 동일한 OpenGL 컨텍스트를 사용하는 것입니다.