代码之家  ›  专栏  ›  技术社区  ›  zython Hiery Nomus

如何用opengl和pyglet设置裁剪平面

  •  1
  • zython Hiery Nomus  · 技术社区  · 7 年前

    我正在解决我的代码的一个问题,如果任何原语的深度值不是零,它将不会在屏幕上呈现。我怀疑它被剪掉了。

    有没有一个简单的pythonic方法来设置我在pyglet的剪辑平面?

    到目前为止这是我的代码:

    import pyglet
    from pyglet.gl import *
    import pywavefront
    from camera import FirstPersonCamera
    
    
    def drawloop(win,camera):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        #glClearColor(255,255,255,255)
        glLoadIdentity()
        camera.draw()
    
        pyglet.graphics.draw(2, pyglet.gl.GL_POINTS,
        ('v3f', (10.0, 15.0, 0.0, 30.0, 35.0, 150.0))
        )
        glPointSize(20.)
        return pyglet.event.EVENT_HANDLED
    
    
    def main():
        win = pyglet.window.Window()
        win.set_exclusive_mouse(True)
        win.clear()
        camera = FirstPersonCamera(win)
        @win.event
        def on_draw(): 
            drawloop(win,camera)
        def on_update(delta_time):
            camera.update(delta_time)
        pyglet.clock.schedule(on_update)
        pyglet.app.run()
    
    if __name__ == '__main__':
        main()
    

    我正在使用 FirstPersonCamera 此处的代码片段:

    https://gist.github.com/mr-linch/f6dacd2a069887a47fbc

    1 回复  |  直到 7 年前
        1
  •  1
  •   Rabbid76    7 年前

    我正在解决我的代码的一个问题,如果任何原语的深度值不是零,它将不会在屏幕上呈现。我怀疑它被剪掉了。

    你必须建立一个投影矩阵来解决这个问题。设置正交投影矩阵或透视投影矩阵。

    投影矩阵描述从场景中的三维视图点到视口中的二维点的映射。它从眼睛空间转换到剪辑空间,剪辑空间中的坐标通过与 w 剪辑坐标的组件。ndc在(-1,-1,-1)到(1,1,1)之间。
    所有不在clippspace中的几何体都被剪裁。

    在正交投影中,视图空间中的坐标线性映射到剪辑空间坐标,剪辑空间坐标等于规范化设备坐标,因为 W 分量为1(用于笛卡尔输入坐标)。
    “左”、“右”、“下”、“上”、“近”和“远”的值定义了一个框。长方体体积内的所有几何体在视口上都是“可见”的。

    orthographic projection

    在透视投影中,投影矩阵描述了从针孔相机看到的世界上的3d点到视区的2d点的映射。
    摄像机截锥(一个被截断的金字塔)中的眼空间坐标被映射到一个立方体(标准化的设备坐标)。

    perspective projection

    要设置投影矩阵,必须通过 glMatrixMode .

    正交投影可以通过 glOrhto :

    w, h = 640, 480 # default pyglet window size
    
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho( -w/2, w/2, -h/2, h/2, -1000.0, 1000.0) # [near, far] = [-1000, 1000]
    
    glMatrixMode(GL_MODELVIEW)
    ....
    

    透视投影可以通过 gluPerspective :

    w, h = 640, 480 # default pyglet window size
    
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective( 90.0, 640.0/480, 0.1, 1000.0) # fov = 90 degrees; [near, far] = [0.1, 1000]
    
    glMatrixMode(GL_MODELVIEW)
    ....
    

    我建议使用以下坐标,以“查看”上述两种情况下的点:

    例如.:

    pyglet.graphics.draw(2, pyglet.gl.GL_POINTS,
        ('v3f', (-50.0, -20.0, -200.0, 40.0, 20.0, -250.0)))
    glPointSize(20.0)