2011-12-21 84 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