Reputation: 93
I am using Pyglet to create a main menu for my python game. I want to draw text on top of a box that would act as its container. Whenever I render the text, instead of it having a transparent background, it draws whatever the glClearColor is set to. This also happens whenever I try and draw an image that has no background.
I am currently using these two lines for my textbox and the text.
self.text_box = pyglet.sprite.Sprite(pyglet.image.load('../Resources/Textures/Menu/text_box.png'),640-150,360-25, batch=self.menuBatch,group=boxGroup)
self.play_text = pyglet.text.Label("Play", font_name="Arial", font_size=32, x=640, y=360, anchor_x='center', anchor_y='center', color=(255,255,255,255), batch=self.menuBatch,group=textGroup)
Then I just call self.menuBatch.draw(). A picture of the problem I am having is:
Upvotes: 3
Views: 1632
Reputation: 65
I have done something very similar to this before when making the GUI for one of my 3D programs. To make things very simple, I firstly turned off GL_DEPTH_TEST before the draw() call and then I re-enabled GL_DEPTH_TEST after the draw() call. I believe that the reason why the previous answer was working for them is because they didn't have GL_DEPTH_TEST enabled in the first place. I made a button class that you could maybe use as well (It's important to note that the argument "pos" is for the (x, y) coordinate of the lower left corner of the button and the argument "dim" is for the (width, height) dimensions of the button. The "texture_coords" argument refers to the texture coordinates of the background image of the button. If you want the full image, just leave it at the default. The rest is pretty self explanatory). So here's the code:
class Button:
def __init__(self, btn_img_file, text = "Button", pos = (0, 0), dim = (10, 10), text_color = (255, 255, 255), texture_coords = (0, 0, 1, 0, 1, 1, 0, 1)):
self.x, self.y = pos
self.w, self.h = dim
self.text = text
self.img = btn_img_file
self.tex = get_tex(self.img)
self.coords = texture_coords
self.color = text_color
self.batch = pyglet.graphics.Batch()
def on_click(self, mouse_x, mouse_y, function, *args, **kwargs):
x, y = self.x, self.y
X, Y = x + self.w, y + self.h
if mouse_x > x and mouse_x < X and mouse_y > y and mouse_y < Y:
function(*args, **kwargs)
def draw(self):
x, y = self.x, self.y
X, Y = x + self.w, y + self.h
font_size = (self.w // len(self.text)) - 5
label = pyglet.text.Label(self.text,
font_name = 'Times New Roman',
font_size = font_size,
x = x + (self.w // 2), y = y + (self.h // 2),
anchor_x = 'center', anchor_y = 'center',
color = (*self.color, 255))
self.batch.add(4, GL_QUADS, self.tex, ('v2f', (x, y, X, y, X, Y, x, Y)), ('t2f', self.coords))
glDisable(GL_DEPTH_TEST)
self.batch.draw()
label.draw()
glEnable(GL_DEPTH_TEST)
I hope this was helpful!
~ Rick Bowen
Upvotes: 1
Reputation: 345
For transparency effects to work, 'blend' should be enabled in OpenGL.
To enable blend:
glEnable(GL_BLEND) # transparency
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) # transparency
This complete snippet is working for me:
import pyglet
from pyglet.gl import *
# Pyglet Window stuff ---------------------------------------------------------
batch = pyglet.graphics.Batch() # holds all graphics
config = Config(sample_buffers=1, samples=4,depth_size=16, double_buffer=True, mouse_visible=False)
window = pyglet.window.Window(fullscreen=False, config=config)
glClearColor( 0, 100, 0, 255) # background color
glEnable(GL_LINE_SMOOTH)
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE)
glEnable(GL_BLEND) # transparency
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) # transparency
play_text = pyglet.text.Label("Play", font_name="Arial", font_size=32, x=240, y=140, anchor_x='center', anchor_y='center', color=(255,0,255,255), batch=batch,group=None)
text_box = pyglet.sprite.Sprite(pyglet.image.load('text_box.png'),240-150,160-25, batch=batch,group=None)
@window.event
def draw(dt):
window.clear()
batch.draw()
if __name__ == "__main__":
pyglet.clock.schedule_interval(draw, 1.0/60)
pyglet.app.run()
Upvotes: 2