[英]Blending 2 QImage in Qt OpenGL with mask
I try to make a transition animation between 2 pages in OpenGL. 我尝试在OpenGL中的2页之间制作过渡动画。 I have 2 QImages objects, tex1 - the current page, tex2 - the next page. 我有2个QImages对象,tex1-当前页面,tex2-下一页。 The mask is the image drawed in OpenGL. 遮罩是在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 ();
The texture colors are always black, tex1 and and tex 2 are valid images. 纹理颜色始终为黑色,tex1和tex 2为有效图像。 The code print in console: tex1 sizes 390 520 tex2 sizes 390 520
控制台中的代码打印: tex1 sizes 390 520 tex2 sizes 390 520
Which is the problem? 这是什么问题?
(... assuming the rest of the code is correct ...), the problem is here: (...假设其余代码正确无误...),问题出在这里:
m_program->setUniformValue (m_tex1_loc, m_tex1); m_program->setUniformValue (m_tex2_loc, m_tex2);
When you want to set some sampler
object in a shader to sample from a certain texture, you don't set its value to the texture object, but to the index of the texture unit that has that texture currently bound to. 当您想要在着色器中设置一些sampler
对象以从某个纹理采样时,您无需将其值设置为该纹理对象,而是将其当前绑定到该纹理的纹理单元的索引设置为。
Since m_tex1
is bound onto the GL_TEXTURE0
texture unit, and mtex2
to GL_TEXTURE1
, then do 由于m_tex1
绑定到GL_TEXTURE0
纹理单元,并且mtex2
到GL_TEXTURE1
,所以执行
m_program->setUniformValue (m_tex1_loc, 0);
m_program->setUniformValue (m_tex2_loc, 1);
If you like more to think in terms of GL_TEXTUREX
enums, subtract GL_TEXTURE0
from them to get the index of the texture unit: 如果您想更多地考虑GL_TEXTUREX
枚举, GL_TEXTURE0
从其中减去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);
Then, to nitpick on the rest: avoid GL_QUADS
(gone in the core profile); 然后,其余部分:避免GL_QUADS
(在核心配置文件中消失); and glEnable(GL_TEXTURE_2D)
has no longer any meaning (it will actually raise an error). glEnable(GL_TEXTURE_2D)
不再具有任何意义(实际上会引发错误)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.