in the GPU drawing examples (/doc/python_api/examples/), they all create static batches. You create it and then render it forever.
But in some cases you want to draw something that changes with time.
How can you modify the contents of a preexisting GPUVertBuf object? Do you have to call attr_fill again, with different data? I guess what I’m looking for is functions that represent glBufferData or glMapBuffer.
So while looking for other ways I noticed that the BGL module is still around 2.80 (I thought it was going to be removed), so we can manually create VBOs for dynamic use, using OpenGL examples around the web as reference. It takes more code but then you have absolute control.
UPDATE: this is now available on BGL, check the last posts in this thread for guidance.
ORIGINAL POST: To others in the future: it’s not possible to use raw OpenGL with VBOs for drawing, because to do that you need to be able to send a “null pointer” value to a function (glVertexAttribPointer), but the BGL wrapper over that function expects a bgl.Buffer object – even if you fill this bgl.Buffer with “0” it’ll not be a null value (it’ll be the pointer to the bgl.Buffer object, which is definitely not null).
This problem has been talked about in the past, there are a few mailing-list emails and forum posts about it, but the problem persists. I hope @Hypersomniac can be made aware of it.
look inside draw() you can see the uniforms feed data to the shader. This is also the standard way the new API of OpenGL is doing this. If you don’t like the computations then you will need diffident shaders and change the shader each time you want to do something else by binding the glProgram to the appropriate shader.
Please note I have zero experience with GPU module, I used to use BGL but once Blender devs announced that they wanted to move away from BGL and because I had already loads of issues with debugging I decided to customize the Blender code itself. So I have not touched bgl for month now.
If I remember correctly bgl.buffer is nothing special just a pointer to a c array so I don’t know if numpy can help here with its arrays.
Generally speaking shaders should be precompiled and not generated runtime because Python could severely slow you down.
If you look in the source of draw_circle_2d, it’s creating a new vertex buffer and shader object on each draw call, which is very wasteful.
You also can’t draw other primitive types without creating a whole new gpu.types.Batch object, when in raw OpenGL you can redraw the same data multiple times with different primitive types because it’s a simple parameter in the drawing function.
Lastly, in PyOpenGL they use c_types.voidptr or something like that to indicate a null pointer, but the BGL wrapper doesnt accept anything other than of bgl.Buffer type, as it’s defined that way in the source.
It really depends what you want to, the example I linked it was just to show the use of uniforms
if you do not want to generate new vertex buffers and optimise the draw process then you will have to make your own circle_2d assuming you want to draw circles. If you want to move things around then you can have a face that is moved via translation on the uniforms.
Of course if you aim for a large collection of primitives , you should not be using this approach anyway because as I said python will become the bottleneck here.
What I would have done , have one face, one vertex buffer, one index buffer and one texture and then use Cairo to draw the actual primitives and then just use the texture that Cairo would create (basically a simple image) with the GPU module on top of the face.
Hi @GottfriedHofmann and@ RNavega could you point me to a good example of updating vertex buffer geom as you are describing. I’m just starting to delve into updating some rather complex (to me) bgl drawing modules. My first dive would be to just draw several points that the user can click and drag in 3D.
What this thread was about was the bgl.glVertexAttribPointer() function, the last parameter of it is an offset pointer to the first element that you want to begin drawing, from the buffer currently bound.
With the latest BGL, on that last parameter, you can specify the start of the buffer (use None), or some other index into the buffer (use an integer).
We usually draw the whole buffer – all its vertices – so 99% of the time you’ll use None as that parameter to use all data.
When you do want to use an index into the buffer so as to skip part of it, consult this: https://stackoverflow.com/a/39684775