Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Multi Textures VBO shaders

  1. #1
    Junior Member Newbie
    Join Date
    Nov 2010
    Posts
    26

    Multi Textures VBO shaders

    Hi,

    I'm using 3rd party that provides 2d and 3d views.
    In both of them i am doing my drawing in pure OpenGL commands.

    And now the problem:
    I'm drawing quads with textures, and i'm doing it using VBO and shaders.

    In the data arrays I'm providing for every vertex an attribute which is the texture number,
    and according to this number i'm fetching the right sampler2D in the fragment shader.
    It is working very good in 2D.

    Application code
    Code :
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, intTexID1);
    glActiveTexture(GL_TEXTURE0 + 1);
    glBindTexture(GL_TEXTURE_2D, intTexID2);
     
    glActiveTexture(GL_TEXTURE0); // resetting the active texture back
     
    glUniform1iv(UniformTextureLoc, new float[]{ 0, 1 });
    Shader code
    Code :
    varying vec4 v_texture_color;
    varying float v_texture_id; // The attribute from the vertex
    uniform sampler2D u_textures[10];
     
    void main(void)
    {
      gl_FragColor = v_texture_color * texture2D(u_textures[v_texture_id], gl_TexCoord[0].xy);
    }

    In 3D, it is working (after allot of fixes) but weird problem occurs.

    I've attached a screen preview of the problem. There are 2 quads. each has different textures.

    It's look like the second texture is acting weird (the green). every movement of the camera it's showing something else, but its mixing the textures - It's like he is using some of the first texture also sometimes.

    I've had few problems with this 3rd party before, but I found my mistakes (like not setting back the active texture to GL_TEXTURE0, or reset the binned buffer glBindBuffer(GL_ARRAY_BUFFER, 0)).

    The thing is that it is working on 2D. so the 3rd party must enable\disable something that i'm not familiar with.

    Is it familiar to anyone ? any ideas ?

  2. #2
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,171

    Re: Multi Textures VBO shaders

    varying vec4 v_texture_color;
    varying float v_texture_id; // The attribute from the vertex
    uniform sampler2D u_textures[10];

    void main(void)
    {
    gl_FragColor = v_texture_color * texture2D(u_textures[v_texture_id], gl_TexCoord[0].xy);
    }
    I can't way that this is the actual problem, but the sampler array is an array of integers. You have supplied a float and it is being interpolated by the fragment shader.

    perhaps try setting:
    varying float v_texture_id;
    to:
    flat varying float v_texture_id;
    ...in both the VS and FS

    and in the FS

    int lookup = int (v_texture_id); //cast as integer

    gl_FragColor = v_texture_color * texture2D(u_textures[lookup], gl_TexCoord[0].xy);

  3. #3
    Junior Member Newbie
    Join Date
    Nov 2010
    Posts
    26

    Re: Multi Textures VBO shaders

    The float array was my mistake - I just wanted to simplify my code.. It is int array in real. my bad.

    I've tried the flat modifier, but didn't quiet made it work. because it always threw compilation error.

    I've Tried the int casting of the v_texture_id, and it didn't work.
    although it gave me an angle to solve it. I've thought that maybe this varying is not an exact values like i sent it - such as 0 or 1 (maybe like 0.000001 and 0.999999) - so i just round the value.. and boom. works great.

    still don't know why it is working like this (Do you ?) but what the hack. It works great now. It haven't harm the performances due to the round method. so.. great.

    I've attached the result image just for fun.

    Thanks very much for the help, and the new angle

  4. #4
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,716

    Re: Multi Textures VBO shaders

    Samplers are special types in OpenGL. Though they are technically uniforms and are treated as such by the API, you can't really treat them like any old uniform.

    Arrays of samplers are highly restricted. In particular, unless you're on GLSL 4.10 hardware or better, the index you use to access an array of samplers must be a compile-time constant. A varying value isn't a compile-time constant. Even on 4.10+ hardware, it needs to be "dynamically uniform", which means the value must be the same for all primitives for any one triangle being rendered. Hence the need for `flat`.

    If you're breaking these rules and it appears to work, appearances can be deceiving. Porting such rule violating code to other hardware may fail spectacularly.

  5. #5
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,171

    Re: Multi Textures VBO shaders

    I agree with Alfonso. Sampler arrays are an oddity in GLSL and you really do need to use the flat keyword for your varyings.
    Perhaps the compile error is due to too low a version number for the GLSL shaders.
    Have you tried adding the following to both the VS and FS:

    #version 150 compatibility

    See if that makes a difference (using GLSL 150 = GL 3.2) when you use the shader code I posted.

  6. #6
    Junior Member Newbie
    Join Date
    Nov 2010
    Posts
    26

    Re: Multi Textures VBO shaders

    It was the version indeed, few adjustments and it works like you said, without using round method.

    About the arrays, let me get you guys straight. You're suggestion is not to use more then one texture in one draw Array ?

    Is there any other way to do what i wishes ? without sampler array.

  7. #7
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,171

    Re: Multi Textures VBO shaders

    You're suggestion is not to use more then one texture in one draw Array
    Definately not. Batch as much as you can, where you can.
    Is there any other way to do what i wishes ? without sampler array
    Perhaps try Sampler3D or sampler2DArray in your shader. If all the textures have the same dimension and bit depth, then either of these is good.
    Note sampler2DArray is not the same thing as you had originally posted which was "uniform sampler2D u_textures[10];"
    That is a uniform array of sampler2D - not the same thing.

  8. #8
    Junior Member Regular Contributor Kopelrativ's Avatar
    Join Date
    Apr 2011
    Posts
    212

    Re: Multi Textures VBO shaders

    There is the technique of using a texture atlas. That is, you create one big texture with all your textures in it.

    This can also be implemented using a GL_TEXTURE_2D_ARRAY.

  9. #9
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,171

    Re: Multi Textures VBO shaders

    Just to be clear.
    Sampler2DArray is from the extension GL_TEXTURE_2D_ARRAY.
    To use the new sampler type you need to enable it in the shader:
    #extension GL_EXT_texture_array : enable

    You could use an atlas as suggested. For this you would need to provide different u,v texture coordinates per vertex to sample from the atlas texture. You don't need Sampler2DArray for this as just a single texture is required.

  10. #10
    Junior Member Regular Contributor Kopelrativ's Avatar
    Join Date
    Apr 2011
    Posts
    212

    Re: Multi Textures VBO shaders

    Bionic: I started to type my answer before your had arrived, that is why I repeat what you said.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •