Jump to content
  • Advertisement
Sign in to follow this  
MindWipe

OpenGL Multitexturing problems

This topic is 3714 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello again. I did google and check old GDnet threads about this issue, but I can't seem to find what I'm doing wrong. So I want to blend topics together to make this anaglyph 3d (blue/red), but first I just wanted to blend the two pics over each other before I'll do anything fancy to it. But I'm having a problem getting my shader to see both textures. Here's my rendering code:
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glDisable(Gl.GL_DEPTH_TEST);
Gl.glUseProgram(p4);

Gl.glActiveTexture(Gl.GL_TEXTURE0);
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, leftEye);

Gl.glActiveTexture(Gl.GL_TEXTURE1);
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, rightEye);

orthoView(openGLControl.Width, openGLControl.Height);
Gl.glLoadIdentity();

Helper.RenderTexturedQuad2D(new Vector3D(0, 2048, 0), new Vector3D(2048, 0, 0.0f), new Vector3D(0.0f, 0.0f, 1.0f));

And here's my simple shader

uniform sampler2D left;
uniform sampler2D right;
	
void main()
{
	vec4 leftColor = texture2D(left,gl_TexCoord[0].st);
	vec4 rightColor = texture2D(right,gl_TexCoord[0].st);
	
	gl_FragColor = leftColor * 0.5 + rightColor * 0.5;
}


The shader apparently only sees texture0, so both the left & right sampler2d equals that texture. Ideas? /MindWipe

Share this post


Link to post
Share on other sites
Advertisement
You need to bind the uniform to the active texture as well.

A texture is bound to a "sampler" (I'm not sure of the terminology here), and the sampler is bound to a uniform... And you missing the last step.

In your example, it's going to be something like:
glUniform(locationLeft,0);
glUniform(locationRight,1);

You can get the location using glGetUniformLocation.

Just to make things double clear, you are actually playing with 3 numbers here:
- the texId
- the active texture (or sampler)
- the uniform location
And you "just" need to bind them all (in the darkness if you wish)


edit: replaced glGetAttribLocation by glGetUniformLocation.

[Edited by - purpledog on April 22, 2008 9:11:21 AM]

Share this post


Link to post
Share on other sites
purpledog pretty much has it covered, there is just one thing I want to add and that is that you don't need to call "Gl.glEnable(Gl.GL_TEXTURE_2D);" when using shaders; texture are implicately enabled by the act of sampling from them in a shader.

Share this post


Link to post
Share on other sites
Quote:
Original post by purpledog
You need to bind the uniform to the active texture as well.

A texture is bound to a "sampler" (I'm not sure of the terminology here), and the sampler is bound to a uniform... And you missing the last step.

In your example, it's going to be something like:
glUniform(locationLeft,0);
glUniform(locationRight,1);

You can get the location using glGetAttribLocation.

Just to make things double clear, you are actually playing with 3 numbers here:
- the texId
- the active texture (or sampler)
- the uniform location
And you "just" need to bind them all (in the darkness if you wish)



I see, thanks for the info. But... it's not working. Shouldn't:

Gl.glActiveTexture(Gl.GL_TEXTURE0);
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, leftEye);
Gl.glUniform1i(Gl.glGetAttribLocation(p4, "left"), 0);

Gl.glActiveTexture(Gl.GL_TEXTURE1);
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, rightEye);
Gl.glUniform1i(Gl.glGetAttribLocation(p4, "right"), 1);

do it?

/MindWipe

Share this post


Link to post
Share on other sites

The problem is that you need to specify the samplers from OpenGL. In your shading code, sampler is just a variable (a uniform variable which you can assign from OpenGL).

Before sampling can take place you have to initialize each sampler variable. You do this with glUniform1i function call. The parameters to this function call are, first, the location of the uniform variable in your GLSL code (e.g. the uniform location of "left" or "right") and secondly the texture unit identifier (e.g. 0 for GL_TEXTURE0) - it is important to realize it is NOT the OpenGL texture ID you use for the sampler variable, it is the Texture Unit to which the texture is bound (common mistake).

When you have linked the program you can retrieve the location of each uniform variable with the function call glGetUniformLocation. Note that this retrieves only active uniforms - an active uniform can be thought of as one whose value actually contributes to the output of each shader. Note that the compiler may strip uniforms if they are not deemed active then you will have a problem (an opengl error) when you try to access the uniform with the (invalid) location (also common mistake).

I suggest you retrieve all active uniforms and their location in some data structure (e.g. hashmap) after you have linked your problem successfully. Each time you need to change a uniform, you look up the location in this data structure.

Lets assume you have found the location of each active uniform. Whenever your problem is enabled, you can use function calls like glUniform1i(uniformLocationForLeft, 0) and glUniform1i(uniformLocationForRight, 1) to make your program work. The values for the uniforms stay until the program is relinked (i.e. you do not have to set them ever frame, only when you want them to change).

I recommend the book OpenGL Shading Language (so-called Orange Book) or look at Lighthouse3D tutorials on GLSL (http://www.lighthouse3d.com/opengl/glsl/).

kind regards,
Nicolai

Edited by ndhb

Share this post


Link to post
Share on other sites
Wups, I see now others have already helped - but look at glGetUniformLocation (see above post) instead of glGetAttribLocation :)

Share this post


Link to post
Share on other sites
Quote:
Original post by ndhb
The problem is that you need to specify the samplers from OpenGL. In your shading code, sampler is just a variable (a uniform variable which you can assign from OpenGL).

Before sampling can take place you have to initialize each sampler variable. You do this with glUniform1i function call. The parameters to this function call are, first, the location of the uniform variable in your GLSL code (e.g. the uniform location of "left" or "right") and secondly the texture unit identifier (e.g. 0 for GL_TEXTURE0) - it is important to realize it is NOT the OpenGL texture ID you use for the sampler variable, it is the Texture Unit to which the texture is bound (common mistake).

When you have linked the program you can retrieve the location of each uniform variable with the function call glGetUniformLocation. Note that this retrieves only active uniforms - an active uniform can be thought of as one whose value actually contributes to the output of each shader. Note that the compiler may strip uniforms if they are not deemed active then you will have a problem (an opengl error) when you try to access the uniform with the (invalid) location (also common mistake).

I suggest you retrieve all active uniforms and their location in some data structure (e.g. hashmap) after you have linked your problem successfully. Each time you need to change a uniform, you look up the location in this data structure.

Lets assume you have found the location of each active uniform. Whenever your problem is enabled, you can use function calls like glUniform1i(uniformLocationForLeft, 0) and glUniform1i(uniformLocationForRight, 1) to make your program work. The values for the uniforms stay until the program is relinked (i.e. you do not have to set them ever frame, only when you want them to change).

I recommend the book OpenGL Shading Language (so-called Orange Book) or look at Lighthouse3D tutorials on GLSL (http://www.lighthouse3d.com/opengl/glsl/).

kind regards,
Nicolai de Haan Brøgger



Thanks for an awesome explanation!!

Apparently glGetAttribLocation returns -1 for both left and right so I guess I'll have to findout why.

/MindWipe

Share this post


Link to post
Share on other sites
Quote:
Original post by ndhb
Wups, I see now others have already helped - but look at glGetUniformLocation (see above post) instead of glGetAttribLocation :)


Oh! Right! Awesome! Now it works!

Super thanks to all of you!

Share this post


Link to post
Share on other sites
Quote:
Original post by ndhb
Wups, I see now others have already helped - but look at glGetUniformLocation (see above post) instead of glGetAttribLocation :)


Aouch, sorry for that, my mistake!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!