1

I use PyGLM and PyOpenGL

I have specified the following Shader Storage Buffer in the Vertex Shader:

layout(std430, binding = 1) buffer MVP
{
    mat4 u_proj;
    mat4 u_view;
    mat4 u_model;
} mvp_data;

I have initialized the model, view and projection matrix:

model = glm.mat4(1)
view  = glm.lookAt(glm.vec3(0,-3,0), glm.vec3(0,0,0), glm.vec3(0,0,1))
proj  = glm.perspective(glm.radians(90), self.__vp_size[0]/self.__vp_size[1], 0.1, 100)

How can the buffer object's data store be created and initialized using glBufferData (or glNamedBufferData)

ssbo = glGenBuffers( 1 )
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo )
glBufferData(GL_SHADER_STORAGE_BUFFER, 3*16*4, ???, GL_STATIC_DRAW )

respectively initialized by glBufferSubData (or glNamedBufferSubData)

ssbo = glGenBuffers( 1 )
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo )
glBufferData(GL_SHADER_STORAGE_BUFFER, 3*16*4, None, GL_STATIC_DRAW )
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, ???, ???);

Since the SSBO contains 3 (tightly packed) mat4, the size of the buffer is 3 * 16 * 4 (3 4x4-matrices with element data type float).
So the initialization of the buffer can be done by a NumPy array.
But how the PyGLM matrices can be effectively assigned to the NumPy array?

buffer_data = numpy.zeros(3*16, dtype=numpy.float32)

??? buffer_data = model, view, proj

glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_data.nbytes, buffer_data, GL_STATIC_DRAW)

Or is there an even more efficient solution, without an copying the data to a NumPy array?

0

2 Answers 2

1

Finally I found the solution myself.

It should be noted, that the Shader Storage Buffer consists of 344=48 tightly packed floats.

PyGlm provides the handy functions glm.value_ptr and glm.sizeof. glm.value_ptr corresponds to the glm::value_ptr. glm.sizeof works like c++ sizeof operator for the glm data types.

This functions can be used with the glBufferSubData wrapping of PyOpenGL to updates the buffer data:

glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0,                      glm.sizeof(glm.mat4), glm.value_ptr(model))
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 1*glm.sizeof(glm.mat4), glm.sizeof(glm.mat4), glm.value_ptr(view))
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 2*glm.sizeof(glm.mat4), glm.sizeof(glm.mat4), glm.value_ptr(proj))

A object of type glm.mat4 can be assigned to a numpy.array with shape (4, 4) of type np.float32. So the 3 matrices can be assigned to the elements of a numpy.array with shape (3, 4, 4):

buffer_data = np.empty([3, 4, 4], dtype=np.float32)
buffer_data[0] = model
buffer_data[1] = view
buffer_data[2] = proj

This array can be used to updates the entire buffer data at once:

buffer_size = buffer_data.size * buffer_data.itemsize
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, buffer_size, buffer_data)

Or for the initial glBufferData creation and initialization of the buffer object's data store:

glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_data, GL_DYNAMIC_DRAW)

Since PyGLM version 2.0.0 there is a simpler way to l this. See Using Arrays:

PyGLM's array type was introduced in version 2.0.0 to reduce the likelihood of requiring users to also use numpy besides glm. It's mainly intended to provide a way of passing multiple glm type instances (such as vectors) to external C functions (such as glBufferData).

buffer_data = glm.array(model, view, proj)
glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_data.nbytes, buffer_data.ptr, GL_STATIC_DRAW)
Sign up to request clarification or add additional context in comments.

Comments

0

There is a way to update all the data at once without having to use numpy at all.

In the PyGLM docs, it says (https://github.com/Zuzu-Typ/PyGLM/wiki/Using-arrays):

PyGLM's array type was introduced in version 2.0.0 to reduce the likelihood of requiring users to also use numpy besides glm. It's mainly intended to provide a way of passing multiple glm type instances (such as vectors) to external C functions (such as glBufferData).

What you can do is to wrap the matrices with a glm.array like this:

buffer_data = glm.array(model, view, proj)

Then update the data like this:

glBufferData(GL_SHADER_STORAGE_BUFFER, buffer_data.nbytes, buffer_data.ptr, GL_STATIC_DRAW)

Note: nbytes and ptr are built in members of glm.array, and you use them instead of glm.sizeof and glm.value_ptr.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.