Print text with glut and python

Question:

I’ve written this function for printing some text with python and python opengl

def glut_print( x,  y,  font,  text, r,  g , b , a):

    blending = False 
    if glIsEnabled(GL_BLEND) :
        blending = True

    #glEnable(GL_BLEND)
    glColor3f(1,1,1)
    glRasterPos2f(x,y)
    for ch in text :
        glutBitmapCharacter( font , ctypes.c_int( ord(ch) ) )


    if not blending :
        glDisable(GL_BLEND) 

And the rendering function:

def Draw():
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )

    glut_print( 10 , 10 , GLUT_BITMAP_9_BY_15 , "Hallo World" , 1.0 , 1.0 , 1.0 , 1.0 )
    # draw my scene ......
    glutSwapBuffers()

As a result nothing is written, I’m viewing my geometric and 3D objects; but not the text!
Where’s the problem?

Asked By: Giggi

||

Answers:

A lot of OpenGL programmers get caught by this (myself included).

Although glRasterPos looks like it takes pixel coordinates, they are actually transformed by the modelview and projection matrices before use. Useful if you’re trying to position text in 3D space, not so useful when you want some kind of overlay console or HUD.

The old way to get around this was to push both projection and modelview matrices, set both to identity, draw text, pop both.

Brian Paul of Mesa3D thought this was silly and added a new call glWindowPos which takes actual pixel coordinates in the window. It became standard in OpenGL 1.4 or so. Replace your glRasterPos with glWindowPos and see if that fixes the problem.

Answered By: Hugh

I’ve solved by switching projection like this:

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0.0, 1.0, 0.0, 1.0)
glMatrixMode(GL_MODELVIEW)

glut_print( 10 , 10 , GLUT_BITMAP_9_BY_15 , "Hallo World" , 1.0 , 1.0 , 1.0 , 1.0 )

And after the print I go back to the common 3D model.

@ Hug … I’l try also the glWindowPos

Answered By: Giggi

use gultStrokeCharacter is better, the character can be rotated and scaled since it draws lines to form the character.

Answered By: Sky Stalker

Another solution (based on @Hugh answer and on version PyOpenGL 3.1.6):

class TextView():
    def __init__(self, x, y, color):
        self.x= x
        self.y=y
        self.color= color

    def print(self, text):
        glColor3fv(self.color)
        glPushMatrix();
        glWindowPos2f(self.x, self.y)
        for ch in text :
            glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24 , ctypes.c_int( ord(ch) ) )
        glPopMatrix();

Additionally for Ubuntu 22.04 I had to

sudo apt install libosmesa6 freeglut3-dev

and do

import os
os.environ['PYOPENGL_PLATFORM'] = 'osmesa'

before importing OpenGL.GLUT in your .py file

Answered By: Peter
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.