I have been trying read up a lot on opengl drawing using python and have been trying to create a script which display a text and a 2d shape on the viewport (a rectangle or square). From reading the blender docs I could only find little to no information about it and only got me to display text. The 2d shape drawing is still out of my knowledge. In this code I'm trying to draw a text and a draw a 2d quad in a modal operator but unfortunately the quad doesn't show up but the text is working properly.

How do I draw a 2d shape in a modal operator using bgl ?

import bpy
import blf
import bgl

def draw_textandbox(self, context):

    font_id = 0  
    x_offset = 0
    y_offset = 0

    #The Text-------------------------
    blf.position(font_id, 80, 500, 0)
    blf.size(font_id, 27, 70)
    blf.draw(font_id, "LEVELS:" )

    #The Box, This is the part i wanted to work but unfortunately it doesnt

    bgl.glVertex2f(200, 400)

3 Answers 3


It's a quadrilateral, you need to define 4 verts.

Test method, x and y are pixel coordinates of bottom left corner of rectangle, h and w the height and width (in pixels) respectively.

def draw_box(self, x, y, w, h, color=(0.0, 0.0, 0.0, 1.0)):
    #bgl.glDepthRange (0.1, 1.0)

    bgl.glVertex2f(x + w, y + h)
    bgl.glVertex2f(x, y + h)
    bgl.glVertex2f(x, y)
    bgl.glVertex2f(x + w, y)

Run-able Example

  • $\begingroup$ So the x, y, w, and h are vertex coordinates ? $\endgroup$
    – Retrax
    Oct 23, 2017 at 14:09
  • 1
    $\begingroup$ Note that repeated calls to draw_box() to draw multiple quads in one frame is inefficient. It'll be better to add more calls to glVertex2f() between the glBegin() and glEnd() calls. $\endgroup$
    – dr. Sybren
    Oct 23, 2017 at 14:10
  • 1
    $\begingroup$ @dr.Sybren any news on bgl support (or its repacement) in 2.8 $\endgroup$
    – batFINGER
    Oct 23, 2017 at 14:12
  • $\begingroup$ @batfinger I wouldn't know yet. $\endgroup$
    – dr. Sybren
    Oct 23, 2017 at 21:10
  • $\begingroup$ @Retrax Example $\endgroup$
    – batFINGER
    Oct 24, 2017 at 5:21

So I looked up on samblers example script in the question that batfinger linked, and I worked something out, It would seem that using bg.GL_POLYGON is better than using bl.GL_QUADS because you can add as much as vertices as you want. Nevertheless, it got my job done done of drawing a 2d rectangle/square.

def draw_poly(points):
  for i in range(len(points)):

def draw_callback_px(self, context):
  panel_points = [[10.0, 550.0],  #[x, y]
                  [10.0, 685.0],  #[x, y]
                  [150.0, 685.0], #[x, y]
                  [150.0, 550.0], #[x, y]

  # draw poly
  bgl.glColor4f(1.0, 0.085, 0.0, 0.2)

  # restore opengl defaults
  bgl.glColor4f(0.0, 0.0, 0.0, 1.0)

It seems that due to 2.8 api changes the bgl module was kinda depreciated...? Here's an updated solution for the 2.83 that uses the new gpu module instead of bgl https://docs.blender.org/api/blender2.8/gpu.html?highlight=gpu#module-gpu

import bpy
import gpu
from gpu_extras.batch import batch_for_shader

vertices = (
    (100, 100), (300, 100),
    (100, 200), (300, 200))

indices = (
    (0, 1, 2), (2, 1, 3))

shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices)

def draw():
    shader.uniform_float("color", (0, 0.5, 0.5, 1.0))

bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .