setTexture

Zini

16-01-2008 10:28:18

I am in the process of updating from rev 258 to 313 now. If I remember correctly the setTexture function was mostly removed in favor of skin sets. But I also remember, that some widgets were supposed to retain the setTexture function (Image ?). Unfortunately the function doesn't seem to exist anymore. Any hint?

Edit: I see a setMaterial function. So there is no option to use textures directly anymore? Looks a bit complicated (I need to use RTT in a QuickGUI window).

kungfoomasta

16-01-2008 17:34:37

I need to add a convenience function for the Image/Sheet widgets, but setTexture would simply take a texture, wrap it in an Ogre material, and use that for rendering. Right now it has to be done outside QuickGUI.

Zini

21-01-2008 16:28:29

Doing it outside of QuickGUI is way too inconvenient (simply creating a material wouldn't be enough, since you need a resources loader too). Has the work on this feature started yet? If not, I will have a go at it this week.

kungfoomasta

21-01-2008 17:40:53

I haven't done this yet, I spent time working on the major tasks for the library (clipping), and didn't get around to the relatively smaller ones. :(

Help with this would be greatly appreciated.

TWO

21-01-2008 21:22:58

I'm not very skilled with the lib, but here's my try:


QuickGUIImage.cpp

void Image::setTexture(const Ogre::String& textureName)
{
if(mTextureLocked)
return;

Ogre::MaterialPtr material;

if( Ogre::MaterialManager::getSingleton().resourceExists(textureName) )
{
material = static_cast<Ogre::MaterialPtr>(Ogre::MaterialManager::getSingleton().getByName(textureName));
material->load();
}
else
{
material = Ogre::MaterialManager::getSingleton().create( textureName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
material->getTechnique(0)->getPass(0)->createTextureUnitState( textureName );
}

mMaterialName = textureName;
mQuad->setMaterial(mMaterialName);
mQuad->setTextureCoordinates(Ogre::Vector4(0,0,1,1));
}

kungfoomasta

21-01-2008 21:27:33

Yah, that's similar to what I had in mind. :) (I probably wouldn't have asked for a material name, just generate one based on the widgets name)

But I think since the material is manually created, you have to provide some ManualLoader functionailty, so that the resource can be reloaded. For example, if the quad went invisible and the material was unloaded, it might not load again when the quad is visible. Not sure on this..

Zini

21-01-2008 21:45:49

That is correct. And you shouldn't need to give a material name explicitly. Furthermore I think material-wrapped textures should be reused, when they are applied to more than one widget at a time (so we don't spawn dozens of new materials when showing a new window).

kungfoomasta

21-01-2008 22:29:31

Just to clarify things, setTexture should only apply to Sheet and Image widgets, right? Otherwise the whole skin/skinComponent design becomes useless, and widgets don't get rendered properly. Images/Sheets could have unique textures that aren't re-used a lot, like splash screens or background images. At least this is what I had in mind.

Sheet::setTexture
Image::setTexture

Zini

22-01-2008 11:42:18

That is an interesting point, that should be discussed a little more, before I start with the implementation.

I haven't followed the development of QuickGUI too closely over the last few weeks, so I am not absolutely sure, if my perception of the situation is correct. But here is how I see it:

First we have the skinset. It is used for highly effective drawing of common GUI components (borders, backgrounds, check boxes, title bars, ...).

Then we have the option to use materials and textures. These are less efficient and should be used only for unique images. So if I would need to make a set of different looking buttons, I would make a new skinset instead of using a material, right?

Your examples (splash screen or background image) look more like a case for materials. I wouldn't use the setTexture function here. because these images are usually available at the time, when the program is created, so it is no problem to add a material script instead.

I asked for the setTexture feature, because I need it for textures that are getting available only at runtime. RTT being the obvious example. Screenshots embedded into a saved game would be another. Or think of a guild icon that is fetched from a server for an online game.

So limiting the setTexture to specific icons makes sense. I agree with you on Image, but I am not so sure about Sheet (can't think of a situation, where you can't use a material script with the same ease as a texture).
On the other hand, what about graphical buttons? (think of a save button on a toolbar). Here we could use a setTexture function too.

I thought again about the reusing of texture-wrapping materials. Maybe it is overkill. But since we are creating material names on the fly, we would then need a mechanism for generating unique material names (we can't simply use the texture name with a QuickGUI specific suffix, since a texture could be wrapped in a material more than once).

Comments?

kungfoomasta

22-01-2008 18:42:46

There are ogre methods to see if a material already exists, so its not likely we'll produce duplicate materials. Use the Widget name as part of the material name.

For multiple buttons, I havne't really found an intuitive solution for this. Currently you can make another skin for each button type, or the more practical method, to include the button images in the SkinSet and use the Widget::setSkinComponent method to change between images.

The SkinComponent is a string used to determine what texture from the SkinSet to use. For example, it could be ".window", ".combobox", ".button" etc. The SkinName + SkinComponent is used to get the texture. (ie "qgui" + ".button")

qgui.button.png
...
qgui.button1.png

myButton->setSkinComponent(".button1");

But I don't really want to allow people to modify SkinComponents for all widgets, this really only applies to buttons and borders.

The reason you can't simply use textures for widgets is that the widgets are getting more complex. The console is a list of textboxes, with another textbox for input. I can't say mConsole->setTexture("someTexture.png"), because the widget consists of more than 1 quad, obviously.

I need some kind of functionality specifically for borders and buttons. Other widgets will need a separate skin to define multiple visual representations. Any ideas?

Zini

23-01-2008 10:09:22

There are ogre methods to see if a material already exists, so its not likely we'll produce duplicate materials. Use the Widget name as part of the material name.

Right.


The reason you can't simply use textures for widgets is that the widgets are getting more complex. The console is a list of textboxes, with another textbox for input. I can't say mConsole->setTexture("someTexture.png"), because the widget consists of more than 1 quad, obviously.


For a console this is obviously true. On the other hand for a button (and maybe for some other widgets) it isn't. When we apply a texture to a button, we only want to change the picture, that is shown in the button widget. Not the border or other decorations.


I need some kind of functionality specifically for borders and buttons. Other widgets will need a separate skin to define multiple visual representations. Any ideas?


I don't understand, why you think borders are relevant here. They are common GUI elements, right? So you don't want to create individual borders for specific widgets.

For buttons you will only want to change the image, that is displayed in the button and you should be able to do that independently from the border.

So, how about these functions:

setImageSkinComponent
setImageMaterial
setImageTexture

(the button would obviously only use one of these options at a time)

kungfoomasta

23-01-2008 17:28:46

The reason the current buttons don't look so aesthetically pleasing is because the borders are a part of the image. I need to change this. By having the border as part of the button image, buttons of various sizes will look distorted. Also, border images are widget specific. A user could define a special border for the textbox widget, and another special border for windows, for buttons, etc.

I am planning to modify the "setSkin" function for widgets that have borders. It will ask the SkinSet if the border textures exist, and if so, create borders. You will be able to optionally remove the borders also. Now you can have simple buttons with no borders, or buttons with borders, and this applies to all other border-based widgets.

The borders of buttons will also need to change, for example when the user mouses over the button, the borders should change to the "over" appearance, and "down" when the button goes down.

thecaptain

24-01-2008 02:42:53

Yeah, adding border support for buttons definitely makes sense. Unfortunately, it does mean a lot of images ( 1 + 8 borders for each state)! :wink:

Quick question... do you know why the existing borders have issues on the edges between border elements? There seems to be a 1px overlap or something that makes it look disjoint, as opposed to a smooth connection. I tried fiddling with the size and spacing of the borders, but it seems to either overlap by 1px or have a 1px gap.

Also, I noticed that when a window gets really large, the extended border components seem to leave gaps at the edge as a result of the resizing. I wonder if Ogre has a way of resizing that doesn't introduce blurring at the edges. (This resizing problem also is evident when selecting a small section of text, like 1-2 characters).

kungfoomasta

24-01-2008 04:11:12

I'm not certain, but I do believe that the small rendering artifacts are because the images are very small in resolution, and are being scaled quite a bit. You can disable texture filtering on the material and make sure your skinset textures are of high resolution size, and that may make things look better.

thecaptain

24-01-2008 08:26:16

Cool, I'll try fiddling around with the filtering and such.

@Zini, any word on implementing a setTexture() function for images? I'm in the same boat as you (needing to get RTT working again), so I was also thinking about putting together a setTexture() function to make it easy...

Hopefully it would also support simple loading of image files too. That would be convenient (creating a material script for each icon in a game, even though it would work, would be slow, and probably inefficient).

Zini

24-01-2008 10:49:01

Well, the whole situation got a lot more complex than I expected. Unfortunately updating my application to the current version of QuickGUI was pretty disastrous this time. It took me over a week to restore all functionality (minus the RTT stuff), so the time I can put aside for QuickGUI got cut down. I am still planning to add a simple setTexture implementation (with resources loader and all the stuff) for Images. I should be able to put a bit of time aside for it either tomorrow or over the weekend.

Zini

24-01-2008 13:28:09

Found the time to do some work on it. I have a more or less working version of the setTexture function now. There is still some cleanup to be done. I will post a patch either today or tomorrow.

Zini

24-01-2008 15:46:28

Here we go:

http://www.zpages.de/public/Wrap.patch

Was quite an interesting experience to write this patch. I just learned, that Materials can't/don't need to have manual resources loader.

btw. what is Widget::mTextureLocked good for?

@thecaptain: I haven't included a function for loading of image files. I really don't think that this should go into a GUI library. But if your image files are just ordinary Ogre textures, nothing stops you from using the setTexture function without going through a material script.

kungfoomasta

24-01-2008 17:38:21

Cool, I'll add the patch when I get a chance. The locked texture is for the scenario where you mouse down on a slider and scroll it while the mouse is not over the widget. The "down" texture is applied to the slider, even though the mouse is not over it with button held down. I thought it might be useful to add to the Widget class, and not only the button class.

thecaptain

24-01-2008 19:22:12

Cool, yeah that should be fine. I think Ogre automatically creates textures out of the image files that are loaded anyway.

Thanks a lot for the contribution! :D