日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python opengl加速_OpenGL with python 渲染加速

發(fā)布時間:2024/8/5 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python opengl加速_OpenGL with python 渲染加速 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在python的OpenGL環(huán)境下搭了一個簡易的加載gltf動畫的框架。測試的時候發(fā)現渲染很耗時,做了一些零碎的優(yōu)化,現在的速度還算令人滿意。印象比較深的一個優(yōu)化是針對joint matrix的數據傳輸方式的改變,在此做個記錄。

優(yōu)化之前

之前因為骨骼關節(jié)數量超過了單個shader支持的uniform,所以把骨骼部分的數據改成了UBO(TODO:UBO相關博客)。

按理這一堆joint matrices和joint normal matrices是可以打包一塊傳上去,只傳一次,這樣效率會高很多。

如果用c++寫,可以先開一塊連續(xù)內存,然后每次更新這塊內存,再一次打包傳給ubo就行。但不知道python要怎么處理,所以一開始寫成了這種扣扣搜搜的方式。

class Skin:

def __init__(self, skin: GLTFSkin):

...

def update_ubo(self):

glBindBuffer(GL_UNIFORM_BUFFER, self.ubo_id)

# 逐個更新joint matrix

for i, m in enumerate(self.joint_matrices):

glBufferSubData(GL_UNIFORM_BUFFER, i * glm.sizeof(glm.mat4), glm.sizeof(glm.mat4), glm.value_ptr(m))

offset = len(self.joint_matrices)

# 逐個更新joint normal matrix

for i, m in enumerate(self.joint_normal_matrices):

glBufferSubData(GL_UNIFORM_BUFFER, (i + offset) * glm.sizeof(glm.mat4), glm.sizeof(glm.mat4),

glm.value_ptr(m))

glBindBuffer(GL_UNIFORM_BUFFER, 0)

def update_joints(self, nodes, parent_node):

self.joint_matrices = []

self.joint_normal_matrices = []

# 重新計算joint matrix和joint normal matrix

# 添加到list里待更新

for i, node in enumerate(self.joints):

joint_matrix = parent_node.inverse_world_transform * \

node.world_transform * \

self.inverse_bind_matrices[i]

self.joint_matrices.append(joint_matrix)

normal_matrix = glm.transpose(glm.inverse(joint_matrix))

self.joint_normal_matrices.append(normal_matrix)

self.update_ubo()

優(yōu)化之后

優(yōu)化的思路很簡單,就是提前開一塊空間,每次更新里面的內容再整塊打包上傳。

class Skin:

def __init__(self, skin: GLTFSkin):

# 開一塊連續(xù)的空間

self.mat_merge = np.empty((len(self.joints) * 2 * 4 * 4), dtype=np.float32)

# 獲取這塊連續(xù)空間的首地址

# A pointer to the memory area of ??the array as a Python integer. 用于內存塊的更新

# 這樣的pointer能很方便的用+offset來索引相鄰地址

self.mat_ctypes_ptr = self.mat_merge.ctypes.data

# LP_c_float object 用于ubo的更新

self.mat_ctypes_ptr_float = ctypes.cast(

self.mat_merge.ctypes.data,

ctypes.POINTER(ctypes.c_float))

self.glm_mat4x4_size = 16 * ctypes.sizeof(ctypes.c_float)

self.mat_offset = len(self.joints) * self.glm_mat4x4_size

def update_ubo(self):

glBindBuffer(GL_UNIFORM_BUFFER, self.ubo_id)

# 依舊使用glBufferSubData來傳數據

# 但這次可以多個矩陣一塊,只傳一次

glBufferSubData(GL_UNIFORM_BUFFER, 0, 2 * self.mat_offset,

self.mat_ctypes_ptr_float)

glBindBuffer(GL_UNIFORM_BUFFER, 0)

def update_joints(self, nodes, parent_node):

a_ctypes_ptr = self.mat_ctypes_ptr

step = self.glm_mat4x4_size

offset = self.mat_offset

for i, node in enumerate(self.joints):

joint_matrix = (parent_node.inverse_world_transform *

node.world_transform *

self.inverse_bind_matrices[i])

# 使用cytpes.memmove來更新內存

ctypes.memmove(

a_ctypes_ptr + offset,

bytes(glm.transpose(glm.inverse(joint_matrix))),

?step)

ctypes.memmove(a_ctypes_ptr, bytes(joint_matrix), step)

a_ctypes_ptr += step

self.update_ubo()

ctypes.memmove(dst, src, count)

Same as the standard C memmove library function: copies count bytes from src to dst. dst and src must be integers or ctypes instances that can be converted to pointers.

也可以使用self.mat_ctypes_ptr_float作為ctypes.memmove函數的第一個參數,但無法像self.mat_ctypes_ptr那樣,可以用+offset來方便地找到每個矩陣對應的地址。

原文鏈接:https://blog.csdn.net/suian0424/article/details/106524965

總結

以上是生活随笔為你收集整理的python opengl加速_OpenGL with python 渲染加速的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。