绘制可变数量的线 - PyOpenGL

Draw variable number of lines - PyOpenGL

我想创建一个用户可以多次调用的函数,比如 drawLine(x,y),并且所有这些线都应该一次显示(无替换)。我是 PyOpenGL(和 OpenGL)的新手,我不确定如何去做。截至目前,我知道如何使用类似这样的方法绘制固定数量的线条:

def main_loop(window):
    while (
        glfw.get_key(window, glfw.KEY_ESCAPE) != glfw.PRESS and
        not glfw.window_should_close(window)
    ):
        glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
        glBegin(GL_LINES)
        glVertex2f(0.0,0.0)
        glVertex2f(1.0,1.0)
        glEnd()

        glfw.swap_buffers(window)
        glfw.poll_events()

在这里,我可以多次重复 glBegin(GL_LINES) - glEnd() 块,以使用固定参数绘制固定数量的线。但是变线任务怎么办呢?

换句话说, 我想创建一个函数,在使用 x 和 y 坐标调用时,向屏幕上已经显示的一串行添加一行。根据用户交互,可能会多次调用此函数。我能想到的添加行的唯一方法是在此 main_loop 函数中插入 glBegin-glEnd 块(如上面的代码所示),但如何在运行时执行此操作?

您必须在每一帧中重新绘制整个场景。因此,您需要一个列表来存储线条的点。

创建一个可以绘制 GL_LINE_STRIP 的函数。函数的参数是一个顶点列表:

def draw_line(vertices):
    glBegin(GL_LINE_STRIP)
    for vertex in vertices:
        glVertex2f(*vertex)
    glEnd()

为顶点定义一个空列表:

line_vertices = []

通过用户交互向线条添加新点。例如按下鼠标按钮时:

def onMouseButton(win, button, action, mods):
    global line_vertices
    
    if button == glfw.MOUSE_BUTTON_LEFT:
        if action == glfw.PRESS:
            line_vertices.append(glfw.get_cursor_pos(win))

在主应用程序循环中画线:

while not glfwWindowShouldClose(window):
    # [...]

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    draw_line(line_vertices + [glfw.get_cursor_pos(window)])  

最小示例:

import glfw
from glfw.GLFW import *
from OpenGL.GL import *

def draw_line(vertices):
    glBegin(GL_LINE_STRIP)
    for vertex in vertices:
        glVertex2f(*vertex)
    glEnd()

line_vertices = []

def onMouseButton(win, button, action, mods):
    global line_vertices
    
    if button == glfw.MOUSE_BUTTON_LEFT:
        if action == glfw.PRESS:
            line_vertices.append(glfw.get_cursor_pos(win))

glfw.init()
display_size = (640, 480)
window = glfw.create_window(*display_size, "OpenGL window", None, None)

glfw.make_context_current(window)
glfw.set_mouse_button_callback(window, onMouseButton)

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, display_size[0], display_size[1], 0, -1, 1)

glMatrixMode(GL_MODELVIEW)
glLoadIdentity()

while not glfwWindowShouldClose(window):
    
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    draw_line(line_vertices + [glfw.get_cursor_pos(window)])  

    glfwSwapBuffers(window)
    glfwPollEvents()

glfw.terminate()