1
votes

I am writing my student project and have kinda problem.

My task is to load two textures with the same size (image and grayscale mask) and then apply a blur filter with convolution kernel based on grayscale mask.

I need to provide user interface so I've choosen qt because of its intergration with opengl. Unfortunately I am not very familiar with shaders and opengl etc, so I'm experiencing problems due to huge knowledge lacks.

My idea was to draw simple plane and apply two textures on it, a image and mask, and then in shader code, calculate new pixel value depending on 3x3 kernel built with corresponding pixels in mask image.

Unfortunately, im having problem with having two textures in shader, and completely don't know how to do it.

I found something like this over the network, but it didn't work.


        // initializeGL (texture1,2 and t1,t2 are private GLuint

    texture1 = bindTexture(data);
    texture2 = bindTexture(mask);

    program = new QGLShaderProgram();


    QGLShader *v = new QGLShader(QGLShader::Vertex);
    v->compileSourceFile("vertex.vert");
    v->shaderId();
    QGLShader *f = new QGLShader(QGLShader::Fragment);
    f->compileSourceFile("texture.frag");

    program->addShader(v);
    program->addShader(f);
    program->link();
    program->bind();

    t1  = glGetUniformLocation(v->shaderId(), "Texture0");
    t2 = glGetUniformLocation(v->shaderId(), "Texture1");

and then in paintGL start with


    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture1);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texture2);

    glUniform1i(t1, 0);
    glUniform1i(t2, 1);

    glBegin(GL_QUADS); .... drawing

where the fragment shader code starts with uniform variable declaration as


    uniform sampler2D Texture0;
    uniform sampler2D Texture1;

Can someone tell me what is wrong here, or where I can found proper yet quick knowlegde how to achieve applying two textures in shader?

Thank you in advance.

1

1 Answers

3
votes

glGetUniformLocation (...) operates on linked GLSL programs, not shaders.

You might think that since uniforms appear in individual shaders they are specific to a particular shader object, but that's not the case at all. In fact, GLSL uniforms are not even assigned locations until all stages of a GLSL program (vertex, fragment, geometry, etc.) are linked together. Uniforms that do not affect the final output are eliminated and have no location (glGetUniformLocation (...) returns -1).

What you need to do to fix your problem is replace the following lines:

t1  = glGetUniformLocation(v->shaderId(), "Texture0");
t2 = glGetUniformLocation(v->shaderId(), "Texture1");

With this:

t1  = glGetUniformLocation(program->programId(), "Texture0");
t2 = glGetUniformLocation(program->programId(), "Texture1");