gpt4 book ai didi

python - PyOpenGL - 当某些场景元素需要消失时更新三角形数组

转载 作者:行者123 更新时间:2023-12-01 08:51:23 26 4
gpt4 key购买 nike

我有一个需要快速渲染的场景。所以我成功地将三角形的顶点生成为 numpy,上传到 GPU 并以非常快的速度渲染它。到目前为止一切顺利。

当场景中的某些元素需要从场景中消失时,问题就开始了。我所做的就是遍历整个数组,过滤掉不再需要绘制的场景元素的顶点,重新上传到GPU然后渲染。这显然需要几秒钟,这是 Not Acceptable 。我正在寻找一种快速方法来修改数组并重绘场景。

这是我使用的代码的简化版本:(也希望对代码本身有任何评论)

from OpenGL.GL import *
from OpenGL.GLU import *
import numpy as np
import ctypes

vertex_dtype = [("position", np.float32, 3), ("color", np.float32, 4)]
vertex_array_object = None
vertex_buffer = None
shader_program = .......

def upload_to_gpu(vertices_np):
global vertex_array_object, vertex_buffer
if vertex_array_object is None:
vertex_array_object = glGenVertexArrays(1)
if vertex_buffer is None:
vertex_buffer = glGenBuffers(1)
glBindVertexArray(vertex_array_object)
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
glBufferData(GL_ARRAY_BUFFER, vertices_np.nbytes, vertices_np, GL_STATIC_DRAW)
stride = vertices_np.strides[0]
offset = ctypes.c_void_p(0)
position_location = glGetAttribLocation(shader_program, 'a_position')
glEnableVertexAttribArray(position_location)
glVertexAttribPointer(position_location, 3, GL_FLOAT, False, stride, offset)

offset = ctypes.c_void_p(vertices_np.dtype["position"].itemsize)
color_location = glGetAttribLocation(shader_program, "a_color")
glEnableVertexAttribArray(color_location)
glVertexAttribPointer(color_location, 4, GL_FLOAT, False, stride, offset)

glBindVertexArray(0)
glBindBuffer(GL_ARRAY_BUFFER, 0)

def create_np_array(all_vertices):
vertices_np = np.zeros(len(all_vertices), dtype=vertex_dtype)
cur_idx = 0
for vertex in all_vertices:
if ....should_ignore_triangle....:
continue
vertices_np[cur_idx]["position"] = [vertex[0], vertex[1], vertex[2]]
vertices_np[cur_idx]["color"] = ......
cur_idx += 1

vertices_np = vertices_np[:cur_idx]
return vertices_np

def draw_scene(vertices_np):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(shader_program)
# Set view and projection matrix
glBindVertexArray(vertex_array_object)
glDrawArrays(GL_TRIANGLES, 0, vertices_np.shape[0])

def main():
all_vertices = [[0, 0, 0], [1, 0, 0], [0, 1, 0], ......] # long list of ~million vertices
vertices_np = create_np_array(all_vertices)
upload_to_gpu(vertices_np)

# Now we are ready to start rendering
draw_scene(vertices_np) # works fine

# Now something changes and we need to regenerate the vertices_np and upload it again
vertices_np = create_np_array(all_vertices) # <-- THIS TAKES TOO MUCH TIME
upload_to_gpu(vertices_np)
draw_scene(vertices_np) # works fine

最佳答案

如果您只想省略顶点,但不想添加新顶点,那么我建议只绘制您想要的顶点子集。不要更改 GPU 上的任何数据或重新创建任何顶点数组。

创建一个元组数组,其中包含要绘制的顶点的索引范围。为此,找到必须省略的第一个顶点,并将“范围”元组附加到元组列表中。找到下一个要绘制的顶点并重复该过程直到数组末尾:

def draw_np_array(all_vertices):

idx_list = []
cur_start_idx = 0
cur_end_idx = 0
for vertex in all_vertices:

if ....should_ignore_triangle....:
if cur_end_idx > cur_start_idx:
idx_list.append( (cur_start_idx, cur_end_idx) );
cur_end_idx += 1
cur_start_idx = cur_end_idx
continue

cur_end_idx += 1

if cur_end_idx > cur_start_idx:
idx_list.append( (cur_start_idx, cur_end_idx) );

return idx_list

使用“智能”绘制调用绘制场景:

def draw_scene(idx_list):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(shader_program)
# Set view and projection matrix
glBindVertexArray(vertex_array_object)

for idx_range in idx_list:
start = idx_range[0]
count = idx_range[1]-idx_range[0]
glDrawArrays(GL_TRIANGLES, start, count)

您可以使用glMultiDrawArrays进一步改进这一点,它可以通过一次绘制调用绘制数组的多个范围,而不是在循环中绘制数组。

关于python - PyOpenGL - 当某些场景元素需要消失时更新三角形数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53096845/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com