有没有办法更快地渲染点OpenGL

2023-12-31

我需要在 openGL 中可视化大约 50k-60k 点,我设法将它们全部打印出来,但是当我使用旋转时,每次旋转之间需要花费很多时间,因为它只是打印每一帧的所有数据。 有没有办法一次性打印所有数据并冻结数据的导入,以便保留图像但停止处理?

def PointClouds(pcd_files): #pcd_file
   glBegin(GL_POINTS)
   for i in pcd_files:
       pc = pypcd.PointCloud.from_path(i)
       number_of_points = pc.get_metadata().get('points')
       z = pc.pc_data['z']
       x = pc.pc_data['x']
       y = pc.pc_data['y']
       for j in range(number_of_points):
           glVertex3f(x[j], y[j], z[j])
   glEnd()

主要是:

files = glob.glob(os.getcwd() + "\\" + PCD_OutPutDirectory + "\*.pcd")

pygame.init()
display = (1700, 1000)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
gluPerspective(50, (display[0] / display[1]), 0.1, 5000)
glTranslatef(0, 0, -1000)
Clock = pygame.time.Clock()
while True:
    Clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    glRotatef(2, 1, 1, 3)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    PointClouds(files)
    pygame.display.flip()

打印所有点,但在每次旋转之间遍历所有点并再次打印它们,因为有 60k+ 点,每次旋转之间需要太多时间。我需要它只读取一次点并冻结图像而不是旋转。 谢谢您的帮助


瓶颈是 for 循环和glBegin/glEnd顺序。数据是从每一帧的文件中读取的。 请注意,通过使用绘图glBegin/glEnd https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glBegin.xml序列和固定函数矩阵堆栈几十年来已被弃用。 在启动时读取一次文件并创建一个顶点缓冲区对象 https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_Buffer_Object。 (阅读更多关于顶点规格 https://www.khronos.org/opengl/wiki/Vertex_Specification and Shader https://www.khronos.org/opengl/wiki/Shader最先进的渲染方式。)

与现有代码最接近的解决方案是使用客户端功能glEnableClientState https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glEnableClientState.xml和固定的功能属性glVertexPointer https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glVertexPointer.xml。使用此解决方案,您不需要任何着色器程序。
在下文中我假设您使用PyOpenGL http://pyopengl.sourceforge.net/.

将顶点坐标加载到数组中

def LoadVertices(pcd_files):
    vertices = []
    for i in pcd_files:
       pc = pypcd.PointCloud.from_path(i)
       number_of_points = pc.get_metadata().get('points')
       z = pc.pc_data['z']
       x = pc.pc_data['x']
       y = pc.pc_data['y']
       for j in range(number_of_points):
           vertices += [x[j], y[j], z[j]]
    return vertices

创建一个顶点缓冲区对象 https://www.khronos.org/opengl/wiki/Vertex_Specification#Vertex_Buffer_Object并创建并初始化缓冲区对象的数据存储:

import ctypes
def CreateBuffer(vertices):
    bufferdata = (ctypes.c_float*len(vertices))(*vertices) # float buffer
    buffersize = len(vertices)*4                           # buffer size in bytes 

    vbo = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, buffersize, bufferdata, GL_STATIC_DRAW) 
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    return vbo

创建一个可以绘制的函数点基元 https://www.khronos.org/opengl/wiki/Primitive#Point_primitives从缓冲区:

def DrawBuffer(vbo, noOfVertices):
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glEnableClientState(GL_VERTEX_ARRAY)
    glVertexPointer(3, GL_FLOAT, 0, None)

    glDrawArrays(GL_POINTS, 0, noOfVertices)

    glDisableClientState(GL_VERTEX_ARRAY)
    glBindBuffer(GL_ARRAY_BUFFER, 0)

在您的程序中使用此函数:

files = glob.glob(os.getcwd() + "\\" + PCD_OutPutDirectory + "\*.pcd")

pygame.init()
display = (1700, 1000)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)

vArray    = LoadVertices(files)
noPoints  = len(vArray) // 3
bufferObj = CreateBuffer(vArray)

gluPerspective(50, (display[0] / display[1]), 0.1, 5000)
glTranslatef(0, 0, -1000)
Clock = pygame.time.Clock()
while True:
    Clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    glRotatef(2, 1, 1, 3)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    DrawBuffer(bufferObj, noPoints)

    pygame.display.flip()

如果你想为每个点添加单独的颜色,那么顶点及其属性不仅仅由坐标组成(x, y, z),它还必须RGB颜色 https://en.wikipedia.org/wiki/RGB_color_model (x, y, z, r, g, b),因此每个属性元组由 6 个分量组成,而不是 3 个。

固定功能颜色属性必须由客户端状态启用GL_COLOR_ARRAY。添加属性由指定glColorPointer https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glColorPointer.xml.

每个属性元组的大小为 24 字节,因为元组由 6 个组件组成(x, y, z, r, g, b)每个组件的大小为 4 字节(这是float).
该大小必须传递给第三个参数(sride) of glVertexPointer分别glColorPointer.

如果绑定了命名缓冲区对象,则最后一个参数glVertexPointer分别glColorPointer被视为缓冲区对象缓冲区存储中的字节偏移量。偏移量是属性第一个组成部分的字节数。
的情况下glVertexPointer偏移量为 0,因为(x, y, z)是属性元组中的第一个组件。 的情况下glColorPointer偏移量是 3*4=12 字节,因为(r, g, b)在3个坐标之后(x, y, z)每个组件的大小为4。 由于最后一个参数的类型是指针,因此必须将偏移量转换为ctypes.c_void_p (e.g. ctypes.c_void_p(3*4))。对于这个Python内置库ctypes https://stackoverflow.com/questions/56810151/glbuffersubdata-havent-implemented-type-inference-for-lists-yet-instanced-r/56810999#56810999必须进口。如果偏移量为0,None可以用来代替ctypes.c_void_p(0).

顶点属性的规范可能如下所示:

glBindBuffer(GL_ARRAY_BUFFER, vbo)

stride = 6*4 # (24 bates) : [x, y, z, r, g, b] * sizeof(float)

glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer(3, GL_FLOAT, stride, None)

glEnableClientState(GL_COLOR_ARRAY)
offset = 3*4 # (12 bytes) : the rgb color starts after the 3 coordinates x, y, z 
glColorPointer(3, GL_FLOAT, stride, ctypes.c_void_p(offset))

全部一起:

import ctypes 

def LoadVertices(pcd_files):
    attributes = []
    for i in pcd_files:
       pc = pypcd.PointCloud.from_path(i)
       number_of_points = pc.get_metadata().get('points')
       z = pc.pc_data['z']
       x = pc.pc_data['x']
       y = pc.pc_data['y']
       r = # set the RGB color data here
       g =
       b = 
       for j in range(number_of_points):
           attributes += [x[j], y[j], z[j], r[j], g[j], b[j]]
    return attributes

def CreateBuffer(attributes):
    bufferdata = (ctypes.c_float*len(attributes))(*attributes) # float buffer
    buffersize = len(attributes)*4                             # buffer size in bytes 

    vbo = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, buffersize, bufferdata, GL_STATIC_DRAW) 
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    return vbo

def DrawBuffer(vbo, noOfVertices):
    glBindBuffer(GL_ARRAY_BUFFER, vbo)

    stride = 6*4 # (24 bates) : [x, y, z, r, g, b] * sizeof(float)

    glEnableClientState(GL_VERTEX_ARRAY)
    glVertexPointer(3, GL_FLOAT, stride, None)

    glEnableClientState(GL_COLOR_ARRAY)
    offset = 3*4 # (12 bytes) : the rgb color starts after the 3 coordinates x, y, z 
    glColorPointer(3, GL_FLOAT, stride, ctypes.c_void_p(offset))

    glDrawArrays(GL_POINTS, 0, noOfVertices)

    glDisableClientState(GL_VERTEX_ARRAY)
    glDisableClientState(GL_COLOR_ARRAY)
    glBindBuffer(GL_ARRAY_BUFFER, 0)
files = glob.glob(os.getcwd() + "\\" + PCD_OutPutDirectory + "\*.pcd")

pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)

vArray    = LoadVertices(files)
noPoints  = len(vArray) // 6  # 6 components per attribute tuple
bufferObj = CreateBuffer(vArray)

gluPerspective(50, (display[0] / display[1]), 0.1, 5000)
glTranslatef(0, 0, -1000)
Clock = pygame.time.Clock()
while True:
    Clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    glRotatef(2, 1, 1, 3)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    DrawBuffer(bufferObj, noPoints)

    pygame.display.flip()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有没有办法更快地渲染点OpenGL 的相关文章

  • 存储 OpenGL 状态

    假设我正在尝试用 C 制作某种小型 opengl 图形引擎 我读过通过访问 opengl 状态glGet 函数可能非常昂贵 虽然访问 opengl 状态似乎是一个经常操作 并且强烈建议将 opengl 状态的副本存储在具有快速读 写访问权限
  • 在Python中,如何将矩阵逆时针旋转90度?

    gt gt gt def rotate matrix k List List int For example if I have m 1 2 3 2 3 3 5 4 3 rotate matrix m should give me 3 3
  • 如果 Excel 文件是由程序创建的,Pandas read_excel 对于具有简单公式的单元格返回 nan [重复]

    这个问题在这里已经有答案了 I use pd read excel读取由以下命令创建的 excel 文件openpyxl并从一个网址下载 解析后的数据框将给出nan如果单元格值是公式 which formula is simply 100
  • Python 转换矩阵

    我有一个如下所示的列表 2 1 3 1 2 3 1 2 2 2 我想要的是一个转换矩阵 它向我显示如下序列 1 后跟 1 的频率是多少 1 后面跟着 2 的频率是多少 1 后跟 3 的频率是多少 2 后跟 1 的频率是多少 2 后跟 2 的
  • Flask 中“缺少 CSRF 令牌”,但它在模板中呈现

    问题 当我尝试登录 使用 Flask login 时 我得到Bad Request The CSRF session token is missing但令牌正在呈现 在模板中 secret key 已设置 并且我在本地运行localhost
  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 使用 NumPy 编写一个函数来计算具有特定公差的积分

    我想编写一个自定义函数来以特定容差对表达式 python 或 lambda 函数 进行数字积分 我知道与scipy integrate quad人们可以简单地改变epsabs但我想使用 numpy 自己编写该函数 From 这篇博文 htt
  • 无法在 virtualenv 中安装 libxml2

    我有一个问题libxml2蟒蛇模块 我正在尝试将其安装在python3 虚拟环境使用以下命令 pip install libxml2 python3 但它显示以下错误 Collecting libxml2 python3 Using cac
  • App Engine NDB:如何访问属性的 verbose_name

    假设我有这个代码 class A ndb Model prop ndb StringProperty verbose name Something m A m prop a string value 当然 现在如果我打印 m prop 它会
  • 使用pathlib获取主目录

    翻看新的pathlib在 Python 3 4 中 我注意到没有任何简单的方法来获取用户的主目录 我能想到的获取用户主目录的唯一方法是使用旧的os path像这样的库 import pathlib from os import path p
  • Python - Unicode 到 ASCII 的转换

    我无法在不丢失数据的情况下将以下 Unicode 转换为 ASCII u ABRA xc3O JOS xc9 I tried encode and decode他们不会这么做 有人有建议吗 Unicode 字符u xce0 and u xc
  • 高级描述熊猫

    有没有像 pandas 那样更高级的功能 通常我会继续这样 r pd DataFrame np random randn 1000 columns A r describe 我会得到一份很好的总结 就像这样 A count 1000 000
  • 更改 Matplotlib 投影轴的背景颜色

    我正在尝试使用 Cartopy 创建一个图形 该图形需要在未投影的轴上绘制投影轴 这是一个尽可能简单的代码版本 它将轴上的内容替换为背景颜色 import matplotlib pyplot as plt import cartopy cr
  • 无法使用 python rasterio、gdal 打开 jp2 (来自哨兵)

    我试图在 python 中将 jp2 栅格产品作为栅格打开 但当我们使用 raterio 和 gdal 包时没有成功 我收到此错误 RasterioIOError b4 jp2 not recognized as a supported f
  • python Recipe:列出最接近等于值的项[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 考虑像这样的列表 0 3 7 10 12 15 19 21 我想获得最接近任何值的最近的最小数字 所以如果我通过4 我会得到3 如果我
  • 是否可以在Python中将日+月(不是年)与当前日+月进行比较?

    我正在获取 5 月 10 日 格式的数据 我试图弄清楚它是今年还是明年 该日期仅一年 因此 5 月 10 日表示 2015 年 5 月 10 日 而 5 月 20 日表示 2014 年 5 月 20 日 为此 我想将字符串转换为日期格式并进
  • 如何创建用于霍夫曼编码和解码的树?

    对于我的作业 我将对霍夫曼树进行编码和解码 我在创建树时遇到问题 并且陷入困境 不要介意打印语句 它们只是让我测试并查看函数运行时的输出是什么 对于第一个 for 循环 我从主块中用于测试的文本文件中获取了所有值和索引 在第二个 for 循
  • 两种 ODE 求解器之间的差异

    我想知道 两者之间有什么区别ODEINT and solve ivp用于求解微分方程 它们之间有什么优点和缺点 f1 solve ivp f 0 1 y0 y0 is the initial point f2 odeint f y0 0 1
  • 为boost python编译的.so找不到模块

    我正在尝试将 C 代码包装到 python 中 只需一个类即可导出两个函数 我编译为map so 当我尝试时import map得到像噪音一样的错误 Traceback most recent call last File
  • 基于值的 matplotlib 条形图颜色

    有没有一种方法可以根据条形图的值对条形图的条形进行着色 例如 values below 0 5 red values between 0 5 to 0 green values between 0 to 08 blue etc 我找到了一些

随机推荐

  • 在 Perl 中,如何访问另一个包中定义的标量?

    我似乎被困在尝试访问另一个包中定义的标量 并将示例缩小为一个简单的测试用例 我可以在其中重现问题 我希望能够使用我们的机制访问对 Example 包中定义的列表的引用 但是 Dumper 显示该变量在 example pl 中始终未定义 E
  • 从控制器返回 razor 解析的 Javascript 作为 ViewResult

    我已经成功创建了一个 mvc razor Web 应用程序 它返回已由 razor 解析的 css 文件 每次有背景图像时 我都会有一个 razor 片段 它将 URL 前缀写入图像文件名 CSS 现在看起来像这样 body backgro
  • 自定义后退按钮标题并保留滑动返回手势

    问题 我想在弹出的视图控制器中自定义导航后退按钮标题 例如 Whatsapp 但是 如果您使用 在弹出视图控制器中分配新的 backBarButtonItem 将禁用向后滑动手势 self navigationController inte
  • Active Directory 跨域 - 使用PrincipalContext 的组成员

    我试图通过使用 C 中的 DirectoryServices AccouneManagement 命名空间类来获取给定活动目录组的成员 如果我为特定域指定了主体上下文对象构造函数 那么每当我访问来自其他域的组中的成员时 我都会遇到以下错误
  • 为什么 Spark 中聚集和折叠两个不同的 API?

    当使用Scala标准库时 我可以这样做 scala gt val scalaList List 1 2 3 scalaList List Int List 1 2 3 scala gt scalaList foldLeft 0 acc n
  • 你能写一个到锚点的 301 重定向吗?

    这是有效且正确的吗 RewriteRule myOldPage html index php info R 我特别感兴趣的是 info part 是的 这是一个有效的 301 重定向 HTTP标准 http www w3 org Proto
  • 通过 OR 或 AND 连接(粘合)where 条件(Arel、Rails3)

    我有一些complex查询 使用子查询等 并希望使用 OR 或 AND 语句将它们粘合在一起 例如 where1 table where where2 table where 我想要类似的东西 where3 where1 or where2
  • iPhone 开发 - 内存管理经验教训

    我需要内存管理方面的课程 我有一个使用多个视图 大约 10 个 的应用程序 其中一些附加到选项卡控制器 问题是我正在使用图像 许多图像是我从网络服务加载的 我面临以下问题 当我在表视图中滚动时 内存不断增加 为什么 我从 Apple 网站检
  • 如何将 aria 标签分配给侧边栏

    我正在使用 Siteimprove 的 chrome 扩展浏览客户的网站来测试合规性 我在一个侧边栏区域的两侧收到 具有相同名称的地标 错误 在functions php的注册侧边栏代码中 我有 before widget gt
  • 如何使用单个按钮创建 Firefox 插件(与 Echofon 相同)?

    I want to how to create Firefox plugin with custom compact menu same like Firefox window Just now I saw in Echofon Here
  • 显示列表视图时在后台下载图像

    我有一个列表 其中包含我在列表中显示的图像的所有 URI 现在我想在后台运行一个线程 从网络获取这些图像并将它们存储在 SD 卡上 因此 当我单击列表中的特定元素而不是从 Web 获取时 它应该从新活动中的 SD 卡获取 我该怎么做呢 Yo
  • 图书馆插件:: 找不到图书馆资源

    我目前正在将 Android 库转换为 Unity 插件 我已经走了很长一段路 但现在我陷入了无法从 Unity 访问库资源的地步 应用程序运行良好 直到我实际从库中调用视图 这是我当时收到的错误日志 12 12 13 37 36 495
  • iPhone 12 和 iPhone 13 上的颠倒方向

    我有一个 iOS 应用程序 可以在运行 iOS 15 6 的 iPhone 7 上上下旋转 然而 同一个应用程序在运行 iOS 15 6 1 的 iPhone 13 或 iPhone 12 上不会上下旋转 Apple 是否在较新的设备或 i
  • Android 中“FLAG_BLUR_BEHIND”的替代方案?

    我可以看到 当我使用 API 演示中所示的相同标志来模糊背景时 我收到一条警告 表明它已被弃用 字段 WindowManager LayoutParams FLAG BLUR BEHIND 已弃用 我读过相关内容 发现 不再支持模糊 这是否
  • 重新创建 Fabric.js 画布并导出为图像?

    我有一个画布 用户可以在其中使用另一个画布中的图像创建设计div他们点击 将其发送到 Fabric js 画布 并在其中移动等等 由于画布的大小是width 270 and height 519 比成品小 我需要用尺寸为的画布重新创建它wi
  • 使用 Apple Enterprise Developer Program 部署 iOS 应用程序

    我已经为我需要部署的公司创建了一个应用程序 该应用程序仅供内部使用 因此不会在 App Store 上提供 我是否需要为要在其设备上安装应用程序的每个人提供 UDID 这是不可能的 因为有 500 名员工 是否有人拥有有关仅使用企业开发人员
  • 指定 64 位对齐

    给定一个结构定义 例如 struct foo int a b c 指定它应始终与 64 位地址对齐的最佳 最简单 最可靠和可移植 方法是什么 即使在 32 位版本上也是如此 我正在使用 C 11 和 GCC 4 5 2 并希望也支持 Cla
  • 上传的图像在canvas中拖动,在html5中可触摸和旋转

    我是 Html5 的新手 我正在上传图像 但它没有显示在画布中 如果我提供图像的直接来源 那么它将起作用 我从此链接获取帮助javascript 上传图像文件并将其绘制到画布中 https stackoverflow com questio
  • 包含“点目录”时的 Path.relativize 行为

    About Path relativize你可以阅读的方法 此方法尝试构造一个相对路径 当 根据此路径解析 产生一个定位相同文件的路径 作为给定的路径 例如 在 UNIX 上 如果此路径是 a b 并且 给定路径是 a b c d 那么生成
  • 有没有办法更快地渲染点OpenGL

    我需要在 openGL 中可视化大约 50k 60k 点 我设法将它们全部打印出来 但是当我使用旋转时 每次旋转之间需要花费很多时间 因为它只是打印每一帧的所有数据 有没有办法一次性打印所有数据并冻结数据的导入 以便保留图像但停止处理 de