首页 文章

Qt OpenGL纹理透明度问题

提问于
浏览
-1

我正在研究Qt中的一个查看器,以在顶部显示带有线条或文本的图像 . 我在几个图层上组织了图像,线条和文本,每个图层都是GL_QUADS . 如果我在z中堆叠图像然后在线上绘制一个图层,那么它们都按预期工作 . 但我想在其他几个层 at the same z 上绘制更多的线作为第一个线层,这就是结果:lines layers conflict .

我没有破坏底层图像 . 此外,如果我绘制另一个图层 at the same z 作为线图层但有一些文本,这是结果:text layer issue .

文本图层在所有不连续的图层中创建一个洞,您可以看到背景 .

线条和文本在QImage上使用QPainter绘制:

m_img = new QImage(&m_buffer[0], width, height, QImage::Format_RGBA8888);
m_img->fill(Qt::transparent);

QPen pen(color);
pen.setWidth(2);
m_painter.begin(m_img);
m_painter.setRenderHints(QPainter::Antialiasing, true);
m_painter.setPen(pen);
m_painter.drawLines(lines);
m_painter.end();

QFont font;
int font_size = font.pointSize() * scale;
if (font_size > 0) { font.setPointSize(font_size); }
QPen pen(color);
m_painter.begin(m_img);
m_painter.setRenderHints(QPainter::Antialiasing, true);
m_painter.setFont(font);
m_painter.setPen(pen);
for(int index = 0; index < messages.size(); index++)
    m_painter.drawText(positions.at(index), messages.at(index));
m_painter.end();

和纹理:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->width(), d->height(), 0, GL_RGBA,  GL_UNSIGNED_BYTE, d->data());

这是我的纹理设置():

GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST/*GL_LINEAR*/);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST/*GL_LINEAR*/);
opengl_error_check(__FILE__, __LINE__);

这是我的initializeGL():

glClearColor(0.0, 0.25, 0.5, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_MULTISAMPLE);
glEnable(GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glShadeModel(GL_FLAT);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

最后我在QGLWidget中设置了QGLFormat(QGL :: AlphaChannel) .

我知道在同一个z上使用重叠平面存在z-fighting的问题,但据我所知,只有重叠纹理不透明才有意义 . 在我的情况下,一些工件可能会被预期在线交叉,但我不明白为什么线消失 . 由于我使用相同的方式绘制线条和文本,我不明白为什么文本层影响图像而不是线条 .

最后一点:我在glTexImage2D()之前的所有纹理中都打印了像素值,并且值是预期的 .

我很确定有一些明显的错误,有人能指出我错在哪里吗?

1 回答

  • 1

    OpenGL的工作原理是“画家” . 除非您使用Z-ordering(又名深度测试),否则最后绘制的内容将在顶部绘制 . 它就像墙上的泼漆一样,因此就是这个词 . Nota bene:默认情况下,深度测试是关闭的,一般情况下,它会降低渲染速度 .

    如果使用Z排序,OpenGL将"hide"片段落入"window space"(颜色缓冲区)的区域,其中已存在具有更大Z值的"paint" . 因此,OpenGL中没有基于深度的"automatic"透明度: to emulate transparency you must paint things in proper order, with proper blending mode. 如果对象相交或自相交,这可能证明是有问题的 . 使用透明度和阴影创建复杂场景需要使用称为延迟渲染的技术 .

    如果你使用相同的Z进行绘制,结果又取决于混合,如果颜色是实心的,你只需要重新绘制已经存在的内容,就像深度测试关闭一样 .

    PS . 没有足够的关于文本问题的数据,我没有看到任何文本,但看起来你在OpenGL的输出上绘画 . 哪个小部件是,QGLWidget或QOpenGLWindget?事实上,这两个源写入单独的传递,并且Qt使用平台依赖性手段绘制字体,因此文本可能被覆盖?不建议在OpenGL中使用Qt的painter输出,您可能需要考虑使用库在OpenGL中输出文本 .

相关问题