PDA

View Full Version : Textures in glsl



chlorinedreams
12-01-2010, 10:34 PM
Hello,
I am trying to accumulate optical flow vectors per-pixel in a RGBAFP16 texture by adding a vector from another texture. The problem is that no matter what I do, the texture bound to GL_TEXTURE1_ARB always returns 0.

In the code below if I set the OpticalFlowGLTexture in GL_TEXTURE0_ARB, then that is what is rendered. If I set AdvectionGLTexture, then that is what is rendered.

Any ideas?

//************** C++ Code ************************************

glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, AdvectionGLTexture);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);

glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, OpticalFlowGLTexture);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);



PainterlyRenderingMipMapRTT[CurrentMovementRTT]->PushRenderTargets();

for( CDUInt32 i = 0; i < NumMipMaps-1; i++ )
{

AdvectionShader->SetActive( CDTRUE );

CDInt32 Tex1 = glGetUniformLocationARB(GLShaderHandle, "OpticalFlowTexture");
CDInt32 Tex0 = glGetUniformLocationARB(GLShaderHandle, "AdvectionTexture");

glUniform1iARB( Tex0, 0 );
glUniform1iARB( Tex1, 1 );

PainterlyRenderingMipMapRTT[CurrentMovementRTT]->GenerateMipmaps( 0, i, i, StrokeDataFunctor );

AdvectionShader->SetActive( CDFALSE );
glFinish();
}



//************** glsl fragment shader *************************
uniform sampler2D AdvectionTexture; // Advection
uniform sampler2D OpticalFlowTexture; // Optical flow


vec2 UnpackOpticalFlow( in vec2 OFV, in float Mag )
{
const vec2 One = vec2( 1.0, 1.0 );
float S = pow( 2.0, Mag * 32.0 )/1024.0;
return (OFV.xy * 2.0 - One) * S;
}

// SCALARVAL is 2.0^MipLevel
// INVSCALEVAL is 1.0/SCALARVAL

void main( void )
{
vec2 Scalar = vec2( SCALARVAL, SCALARVAL );
vec2 InvScale = vec2( INVSCALEVAL, INVSCALEVAL );

vec2 SuperTextureCoordinate = gl_TexCoord[0].st * Scalar;

vec2 ResetThreshold = InvScale;

const vec2 UVLow = vec2( 0.0002, 0.0002 );
const vec2 UVHi = vec2( 0.9999, 0.9999 );

vec4 PreviousPixelAdvections;
// PreviousPixelAdvections = texture2DLod( AdvectionTexture, clamp( SuperTextureCoordinate, UVLow, UVHi ), float( LODLEVEL ) );
PreviousPixelAdvections = texture2DLod( AdvectionTexture, SuperTextureCoordinate, float( LODLEVEL ) );

vec4 CurrentFlows;
// CurrentFlows = texture2DLod( OpticalFlowTexture, SuperTextureCoordinate, float( LODLEVEL ) );
CurrentFlows = texture2DLod( OpticalFlowTexture, SuperTextureCoordinate, float( LODLEVEL ) );

vec2 OpticalFlowVec = UnpackOpticalFlow( CurrentFlows.xy, CurrentFlows.z );

vec2 CurrentResult = PreviousPixelAdvections.xy;
vec2 CurrentSecondResult = PreviousPixelAdvections.zw;

if( (abs( CurrentResult.x ) >= abs( ResetThreshold.x )) || (abs( CurrentResult.y ) >= abs( ResetThreshold.y )) )
{
CurrentResult = CurrentSecondResult;
CurrentSecondResult = vec2( 0.0, 0.0 );
}
else
{
CurrentResult = CurrentResult + OpticalFlowVec;
}

CurrentSecondResult = OpticalFlowVec.xy + 0.000000001 * CurrentResult;

gl_FragData[0] = vec4( CurrentResult.x, CurrentResult.y, CurrentSecondResult.x, CurrentSecondResult.y );
}

chlorinedreams
12-01-2010, 10:36 PM
Oh I forgot to mention that PainterlyRenderingMipMapRTT are RGBA16f textures and ping-pong, writing to Current and reading from Previous.

BionicBytes
12-02-2010, 07:50 AM
What are the values of the getuniformlocation calls?

chlorinedreams
12-02-2010, 10:53 AM
AdvectionTexture returns 0
OpticalFlowTexture returns 1

I am also checking for errors when compiling the shaders.

chlorinedreams
12-02-2010, 12:56 PM
The problem is that whatever sampler is bound to GL_TEXTURE1 always returns vec4( 0.0, 0.0, 0.0, 0.0 ) on the texture2D(...) call.

If the advection texture is bound to GL_TEXTURE1 then the optical flow texture is the result (of the CurrentResult = CurrentResult (0) + OpticalFlowVec; call)

If the OpticalFlowTexture is bound to GL_TEXTURE1 then the decompression does a (0*2-1)/1024 resulting in a consistent -1/1024 value for xy accumulated to the output.

chlorinedreams
12-06-2010, 01:41 PM
Ok, I believe I have figured this out. While I was setting textures 0 and 1 in the application, my render-to-texture library was resetting texture 0. I guess that setting texture N invalidates textures N+1...?

I guess this means that I have to break encapsulation just a bit to allow the intended textures to be set in the correct order: 0->1->2->...->N

mhagain
12-06-2010, 04:16 PM
Ok, I believe I have figured this out. While I was setting textures 0 and 1 in the application, my render-to-texture library was resetting texture 0. I guess that setting texture N invalidates textures N+1...?
It shouldn't; I've often set textures in reverse or mixed-up order (GL_TEXTURE1, GL_TEXTURE0, GL_TEXTURE2 for example) with no ill effects. More likely to be a bug in your library. Otherwise maybe try setting your uniforms before your glBindTexture calls?