bgl.Buffer creation sloooooow

Hi,

I have written a script that displays a bytearray (via texture) in a 3d view. So far, everything is running, however creating a bgl.Buffer from my bytearray is way too slow (80ms for 512x512).

What I do is:
buffer = bgl.Buffer(bgl.GL_BYTE, [512 * 512 * 4], data) # <-- more than 80ms here!
bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA, 512, 512, 0, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)

Is there a better way to do that? I could as well call an external program if that is possible and makes it faster…?

Don’t know if it’ll be any faster since pixel access is also slooooow but you can create a gl buffer directly from an Image class. When I was testing it after porting it over from 2.4x it didn’t seem that slow and I don’t have a VFX card anyone would consider fast.

Actually, now that I think about it, I was using bgl.Buffer to draw the webcam image in the 3dview in one of my boring ass videos so it can’t be all that slow.

----edit----

Eh, looking at the code in the video it turns out I wasn’t really using bgl.Buffer…

bgl buffer seems to be always slow, if you look at the code you’ll see that it’s a python object. I didn’t fully understand the code, but it seems like it’s often re-initilized and changes are made the python-way. That said, I suggest to write things in plain C if speed is important.

Thanks for your replies. Yes, the issue here is that bgl.Buffer is a Python object, which then allocates memory and copies data in every update view call.

In the meantime I wrote a python extension module (C module, as also suggested by CoDEmanX) and now do everything there. This is - even for small resolutions - roughly 100x faster :slight_smile:

I initially wanted to avoid a separate extension module, but this seems to be the only way to go.

wow sounds great! could you share (at least parts) of the code? I’m mainly interested into how to create such a python extension and i’m also interested into bgl buffer - i’d like to read the buffer of the 3d view for several frames and combine that into a new buffer and render it in the 3d view (for ghosting).

Posting the whole code here does not really make sense as it is already very long and specialized. A good starting point for extension modules is http://docs.python.org/2/extending/extending.html

What you need to do is

  1. Write your own extension with a method including all your OpenGL draw code
  2. compile
  3. put it in somewhere where blender/python can find it (e.g. in the folder containing your script)
  4. call it from your python script (e.g. from view_draw of a class that extends bpy.types.RenderEngine).

Hope that helped somehow.

I still have to figure out how to trigger redraw events from a script. Does anybody have a clue?

Thanks for that outline nb5000!
4. Does it mean the 3d view in blender will only show what is drawn by the opengl code of the extension? For my puposes, I would need the usual screen content of the POST_VIEW state as input for processing (multiple 3d view captures blended with varying transparency)

bpy lets you tag regions and areas for redraw, but it doesn’t force an immediate redraw:

e.g. bpy.context.area.tag_redraw()

Also read this:
http://www.blender.org/documentation/blender_python_api_2_68_2/info_gotcha.html#can-i-redraw-during-the-script