[PYTHON] [Blender] Use OpenGL from inside the script

Have you ever wanted to create your own UI while developing a Blender add-on? When creating a UI, it is necessary to display images etc. in Blender, but fortunately the Blender API exposes an API for accessing OpenGL. If you use this API together with the mouse event introduced in the following article, you can build your own UI without following the UI dedicated to Blender.

[Blender] How to handle mouse and keyboard events in Blender scripts

However, even though APIs are provided, not all OpenGL functions are provided with APIs. Therefore, what you can do is limited to the range of API provided by Blender, but if it is a simple drawing process like the add-on UI, I think that the provided API is enough.

In this article, I will introduce a sample to draw a rectangle in View3D and explain how to use OpenGL from Blender.

Sample code

opengl_on_blender.py



import bpy
import bgl    #Required to use OpenGL from inside Blender


bl_info = {
    "name": "Tutorial: OpenGL on Blender",
    "author": "Nutti",
    "version": (1, 0),
    "blender": (2, 74, 0),
    "location": "View3D > Tutorial: OpenGL on Blender",
    "description": "Tutorial: Use Blender's OpenGL API.",
    "warning": "",
    "support": "COMMUNITY",
    "wiki_url": "",
    "tracker_url": "",
    "category": "3D View"
}


class RectRenderer(bpy.types.Operator):
    """Draw a rectangle"""
    
    bl_idname = "view3d.rect_renderer"
    bl_label = "Rect renderer"

    __handle = None    #Drawing function
    
    #Register the drawing function in the "View3D" area
    @staticmethod
    def handle_add():
        RectRenderer.__handle = bpy.types.SpaceView3D.draw_handler_add(
            RectRenderer.render_rect,
            (), 'WINDOW', 'POST_PIXEL')

    #Unregister the drawing function in the "View3D" area
    @staticmethod
    def handle_remove():
        if RectRenderer.__handle is not None:
            bpy.types.SpaceView3D.draw_handler_remove(
                RectRenderer.__handle, 'WINDOW')
            RectRenderer.__handle = None
    
    #Drawing function body in the "View3D" area
    @staticmethod
    def render_rect():
        #Creating a drawing area
        positions = [
            [10.0, 10.0],     #Lower left
            [10.0, 600.0],    #upper left
            [600.0, 600.0],   #Upper right
            [600.0, 10.0]     #Lower right
            ]

        #Draw rectangle with OpenGL
        bgl.glEnable(bgl.GL_BLEND)    #Enable alpha blending
        bgl.glBegin(bgl.GL_QUADS)    #Start drawing rectangle
        bgl.glColor4f(0.7, 0.5, 0.3, 0.6)    #Specify the color of the rectangle to draw
        for (v1, v2) in positions:
            bgl.glVertex2f(v1, v2)    #Registration of vertices
        bgl.glEnd()    #Finish drawing the rectangle


#Processing when installing a script
def register():
    bpy.utils.register_module(__name__)
    RectRenderer.handle_add()


#Processing when uninstalling a script
def unregister():
    bpy.utils.unregister_module(__name__)
    RectRenderer.handle_remove()


if __name__ == "__main__":
    register()

How to use

  1. Install the plugin by referring to the Blender Wiki page.
  2. Confirm that the rectangle is displayed in View3D.

20150722.jpg

Explanation of sample code

The basic explanation of the Blender script is introduced in the following article, so here we will focus on the explanation of the newly added elements. [\ Blender ] How to make a Blender plugin

import bgl module

In order to use the OpenGL API provided by Blender, you need to import the bgl module.

import bgl

Registration of "View3D" drawing function

When installing the script, call ``` RectRenderer.handle_add ()` `` to register the drawing function. This will allow the rectangle to be drawn after the script is installed.

#Processing when installing a script
def register():
    bpy.utils.register_module(__name__)
    RectRenderer.handle_add()

RectRenderer.handle_add()Is implemented as a static method.



#### **`bpy.types.SpaceView3D.draw_handler_add()Is a function that registers a drawing function for the "View3D" area.`**

Specify ** drawing function body ** in the first argument and ** parameters ** to be passed to the drawing function argument specified in the first argument in the second argument. Save the ** handler **, which is the return value of bpy.types.SpaceView3D.draw_handler_add ()` ``, to the variable` `__handle in case you want to release the registered drawing function. I will.

    #Register the drawing function in the "View3D" area
    @staticmethod
    def handle_add():
        RectRenderer.__handle = bpy.types.SpaceView3D.draw_handler_add(
            RectRenderer.render_rect,
            (), 'WINDOW', 'POST_PIXEL')

Unregister "View3D" drawing function

When uninstalling the script, call `RectRenderer.handle_remove ()` to unregister the drawing function. Prevents rectangles from being drawn after the script has been uninstalled.

#Processing when uninstalling a script
def unregister():
    bpy.utils.unregister_module(__name__)
    RectRenderer.handle_remove()

RectRenderer.handle_remove()Is implemented as a static method.



#### **`bpy.types.SpaceView3D.draw_handler_remove()Is a function that cancels the drawing function registered for the "View3D" area.`**

Pass the ** handler **, which is the return value of ``` bpy.types.SpaceView3D.draw_handler_add ()` ``, as the first argument.

    #Unregister the drawing function in the "View3D" area
    @staticmethod
    def handle_remove():
        if RectRenderer.__handle is not None:
            bpy.types.SpaceView3D.draw_handler_remove(
                RectRenderer.__handle, 'WINDOW')
            RectRenderer.__handle = None

"View3D" drawing function body

Drawing processing is added to the drawing function body. As anyone who has used OpenGL will know immediately, it is very similar to how to use OpenGL in C language. However, note that `bgl.``` is prefixed to the function because it uses the `bgl``` module. There is a lot of information on the Web about how to use OpenGL in C language, so I will not explain the specific usage of OpenGL here. For the sample shown this time, the specific processing content is described as a comment in the source code, so please check it. You can check the OpenGL API published in Blender from the following URL. http://www.blender.org/api/blender_python_api_2_60_4/bgl.html

    #Drawing function body in the "View3D" area
    @staticmethod
    def render_rect():
        #Creating a drawing area
        positions = [
            [10.0, 10.0],     #Lower left
            [10.0, 600.0],    #upper left
            [600.0, 600.0],   #Upper right
            [600.0, 10.0]     #Lower right
            ]

        #Draw rectangle with OpenGL
        bgl.glEnable(bgl.GL_BLEND)    #Enable alpha blending
        bgl.glBegin(bgl.GL_QUADS)    #Start drawing rectangle
        bgl.glColor4f(0.7, 0.5, 0.3, 0.6)    #Specify the color of the rectangle to draw
        for (v1, v2) in positions:
            bgl.glVertex2f(v1, v2)    #Registration of vertices
        bgl.glEnd()    #Finish drawing the rectangle

Recommended Posts

[Blender] Use OpenGL from inside the script
Use the Flickr API from Python
[Blender] Assign shortcut keys to your own functions inside the script
Use Django from a local Python script
Use the Kaggle API inside a Docker container
Use the nghttp2 Python module from Homebrew from pyenv's Python
Access the variables defined in the script from the REPL
How to pass arguments when invoking python script from blender on the command line
Get the return code of the Python script from bat
I wanted to use the Python library from MATLAB
The Blender script (2.8) that erases only the skirt is completed
The first step to getting Blender available from Python
Use thingsspeak from python
Use fluentd from python
Use MySQL from Python
Use MySQL from Python
Use BigQuery from python.
Use mecab-ipadic-neologd from python
[Part 4] Use Deep Learning to forecast the weather from weather images
[Part 1] Use Deep Learning to forecast the weather from weather images
[Part 3] Use Deep Learning to forecast the weather from weather images
Access the file with a relative path from the execution script.
Create an example game-like stage with just the Blender 2.80 script
[Part 2] Use Deep Learning to forecast the weather from weather images
I tried changing the python script from 2.7.11 to 3.6.0 on windows10