使用 Pyglet 绘制基元

Drawing Primitives with Pyglet

我是 pyglet 和 opengl 的新手,我无法 GL_LINES 工作。 GL_POINTS 没问题。我不断收到此错误:ValueError:只能分配相同大小的序列。显然我似乎定义了错误的顶点数但是 这个计数对我来说似乎是正确的,但我不知道如何解决它。

@window.event
def on_draw():
    glClear(GL_COLOR_BUFFER_BIT)

    howmany=i=2
    coords=[];colors=[]
    while i>0:
        x=random.randint(0,window.width)
        y=random.randint(0,window.height)
        x2=random.randint(0,window.width)
        y2=random.randint(0,window.height)
        coords.append(x); coords.append(y); coords.append(x2); coords.append(y2)
        #c=(random.randint(0,255),random.randint(0,255),random.randint(0,255))
        #c2=(random.randint(0,255),random.randint(0,255),random.randint(0,255))
        #for cx in c: colors.append(cx)
        #for cx in c2: colors.append(cx)
        i=i-1

    coords=tuple(coords)
    colors=tuple(colors)
    vertex_list=pyglet.graphics.vertex_list(howmany,('v2i', coords))#,('c3B', colors))
    vertex_list.draw(pyglet.gl.GL_LINES)

如果可以的话,我会着手优化您的代码,同时解决您的问题。
一个接一个地渲染素数会对系统造成极大的负担,因为您将在尝试渲染每个逻辑操作的同时进行逻辑操作,这可能会导致绘图过程中出现故障。

因此,我会考虑尝试尽快完成您的逻辑操作,并将集体数据块扔到图形卡上,为此您需要使用一种叫做 batched rendering 的东西。

@window.event
def on_draw():
    main_batch = pyglet.graphics.Batch()
    glClear(GL_COLOR_BUFFER_BIT)

    # for is less likely to get stuck than while
    for i in range(2):
        x = random.randint(0,window.width)
        y = random.randint(0,window.height)
        dest_x = random.randint(0,window.width)
        dest_y = random.randint(0,window.height)

        main_batch.add(2, gl.GL_LINES, None,
                            ('v2f', (x, y, dest_x, dest_y)),
                            ('c3B', (255, 0, 0, 0, 255, 0)) #c3B is a gradient (0,0,0, 255,255,255) combo
                                                            # this gradient will be per line, not end to end.
                        )
    main_batch.draw()

可能让您感到困惑的是 v2i 中的 2 以及 color 和行数之间的关系。请参阅您的示例中的 howmany 将定义 cords 中有多少个端点,而不是您有多少行。

意思是,如果你有 2 lines,那就是 4 endpoints,因为每一行都有一个开始和结束坐标。解决方案是 howmany*2,因为在 2D 直线中总是有固定数量的位置。

但是,问题在于您还为每一行分配了颜色,这意味着 colors 列表的长度必须与特定的 cords 列表的长度相匹配方式,因为它们将彼此直接相关。

所以在我上面的例子中,我将一次添加一行作为具有给定颜色的单个对象到批处理中,它的效果稍差,但可以作为演示。添加两行后,我将渲染该批次。

如果你想做同样的操作但是有 2 行,你会做这样的事情:

main_batch.add(4, gl.GL_LINES, None,
                            ('v2i', (100,100, 120,100,   # start -> end
                                     120,100, 120,150))  # start -> end
                        )

现在 4 sa in x,y -> x,y -> x,y -> x,y,4 个坐标。
现在我在这个代码块中省略了颜色只是为了向您展示如何添加多线顶点线。此代码将默认为白线并且可渲染。

你可以这样做:

 glColor3f(1, 0, 0) # Produces a red line
 main_batch.draw()

要更改那条 4 线的颜色,或者.. 您可以在创建线时定义颜色线。 c3B 基本上意味着每个 "definition" 有 3 种颜色,也就是您的标准 RGB 值。但是每个 x,y 坐标需要一个 RGB 定义。所以它看起来像这样:

main_batch.add(4, gl.GL_LINES, None,
                            ('v2i', (100,100, 120,100,   # start -> end
                                     120,100, 120,150)),  # start -> end

                             ('c3B', (0,0,0, 255,255,255,
                                      0,0,0, 255,255,255))
                        )

这会创建两条连接线,每条线都有一个从黑到白的渐变,并将 "shape" 添加到一个批次中并一次渲染整个批次。
您创建的下一个线条形状可以添加到同一批次并在同一迭代中渲染两条线。

为了使其更紧凑并将其转换回您最初设置列表的方式:

cords = (100,100, 120,100, 120,100, 120,150)
howmany = len(cords) / 2 # How many lines, not cordinates

colors = (0,0,0, 255,255,255)*howmany
main_batch.add(howmany, gl.GL_LINES, None, ('v2i', cords), ('c3B', colors))