I have made some progress figuring this out. Minimal code repro below.
The text unexpectedly appears black only when I convert my Texture
into an ImageData, by calling get_image_data() on it.
I did this conversion because I add the image to a texture atlas for
rendering speed, and when adding the original Texture, I got:
File "C:\Python26\lib\site-packages\pyglet\image\__init__.py", line
482, in
blit_to_texture
raise ImageException('Cannot blit %r to a texture.' %
self)
pyglet.image.ImageException: Cannot blit <TextureRegion 12x28> to a
texture.
So, I think my only absolutely critical question is: How should I be
adding the Textures returned from label2texture() to my texture atlas?
Howevever, I clearly still have minstunderstood lots.
If I remove all usage of a Texture atlas (as in the minimal repro
below) and leave the Texture as a Texture, then the text is not
rendered black. It is rendered exactly as the current vertex color.
This still surprises me. Tristam, you say that the vertex color
multiplies the texture color, which I interpret to mean:
color visible on screen = pixel color in the texture * current
vertext color
(where all these are three component rgb values, with each component
normalised to lie within range 0.0 to 1.0, and the multiply operator
works like this:
Rout = Rtexture * Rvert
Gout = Gtexture * Gvert
Bout = Btexture * Bvert
But that isn't precisely what I'm seeing. As visible in the repro
below, it looks like:
color visible on screen = current vertext color
i.e. the drawing the label yellow (255, 255, 0), and setting the
current pixel color to blue (0, 0, 255), I see blue text on screen.
How does Bout get a non-zero value, if Btexture = 0?
Thanks for any understanding anyone can bequeath me with.
- Jonathan aka tartley
import code
import pyglet
from pyglet.text import Label
from
pyglet.gl import *
def label2texture(label):
vertex_list = label._vertex_lists[0].vertices[:]
xpos = map(int, vertex_list[::8])
ypos = map(int, vertex_list[1::8])
glyphs = label._get_glyphs()
xstart = xpos[0]
xend = xpos[-1] + glyphs[-1].width
width = xend - xstart
ystart = min(ypos)
yend = max(ystart+glyph.height for glyph in glyphs)
height = yend - ystart
texture = pyglet.image.Texture.create(width, height,
pyglet.gl.GL_ALPHA)
for glyph, x, y in zip(glyphs, xpos, ypos):
data = glyph.get_image_data()
x = x - xstart
y = height - glyph.height - y + ystart
texture.blit_into(data, x, y, 0)
return texture
class Render(object):
def create_image(self):
label = pyglet.text.Label(
text='yellow text',
font_name = 'Times New Roman',
font_size = 48,
bold = True,
x = 20,
y = 5,
color = (255, 255, 0, 255), # YELLOW
)
image = label2texture(label)
# converting the Texture to an ImageData turns the text black
# so don't do that
# but then how can we add this texture to a texture atlas?
# image = image.get_image_data()
image.anchor_x = image.width / 2
image.anchor_y = image.height / 2
return image
def init(self):
self.win = pyglet.window.Window()
self.win.on_draw = self.draw
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glClearColor(0.9, 0.5, 0.7, 0.0)
self.image = self.create_image()
pyglet.app.run()
def draw(self):
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0.0, 0.0, 1.0) # current vertex color = blue
# image displays text in the current vertex color?
self.image.blit(self.win.width / 2, self.win.height / 2)
if __name__ == '__main__':
r = Render()
r.init()