Android OpenGL ES - 我无法使gluLookAt/gluPerspective工作

del*_*ium 1 java 3d android opengl-es

以下文字有点长,因为我想确保那些有类似问题的人,例如google这个页面可以轻松地轻松地遵循确切的问题及其解决方案.但现在我的问题:

我最近开始在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);
Run Code Online (Sandbox Code Playgroud)

接下来的几点是关于我在上面的代码中对相机设置的推定知识的简短说明.如果我在下面的解释中出错了,请纠正我,因为这可能已经解决了我的所有问题!

  1. glMatrixMode(GL10.GL_PROJECTION)切换到更改相机矩阵(我之后直接加载了一个单位矩阵)
  2. GLU.gluPerspective(gl,67,aspect_ratio,1,100)设置透视投影,其在y维度上具有67度视角的视图截面.使用"aspect_ration =(float)width/height"OpenGL计算x维度中的视角.此外,"1"是近剪裁平面,而"100"是在这种情况下远剪裁平面的值.
  3. 据我所知无关紧要,在调用代码gluLookAt的地方,只要它在实际绘图之前完成(虽然我不确定).在这个例子中,我首先更改为MODELVIEW矩阵,加载一个单位矩阵,然后调用gluLookAt.3.
  4. "GLU.gluLookAt(gl,0,0,20,0,0,0,0,1,0)"实际上由三个3元素向量组成.初始值(本例中为(0,0,20))设置摄像机在世界坐标中的位置(即正Z轴上的20个单位,这意味着它"伸出"手机屏幕的正面).第二个矢量确定摄像机看到的世界坐标系中的点(在此示例中,坐标系的原点,即摄像机沿负z轴观察).第三个向量是向上矢量,它定义了摄像机坐标系的y轴方向(因此也是x轴通过交叉积与从摄像机位置到它所看到的点的矢量).

三角绘图代码是从教程中复制的(但我在其他教程中也发现了类似的代码,所以我认为这不是问题).

据我所知,相机现在位于(0,0,20)并朝向坐标系的原点.它的绘图截头从z值19开始,一直到-80(相机在z轴点20处,沿着负z轴看;它的观察截头体有近和远的平面在1和100(都看着在这种情况下,沿着负z轴),分别).因此,三角形应该是可见的,因为其顶点位于z轴= 0平面(即xy平面)上的原点周围,这明显位于观察截头体内.此外,绘制的顶点以逆时针顺序排列; OpenGL中的默认值.

因此,在对问题进行了长时间的介绍之后,我的简单问题是:我搞砸了什么,以至于这段代码没有按照我的期望去做?

小智 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在每次API调用之后,以宗教的方式检查,以防万一.(assert(glGetError()==GL_NO_ERROR)将为初学者做,但你真的想要一个小循环,也打印结果,gluErrorString以便更容易看到可能是错误的.)
  • 确保你做了一个glBindBuffer将你的ARRAY_BUFFERARRAY_ELEMENT_BUFFER绑定设置为0.要初始化一个VBO,你必须绑定它,所以如果你有一些东西设置一个它可能只是让它绑定.这将填补你的glVertexPointer.
  • 沿着最后几个 - 明确地设置更多状态.在这种情况下,例如,您可能想要glDisableClientState其他数组类型,以防万一.根据文档,GL启动时顶点阵列被禁用,但这是一种值得消除的可能性.