将Qt OpenGL中的2个QImage与掩码混合

时间:2016-03-12 19:11:42

标签: c++ qt opengl-es

我尝试在OpenGL中在2页之间制作过渡动画。我有2个QImages对象,tex1 - 当前页面,tex2 - 下一页。掩码是在OpenGL中绘制的图像。

tex1.load ("tex1.jpg", "JPG");
tex1 = tex1.convertToFormat (QImage::Format_RGB888);
tex2.load ("tex2.jpg", "JPG");
tex2 = tex2.convertToFormat (QImage::Format_RGB888);

if (!m_program) {

    initializeOpenGLFunctions ();

    m_program = new QOpenGLShaderProgram ();
    qDebug () << m_program->addShaderFromSourceCode (QOpenGLShader::Vertex,
                                                     "attribute highp vec4 posAttr;\n"
                                                     "attribute lowp vec4 colAttr;\n"
                                                     "uniform highp mat4 matrix;\n"

                                                     "varying highp vec2 coord;\n"
                                                     "varying lowp vec4 col;\n"

                                                     "void main() {\n"
                                                     "      col = colAttr;\n"
                                                     "      coord = vec2(gl_MultiTexCoord0.xy);\n"
                                                     "      gl_Position = matrix * posAttr;\n"
                                                     "}"
                                                    );
    qDebug () << m_program->addShaderFromSourceCode (QOpenGLShader::Fragment,
                                                     "varying highp vec2 coord;\n"
                                                     "varying lowp vec4 col;\n"

                                                     "uniform sampler2D texx1;\n"
                                                     "uniform sampler2D texx2;\n"

                                                     "void main() {\n"
                                                     "      mediump vec4 texture1Color = texture2D(texx1, coord);\n"
                                                     "      mediump vec4 texture2Color = texture2D(texx2, coord);\n"
                                                     "      gl_FragColor = mix(texture1Color, texture2Color, col);\n"
                                                    );
    qDebug () << m_program->link ();


}
qDebug () << m_program->bind ();

int vert = m_program->attributeLocation ("posAttr");
int cols = m_program->attributeLocation ("colAttr");
int matx = m_program->uniformLocation ("matrix");

m_program->enableAttributeArray (vert);
m_program->enableAttributeArray (cols);


GLfloat vertex [40] = {
    center_x,           current_rgb_top,
    center_x,           current_mono_top,
    current_mono_left,  center_y,
    current_rgb_left,   center_y,

    current_rgb_left,   center_y,
    current_mono_left,  center_y,
    center_x,           current_mono_bottom,
    center_x,           current_rgb_bottom,

    center_x,           current_rgb_bottom,
    center_x,           current_mono_bottom,
    current_mono_right, center_y,
    current_rgb_right,  center_y,

    current_rgb_right,  center_y,
    current_mono_right, center_y,
    center_x,           current_mono_top,
    center_x,           current_rgb_top,

    center_x,           current_mono_top,
    current_mono_right, center_y,
    center_x,           current_mono_bottom,
    current_mono_left,  center_y,
};

QMatrix4x4 matrix;
matrix.ortho (0., viewportSize.width (), viewportSize.height (), 0., -1, 1);

GLuint m_tex1, m_tex2;
glGenTextures (1, &m_tex1);
glBindTexture (GL_TEXTURE_2D, m_tex1);
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex1.width(), tex1.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, tex1.bits());
glBindTexture (GL_TEXTURE_2D, 0);

qDebug() << "tex1 sizes" << tex1.width() << tex1.height();

glGenTextures (1, &m_tex2);
glBindTexture (GL_TEXTURE_2D, m_tex2);
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex2.width(), tex2.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, tex2.bits());
glBindTexture (GL_TEXTURE_2D, 0);

qDebug() << "tex2 sizes" << tex2.width() << tex2.height();

glVertexAttribPointer (vert, 2, GL_FLOAT, GL_FALSE, 0, vertex);
glVertexAttribPointer (cols, 3, GL_FLOAT, GL_FALSE, 0, colors);

m_program->setUniformValue (matx, matrix);

glViewport (0, 0, viewportSize.width (), viewportSize.height () );

glDisable (GL_DEPTH_TEST);
glClearColor (0.5, 0.5, 0.5, 1);

glClear (GL_COLOR_BUFFER_BIT);

glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, m_tex1);


glActiveTexture (GL_TEXTURE1);
glBindTexture (GL_TEXTURE_2D, m_tex2);

GLint m_tex1_loc, m_tex2_loc;

m_tex1_loc = m_program->uniformLocation ("texx1");
m_tex2_loc = m_program->uniformLocation ("texx2");

m_program->setUniformValue (m_tex1_loc, GL_TEXTURE0 - GL_TEXTURE0);
m_program->setUniformValue (m_tex2_loc, GL_TEXTURE1 - GL_TEXTURE0);

glDrawArrays (GL_TRIANGLE_STRIP, 0, 20);

m_program->disableAttributeArray (0);
m_program->disableAttributeArray (1);

m_program->release ();

glEnd ();

纹理颜色始终为黑色,tex1和tex 2为有效图像。控制台中的代码打印: tex1 sizes 390 520 tex2 sizes 390 520

问题出在哪?

1 个答案:

答案 0 :(得分:0)

(...假设其余代码是正确的......),问题在于:

m_program->setUniformValue (m_tex1_loc, m_tex1);
m_program->setUniformValue (m_tex2_loc, m_tex2);

如果要在着色器中设置一些sampler对象以从某个纹理中进行采样,则不要将其值设置为纹理对象,而是设置为 索引具有当前绑定到的纹理的纹理单元

由于m_tex1绑定到GL_TEXTURE0纹理单元,mtex2绑定到GL_TEXTURE1,所以

 m_program->setUniformValue (m_tex1_loc, 0);
 m_program->setUniformValue (m_tex2_loc, 1);

如果您想更多地考虑GL_TEXTUREX枚举,请从中减去GL_TEXTURE0以获取纹理单元的索引

 // same as before. possibly more verbose/explicit
 m_program->setUniformValue (m_tex1_loc, GL_TEXTURE0 - GL_TEXTURE0);
 m_program->setUniformValue (m_tex2_loc, GL_TEXTURE1 - GL_TEXTURE0);

然后,对其余部分进行挑剔:避免GL_QUADS(在核心档案中消失);并且glEnable(GL_TEXTURE_2D)已经没有任何意义(它实际上会引发错误)。