Enhancement to LWJGLTextureState

According to this:



http://developer.nvidia.com/object/General_FAQ.html#t6



newer graphic cards have more texture units than reported by GL_MAX_TEXTURE_UNITS. For example Radeon 9700 reports 8 but has 16, so is a nV6600 reporting 4 but also has 16. nV graphic cards above FX5200 all report only 4 but have more units. Those extra units are not accessible to fixed functionality, only to fragment shaders. So i went on vandalizing the above class, and made changes to use those extra units. The changes are minor all in all, and mostly involve "if" branches around code that do not apply to units numbered >= GL_MAX_TEXTURE_UNITS. If one of the devs is interested in checking it and putting this into jME, I'm ready to send it.



The biggest change to apps is that there are 4 methods for getting the number of texture units:



TextureState.getNumberOfFixedUnits()

Reports the number of units available to fixed functionality.



TextureState.getNumberOfFragmentUnits()

Reports the number of units available to fragment shaders.



TextureState.getNumberOfVertexUnits()

Reports the number of units available to vertex shaders.



TextureState.getNumberOfUnits()

This reported getNumberOfFixedUnits(), now would report the maximum of the above 3. If no shaders are supported it is the same as getNumberOfFixedUnits(), so this should work without problems on older cards.



Another effect is that there still can only be getNumberOfFixedUnits() texture coordinates per vertex. Units not accessible to fixed functionality simply don't have their own texcoords.


Sounds like the type of thing we should have really :slight_smile:

Sounds good, as long as we are careful with the texcoord code.

I want to bring this topic up again.



I have the problem that the TextureState reports only 4 Texture Units instead of 16 that my card supports.



What about this problem? Any plans for this?

Madlion, are you actually using shaders then?



I plan to get vear's code in this week, he already mailed it to me.

llama said:

Madlion, are you actually using shaders then?

Yes i'm trying to do. ;)

llama said:

I plan to get vear's code in this week, he already mailed it to me.

Good to hear that. ^^

Are there 2 different sets of max textures?  One for fixed pipeline and one for the (i don't know what to call it) ?soft pipeline? Would there be anyway to store stuff in soft pipeline and use them in the fixed? 

There is only one set of units, but the fixed pipeline sees only the the first 4 (on nV) or first 8 (on ATI), you cant do anything with shader-only units from fixed pipeline.



I can imagine two uses for so much (16) units: doing splatting in single pass and caching the textures (storing textures of more models into single state, but not using all textures the same time). For the first you absolutely need shaders, the second use isnt so promising after i tryed it. Setting more textures than the currrent drawn model requires can turn out that you set textures all the time which you absolutely dont use.

OK, I have most of this ported to the latest CVS version.



However, I'm not sure if it's a good idea to change the behaviour of TextureState.getNumberOfUnits() to return the maximum number of units, because of backwards compatability… I'll probably make an additional method for that (getNumberOfUnits could be deprecated in the long run).



Also, I might change some GL20 methods to ARB to be consistent with the rest of jME. Though, neither of them seem to be giving me any result other than 0 for the vertex part.


Hmm, looking closer…  getNumberOfUnits is used in a lot of our code here at NCsoft for things such as creating arrays that are the right size to fit just the used number of texture coordinate arrays in, etc.  The method is also used in LWJGLRenderer.prepVBO in the same manner.



Instead of changing that method and breaking expected behavior, let's provide a getMaxNumberOfUnits as that more accurately reflects the intent of his method.

Yes, that's what I suggested. I already created a new method getNumberOfTotalUnits(), deprecated getNumberOfUnits() and made it return getFixedNumberOfUnits(). Also updated all jME classes that used getNumberOfUnits() to use either getFixedNumberOfUnits() or getNumberOfTotalUnits() (in the parts of the renderer where it's needed, in other words where vear did not change it to Vertex or Fragment).



However,I still get 0 for GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS or GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB . I'm sure my card can do vertex shaders… but I'm starting to guess this is a PS 3.0 feature. I don't think in vertex shaders in <= PS 2.0 can touch textures so I guess it should be 0?



I still have to describe this feature for the javadoc, so if some "shady" figure could do this…

Did some searching on my own, seems to confirm more or less what I said, so I hope it's reasonably correct. Now in CVS…



Maybe I should check in the test too… it's kinda nice to suddenly see all those texture units at work :slight_smile:

Hm, nV6600 reports 4 vertex tex units, but that could be software emulation too, which is said to be sloow. But anyway, the possibility to know about vertex tex units is a prerequisite to use them. I have some enhancements to GLSLShaderObjectsState too, but its too much off jME standards. If there is interest, i can describe what issues i tryed adressing, and what would be in my view the best way of adressing those issues the proper way, and not by only enhancing the GLSLState.

6600 is PS3.0, so that would make sense.



The "PS 3.0" term is confusing, because the values retrieved relate to GLSL. But accesing the texture units from a GLSL vertex shader (a useful feature, eg. for loading a heightmap to a mesh) is only supported if your card supports the more commenly referred to PS 3.0. My Ati X700 is PS 2.0, so it makes sense that it's 0.



About your GLSL stuff, you can always post it, maybe someone will pick up on it… :slight_smile: