JOGL backend GLSL how to bind texture to a sampler

Have jReality programming problems or questions? Post them here.
Post Reply
STRESS
Posts: 141
Joined: Mon 19. Jan 2009, 12:10

JOGL backend GLSL how to bind texture to a sampler

Post by STRESS » Mon 16. Mar 2009, 19:10

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 :lol: )

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.

User avatar
gunn
Posts: 323
Joined: Thu 14. Dec 2006, 09:56
Location: TU Berlin
Contact:

Post by gunn » Tue 17. Mar 2009, 17:48

Good question. I've written a further tutorial example GLShadingLangExample03 which can be accessed here.

It's also now in the jReality svn repository.
jReality core developer

STRESS
Posts: 141
Joined: Mon 19. Jan 2009, 12:10

Post by STRESS » Wed 18. Mar 2009, 11:25

Awesome! Thank you very much for the quick response gunn!

STRESS
Posts: 141
Joined: Mon 19. Jan 2009, 12:10

Post by STRESS » Wed 18. Mar 2009, 12:45

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)

STRESS
Posts: 141
Joined: Mon 19. Jan 2009, 12:10

Post by STRESS » Wed 18. Mar 2009, 16:43

Out of curiosity: Does the multitexturing stuff actually work?

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);
And I changed the shader (sampler.frag) to this

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;
}

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]

STRESS
Posts: 141
Joined: Mon 19. Jan 2009, 12:10

Post by STRESS » Thu 19. Mar 2009, 12:43

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

Code: Select all

brickProg.setUniform("sampler",0);
brickProg.setUniform("sampler2",1);
instead of

Code: Select all

brickProg.setUniform("sampler",Texture2D.GL_TEXTURE0);
brickProg.setUniform("sampler2",Texture2D.GL_TEXTURE0+1);
it still doesn't explain the exception though

User avatar
gunn
Posts: 323
Joined: Thu 14. Dec 2006, 09:56
Location: TU Berlin
Contact:

Post by gunn » Fri 20. Mar 2009, 14:56

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.
jReality core developer

User avatar
gunn
Posts: 323
Joined: Thu 14. Dec 2006, 09:56
Location: TU Berlin
Contact:

Re: JOGL backend GLSL how to bind texture to a sampler

Post by gunn » Wed 10. Jul 2013, 15:14

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.
jReality core developer

Post Reply