2017-02-19 20 views
0

Можно ли добавить предварительный просмотр камеры в моем игровом представлении? Я попытался добавить предварительный просмотр камеры в игровое поле.Как добавить предварительный просмотр камеры внутри игрового поля (вид на поверхности)

E/SurfaceHolder: Exception запирающая поверхность 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 для рисования вашей игры и предварительного просмотра камеры.