Sign in to follow this  
doctorsixstring

OpenGL GLSL tc_offset variable

Recommended Posts

I'm trying to implement the blur fragment shader from the OpenGL Superbible, but I'm confused as to where the tc_offset variable is being set. Here's the code:
uniform sampler2D sampler0;
uniform vec2 tc_offset[9];

void main(void)
{
    vec4 sample[9];
    for( int i = 0; i < 9; i++ )
    {
        sample[i] = texture2D( sampler0, gl_TexCoord[0].st + tc_offset[i] );
    }
				
    //  1 2 1
    //  2 1 2  /  13
    //  1 2 1
				
    gl_FragColor = sample[1];/*(sample[0] + (2.0*sample[1]) + sample[2] + 
        (2.0*sample[3]) + sample[4] + (2.0*sample[5]) + 
        sample[6] + (2.0*sample[7]) + sample[8]) / 13.0;
}

Is tc_offset automatically set to the texture coordinates of the neighboring texels, like sampler0 is automatically set to the first texture unit?

Share this post


Link to post
Share on other sites
Quote:
Original post by doctorsixstring
Is tc_offset automatically set to the texture coordinates of the neighboring texels,

You have to set them yourself application side.

Quote:
Original post by doctorsixstring
like sampler0 is automatically set to the first texture unit?

It's not. This is just a coincidence. All uniform variables are initialized to zero before first use, regardless of their name, type or usage in the shader. You could call the variable "sampler23" or "greenSamplerWithRedDots" and both would still point to unit 0 by default.

Share this post


Link to post
Share on other sites
That makes sense. I did some reading on glGetUniform, and it looks like I first need to query the location of a uniform variable with glGetUniformLocation() before setting it with glUniform().

If that's the case, then I'm not sure what I'm doing wrong. Calling glGetUniformLocation for the tc_offset variable returns -1. Calling it for sampler0 returns 0, so that seems to indicate a problem with tc_offset. I also tried creating other variables (e.g. "uniform int a;"), but -1 was returned for those, too. I also noticed that calling glGetProgramiv with GL_ACTIVE_UNIFORMS returned 1, regardless of how many uniform variables I declared.

Here's a code snippet. I'm using Python, but the GL calls should be clear regardless:


self.program = glCreateProgram()
glAttachShader(self.program, fragmentShader)
glLinkProgram(self.program)
glValidateProgram(self.program)

print glGetUniformLocation( self.program, "sampler0" ) # returns 0
print glGetUniformLocation( self.program, "tc_offset" ) # returns -1




That code is executed after creating and compiling the shader (stored in the fragmentShader variable).

Share this post


Link to post
Share on other sites
Quote:
Original post by doctorsixstring
That makes sense. I did some reading on glGetUniform, and it looks like I first need to query the location of a uniform variable with glGetUniformLocation() before setting it with glUniform().

Correct.

Quote:
Original post by doctorsixstring
If that's the case, then I'm not sure what I'm doing wrong. Calling glGetUniformLocation for the tc_offset variable returns -1. Calling it for sampler0 returns 0, so that seems to indicate a problem with tc_offset. I also tried creating other variables (e.g. "uniform int a;"), but -1 was returned for those, too. I also noticed that calling glGetProgramiv with GL_ACTIVE_UNIFORMS returned 1, regardless of how many uniform variables I declared.

Keep in mind that uniforms declared without being actively used by the shader will be optimized away by the GLSL compiler. So simply declaring a new variable without actually accessing it (or without using the results of operations done with it) will result in glGetUniformLocation returning -1. The optimizer is usually very smart with this, and will remove uniforms whenever it sees the slightest possibility of doing so.

Share this post


Link to post
Share on other sites
Quote:
Original post by Yann L
Keep in mind that uniforms declared without being actively used by the shader will be optimized away by the GLSL compiler.


That makes perfect sense, and I immediately noticed the problem after reading this. If you look closely at the code in my original post, you'll notice that I was simply setting gl_FragColor = sample[1]. A multi-line comment was started (but not ended) after that, so the tc_offset usage was optimized away.

I just changed it to the following code, and glGetUniformLocation returns 1 for the variable, and glGetProgramiv with GL_ACTIVE_UNIFORMS returns 2.


gl_FragColor = (sample[0] + (2.0*sample[1]) + sample[2] +
(2.0*sample[3]) + sample[4] + (2.0*sample[5]) +
sample[6] + (2.0*sample[7]) + sample[8]) / 13.0;



Thanks!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this