【发布时间】:2020-07-18 18:19:52
【问题描述】:
从QOpenGLWidget 和QOpenGLFunctions_4_5_Core 继承时,如果我在调用update() 之前调用glActiveTexture(GL_TEXTURE1)(或任何其他非零数字),则屏幕上的纹理将完全显示为黑色。
相关代码sn-ps:
void OpenGLWidget::paintGL() {
if (fp) {
// First paint seems to always happen before the first update
qDebug() << "First Paint";
fp = false;
}
glClear(GL_COLOR_BUFFER_BIT);
unsigned int tex;
glGenTextures(1, &tex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
QImage img = QImage("textures/awesomeface.png").convertToFormat(QImage::Format_RGBA8888).mirrored();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
glTextureParameteri(tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteri(tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTextureParameteri(tex, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTextureParameteri(tex, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glUseProgram(frame_shader.get_id());
glBindVertexArray(frame_vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
// Clean up
glDeleteTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(0);
// This doesn't cause the textures to be black
glActiveTexture(GL_TEXTURE1);
}
还有mainloop函数:
void OpenGLWidget::main_loop() {
if (fu) {
qDebug() << "First Update";
fu = false;
}
// This causes the textures to completely black
// Change GL_TEXTURE1 to GL_TEXTURE0 (or get rid of it glActiveTexture
// completely) and textures will work once again
glActiveTexture(GL_TEXTURE1);
update();
}
着色器仍然可以绘制到屏幕上;如果我在片段着色器中设置纯色,颜色将正确显示到屏幕上。似乎只有用户制作的纹理完全变黑了。
我没有收到任何 OpenGL 错误。
完整的 MRE 可以在以下位置找到:https://github.com/Luminic/MRE_QOpenGLWidget_glActiveTexture_GL_TEXTURE1_before_update
有谁知道是什么导致了这种奇怪的行为?
【问题讨论】:
-
你所做的在这里是未定义的行为,引用 QtOpenGLWidget 的文档:“当调用
paintGL()、resizeGL()或initializeGL()时,你的小部件的 OpenGL 渲染上下文是当前的。如果你需要要从其他地方调用标准的 OpenGL API 函数(例如,在您的小部件的构造函数或您自己的绘图函数中),您必须先调用makeCurrent()。”不确定这将如何产生此处观察到的效果,但请注意 QT 在底层保留了一个渲染到纹理机制以渲染到窗口,您可能会在那里搞砸一些事情。