PDA

View Full Version : Sample regular texture, output to integer texture



jpack
04-08-2011, 11:32 AM
Okay, so I'm having trouble using shaders + samplers to render to an integer texture.

Setup:

Windows 7
NVIDIA 9800 GTX, Drivers 266.58

OpenGL 3.3 core

Texture A: GL_RGBA8 internal with GL_RGBA format set to all white, nearest min/mag (no mipmap), mipmaps generated anyways

Texture B: GL_RGBA8UI internal with GL_RGBA_INTEGER format set to black, nearest min/mag (no mipmap), mipmaps generated anyways

Depth testing + culling = disabled

If I render A to the screen I get an all white screen. Good!

However, if I render A to an FBO which has B as a render texture with the following shaders:

Vertex:


#version 330 core

layout( location = 0 ) in vec2 in_Position;
out vec2 ex_TextureCoordinates;


void main(void)
{
gl_Position = vec4( in_Position, 0.0, 1.0 );
ex_TextureCoordinates = (in_Position + 1.0) * 0.5;
}

Fragment:


#version 330 core

in vec2 ex_TextureCoordinates;
layout( location = 0 ) out uvec4 out_Color;

uniform sampler2D theTextureSampler;

void main()
{
vec4 interColor = texture( theTextureSampler, ex_TextureCoordinates ) * 255.0f;
out_Color = uvec4( interColor );
}

And then render B to the screen the screen is all black. However, I've proved that A is all white so
B should also be all white.

If I change the out_Color in the fragment shader to uvec4( 255,255,255,255) and then render B to the screen I do see all white on the screen. Likewise, if I change out_Color to uvec4( ex_TextureCoordinates * 255.0, 0, 255 ), I see the screen going from black in the lower left to green in the upper left, to red in the lower right and to yellow in the upper right. This is expected due to the texture coordinates.

Also, if I change the fragment shader to:



void main()
{
vec4 interColor = texture( theTextureSampler, ex_TextureCoordinates ) * 255.0f;
if( interColor.x == 0.0f )
interColor.x = 255.0f;
out_Color = uvec4( interColor );
}

The final screen is all red, as expected.

Thus, reading from the uniform sampler2D theTextureSampler is giving me back all zeros when it should be giving me back all ones.

I am positive the texture (A) is texture complete, and it is active on texture stage 0 and the uniform is set. In fact, the way I make sure texture A is correct is to use the same shader code but slightly modified: the output is to the screen so the out_Color is a vec4 instead of a uvec4, thus, sampling texture A is working.

Is there something wrong with my drivers? Or is it something wrong with my code elsewhere? Or is it possible that this usage is incorrect: ie: Should I be able to sample from a normalized texture in the same shader that I output to an integer texture.

Thank you so much for your time and any input =)

mobeen
04-08-2011, 01:18 PM
R u using linear filtering? If so use nearest filtering instead for the theTextureSampler texture and let us know if u still get the same result.

Alfonse Reinheart
04-08-2011, 02:22 PM
And then render B to the screen the screen is all black.

It's an unsigned integral texture format. It's not displayable. So how are you displaying it?

jpack
04-08-2011, 03:03 PM
R u using linear filtering? If so use nearest filtering instead for the theTextureSampler texture and let us know if u still get the same result.

Both textures are using nearest filtering. Doesn't work.




It's an unsigned integral texture format. It's not displayable. So how are you displaying it?

By texturing a screen aligned quad using the values stored in it.

Fragment Shader:


#version 330 core

in vec2 ex_TextureCoordinates;
layout( location = 0 ) out vec4 out_Color;

uniform usampler2D uTextureSampler;

void main()
{
vec4 interColor = vec4(texture( uTextureSampler, ex_TextureCoordinates ) );

out_Color = interColor / 255.0f;
}



This code samples the uint values in the texture, changes them to float, and normalizes to [0,1], and writes that result to the frame buffer (the back buffer in this case as we are talking about the screen). This works... I've done it to many integer textures, always with the expected results.

The previous point is moot anyways since doing a glGetTexImage on the unsigned integer texture also results in all zeros after rendering into it using texture A (a GL_RGBA8 texture) as the source sampler. Whereas, if I don't sample texture A and just output some constant color (or even using the texture coordinates) then glGetTexImage gives me the color I output.

jpack
04-11-2011, 06:49 PM
Solved: Seems I didn't check well enough to see that the current active texture was incorrect and that the "good" results I was getting before were a fluke. Hey, apparently sometimes you've got to take a break before checking 15 times if something is correct =)

Thank you to all who took the time to read and/or answer.