2011-12-21 87 views
2

我想在Android上的OpenGl中渲染一個簡單的正方形。相同的代碼在真實設備上運行正常,但在仿真器上正方形變形。這隻發生在我使用高zFar值(在本例中它是zNear = 80000,zFar = 80100)並且不依賴於zNear和zFar之間的距離時。深度測試被禁用,所以我認爲它與深度緩衝區沒有任何關係。Android模擬器OpenGL遠飛機距離

這是怎麼看起來真實設備上:

http://imgur.com/9246P

,這是它的外觀上的仿真器。

http://i.imgur.com/L0IKv.png

當方旋轉變形變得更加明顯,並且在某些時候方塊消失,然後又重新出現。

我知道模擬器使用OpenGl的不同實現,也許這是一個錯誤? 有人知道它爲什麼會這樣嗎?

public class SquareTestActivity extends Activity { 

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

     GLSurfaceView glView = new GLSurfaceView(this); 
     glView.setRenderer(new SquareRenderer()); 

     setContentView(glView); 
    } 

    public class SquareRenderer implements Renderer { 
     private final float[] verts = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f }; 
     private final int nrOfVerts = verts.length/3; 
     private FloatBuffer vertBuf; 

     private float rotation; 

     public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 

      gl.glDisable(GL10.GL_DEPTH_TEST); 

      gl.glColor4f(1, 0, 0, 1); 

      ByteBuffer byteBuffer = ByteBuffer.allocateDirect(verts.length * Float.SIZE/8); 
      byteBuffer.order(ByteOrder.nativeOrder()); 
      vertBuf = byteBuffer.asFloatBuffer(); 
      vertBuf.put(verts); 
      vertBuf.position(0); 
     } 

     public void onSurfaceChanged(GL10 gl, int width, int height) { 
      gl.glViewport(0, 0, width, height); 

      gl.glMatrixMode(GL10.GL_PROJECTION); 
      gl.glPushMatrix(); 
      gl.glLoadIdentity(); 
      GLU.gluPerspective(gl, 90, (float) width/height, 80000, 80100); 
      gl.glMatrixMode(GL10.GL_MODELVIEW); 
     } 

     public void onDrawFrame(GL10 gl) { 
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 

      gl.glLoadIdentity(); 
      GLU.gluLookAt(gl, 0, 0, 80050, 0, 0, 0, 0, 1, 0); 
      gl.glRotatef(rotation, 0, 0, 1); 
      gl.glScalef(80000, 80000, 1); 

      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuf); 
      gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, nrOfVerts); 

      rotation ++; 
     } 
    } 
} 

在此先感謝。

+0

如果您有,即使是便宜的設備,我也會建議僅對實際的decives進行測試。您可能會體驗到模擬器中不存在的OpenGL警告。 OpenGL的規格非常精確,但也很全面,所以它們並沒有完全實現。我認爲這可能是一個數字精度問題,可能因平臺而異。如果該應用程序用於公開發布,則必須在「某些」設備上進行測試。 – dronus 2011-12-21 15:57:06

+0

我已經在廣泛的設備上進行了測試,它在所有設備上按預期工作。我希望我可以放棄仿真器支持,但是因爲這是一個用戶可能期望能夠在其模擬器上運行的庫項目。 – gq3 2011-12-21 16:09:20

+0

所以模擬器只是另一種設備,請... – dronus 2011-12-21 16:14:10

回答

2

我從你的代碼中再現了這個效果,如果你將所有這些80000-ish數字除以10,問題就會消失。我懷疑模擬器的OpenGL實現在內部使用了定點算法,這會導致它與數字很大的鬥爭。如果它使用glFixed格式(S15.16),它將無法處理大於32768的數字。

+0

是的,我也懷疑,變形開始出現在該範圍內。儘管如此,爲什麼將OpenglES中使用的浮點數學僅僅替換爲模擬器? – gq3 2011-12-22 17:41:03

+1

[Wikipedia](http://en.wikipedia.org/wiki/OpenGL_ES)提到了OpenGL ES的常見簡介,它只支持固定點。也許模擬器只實現該配置文件。 (儘管如此,我正在努力尋找任何確認。) – 2011-12-22 19:21:59