Texture unit problem...

Hi i try to use shader to display frame (YUV in 3 plans), i use epoxy and GtkGLArea.
my GC (intel iris) support max texture unit : 8

My problem is that on my shader the last created texture seem to be use for all sampler ?

  • if i create only the first one (Y 320x240 8 bits), my shader display it (Y) as expected.
  • if i create 2 textures (add U 160x240 8 bits), my shader display it (U) in place of first one (Y).
  • if i create 3 textures (add V 160x240 8 bits), my shader display it (V) in place of first one (Y).

For my test, i modify the shader to display only Y (i apply a factor of 0.00001 to U & V to ensure that shader compiler do not remove associated sampler…

I remove all error check to simply the code.

Thanks for your help i send all my weekend on this problem…

WCdr

I create 3 textures (one 8 bits channel) like this :
guint id {};
glGenTextures ( 1, &id);
glBindTexture ( GL_TEXTURE_2D, id );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
glTexImage2D ( GL_TEXTURE_2D, 0, GL_RED, sizeWidth, sizeHeight, 0, GL_RED, GL_UNSIGNED_BYTE, pvData );
=> I check image data it’s ok (dim & bitmap)
=> I store each id on my texture object.

I get shader sampler like this :
Load vertex shader
Load fragment shader
Link program
m_uiSamplerIndexY = glGetUniformLocation ( scpProgram, “Texture0” );
m_uiSamplerIndexU = glGetUniformLocation ( scpProgram, “Texture1” );
m_uiSamplerIndexV = glGetUniformLocation ( scpProgram, “Texture2” );
Detach vertex & fragment.
=> I check all index, there’s valid : 1, 2 & 3

I render like this :
glClearColor ( 0.0F, 0.0F, 0.0F, 1.0F );
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glActiveTexture ( GL_TEXTURE0 );
m_oTexture.Bind ();
glUniform1i ( m_uiSamplerIndexY, 0 );

glActiveTexture ( GL_TEXTURE1 );
m_oTextureU.Bind ();
glUniform1i ( m_uiSamplerIndexU, 1 );

glActiveTexture ( GL_TEXTURE2 );
m_oTextureV.Bind ();
glUniform1i ( m_uiSamplerIndexV, 2 );

glUniformMatrix4fv ( m_uiMatrixIndex, 1, GL_FALSE, m_matrixTransform.data ());
glBindVertexArray ( m_uiVertexIndex );
glDrawArrays ( GL_TRIANGLE_STRIP, 0, m_arrayVertexDesc.size ());

Vertex shader.
#version 330 core

in vec2 posVertex;
in vec2 uvVertex;

uniform mat4 matrixTransform;

smooth out vec2 coordTexture;

void main()
{
coordTexture = uvVertex;
gl_Position = matrixTransform * vec4 ( posVertex, 0.0, 1.0 );
}

#version 330 core

uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;

smooth in vec2 coordTexture;

void main ()
{
float fY = texture2D ( Texture0, coordTexture ).r;
float fU = texture2D ( Texture1, coordTexture ).r;
float fV = texture2D ( Texture2, coordTexture ).r;

float fPixel = fY + ( fU + fV ) * 0.00001;

gl_FragColor = vec4 ( fPixel, fPixel, fPixel, 1.0 );

}

There’s nothing wrong with the code you posted, so the problem is somewhere in the code which wasn’t posted.

One thing I can see is that you don’t seem to have a glUseProgram call, but maybe that’s in the code you haven’t posted?

I put it just after glClear

Thanks for your help…

Thanks, but there’s no more opengl code… maybe be an other bugs on GtkGLArea (gtkmm 3.18.0, gtk 3.18.9), i already solve two :
1 - Inheritance issue, i solve it using composition.
2 - Destruction issue, i intercept application close to call opengl release code…
or an issue in my c++14 encapsulation, i already remove camera code using dumped raw frame (checked with external program viewer)

I plan to write a separate program using pure xcb & glx without any encapsulation in pure C instead…

Thanks for your help…

float fY = texture2D ( Texture0, coordTexture ).r;

texture2D is deprecated in version 330 core. Use texture instead:

float fY = texture ( Texture0, coordTexture ).r;

Probability is that your shaders failed to compile and (I guess) you’re not doing error checking.

[QUOTE=mhagain;1283031]

float fY = texture2D ( Texture0, coordTexture ).r;

texture2D is deprecated in version 330 core. Use texture instead:

float fY = texture ( Texture0, coordTexture ).r;

Probability is that your shaders failed to compile and (I guess) you’re not doing error checking.[/QUOTE]

My problem is not that shader do not compile (or link), i check error and every is ok, my problem is that last loaded texture seems to override previous one…

I replace texture2D by texture, no change…

Thanks for you answer,

[QUOTE=wizardcoder;1283032]My problem is not that shader do not compile (or link), i check error and every is ok, my problem is that last loaded texture seems to override previous one…

I replace texture2D by texture, no change…

Thanks for you answer,[/QUOTE]

OK.

The reason why I’m saying this is that the behaviour you’re reporting is consistent with shaders failing to compile or link; i.e as if glUseProgram (0) were called, or as if glUseProgram with a valid program object name were never called; or consistent with using the old fixed pipeline with GL_REPLACE mode in all of your texture units.

[QUOTE=mhagain;1283033]OK.

The reason why I’m saying this is that the behaviour you’re reporting is consistent with shaders failing to compile or link; i.e as if glUseProgram (0) were called, or as if glUseProgram with a valid program object name were never called; or consistent with using the old fixed pipeline with GL_REPLACE mode in all of your texture units.[/QUOTE]

Good information, i don’t notice this information, i am a newbie with OpenGL, normally y use DirectX with is object api, it’s more natural for me… the switch to Linux with all is library is hard :slight_smile:

Thanks for your answer