Texture Clamping on Direct Labels

Hey guys,

Im creating GUI elements using directlabel that have png images with alpha applied. I am getting artifacts at the edge of the labels that I believe are caused by the texture being set to WMRepeat not WMClamp.

My question is this: How can I change the texture uvmode on a DirectLabel element?

I suppose more importantly is this going to work:

tex = ??codeToGetLabelTexture??(label) 
tex.setWrapu(Texture.WMClamp)
tex.setWrapv(Texture.WMClamp)

Any help is appreciated.

By “label”, do you mean the text that is generated for the label when you pass in a text string?

This is not a single texture, but is rather a special font texture that contains each of the alphabetic characters in a palette, which is indexed into by individual polygons that are cleverly arranged to look like a single line of text.

It is indeed possible for artifacts to be introduced between the letters in this case, though this is rare with the default settings. If this is in fact happening to you, you can tweak the font parameters for the font in question to adjust this.

But I wonder if this is in fact what you’re seeing. Can you provide a screenshot?

David

Ahhh. You know it never occured to me that my post would be ambiguous, but after reading your post David I can see that it was totally misleading :slight_smile:

I am using a DirectLabel with no text, but that has an image on it. I am constructing a gui skin builtup of different directlabels that have different images on them or have different texture coords and point to the same image (a simple skin file). I then read this in using xml and build up a window frame.

As you can see it mostly works correctly. Ignore the middle of the window, that is an image skinning problem.

But you can see in the part that I have magnified I am getting a slight wrap around on because of the variation of alpha from the top and bottom lines of the image. So in this case I would like to clamp v so it doesn’t repeat. (In case its still not that evident there shouldn’t be a faint white line running horizontally through the magnified part)

Hope that makes more sense.

Ok, I understand.

There are two ways to get a texture image for a DirectLabel. One is to load it explicitly via loader.loadTexture(), and the other is to extract it from a model. Which one are you using?

If you are loading it explicitly, then you have a pointer to the texture object, and you can specify the wrap parameters at the time you load it:

tex = loader.loadTexture('myTexture.png')
tex.setWrapu(Texture.WMClamp)
tex.setWrapv(Texture.WMClamp)
label = DirectLabel(image = tex, ...)

If you are extracting the texture from a model file that you have loaded, the easiest way to specify the wrap parameters is to specify them as part of the model itself, e.g. from the modeling package that generated the model. If you are using egg-texture-cards to generate this model you can use the -wm parameter.

But if you can’t or don’t want to specify the wrap parameters in the model, you can also extract the texture from the model at run time, e.g.:

tex = model.findTexture('*')
tex.setWrapu(Texture.WMClamp)
tex.setWrapv(Texture.WMClamp)
label = DirectLabel(image = tex, ...)

Your original post asked about extracting the texture from the DirectLabel after it has already been created, and this is possible too, but a little bit trickier; and unless you have an extremely unusual situation I suspect it’s probably easier to set these parameters before the DirectLabel has been created.

David

Thanks for the quick response.

I didn’t even know you could pass a texture in as the image flag on a directLabel!

I was passing it the filepath and letting the label load it, hence the ‘how do I get a texture out of a label’ question :slight_smile:

That simplifies things a lot.

Thanks David

Actually I got an error when doing the following:

texture = loader.LoadTexture(…

l = DirectLabel(image=texture, scale=(0.5, 0, 0.5), relief = None)

With an error about directframe trying to get the len of the texture object in setImage.

So is this possible?

Hmm, you’re right. It seems that the DirectGui system expects either a texture filename or a NodePath there, but not a Texture object itself. That’s probably just an oversight.

Still, you can work around it by doing the loader.loadTexture() call first, and then passing the same filename in for the DirectLabel. Since the DirectLabel will perform another loader.loadTexture() call with that filename, which will return the very same pointer that you just operated on, it will still work as you want it to.

In the meantime, I’ll correct DirectLabel so that you can pass in a raw Texture object as well.

David

I had the same thought and have implemented it that way.

However It seems I need clamp to edge, not just clamp. So I will probably have to use WMMirror or some such. I’m going to have to experiment it seems…

Thanks for the help.

Just to let you know WMMirror worked for me in this situation.

Thanks for all your help David.

Ok, great! Although I’m pretty sure WMClamp is actually implemented as clamp-to-edge if the driver supports it, so I’m surprised that didn’t work for you.

David

I got a strang effect with WMClamp, it seemed to wrap the texture properly but any pixel value that should of been clamped was coming through darker than the non clamped pixels.

It was a strange effect and it seemed to happen on any texture I applied not just ones with alpha.

What do you make of it:

I have a Geforce 6800 running the 77.?? drivers from the battlefield 2 demo. I’m not sure if the drivers are official yet so that could be effecting it.

Hmm, that’s “clamp” behavior all right, not clamp-to-edge.

Are you running DirectX or OpenGL? Does it look the same in the opposite driver?

David

Interesting.

I get correct behaviour in dx7 and dx8 (ignore the thick grey line on the left of the image, that’s not part of the label):

Incorrect in dx9 and gl. More evidence that its a driver issue I’m thinking. Might see if there are newer official drivers for the card

Well the latest drivers (70.72) do not effect the result. Works in dx7 and dx8, not gl and dx9.

If you want me todo more testing let me know. But it makes sense for me to use WMMirror in this situation as it will work on pretty much all cards and more importantly works on all 4 versions of the panda renderer on my card :slight_smile: