2017-02-19 68 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上下文來繪製遊戲和相機預覽。

相關問題