Important: Please read the Qt Code of Conduct -

Pass a QImage to an opengl GLSL sampler

  • Hello, I am writing a rendering engine and am running into problems with texturing my models

    I have a very simpler shader to test texturing:
    vertex shader:
    @Attribute vec4 Vertex;
    Attribute vec2 texcoords;

    uniform mat4 mvp;

    varying vec2 outTexture;

    void main()
    gl_Position = mvp * Vertex;
    outTexture = texcoords;

    and fragment shader:
    @uniform sampler2D tex;

    varying vec2 outTexture;

    void main()
    vec4 color = texture2D(tex, outTexture);
    gl_FragColor = color;

    I am passing my texture coordinates to the shaders correctly
    My problem is with binding a QImage and sending it to its texture uniform.

    I am using the following code to bind the texture:
    const QString& filename;
    GLuint m_texture;

    QImage image(filename);
    image = image.convertToFormat(QImage::Format_ARGB32);

    glGenTextures(1, &m_texture);
    glBindTexture(GL_TEXTURE_2D, m_texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width(), image.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());


    The shader works and I can pass a uniform to the matrix and attributes to the vertex and texture coordinates, but when I try to send a uniform to the texture the same way as such:
    @effect->setUniformValue(effect->uniformLocation("tex", texture->m_texture));@
    the program crashes with an "access violation reading location" error with glGetError() returning "invalid enumerant"

    Interestingly, when I try running the program without attempting to send the texture to the sampler, the texture is actually appearing on the model. Which makes me think the way I'm binding it has something to do with the legacy texture handling and the texture is being bound to a particular texture address which is being picked up by the shader. This is not the effect I want because I want the programmer to be able to explicitly state at draw time what texture should be passed to the uniform (just as any other uniform is set)

    How can I pass the texture to it's sampler, what do I need to change when binding a texture?

    Thank you

  • Hi,
    I am not used to work with the Qt ShaderProgram environment yet, but here is my guess:

    • it seems that you are passing the texture number generated by

    @glGenTextures(1, &m_texture);@
    i.e. m_texture value, when in fact you need to set what is the texture unit the binded texture will have. You control the texture unit. In this case you must use 0, 1, ... until the number your card supports. For instance, when you bind a texture, you can select in what active texture unit it is placed.

    @glActiveTexture(GL_TEXTURE0 + unit); //This is the number not m_texture@

    That is, the same texture, m_texture, can be in different texture units (0, 1, 2...).
    Also make sure you have selected correct options for bindTexture, to avoid problems with allocation.

  • I don't know if I made myself clear, but if you need further help, just ask.

Log in to reply