Texture JOGL -> GLSL

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Texture JOGL -> GLSL

AlexRNL
Hi guys!

I'm currently working on a JOGL project and I've run into something strange.

I'm using shaders to process my texture here is the (simplified) code that i'm using :

Shader setup
gl.glShaderSource(vertexShader, vertexFile.length, vertexFile, null);
gl.glShaderSource(fragmentShader, fragmentFile.length, fragmentFile, null);

gl.glCompileShader(vertexShader);
gl.glCompileShader(fragmentShader);
programShader = gl.glCreateProgram();

gl.glAttachShader(programShader, vertexShader);
gl.glAttachShader(programShader, fragmentShader);
		
processGLErrors(gl.glGetError(), "b4");
textureLocation = gl.glGetUniformLocation(programShader, "Texture"); //FIXME should be after linking...
processGLErrors(gl.glGetError(), "text-loc");

gl.glLinkProgram(programShader);

xMinLocation = gl.glGetUniformLocation(programShader, "xMi");

Rendering loop
currentTrace.getTexture() is a com.sun.opengl.util.texture.Texture object
gl.glUseProgram(programShader);

currentTrace.getTexture().enable();
currentTrace.getTexture().bind();
gl.glUniform1i(textureLocation, currentTrace.getTexture().getTextureObject());
gl.glUniform1f(xMinLocation, xMin);

gl.glBegin(GL.GL_QUADS);
//Drawing
gl.glEnd();
currentTrace.getTexture().disable();
gl.glUseProgram(0);

First, I realized that the binding of the texture was not necessary because I'm doing it 'manually' in my shader. But when I remove the lines, it wasn't working all the time...

Also, when I'm using that code, i'm getting a correct result (textures applied and processed by the shader). But it I have an invalid operation error just after getting the location of Texture which appeared to be normal because I should only do that after the linking. When I moved the line after the linking, it wasn't working anymore!! The shaders were still working but there was no texture.

Do any of you have a clue of why this is happening?
Thanks :)
Reply | Threaded
Open this post in threaded view
|

Re: Texture JOGL -> GLSL

Demoscene Passivist
Administrator
For using textures with shaders u have to use the "active texture unit number" instead of the generated "texture id" a sampler uniform value. U are using the "texture id" from getTextureObject() instead. Thats why ur code works unreliable. Try doing stg like this:

inGL.glActiveTexture(inTextureUnit);
inTexture.enable();
inTexture.bind();
ShaderUtils.setUniform1i(inGL,inProgramID,inSamplerUniformName,inTextureUnitNumber);
inTexture.disable();
Reply | Threaded
Open this post in threaded view
|

Re: Texture JOGL -> GLSL

AlexRNL
Demoscene Passivist wrote
For using textures with shaders u have to use the "active texture unit number" instead of the generated "texture id" a sampler uniform value. U are using the "texture id" from getTextureObject() instead. Thats why ur code works unreliable. Try doing stg like this:

inGL.glActiveTexture(inTextureUnit);
inTexture.enable();
inTexture.bind();
ShaderUtils.setUniform1i(inGL,inProgramID,inSamplerUniformName,inTextureUnitNumber);
inTexture.disable();
Thanks for your answer, it seems it will to solve my problem(s) !

However, I can't find the class ShaderUtils. I have found another example for using this class here. I have search in JOGL 1.1 & JOGL 2.0 but I only found this class (without the 's') and there is no function such as 'setUniform1i).
Reply | Threaded
Open this post in threaded view
|

Re: Texture JOGL -> GLSL

Demoscene Passivist
Administrator
ShaderUtils is part of my own framework and not an official part of the JOGL distribution (wich has its own set of utility classes for shader handling). The code for the class can be found on my github repository: ShaderUtils.java 

If u don't like to use my stuff u can simply replace/inline the setUniform1i with this simple code snippet:
    public static void setUniform1i(GL2 inGL,int inProgramID,String inName,int inValue) {
        int tUniformLocation = inGL.glGetUniformLocation(inProgramID,inName);
        if (tUniformLocation != -1) {
            inGL.glUniform1i(tUniformLocation, inValue);
        } else {
            BaseLogging.getInstance().warning("UNIFORM COULD NOT BE FOUND! NAME="+inName);
        }
    }
Reply | Threaded
Open this post in threaded view
|

Re: Texture JOGL -> GLSL

AlexRNL
Demoscene Passivist wrote
ShaderUtils is part of my own framework and not an official part of the JOGL distribution (wich has its own set of utility classes for shader handling). The code for the class can be found on my github repository: ShaderUtils.java 

If u don't like to use my stuff u can simply replace/inline the setUniform1i with this simple code snippet:
    public static void setUniform1i(GL2 inGL,int inProgramID,String inName,int inValue) {
        int tUniformLocation = inGL.glGetUniformLocation(inProgramID,inName);
        if (tUniformLocation != -1) {
            inGL.glUniform1i(tUniformLocation, inValue);
        } else {
            BaseLogging.getInstance().warning("UNIFORM COULD NOT BE FOUND! NAME="+inName);
        }
    }
Thanks a lot, it works fine now :)

One last question... To activate the texture, i'm using GL_TEXTURE0. But i'm wondering what this value represent, is it the first texture loaded? is it the texture which has the identifier 0?
Reply | Threaded
Open this post in threaded view
|

Re: Texture JOGL -> GLSL

Demoscene Passivist
Administrator
>One last question... To activate the texture, i'm using GL_TEXTURE0.
>But i'm wondering what this value represent, is it the first texture loaded?
>is it the texture which has the identifier 0?

Modern GPUs can only handle a limited number of simultaneous textures. This limitation is abstracted as "texture units" in OpenGL. The number of textures to be used (e.g. by a shader) is queriable from the constant GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (usually 8+ on a modern GPU).

GL_TEXTURE0 is such a "texture unit" from wich u have usually 7 more. The way u use one of these units is to "active" it with "glActiveTexture(inTextureUnitNumber)". After activation u can bind a texture to it with "glBindTexture(inTextureID)". After u have activated the texture unit and bound a texture to it u can then inform ur shader to use this texture unit as sampler uniform.

So the shader has no idea what texture it is actually using, it is simply using the bound texture unit as source for the texture data.

For an example using 4 texture units bound to 4 different textures take a look at my GL3_ParallaxOcclusionMapping.java
Reply | Threaded
Open this post in threaded view
|

Re: Texture JOGL -> GLSL

AlexRNL
Demoscene Passivist wrote
Modern GPUs can only handle a limited number of simultaneous textures. This limitation is abstracted as "texture units" in OpenGL. The number of textures to be used (e.g. by a shader) is queriable from the constant GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (usually 8+ on a modern GPU).

GL_TEXTURE0 is such a "texture unit" from wich u have usually 7 more. The way u use one of these units is to "active" it with "glActiveTexture(inTextureUnitNumber)". After activation u can bind a texture to it with "glBindTexture(inTextureID)". After u have activated the texture unit and bound a texture to it u can then inform ur shader to use this texture unit as sampler uniform.

So the shader has no idea what texture it is actually using, it is simply using the bound texture unit as source for the texture data.

For an example using 4 texture units bound to 4 different textures take a look at my GL3_ParallaxOcclusionMapping.java
OK, I understand how it works now!

Thanks again this conversation has been very helpful!