JOGL backend GLSL how to bind texture to a sampler
JOGL backend GLSL how to bind texture to a sampler
I wonder how in jReality you can bind a texture to a specific GLSL sampler. Since IIRC in OpenGL you have to bind a specific texture unit number to the symbolic sampler name. Which is already a major pain! (These are the days where I remember why I like D3D so much more )
Is there anything which does that for you automatically or do you have to handcode everything by acessing the JOGL object itself? But even so how can I tell which texture on a AppearanceAttribut gets bind to which texture unit?
I looked through the source but couldn't find anything the closest what I saw was the BumpmapPolygonShader.java in the polymake-release tag but it doesn't seem to get used anywhere else in the source repository.
Is there anything which does that for you automatically or do you have to handcode everything by acessing the JOGL object itself? But even so how can I tell which texture on a AppearanceAttribut gets bind to which texture unit?
I looked through the source but couldn't find anything the closest what I saw was the BumpmapPolygonShader.java in the polymake-release tag but it doesn't seem to get used anywhere else in the source repository.
Good question. I've written a further tutorial example GLShadingLangExample03 which can be accessed here.
It's also now in the jReality svn repository.
It's also now in the jReality svn repository.
jReality core developer
Actually there is a slight mistake in the tutorial. In the bottom code example, I think it should be
AttributeEntityUtility.createAttributeEntity(
Texture2D.class, POLYGON_SHADER+"."+TEXTURE_2D_2, ap, true);
instead of
AttributeEntityUtility.createAttributeEntity(
Texture2D.class, ap, POLYGON_SHADER+"."+TEXTURE_2D_2, true);
as according to the JavaDoc it is
createAttributeEntity(Class clazz, String prefix, Appearance a, boolean readDefaults)
AttributeEntityUtility.createAttributeEntity(
Texture2D.class, POLYGON_SHADER+"."+TEXTURE_2D_2, ap, true);
instead of
AttributeEntityUtility.createAttributeEntity(
Texture2D.class, ap, POLYGON_SHADER+"."+TEXTURE_2D_2, true);
as according to the JavaDoc it is
createAttributeEntity(Class clazz, String prefix, Appearance a, boolean readDefaults)
Out of curiosity: Does the multitexturing stuff actually work?
I changed the GLShadingExample03.java by adding following lines:
And I changed the shader (sampler.frag) to this
And it looks to me that on sample and sampler2 both the first texture is assigned to but not my gradient texture.
Now when I tried to use TextureUnit_2 by using TEXTURE2D_2 I got this nice stacktrace when starting up:
java.lang.reflect.InvocationTargetException
at java.awt.EventQueue.invokeAndWait(Unknown Source)
at de.jreality.jogl.Viewer.render(Viewer.java:450)
at de.jreality.ui.viewerapp.ViewerSwitch.render(ViewerSwitch.java:198)
at de.jreality.util.RenderTrigger$RenderTriggerSingleCaster.render(Rende
rTrigger.java:232)
at de.jreality.util.RenderTrigger.fireRender(RenderTrigger.java:148)
at de.jreality.util.RenderTrigger.finishCollect(RenderTrigger.java:270)
at de.jreality.toolsystem.ToolSystem.processToolEvent(ToolSystem.java:34
2)
at de.jreality.toolsystem.ToolEventQueue$1.run(ToolEventQueue.java:79)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: no such entity
at de.jreality.scene.data.AttributeEntityUtility.createAttributeEntity(A
ttributeEntityUtility.java:408)
at de.jreality.jogl.shader.DefaultPolygonShader.setFromEffectiveAppearan
ce(DefaultPolygonShader.java:144)
at de.jreality.jogl.shader.DefaultGeometryShader.setFromEffectiveAppeara
nce(DefaultGeometryShader.java:91)
at de.jreality.jogl.shader.DefaultGeometryShader.createFromEffectiveAppearance(DefaultGeometryShader.java:76)
at de.jreality.jogl.JOGLPeerComponent.updateShaders(JOGLPeerComponent.ja
va:373)
at de.jreality.jogl.JOGLPeerComponent.handleAppearanceChanged(JOGLPeerCo
mponent.java:354)
at de.jreality.jogl.JOGLPeerComponent.preRender(JOGLPeerComponent.java:1
60)
at de.jreality.jogl.JOGLPeerComponent.render(JOGLPeerComponent.java:133)
at de.jreality.jogl.JOGLPeerComponent.renderChildren(JOGLPeerComponent.j
ava:182)
at de.jreality.jogl.JOGLPeerComponent.render(JOGLPeerComponent.java:134)
at de.jreality.jogl.JOGLPeerComponent.renderChildren(JOGLPeerComponent.j
ava:182)
at de.jreality.jogl.JOGLPeerComponent.render(JOGLPeerComponent.java:134)
at de.jreality.jogl.JOGLPeerComponent.renderChildren(JOGLPeerComponent.j
ava:182)
at de.jreality.jogl.JOGLPeerComponent.render(JOGLPeerComponent.java:134)
[/code]
I changed the GLShadingExample03.java by adding following lines:
Code: Select all
byte[] imageRGBAdata = new byte[512 * 4];
for (int x = 0; x < 512; x++)
{
int red = (x >> 1);
int green = (x >> 2);
int blue = (x << 1)%255;
imageRGBAdata[x*4] = (byte)red;
imageRGBAdata[x*4+1] = (byte)green;
imageRGBAdata[x*4+2] = (byte)blue;
imageRGBAdata[x*4+3] = ~0;
}
de.jreality.shader.ImageData lookupImg =
new de.jreality.shader.ImageData(imageRGBAdata, 512, 1);
Texture2D gradTexture = (Texture2D)
AttributeEntityUtility.createAttributeEntity(Texture2D.class, POLYGON_SHADER+"."+TEXTURE_2D_1, ap, true);
gradTexture.setImage(lookupImg);
brickProg.setUniform("sampler2",Texture2D.GL_TEXTURE0+1);
Code: Select all
uniform sampler2D sampler;
uniform sampler2D sampler2;
void main(void)
{
//following code mimics the standard shader with MODULATE apply mode.
vec4 currentSample = texture2D(sampler,gl_TexCoord[0].st);
vec4 currentSample2 = texture2D(sampler2,gl_TexCoord[0].st);
gl_FragColor = currentSample * currentSample2 * gl_Color;
}
Now when I tried to use TextureUnit_2 by using TEXTURE2D_2 I got this nice stacktrace when starting up:
java.lang.reflect.InvocationTargetException
at java.awt.EventQueue.invokeAndWait(Unknown Source)
at de.jreality.jogl.Viewer.render(Viewer.java:450)
at de.jreality.ui.viewerapp.ViewerSwitch.render(ViewerSwitch.java:198)
at de.jreality.util.RenderTrigger$RenderTriggerSingleCaster.render(Rende
rTrigger.java:232)
at de.jreality.util.RenderTrigger.fireRender(RenderTrigger.java:148)
at de.jreality.util.RenderTrigger.finishCollect(RenderTrigger.java:270)
at de.jreality.toolsystem.ToolSystem.processToolEvent(ToolSystem.java:34
2)
at de.jreality.toolsystem.ToolEventQueue$1.run(ToolEventQueue.java:79)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: no such entity
at de.jreality.scene.data.AttributeEntityUtility.createAttributeEntity(A
ttributeEntityUtility.java:408)
at de.jreality.jogl.shader.DefaultPolygonShader.setFromEffectiveAppearan
ce(DefaultPolygonShader.java:144)
at de.jreality.jogl.shader.DefaultGeometryShader.setFromEffectiveAppeara
nce(DefaultGeometryShader.java:91)
at de.jreality.jogl.shader.DefaultGeometryShader.createFromEffectiveAppearance(DefaultGeometryShader.java:76)
at de.jreality.jogl.JOGLPeerComponent.updateShaders(JOGLPeerComponent.ja
va:373)
at de.jreality.jogl.JOGLPeerComponent.handleAppearanceChanged(JOGLPeerCo
mponent.java:354)
at de.jreality.jogl.JOGLPeerComponent.preRender(JOGLPeerComponent.java:1
60)
at de.jreality.jogl.JOGLPeerComponent.render(JOGLPeerComponent.java:133)
at de.jreality.jogl.JOGLPeerComponent.renderChildren(JOGLPeerComponent.j
ava:182)
at de.jreality.jogl.JOGLPeerComponent.render(JOGLPeerComponent.java:134)
at de.jreality.jogl.JOGLPeerComponent.renderChildren(JOGLPeerComponent.j
ava:182)
at de.jreality.jogl.JOGLPeerComponent.render(JOGLPeerComponent.java:134)
at de.jreality.jogl.JOGLPeerComponent.renderChildren(JOGLPeerComponent.j
ava:182)
at de.jreality.jogl.JOGLPeerComponent.render(JOGLPeerComponent.java:134)
[/code]
I found the problem or mistake! There is a second error in the tutorial when you attach textures to a sampler in GLSL you take the sampler unit relative number instead of it's GL_TEXTURE namespace parameter so in this case it should be
instead of
it still doesn't explain the exception though
Code: Select all
brickProg.setUniform("sampler",0);
brickProg.setUniform("sampler2",1);
Code: Select all
brickProg.setUniform("sampler",Texture2D.GL_TEXTURE0);
brickProg.setUniform("sampler2",Texture2D.GL_TEXTURE0+1);
Thanks for the correction. Yes, the samplers need to be specified as uniform parameters as offsets from the 0th texture unit, rather than as absolute values. I couldn't tell from the documentation what the correct choice was. APparently it you don't set it right, it uses the value 0.
I additionally worked over the example to include two textures as you indicated in your post. I also added new versions of the TextureUtility.createTexture() method to include a specification of which texture unit should be created. so you don't need to use the createAttributeEntity() method. I also adopted the version of sampler.frag you posted, with the addition that I use different texture coordinates for the two different texture lookups. I haven't had time to update the tutorial text yet, but have checked in the corrected versions of the changed source code into the svn repository.
I additionally worked over the example to include two textures as you indicated in your post. I also added new versions of the TextureUtility.createTexture() method to include a specification of which texture unit should be created. so you don't need to use the createAttributeEntity() method. I also adopted the version of sampler.frag you posted, with the addition that I use different texture coordinates for the two different texture lookups. I haven't had time to update the tutorial text yet, but have checked in the corrected versions of the changed source code into the svn repository.
jReality core developer
Re: JOGL backend GLSL how to bind texture to a sampler
The tutorial text appears to me to more or less up-to-date (compare with the source code). At least it shows how to specify and use two different texture units. Is there something else missing from the tutorial? I'm glad to add it if you provide the details which are missing.
Note: the source code for the java class GLSLShaderExample03.java and the fragment shader sampler.frag both had small errors which I've corrected today and checked in. These will filter down to the tutorial in the wiki when the next jReality release is made. You can of course check them out of the svn repository now.
Note: the source code for the java class GLSLShaderExample03.java and the fragment shader sampler.frag both had small errors which I've corrected today and checked in. These will filter down to the tutorial in the wiki when the next jReality release is made. You can of course check them out of the svn repository now.
jReality core developer