I attempted to use a pygame font surface and converting it to pixel data using data = pygame.image.tostring(img, "RGBA", 1)
and then used a gl function to create an opengl texture and draw it with glDrawArrays using shaders too. However, the results are simply a white screen without any text.
Here is the code I attempted:
from __future__ import division
import pygame
import numpy as np
from OpenGL.GL import *
from OpenGL.GL import shaders
from pygame import *
pygame.init()
screen = pygame.display.set_mode((600, 400), DOUBLEBUF | OPENGL)
vertex_shader = shaders.compileShader("""
#version 130
in vec3 position;
out vec2 fragTexCoord;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
fragTexCoord = gl_Position.xy;
}
""", GL_VERTEX_SHADER)
fragment_shader = shaders.compileShader("""
#version 130
in vec2 fragTexCoord;
uniform sampler2D textureSampler;
out vec4 fragmentColor;
void main() {
fragmentColor = texture(textureSampler, fragTexCoord);
}
""", GL_FRAGMENT_SHADER)
shader_program = shaders.compileProgram(vertex_shader, fragment_shader)
img = pygame.font.Font(None, 50).render("Hello", True, (255, 255, 255))
w, h = img.get_size()
texture = glGenTextures(1)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glBindTexture(GL_TEXTURE_2D, texture)
glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
data = pygame.image.tostring(img, "RGBA", 1)
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)
quad_vertices = np.array([
[-1.0, -1.0, 0.0],
[ 1.0, -1.0, 0.0],
[ 1.0, 1.0, 0.0],
[-1.0, 1.0, 0.0],
], dtype=np.float32)
projection_matrix_loc = glGetUniformLocation(shader_program, "projectionMatrix")
modelview_matrix_loc = glGetUniformLocation(shader_program, "modelViewMatrix")
projection_matrix = np.array([[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, -1.0, -1.0],
[0.0, 0.0, -1.0, 1.0]], dtype=np.float32)
modelview_matrix = np.identity(4, dtype=np.float32)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
exit()
glClear(GL_COLOR_BUFFER_BIT)
glUseProgram(shader_program)
glUniformMatrix4fv(projection_matrix_loc, 1, GL_FALSE, projection_matrix)
glUniformMatrix4fv(modelview_matrix_loc, 1, GL_FALSE, modelview_matrix)
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, quad_vertices.size * quad_vertices.dtype.itemsize, quad_vertices, GL_STATIC_DRAW)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
glBindTexture(GL_TEXTURE_2D, texture)
glDrawArrays(GL_TRIANGLE_FAN, 0, 4)
glUseProgram(0)
pygame.display.flip()
pygame.time.Clock().tick(60)
You must set the background color when you render the text:
flont = pygame.font.Font(None, 50)
img = font.render("Hello", True, (255, 255, 255), (0, 0, 0))
See also pygame + opengl = display text