Write Text to Texture issues

Jzone

23-04-2009 21:38:04

I'm currently playing around with the python implementation of WriteToTexture, and I'm having a couple problems.

I have a handful of differently colored textures for the same mesh. These colors can change throughout the program, and will be regularly written to with some information. This... somewhat works. The problem is that when a box changes to a differently colored texture, not all of the previous texture is removed. (You can see this in the image below)

The top bar shows the green of the previous texture on the top(not seen) and bottom, while the bottom bar is displayed properly.

The second problem is that if I start the text with a " " (space), the leading space(s) are stripped, forcing the text all the way left. This is problematic because I do not want to have to manually position the text. (what if I want to change fonts or font sizes later?)

I have been looking at this code for several hours now and I'm getting nowhere fast. Any help would be greatly appreciated.

Relevant code for texture changes:
## Some variables we will use
strkey = 'uniqueIdentifier'
box_text = ' sample text '
# Get the original untouched texture for the color we need
origTexture = ogre.TextureManager.getSingleton().getByName(
"infobar_texture_%s.jpg" % self.colors[toUpdate[key]['tid']])

## If the entity already exists, we want to update it to the proper texture.
if self.sceneManager.hasEntity(strkey):
# If we had made the entity invisible, make it visible again.
if not self.sceneManager.getEntity(strkey).getVisible():
self.sceneManager.getEntity(strkey).setVisible(True)

# Get the node for our entity, and reposition it.
node = self.sceneManager.getSceneNode(strkey)
offset = ((toUpdate[key]['pos'] - 1) * 18)
node.setPosition(ogre.Vector3(0, offset, 0))

# Get our entities current texture, and blit with the color we want
# This should be clearing all text
# and replacing the old color completey --This is not working
texture = ogre.TextureManager.getSingleton().getByName(strkey)
texture.getBuffer().blit(origTexture.getBuffer())

# Finally, write onto the texture --Mostly works, lose leading spaces.
WriteToTexture(box_text, texture, ogre.Box(30,47,500,100),
self.font, ogre.ColourValue(1.0,1.0,1.0,1.0), 'l')

Code for WriteToTexture can be found at the link at the beginning of this post.

Update:
I have found a (temporary at the very least) solution to the problem of the colors not being overwritten properly. I don't like this solution, as I presume it's using more memory and processor cycles than it needs to. But unless someone can give me some insight, it will have to do for now.
## Some variables we will use
strkey = 'uniqueIdentifier'
box_text = ' sample text '
# Get the original untouched texture for the color we need
origTexture = ogre.TextureManager.getSingleton().getByName(
"infobar_texture_%s.jpg" % self.colors[toUpdate[key]['tid']])

## If the entity already exists, we want to update it to the proper texture.
if self.sceneManager.hasEntity(strkey):
# Part1 of temp solution. Create a new texture.
temptxr = ogre.TextureManager.getSingleton().createManual(strkey,"General",
ogre.TEX_TYPE_2D, 512, 512, ogre.MIP_UNLIMITED ,
ogre.PF_X8R8G8B8, ogre.TU_STATIC|ogre.TU_AUTOMIPMAP)
temptxr.getBuffer().blit(origTexture.getBuffer())
# If we had made the entity invisible, make it visible again.
if not self.sceneManager.getEntity(strkey).getVisible():
self.sceneManager.getEntity(strkey).setVisible(True)

# Get the node for our entity, and reposition it.
node = self.sceneManager.getSceneNode(strkey)
offset = ((toUpdate[key]['pos'] - 1) * 18)
node.setPosition(ogre.Vector3(0, offset, 0))

# Get our entities current texture, and blit with the color we want
# This should be clearing all text
# and replacing the old color completey --This is not working
texture = ogre.TextureManager.getSingleton().getByName(strkey)
texture.getBuffer().blit(origTexture.getBuffer())

# Finally, write onto the texture --Mostly works, lose leading spaces.
WriteToTexture(box_text, texture, ogre.Box(30,47,500,100),
self.font, ogre.ColourValue(1.0,1.0,1.0,1.0), 'l',
tBuff=temptxr.getBuffer()) # slight modification here

# Replace the texture with the written temp texture, and unload our temp txr.
texture.getBuffer().blit(temptxr.getBuffer())
temptxr.unload())

Jzone

28-05-2009 22:15:40

In continuing to use this method to write text on textures, I've noticed that the speed is nowhere near what I need it to be. Ranging from 0.15 to 0.62 seconds for a single write operation, typically averaging around 0.2 seconds.

Considering that I am in high load situations performing dozens of these writes at a time, and that since I haven't found a way to thread the write so that it doesn't cause the rest of the program to lock up and become unresponsive, this is no good for my use.

I have been looking into using decals to simply overlay a series of letter/number decals (contained on a "font texture") onto my objects in order to improve the speed. I'm not sure what kind of memory hit this would cause, or if there would be much of a performance gain in layering a series of decals onto the texture to imitate the texture write. Also, I remember seeing some mention of a limit to the number of decals that can be applied to an object (though I think that limit was increased a fair amount?).

Something else I thought about doing was converting polygon font into python, but I fear I lack the knowledge and the endeavor would ultimately prove to only increase the memory footprint without improving creation time for the text.

Anyway, if anyone has any experience with the write to texture (perhaps some way of improving the speed), some information regarding layering on lots of decals, or just an alternative better solution to this whole mess I would be very glad to hear it.

(Unfortunately I can't use billboards because as I understand they must always face the screen, and my text should be able to turn at angles with the object it is attached to.)

P.S. Sorry about the double-post, but I figured it was better than creating a new thread.