This is current code in TextureUnitStateUnitPeer.java:
if ( !statesCache.enabled || statesCache.currentCombineMode_RGB[ unit ] != ta.getCombineRGBMode() )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB, ta.getCombineRGBMode().toOpenGL() );
statesCache.currentCombineMode_RGB[ unit ] = ta.getCombineRGBMode();
}
if ( !statesCache.enabled || statesCache.currentCombineMode_Alpha[ unit ] != ta.getCombineAlphaMode() )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_COMBINE_ALPHA, ta.getCombineAlphaMode().toOpenGL() );
statesCache.currentCombineMode_Alpha[ unit ] = ta.getCombineAlphaMode();
}
if ( !statesCache.enabled || statesCache.currentCombineSource0_RGB[ unit ] != ta.getCombineRGBSource( 0 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE0_RGB, ta.getCombineRGBSource( 0 ).toOpenGL() );
statesCache.currentCombineSource0_RGB[ unit ] = ta.getCombineRGBSource( 0 );
}
if ( !statesCache.enabled || statesCache.currentCombineSource0_Alpha[ unit ] != ta.getCombineAlphaSource( 0 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE0_ALPHA, ta.getCombineAlphaSource( 0 ).toOpenGL() );
statesCache.currentCombineSource0_Alpha[ unit ] = ta.getCombineAlphaSource( 0 );
}
if ( !statesCache.enabled || statesCache.currentCombineFunction0_RGB[ unit ] != ta.getCombineRGBFunction( 0 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND0_RGB, ta.getCombineRGBFunction( 0 ).toOpenGL() );
statesCache.currentCombineFunction0_RGB[ unit ] = ta.getCombineRGBFunction( 0 );
}
if ( !statesCache.enabled || statesCache.currentCombineFunction0_Alpha[ unit ] != ta.getCombineAlphaFunction( 0 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND0_ALPHA, ta.getCombineAlphaFunction( 0 ).toOpenGL() );
statesCache.currentCombineFunction0_Alpha[ unit ] = ta.getCombineAlphaFunction( 0 );
}
if ( !statesCache.enabled || statesCache.currentCombineSource1_RGB[ unit ] != ta.getCombineRGBSource( 1 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE1_RGB, ta.getCombineRGBSource( 1 ).toOpenGL() );
statesCache.currentCombineSource1_RGB[ unit ] = ta.getCombineRGBSource( 1 );
}
if ( !statesCache.enabled || statesCache.currentCombineSource1_Alpha[ unit ] != ta.getCombineAlphaSource( 1 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE1_ALPHA, ta.getCombineAlphaSource( 1 ).toOpenGL() );
statesCache.currentCombineSource1_Alpha[ unit ] = ta.getCombineAlphaSource( 1 );
}
if ( !statesCache.enabled || statesCache.currentCombineFunction0_RGB[ unit ] != ta.getCombineRGBFunction( 1 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND1_RGB, ta.getCombineRGBFunction( 1 ).toOpenGL() );
statesCache.currentCombineFunction0_RGB[ unit ] = ta.getCombineRGBFunction( 1 );
}
if ( !statesCache.enabled || statesCache.currentCombineFunction0_Alpha[ unit ] != ta.getCombineAlphaFunction( 1 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND1_ALPHA, ta.getCombineAlphaFunction( 1 ).toOpenGL() );
statesCache.currentCombineFunction0_Alpha[ unit ] = ta.getCombineAlphaFunction( 1 );
}
if ( !statesCache.enabled || statesCache.currentCombineSource2_RGB[ unit ] != ta.getCombineRGBSource( 2 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE2_RGB, ta.getCombineRGBSource( 2 ).toOpenGL() );
statesCache.currentCombineSource2_RGB[ unit ] = ta.getCombineRGBSource( 2 );
}
if ( !statesCache.enabled || statesCache.currentCombineSource2_Alpha[ unit ] != ta.getCombineAlphaSource( 2 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE2_ALPHA, ta.getCombineAlphaSource( 2 ).toOpenGL() );
statesCache.currentCombineSource2_Alpha[ unit ] = ta.getCombineAlphaSource( 2 );
}
if ( !statesCache.enabled || statesCache.currentCombineFunction0_RGB[ unit ] != ta.getCombineRGBFunction( 2 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND2_RGB, ta.getCombineRGBFunction( 2 ).toOpenGL() );
statesCache.currentCombineFunction0_RGB[ unit ] = ta.getCombineRGBFunction( 2 );
}
if ( !statesCache.enabled || statesCache.currentCombineFunction0_Alpha[ unit ] != ta.getCombineAlphaFunction( 2 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND2_ALPHA, ta.getCombineAlphaFunction( 2 ).toOpenGL() );
statesCache.currentCombineFunction0_Alpha[ unit ] = ta.getCombineAlphaFunction( 2 );
}
if ( !statesCache.enabled || statesCache.currentCombineRGBScale[ unit ] != ta.getCombineRGBScale() )
{
gl.glTexEnvi( GL.GL_TEXTURE_ENV, GL.GL_RGB_SCALE, ta.getCombineRGBScale() );
statesCache.currentCombineRGBScale[ unit ] = ta.getCombineRGBScale();
}
So there are some problems with this.
1. Performance can be improved by "getting" things once, instead of call get 3 times for each item. Inside of get, a System.arraycopy occurs every time static "values()" is called. (This too can be avoided by calling values() once and storing it into an array).
2. There are a few lines which are incorrect:
if ( !statesCache.enabled || statesCache.
currentCombineFunction0_RGB[ unit ] != ta.getCombineRGBFunction(
1 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND1_RGB, ta.getCombineRGBFunction( 1 ).toOpenGL() );
statesCache.
currentCombineFunction0_RGB[ unit ] = ta.getCombineRGBFunction( 1 );
}
if ( !statesCache.enabled || statesCache.
currentCombineFunction0_Alpha[ unit ] != ta.getCombineAlphaFunction(
1 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND1_ALPHA, ta.getCombineAlphaFunction( 1 ).toOpenGL() );
statesCache.
currentCombineFunction0_Alpha[ unit ] = ta.getCombineAlphaFunction( 1 );
}
if ( !statesCache.enabled || statesCache.
currentCombineFunction0_RGB[ unit ] != ta.getCombineRGBFunction(
2 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND2_RGB, ta.getCombineRGBFunction( 2 ).toOpenGL() );
statesCache.
currentCombineFunction0_RGB[ unit ] = ta.getCombineRGBFunction( 2 );
}
if ( !statesCache.enabled || statesCache.
currentCombineFunction0_Alpha[ unit ] != ta.getCombineAlphaFunction(
2 ) )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND2_ALPHA, ta.getCombineAlphaFunction( 2 ).toOpenGL() );
statesCache.
currentCombineFunction0_Alpha[ unit ] = ta.getCombineAlphaFunction( 2 );
}
3. I noticed that "combineAlphaScale" is missing here too.
4. I noticed in opengl specification that combineRGBScale is a float, not an integer. However, when I tried changing gl.glTexEnvi to gl.glTexEnvf I got an error. I think java binding is incorrect.
http://www.opengl.org/sdk/docs/man/xhtml/glGetTexEnv.xml5. same issues apply to lwjgl peer.
Corrected code is here for TextureUnitStateUnitPeer.java:
TextureCombineMode combineMode;
combineMode = ta.getCombineRGBMode();
if ( !statesCache.enabled || statesCache.currentCombineMode_RGB[ unit ] != combineMode )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB, combineMode.toOpenGL() );
statesCache.currentCombineMode_RGB[ unit ] = combineMode;
}
combineMode = ta.getCombineAlphaMode();
if ( !statesCache.enabled || statesCache.currentCombineMode_Alpha[ unit ] != combineMode )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_COMBINE_ALPHA, combineMode.toOpenGL() );
statesCache.currentCombineMode_Alpha[ unit ] = combineMode;
}
TextureCombineSource combineSource;
combineSource = ta.getCombineRGBSource( 0 );
if ( !statesCache.enabled || statesCache.currentCombineSource0_RGB[ unit ] != combineSource )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE0_RGB, combineSource.toOpenGL() );
statesCache.currentCombineSource0_RGB[ unit ] = combineSource;
}
combineSource = ta.getCombineAlphaSource( 0 );
if ( !statesCache.enabled || statesCache.currentCombineSource0_Alpha[ unit ] != combineSource )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE0_ALPHA, combineSource.toOpenGL() );
statesCache.currentCombineSource0_Alpha[ unit ] = combineSource;
}
TextureCombineFunction combineFunction;
combineFunction = ta.getCombineRGBFunction( 0 );
if ( !statesCache.enabled || statesCache.currentCombineFunction0_RGB[ unit ] != combineFunction )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND0_RGB, combineFunction.toOpenGL() );
statesCache.currentCombineFunction0_RGB[ unit ] = combineFunction;
}
combineFunction = ta.getCombineAlphaFunction( 0 );
if ( !statesCache.enabled || statesCache.currentCombineFunction0_Alpha[ unit ] != combineFunction )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND0_ALPHA, combineFunction.toOpenGL() );
statesCache.currentCombineFunction0_Alpha[ unit ] = combineFunction;
}
combineSource = ta.getCombineRGBSource( 1 );
if ( !statesCache.enabled || statesCache.currentCombineSource1_RGB[ unit ] != combineSource )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE1_RGB, combineSource.toOpenGL() );
statesCache.currentCombineSource1_RGB[ unit ] = combineSource;
}
combineSource = ta.getCombineAlphaSource( 1 );
if ( !statesCache.enabled || statesCache.currentCombineSource1_Alpha[ unit ] != combineSource )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE1_ALPHA, combineSource.toOpenGL() );
statesCache.currentCombineSource1_Alpha[ unit ] = combineSource;
}
combineFunction = ta.getCombineRGBFunction( 1 );
if ( !statesCache.enabled || statesCache.currentCombineFunction1_RGB[ unit ] != combineFunction )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND1_RGB, combineFunction.toOpenGL() );
statesCache.currentCombineFunction1_RGB[ unit ] = combineFunction;
}
combineFunction = ta.getCombineAlphaFunction( 1 );
if ( !statesCache.enabled || statesCache.currentCombineFunction1_Alpha[ unit ] != combineFunction )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND1_ALPHA, combineFunction.toOpenGL() );
statesCache.currentCombineFunction1_Alpha[ unit ] = combineFunction;
}
combineSource = ta.getCombineRGBSource( 2 );
if ( !statesCache.enabled || statesCache.currentCombineSource2_RGB[ unit ] != combineSource )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE2_RGB, combineSource.toOpenGL() );
statesCache.currentCombineSource2_RGB[ unit ] = combineSource;
}
combineSource = ta.getCombineAlphaSource( 2 );
if ( !statesCache.enabled || statesCache.currentCombineSource2_Alpha[ unit ] != combineSource )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_SOURCE2_ALPHA, combineSource.toOpenGL() );
statesCache.currentCombineSource2_Alpha[ unit ] = combineSource;
}
combineFunction = ta.getCombineRGBFunction( 2 );
if ( !statesCache.enabled || statesCache.currentCombineFunction2_RGB[ unit ] != combineFunction )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND2_RGB, combineFunction.toOpenGL() );
statesCache.currentCombineFunction2_RGB[ unit ] = combineFunction;
}
combineFunction = ta.getCombineAlphaFunction( 2 );
if ( !statesCache.enabled || statesCache.currentCombineFunction2_Alpha[ unit ] != combineFunction )
{
gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_OPERAND2_ALPHA, combineFunction.toOpenGL() );
statesCache.currentCombineFunction2_Alpha[ unit ] = combineFunction;
}
int combineScale = ta.getCombineRGBScale();
if ( !statesCache.enabled || statesCache.currentCombineRGBScale[ unit ] != combineScale )
{
gl.glTexEnvi( GL.GL_TEXTURE_ENV, GL.GL_RGB_SCALE, combineScale );
statesCache.currentCombineRGBScale[ unit ] = combineScale;
}
And TextureAttributes.java really ought to use some cached arrays of the enum values() so it doesn't call System.arraycopy for every texture state update:
private static TextureCombineSource[] textureCombineSourceValues = TextureCombineSource.values();
private static TextureCombineFunction[] textureCombineFunctionValues = TextureCombineFunction.values();
...
// example: don't use TextureCombineSource.values() here, used cached array since it doesn't change.
public TextureCombineSource getCombineAlphaSource( int index )
{
return ( textureCombineSourceValues[ combineAlphaSource[ index ] ] );
}