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

时间:2018-06-12 18:24:57

标签: python opengl pyglet coordinate-transformation

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

是否有一种简单的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 个答案:

答案 0 :(得分:1)

  

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

您必须设置投影矩阵才能解决问题。设置正交投影矩阵或透视投影矩阵。

投影矩阵描述了从场景视图的3D点到视口上的2D点的映射。它从眼睛空间转换到剪辑空间,并且通过用剪辑坐标的w分量进行划分,将剪辑空间中的坐标转换为规范化设备坐标(NDC)。 NDC在(-1,-1,-1)到(1,1,1)的范围内。
每个克隆空间之外的几何体都被剪裁。

在正交投影中,视图空间中的坐标线性映射到剪辑空间坐标,剪辑空间坐标等于标准化设备坐标,因为w分量为1(对于笛卡尔输入坐标)。
left,right,bottom,top,near和far的值定义了一个框。框中体积内的所有几何体在视口上都是“可见的”。

orthographic projection

在Perspective Projection中,投影矩阵描述了从针孔相机到视口的2D点看世界中3D点的映射。
相机平截头体(截头金字塔)中的眼睛空间坐标被映射到立方体(标准化设备坐标)。

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)
....

我建议使用以下坐标来“看到”上述两种情况中的要点:

e.g:

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