以下文字有点长,因为我想确保有类似问题的人,例如谷歌此页面可以轻松地轻松地遵循确切的问题及其解决方案。但现在我的问题是:
我最近开始在Android智能手机上编程OpenGL ES,并且遇到了解如何使用gluPerspective和gluLookAt的问题。我想我明白他们做了什么,但我看不到我画的三角形。我在我的活动的onDrawFrame方法中运行以下代码。所述活动使用标记为@Override的onDrawFrame实现GLSurfaceView.Renderer。我的代码是:
gl.glViewport(0, 0, screen_width, screen_height);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //set background to black
gl.glClearDepthf(1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_PROJECTION); // Change PROJECTION matrix
gl.glLoadIdentity();
float aspect_ratio = (float) screen_width / screen_height;
GLU.gluPerspective(gl, 67, aspect_ratio, 1, 100);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glMatrixMode(GL10.GL_MODELVIEW); // Change MODELVIEW matrix
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, 20, 0, 0, 0, 0, 1, 0);
// make triangle with vertices (-2,0,0), (2,0,0), and (0,.5,0)
float[] vertices = { -2f, 0, 0, 2f, 0, 0, 0, .5f, 0 };
ByteBuffer buffer = ByteBuffer.allocateDirect(vertices.length * 4);
buffer.order(ByteOrder.nativeOrder());
FloatBuffer vertex_buffer = buffer.asFloatBuffer();
for (int i = 0; i < 9; i++) {
vertex_buffer.put(vertices[i]);
}
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex_buffer);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_DEPTH_TEST);
接下来的几点是关于我在上面的代码中对相机设置的推定知识的简短说明。如果我在以下解释中出错了,请纠正我,因为这可能已经解决了我的所有问题!
三角绘图代码是从教程中复制的(但我在其他教程中也发现了类似的代码,所以我认为这不是问题)。
据我所知,相机现在位于(0,0,20)并朝向坐标系的原点。它的绘图截头从z值19开始,一直到-80(相机在z轴点20处,沿着负z轴看;它的观察截头体有近和远的平面在1和100(都看着在这种情况下,沿着负z轴),分别)。因此,三角形应该是可见的,因为其顶点位于z轴= 0平面(即xy平面)上的原点周围,这明显位于观察截头体内。此外,绘制的顶点以逆时针顺序排列; OpenGL中的默认值。
所以在对这个问题进行了长时间的介绍之后,我的一个简单的问题是:我搞砸了什么,以至于这段代码不符合我的预期呢?
答案 0 :(得分:6)
我只在PC,Mac和iOS上使用OpenGL,但据我所知,代码看起来很好。然后,我也一直这样做,但我仍然得到空屏幕一段时间,几乎任何时候我从头开始任何3D(无论API)...所以这里有一些事情要尝试,几乎在尝试它们的顺序。希望至少其中一个是你尚未尝试过的东西!
glFlush
,因为你实际上并没有那么多。当你进行缓冲交换时,你会认为驱动程序会为你做这件事,但似乎并不能保证 - 例如Mac OS X似乎并不总是如此。GL_LIGHTING
。如果这个被启用(我认为这是默认情况?)但你没有提供法线,一切都会变黑。 (见上文。)GL_CULL_FACE
。无论你怎么仔细考虑绕线顺序,你仍然有可能犯错。但如果GL_CULL_FACE
关闭,则无法实现。GL_DEPTH_TEST
。当我偶然输入glClearDepth(0)
时,这已经节省了我几次。看起来你在这方面还不错,但它仍然值得一试。glGetError
以防万一。 (assert(glGetError()==GL_NO_ERROR
)会为初学者做,但你真的想要一个小的循环,同时打印gluErrorString
的结果,这样一眼就能看出什么可能是错的。)glBindBuffer
将ARRAY_BUFFER
和ARRAY_ELEMENT_BUFFER
绑定设置为0.要初始化VBO,您必须将其绑定,所以如果您在某处有某些内容设置一个它可能只是让它绑定。这将填满您的glVertexPointer
。glDisableClientState
其他数组类型,以防万一。根据文档,GL启动时顶点阵列被禁用,但这是一种值得消除的可能性。 答案 1 :(得分:2)
在查看了进一步的教程之后我找到了答案(然后在之前使用的那些教程中也注意到了它)!感谢大家的答案,他们在诊断OpenGL问题方面非常有帮助,并且肯定会在将来帮助我!
我的问题的解决方案是...... 问题不是glulookat或gluperspective,而是在我的情况下,FloatBuffer的内部位置。在for(0&lt; i&lt; 9&gt;)循环之后,我没有将变量vertex_buffer的位置设置为0。将缓冲区的位置设置为0可以通过至少两个命令完成:
据我所知,他们做同样的事情。我快速测试了位置重置属于代码的位置,在我的示例代码中我可以在gl.glEnableClientState(GL10.GL_VERTEX_ARRAY)之后调用它,但是我必须在gl.glVertexPointer(3,GL10.GL_FLOAT,0,vertex_buffer)之前调用它。 ),否则返回初始问题。
我希望这可以帮助其他有类似问题的人,或者只是缺少glulookat和gluperspective;)
再次感谢您的建议!
答案 2 :(得分:0)
对于OpenGL ES用户
就我而言,我不得不写
gl.glMatrixMode(gl.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl,45,1,1.5f,50);
gl.glMatrixMode(gl.GL_MODELVIEW);
gl.glLoadIdentity();
不只是
GLU.gluPerspective(gl,45,1,1.5f,50);
采用onSurfaceChanged
方法。