如何将C ++或GLM结构表示为numpy数组?

问题描述 投票:1回答:1

我想将下面的struct表示为numpy数组。

struct UniformBufferObject {
    glm::mat4 model;
    glm::mat4 view;
    glm::mat4 proj;
};

此后,numpy数组应该作为GLSL布局读入:

layout(binding = 0) uniform UniformBufferObject {
    mat4 model;
    mat4 view;
    mat4 proj;
} ubo;

在上面的陈述中,mat4表示4x4矩阵。

下面,我创建了一个python列表,然后我将其转换为具有4x4形状的numpy数组(没有复制),其中每个元素都是dtype=float32

问题:接下来我应该怎么做才能将UniformBufferObject结构表示为numpy数组?

>>> model = [0.1, 0.1, 0.1, 1, 0.1, 0.1, 0.1, 1, 0.1, 0.1, 0.1, 1, 0.1, 0.1, 0.1, 0,]
>>> view = [0.2, 0.2, 0.2, 1, 0.2, 0.2, 0.2, 1, 0.2, 0.2, 0.2, 1, 0.2, 0.2, 0.2, 0,]
>>> proj = [0.3, 0.3, 0.3, 1, 0.3, 0.3, 0.3, 1, 0.3, 0.3, 0.3, 1, 0.3, 0.3, 0.3, 0,]
>>> modeln = np.asarray(model, dtype= 'f4').reshape(4,4)
>>> viewn = np.asarray(view, dtype= 'f4').reshape(4,4)
>>> projn = np.asarray(proj, dtype= 'f4').reshape(4,4)
>>> modeln
array([[0.1, 0.1, 0.1, 1. ],
       [0.1, 0.1, 0.1, 1. ],
       [0.1, 0.1, 0.1, 1. ],
       [0.1, 0.1, 0.1, 0. ]], dtype=float32)
>>> viewn
array([[0.2, 0.2, 0.2, 1. ],
       [0.2, 0.2, 0.2, 1. ],
       [0.2, 0.2, 0.2, 1. ],
       [0.2, 0.2, 0.2, 0. ]], dtype=float32)
>>> projn
array([[0.3, 0.3, 0.3, 1. ],
       [0.3, 0.3, 0.3, 1. ],
       [0.3, 0.3, 0.3, 1. ],
       [0.3, 0.3, 0.3, 0. ]], dtype=float32)
>>> 
python numpy opengl glsl glm-math
1个回答
1
投票

如果在GLSL中,Uniform block被指定为这样

 layout(binding = 0) uniform UniformBufferObject {
     mat4 model;
     mat4 view;
     mat4 proj;
 } ubo;

然后OpenGL不保证,块中的成员按连续顺序存储。 OpenGL不保证元素的内存布局,对齐或顺序。

为了实现良好定义的顺序和内存布局,必须使用qazxsw poi。自OpenGL 3.1 OpenGL ES 3.0或OpenGL扩展memory layout qualifier std140以来提供qazxsw poi布局:

std140

有关布局的详细规范可在以下位置找到:

在具有OpenGL 4.6 API Compatibility Profile Specification; 7.6.2.2 Standard Uniform Block Layout; page 145布局的上述均匀块的情况下,3个矩阵紧密堆积。内存布局连续48(3 * 4 * 4)OpenGL ES 3.2 Specification; 7.6.2.2 Standard Uniform Block Layout; page 113s,大小为192字节

std140

要创建与此内存布局相对应的缓冲区,可以使用平坦的float

EG

mat4 model     byte offset   0: size in bytes  64 = 4*4*sizeof(float)
mat4 view      byte offset  64: size in bytes  64 = 4*4*sizeof(float)
mat4 proj      byte offset 128: size in bytes  64 = 4*4*sizeof(float)
--------------------------------------------------------------------
                                size in bytes 192 = 3*4*4*sizeof(float)
numpy.array

没有必要 model = [0.1, 0.1, 0.1, 1, 0.1, 0.1, 0.1, 1, 0.1, 0.1, 0.1, 1, 0.1, 0.1, 0.1, 0,] view = [0.2, 0.2, 0.2, 1, 0.2, 0.2, 0.2, 1, 0.2, 0.2, 0.2, 1, 0.2, 0.2, 0.2, 0,] proj = [0.3, 0.3, 0.3, 1, 0.3, 0.3, 0.3, 1, 0.3, 0.3, 0.3, 1, 0.3, 0.3, 0.3, 0,] 阵列。但是当然你可以这样做,如果你想直接访问模型矩阵(import numpy as np ubo_data = np.array([model, view, proj], dtype='f4') ),视图矩阵(reshap())和投影矩阵(ubo_data[0])的元素:

ubo_data[1]

注意,甚至没有必要使用ubo_data[2]ubo_data = np.array([model, view, proj], dtype='f4').reshape(3, 4, 4) 数组可以生成具有相同内存布局的缓冲区:

NumPy

使用ctypes,上述每个数据数组都可用于通过import ctypes ubo_data = (ctypes.c_float * 48)(*model, *view, *proj) 创建和初始化统一块缓冲区的缓冲区存储区

PyOpenGL

或者通过glBufferData更新现有缓冲区的数据存储:

ubo = glGenBuffers( 1 )
glBindBuffer(GL_UNIFORM_BUFFER, ubo)
glBufferData(GL_UNIFORM_BUFFER, ubo_data, GL_STATIC_DRAW)
glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo)
glBindBuffer(GL_UNIFORM_BUFFER, 0)

注意,当使用glBufferSubData时,可以直接更新像这样的统一缓冲区的数据:

e.g:

glBindBuffer(GL_UNIFORM_BUFFER, ubo)
glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo_data)
PyGLM
© www.soinside.com 2019 - 2024. All rights reserved.