【问题标题】:PyOpenGL, issue with 3D graphics on a screen using glFrustum and glTranslatePyOpenGL,使用 glFrustum 和 glTranslate 在屏幕上出现 3D 图形问题
【发布时间】:2013-05-08 08:27:32
【问题描述】:

概述:

我正在尝试创建一个类似于此的 3D 应用程序:

www.youtube.com/watch?v=h9kPI7_vhAU. 

我正在使用 OpenCV2.2、Python2.7 和 pyOpenGL。 这可以通过this background maths and code snippet 实现,其中 x、y、z 是观看者眼睛的位置(从网络摄像头抓取!)

问题:

当我这样做时,我渲染的对象(一个立方体)会沿着 z 轴(进入屏幕)拉伸,我不太清楚为什么。它被比作从上方俯视一座非常高的摩天大楼(而不是立方体)。随着眼睛 z 位置的变化,立方体的位置在 z 方向上的变化非常迅速。 This是结果的一帧,已经被拉伸了!

代码(带有 bigD 的编辑):

def DrawGLScene():
    #get some parameters for calculating the FRUSTUM
    NEAR_CLIPPING_PLANE = 0.01
    FAR_CLIPPING_PLANE  = 2
    window = glGetIntegerv(GL_VIEWPORT)
    WINDOW_WIDTH = window[2]
    WINDOW_HEIGHT= window[3]

    #do facial detection and get eye co-ordinates
    eye = getEye()

    #clear window
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    #before any projection transformation command comes these 2 lines:
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()

    #transform projection to that of our eye
    glFrustum(NEAR_CLIPPING_PLANE*(-WINDOW_WIDTH /2 - eye[0])/eye[2],
              NEAR_CLIPPING_PLANE*( WINDOW_WIDTH /2 - eye[0])/eye[2],
              NEAR_CLIPPING_PLANE*(-WINDOW_HEIGHT/2 - eye[1])/eye[2],
              NEAR_CLIPPING_PLANE*( WINDOW_HEIGHT/2 - eye[1])/eye[2],
              NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    glTranslatef(-eye[0],-eye[1],-eye[2])

    drawCube()

    glutSwapBuffers()

getEye() 返回的数据示例如下:

[0.25,0.37,1] 如果观看者的脸靠近屏幕左下角并且距离 1m 远

[-0.5,-0.1,0.5] 如果观看者的脸靠近屏幕的右上角并且距离 0.5m

绘制时立方体的高度、宽度、深度为 2,其中心位于 (0,0,0)。

如果有人想要做一个类似的项目并想要启动或认为问题出在所提供的代码之外的其他地方,我将提供完整的代码。

【问题讨论】:

    标签: python opengl opencv 3d projection


    【解决方案1】:

    你得到奇怪结果的原因是因为:

    glTranslatef(-eye[0],-eye[1],-eye[2])
    

    这个调用应该在

    之后进行
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    

    因为投影矩阵与您的 glFrustum 调用一样已准备好,因此如果您将其乘以一个平移矩阵,它将不再使其成为透视投影矩阵。模型视图矩阵必须描述所有世界和相机转换。

    另外请记住,如果您对模型视图矩阵进行的唯一转换是平移,那么您将始终盯着负 Z 轴。

    【讨论】:

    • 感谢您的回复。虽然你说的是真的,但似乎产生了相同的答案!我已经编辑了上面的代码以包含您的建议。我现在完全被难住了!
    • 好吧,我想我发现了另一个问题:您的 glFrustum() 调用似乎取决于您眼睛的世界空间坐标。看看这张图片i.iinfo.cz/r/photos/opengl/opengl_14_1.gif glFrustum 调用实际上只是定义了您的视野、纵横比以及对象在被切断之前可以走多远的限制。在查看该图像时,将截锥体想象为位于 (0,0,0) 并沿负 Z 轴向下移动。这现在在“相机空间”中,所以世界空间中的任何坐标在这里都没有意义,因为一切都已经被模型视图矩阵转换了
    • 通常,您的左/右/上/下值将由 left|right = +/- near_planetan(0.5*fovx) bottom|top = +/- near_plane i>tan(0.5*fovy) 其中 fovx 和 fovy 是水平和垂直视野。或者您可以选择一个固定的水平或垂直视野和纵横比,并以此方式确定所有平面
    猜你喜欢
    • 2016-02-03
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多