BGL in Blender Game Engine

Hello once again Blender Artists community. I have another question about Bender Game Engine. Looking at the Blender Python API Documentation, I noticed that Blender contains functions for a library called BGL. This appears to be a wrapping on openGL functions for Blender. What I am curious about, is if it is possible to invoke these BGL functions in something like Blender Game Engine. For example, say I wanted to draw a plain white rectangle in the middle of the screen, would something like this be possible in BGL, in the Blender Game Engine? I have been doing some experimenting, and have thus far been unsuccessful in using BGL in BGE. Any help on this is appreciated, thanks.

Weird, I would have guessed that the bgl module worked with the BGE but I just tried some tests of my own and could not get any results. My best result was that nothing happened and my worst was that Blender immediately crashed.

Weird… BGL works just fine in BGE. Both BGUI and Hive use it extensively, you could check if they run on your particular Blender build.

Ideasman told me that PyOpenGL also works, and can also be mixed freely with BGL.

Yes, indeed, it is possible, but you need to utilize the post_draw and pre_draw lists of the current scene. These lists should contain a reference to each function that draws things (and that utilizes the BGL module) to draw things onscreen.

This will get you started.


import bgl
import bge


sce       = bge.logic.getCurrentScene()


def TheList():
    bgl.glBegin(bgl.GL_TRIANGLES)
    bgl.glVertex2f(-1,-1)
    bgl.glVertex2f(1,-1)
    bgl.glVertex2f(-1,1) 
    bgl.glEnd()      


def Draw():
        sce.post_draw = [TheList]
        
Draw()

This is just out of curiosity, but is the above code supposed to do anything visible? Because when I run it, I don’t see anything.

It draws I triangle:

Oh, I see it now. Somehow, I was expecting it to draw in screen space.

Just a quick tip for using post/pre_draw. You should append to these lists instead of assigning:


scene.post_draw.append(myfunc)

This way if other scripts need to register post/pre_draw functions, they wont cause conflicts with your script.

So, if I can use this to do fast instancing?

I am making a modular component based assembly game,
and instancing + Lod could make it very smooth, even on older machines,

say I want 100 objects to all use the same mesh instance,

how would I do that?

This is called Batching, I am working on this myself.

You would start with a batch zone or object, run each child place there vertices into a list, convert them for openGL and draw them.
There is still one problem a mesh of 10 000 polygons made like this drops my frame rate to 15, if I just use blender meshes I can run over 500 000 polygons in a single mesh.

And thanks to Moguri, useful tip!

My script for my 3d logic nodes already maps all vertices using polydata,

this is for labeling faces based on materials,

check it out,

cube.py

Attachments

WrectifiedCurrentZeta(Textured3.0).blend (7.42 MB)

You already have a list of polydata, all you have to do now is run the list using:


bgl.begin(bgl.GL_POLYGON)
for element in ListOfPolydata:
    bgl.glVertex3f(element.x,element.y,element.z)
bgl.end()

Something like this, depending on what data you want to draw.

When you have objects that share the same mesh, the BGE already uses techniques to render them faster than trying to do it yourself with this approach.