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 :) |
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(); |
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). |
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); } } |
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? |
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 |
OK, I understand how it works now! Thanks again this conversation has been very helpful! |
Free forum by Nabble | Edit this page |