Automatically reuse textures

In my opinion I think that texture manager should automatically reuse textures like the old one did in the old core. If you are worried about the mortification of textures you can make a flag that disables this option. People have complied at the drop in frame rate when loading a texture. Doing this would make programming in jme much simpler since programmers would not have to manage texture themselves

Suggest storing a HashMap that maps URL → Texture so that when a URL is loaded with TextureManager, if the hash exist return that given texture?

We can also provide a release function in the manager to remove old textures manually if you know they aren’t needed anymore.



PS: We built something like this into Dirt already if we want to reuse some of that.

Release could sipmly map the URL to null in the hashmap.

The only problem I can see with this is that the texture state automatically uses opengl to delete the texture when it is removed from the state. The two ways I can think of fixing this is having texturemaniger delete the textures a the end of the game, using the distrocter for the texture to delete it in opengl , or have a reference counter like com has to tell it when it is time to delete it. Good luck on the implementation, Cep21, renanse.

Don’t forget there is more to a texture than just the image. The min/max filters and mipmaps. So, if I request a Texture of Flower.png with mipmapping on (standard mipmapping filters), then request a Texture of Flower.png with linear filters, I should get a new Texture.

The first cut of TextureManager with cache has been checked in. TextureKey is a new class used to keep track of textures in the cache; we can update it with more fields if we need to track more properties for unique Texture storage. It keeps track of min and mag filters, flipped and the image location at the moment which should cover all of our current loadTexture uses. Cache is not used in one loadTexture method, the one with a java.awt.Image parameter. I figure that method should eventually be dropped or moved to an external utility or something later so is not worth encouraging with support.



To continue, there’s also removal methods for removing based on Texture or based on TextureKey. Also, there’s a clearCache method for removing all cached references. Please note that these do not currently call out to have these textures removed from OpenGL itself. We might want to implement that.



Finally, I’ve created Loader classes for the various image types. Only the TGALoader is currently in use, but hopefully this will encourage developers out there to fill in the blanks for the other types. With those completed and some tweaks to a few other sections, we could remove our dependency on AWT! :slight_smile:



FYI, I’ve also added equals methods to Image and Texture. The Texture equals method was required for one of the cache removal methods.

I was thinking, The Texture class has meny variables that is changed for each instance such as Envierment map. You solved the problem by having a different texture for each min/max filters but there are other variables. One solution I can think of is having the image class or a another class handle the opengl texture and the texture data and all the other properties that can not change, have this class be the one that is shared and have the texture class be unique. If I am not clear please tell me and I will try to clarify it.

Actually, the only items we need to store are those related to creation in an opengl sense. In other words, those that are setup when assigning a glid. Currently those items are the min/mag filters, aniso-level and wrap mode. All other aspects are applied after loadTexture in any case and are applied in the texture state on each application.



I’ll add wrap and aniso and we should be good to go.

After some thought I realized we don’t need to limit wrap either, so just aniso. That’s all done and in now, so I believe this is done. If you don’t understand why we don’t have to worry about combine modes, wrap, apply and so forth, post here and I’ll explain.



Also, I caught that my addition of aniso some weeks (months?) back may limit cards that do not support aniso texture filtering, so I’ve added a check in there for that. Now those cards should work ok.



Anyhow, this should be done and ready to rock and roll.

I do not understand. The way the code lookes if you lode two textures with the same preamiters you would get one instance. Now if you want one of them to be environment mapped the other one would become environment mapped also.

Sigh, yes that is true… I had originally had a clone method in there and then backed out because of some other issue and forgot that I hadn’t fixed that.



My main goal on the cache is to prevent sending the image to opengl more than once by reusing the same id. That wastes vid memory and so forth. Creating a new Texture object (if we don’t clone the image data itself) is not really a big issue… since it will only hold a few primitive fields.



Here’s a plan on how to complete the picture… When you request a new texture from the manager, it will grab an id from opengl immediately. Thus the Texture objects in the cache are immediately complete with an opengl id. Subsequent calls to get new textures will return a new Texture object that has the id and initial fields from the cache filled in.



Comments?

You still have the problem of texture stares deleting the texture from opengl. I would segest having a counter to how meny textures to a texture are loaded and when memory is low delete the unused ones. (Like a garbage collector.) Keep in mined that even if the textures is not used it may be needed in the future. The rest sounds good.

Hmm, implemented the methods I described and all seems well, but i’m not sure about this removal issue you bring up. If a texture is discarded by gc without being removed from the manager, you’re left with an orphaned texture… We could use gc hooks but I’m not sure about performance and such.

I was suggesting making your own gc that will delete the texture form gl when the app ends or there is no room for more textures. This would solve the problem of having to reload a texture if it is not in use for awhile, it would also give you room for more. If opengl dose not tell you how much room is left on the card, maximum textures could be added to the Property Dialog. This is just one suggestion I am sure there are other ones. Tell me when you chose when you do it.