Binding texture from pbuffer to use with shaderprogram

I use a pbuffer for dynamic texture generation to be used with a shaderprogram and I need to have the textureID.

This really works well with the normal procedure render to texture :
Enable texture2d
Bind the texture
Push your mesh data
Etc…

However I’m writing my own shader programs in which I have to set some uniform sampler2d variables. And for that I have to pass the texture id.

Piece from the fragment shader:


uniform sampler2D colorMap; 
uniform sampler2D bumpMap; 
uniform sampler2D envMap;

The pbuffer is used to create the colorMap, and the other two textures are simply loaded from bmp files.
To set these variables the following call is used from the Java program


gl.glUniform1i(gl.glGetUniformLocation(this.shaderProgramID, "colorMap"), this.colorMapTextureID);

But I can’t get the texture id from the pbuffer (how is it shared ?)
After debugging (eclipse) I saw that the pbuffers texture id (declared private) is always constant (logically and in my case after loading 2 textures from file the pbuffer texture id became always number 3). Thus tried to take the resulting number en pass it just along to the shaderprogram. However the object turned completely black.

Now the strange thing is, when I don’t pass the texture id (and thus in the fragment shader the variable colorMap is not set) the texture appears and is mapped correctly following the fragment program.

Piece from the fragment shader:


vec3 envColor = vec3 (texture2D(envMap, index));
vec3 baseColor = vec3 (texture2D(colorMap, gl_TexCoord[0].st));
vec3 result = mix(envColor, baseColor , mixRatio);	 
gl_FragColor = lightColor * vec4( result,1.0);

and the render code from the Java program:


pbuffer.display();

gl.glUseProgram(this.shaderProgramID);

gl.glActiveTexture(GL.GL_TEXTURE0);
gl.glEnable(GL.GL_TEXTURE_2D);
pbuffer.bindTexture();
//gl.glBindTexture(GL.GL_TEXTURE_2D, colorMap);

gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
gl.glEnable(GL.GL_TEXTURE_GEN_S);
gl.glEnable(GL.GL_TEXTURE_GEN_T);

gl.glActiveTexture(GL.GL_TEXTURE1);
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glBindTexture(GL.GL_TEXTURE_2D, bumpMap);
gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
gl.glEnable(GL.GL_TEXTURE_GEN_S);
gl.glEnable(GL.GL_TEXTURE_GEN_T);

gl.glActiveTexture(GL.GL_TEXTURE2);
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glBindTexture(GL.GL_TEXTURE_2D, envMap);
gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
gl.glEnable(GL.GL_TEXTURE_GEN_S);
gl.glEnable(GL.GL_TEXTURE_GEN_T);

// gl.glUniform1i(gl.glGetUniformLocation(this.programID, "colorMap"), colorMap);
gl.glUniform1i(gl.glGetUniformLocation(this.programID, "bumpMap"),bumpMap);
gl.glUniform1i(gl.glGetUniformLocation(this.programID, "envMap"), envMap);

and then render the mesh (a glusphere atm).
This works on my ATI mobile x700 and NVidia 6800gt without a problem. Now I’m still researching this effect but my goal is to use pbuffers to render more textures. Thus I probably will need to get the pbuffer textureID.
Although this works, it currently seems more like a hack then a real solution.
Someone experienced similar effects and have some solution, or is there something wrong in my approach ?

(using JSR-231 beta 04 – Windows XP sp2)

Render-to-texture for pbuffers isn’t portable and JOGL for example doesn’t support it on X11 platforms. I don’t know the recommended way of doing this in a way compatible with shaders but would recommend you look into the EXT_framebuffer_object extension, which does support render-to-texture portably.

Thanks for the advice.
I changed the program to use fbo’s and now I’m indeed able to get the TextureID.
…. However exactly the same problem :confused:
This is really weird because

Using the normal (without a shader program) way with multitexturing, just rendering the textures over each other, works perfectly. The dynamic texture changes beautifully and is blended through the static textures.

Using the shader program with only static textures loaded from file, works also perfectly. One texture is used as a colormap, another for light effects and the last one for environment mapping.

Using the shader program with the dynamic texture … and the object turns completely black. The other textures are also not visible.

//edit

haha never mind what i have written above. Man i’m feeling very stupid right now :-X
Sending the TextureID to the shaderprogram is totally wrong. It’s the GL_TEXTURE unit where the textureId is binded at. Oww man it is so logical >_<

Here how it works now


		gl.glUseProgram(this.programID);

		gl.glActiveTexture(GL.GL_TEXTURE0);
		gl.glEnable(GL.GL_TEXTURE_2D);
		gl.glBindTexture(GL.GL_TEXTURE_2D, getColorMapID());
		gl.glTexEnvf (GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_COMBINE);
		gl.glTexEnvf (GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB, GL.GL_REPLACE);

		gl.glActiveTexture(GL.GL_TEXTURE1);
		gl.glBindTexture(GL.GL_TEXTURE_2D, getBumpMapID());
		gl.glEnable(GL.GL_TEXTURE_2D);
		gl.glTexEnvf (GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_COMBINE);
		gl.glTexEnvf (GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB, GL.GL_INCR);

		gl.glActiveTexture(GL.GL_TEXTURE2);
		gl.glEnable(GL.GL_TEXTURE_2D);
		gl.glBindTexture(GL.GL_TEXTURE_2D, getEnvironmentMapID());
		gl.glTexEnvf (GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_COMBINE);
		gl.glTexEnvf (GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB, GL.GL_INCR);

		gl.glUniform1i(gl.glGetUniformLocation(this.programID, "colorMap"), 0);
		gl.glUniform1i(gl.glGetUniformLocation(this.programID, "bumpMap"), 1);
		gl.glUniform1i(gl.glGetUniformLocation(this.programID, "envMap"), 2);

		gl.glUniform1f(gl.glGetUniformLocation(this.programID, "mixRatio"), getEnvironmentMixRatio());

		//render mesh 


Well atleast i learned how to use framebuffer objects :smiley:

I have no experience with texture sharing (and thus don’t know how you’d obtain the texture ID for your pbuffer texture), but: you don’t want to assign the texture ID but the texture unit number to your sampler. Since your code will always set ‘colorMap’ to unit 0, ‘bumpMap’ to unit 1 etc, you can do this once, just after your shader program is built.

EDIT: whoops I just noticed your last post, nevermind… ;D