Android和OpenGL - 通过另一个对象查看对象

时间:2011-01-09 21:33:20

标签: android opengl-es light

我是一个总菜鸟,我正在尝试展示我在opengl(Blender)的3D建模程序中构建的小型潜艇。

潜艇是使用一个长圆柱体建造的,球体的末端相交。

我得到的问题是,当我查看结果时,我可以通过圆柱体看到整个球体。我也可以通过球体看到圆柱体的末端。当我点亮时出现。我正在使用环境光和漫射光。我只想看到圆柱外面的一半球体,我不想看到任何内脏。

我已经面对剔除并且它移除了两个物体的正面,但我清楚地看到了球体。

下面我粘贴了我的onSurfaceCreated函数,我在其中设置了所有的opengl参数。任何建议都表示赞赏!

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    //
    gl.glEnable(GL10.GL_DEPTH_TEST);
    //gl.glMatrixMode(GL10.GL_PROJECTION);

    gl.glMatrixMode(GL10.GL_MODELVIEW);

    gl.glEnable(GL10.GL_POLYGON_OFFSET_FILL);

    gl.glEnable(GL10.GL_LIGHTING);
    gl.glEnable(GL10.GL_LIGHT0);

    // Define the ambient component of the first light
    float[] light0Ambient = {0.1f, 0.1f, 0.1f, 1.0f};        
    gl.glLightfv(gl.GL_LIGHT0, gl.GL_AMBIENT, FloatBufferFromFloatArray(light0Ambient, 4));

    // Define the diffuse component of the first light
    float[] light0Diffuse = {0.7f, 0.7f, 0.7f, 1.0f};
    gl.glLightfv(gl.GL_LIGHT0, gl.GL_DIFFUSE, FloatBufferFromFloatArray(light0Diffuse, 4));

    // Define the specular component and shininess of the first light
    float[] light0Specular = {0.7f, 0.7f, 0.7f, 1.0f};
    float light0Shininess = 0.4f;
    //gl.glLightfv(gl.GL_LIGHT0, gl.GL_SPECULAR, FloatBufferFromFloatArray(light0Specular, 4));        

    // Define the position of the first light
    float[] light0Position = {1.0f, 0.0f, 0.0f, 0.0f};
    gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, FloatBufferFromFloatArray(light0Position, 4)); 

    // Define a direction vector for the light, this one points correct down the Z axis
    float[] light0Direction = {0.0f, 0.0f, -1.0f};
    //gl.glLightfv(gl.GL_LIGHT0, gl.GL_SPOT_DIRECTION, FloatBufferFromFloatArray(light0Direction, 3));

    // Define a cutoff angle. This defines a 90° field of vision, since the cutoff
    // is number of degrees to each side of an imaginary line drawn from the light's
    // position along the vector supplied in GL_SPOT_DIRECTION above
    //gl.glLightf(gl.GL_LIGHT0, gl.GL_SPOT_CUTOFF, 180.0f);

    gl.glEnable(GL10.GL_CULL_FACE);
    // which is the front? the one which is drawn counter clockwise
    gl.glFrontFace(GL10.GL_CCW);
    // which one should NOT be drawn
    gl.glCullFace(GL10.GL_BACK);

    gl.glClearDepthf(10f);
    gl.glPolygonOffset(1.0f, 2);

    initShape();

    gl.glScalef(0.5f, 0.5f, 0.5f);
}

5 个答案:

答案 0 :(得分:1)

我知道,你仍然在考虑“初始化一些场景图”。这不是OpenGL的工作原理(哎呀,这是我连续第三次写这个作为答案)。你在onSurfaceCreated中所做的所有事情实际上属于显示例程。 OpenGL不是场景图。在绘制需要该状态的东西之前,您可以设置所需的所有状态。

我在那里看到你的功能“initShape”。我不认为这符合你的意图。

答案 1 :(得分:1)

您是否尝试过检查是否存在背面剔除问题?通过将glEnable(GL_CULL_FACE)更改为glDisable来检查它,只是为了检查它绝对不是那样。可以在同一个网格上同时进行两个绕线顺序,因此对于模型的一个部分进行剔除可能是正确的,但对另一个部分则是错误的 - 最简单的方法是禁用它以确保不是问题。

或者你的表面可能是因为某些原因而没有深度缓冲区而创建的?检查EGLConfig参数以确保不是这种情况。通常默认情况下会使用深度缓冲区创建,但可以覆盖该行为。

使用永远不会看到的内部面孔进行建模也不会为您的实时性能做好事。您应该考虑在混合器中使用布尔'或'操作至少去除内部面,但最终最好是对其拓扑结构进行精心设计,而不仅仅是聚合计数,还要考虑它们的好坏程度。装在一起形成一个三角形条带(这不能解释你现在遇到的问题 - 这只是未来的一个注意事项)

答案 2 :(得分:1)

你确定你有一个启用了深度缓冲的EGL上下文吗?如果您正在使用GLSurfaceView,您可能正在寻找类似SimpleEGLConfigChooser(false)的东西,它应该是SimpleEGLConfigChooser(true)。

答案 3 :(得分:1)

让我们看看你的onDrawFrame()?什么是你的投影,它可以翻转法线和混乱的投影使它看起来很有趣。

深度缓冲或深度测试也存在问题。

编辑:看起来深度测试不是你的问题,因为你可以从与球体相交的多边形看到深度剔除。看起来您的几何是问题。

我会让你的相机移动,然后你可以环顾四周,弄清楚它是什么搞砸了。

答案 4 :(得分:0)

如果您正在使用纹理,请查看您正在使用的混合功能。可能是这样的情况,重叠的像素会像叠加效果一样倍增而不是被覆盖,这就是我想要的。