使用多个 QGLWidgets (QT) 来显示(相同的)3D 纹理?
Using multiple QGLWidgets (QT) to display (same) 3D Texture?
我有一个关于 OpenGL 和 Qt 的问题。到目前为止,我还没有使用过 OpenGL,而是从其他人那里获得了代码。可惜我不能问他。
我创建了多个 CTAGLWidgets(参考 Constructor)来显示不同视角(矢状、轴向、冠状)的 CT 图像数据。因此,我希望所有 OpenGL 小部件都加载创建的 3D 纹理(请参阅源代码的最后一部分)。到目前为止,只有最后一个小部件加载纹理,其他小部件一直显示黑屏。
如有必要,我可以提供额外的代码(着色器,...),但我想我添加了所有相关部分。
我需要更改什么?或者你能提供一个可以帮助我解决问题的link吗?任何事情都会有所帮助!
.cpp 文件的代码片段:
CTAGLWidget::CTAGLWidget(QWidget* parent ) : QGLWidget (parent) {
}
void CTAGLWidget::initShaders() {
setlocale(LC_NUMERIC, "C");
if (!program.addShaderFromSourceFile(QGLShader::Vertex, ":/vshader.glsl"))
close();
if (!program.addShaderFromSourceFile(QGLShader::Fragment, ":/fshader.glsl"))
close();
if (!program.link())
close();
if (!program.bind())
close();
setlocale(LC_ALL, "");
}
void CTAGLWidget::initializeGL() {
initializeGLFunctions();
initShaders();
qglClearColor(Qt::black);
zoom = 1.0;
qNow = QQuaternion(1,0,0,0);
min = QVector3D( 1.0, 1.0, 1.0);
max = QVector3D(-1.0,-1.0,-1.0);
center = QVector3D(0,0,0);
glGenBuffers(1,&vboQuadId);
std::vector<QVector3D> vertex;
vertex.push_back(QVector3D(-2,-2, 0));
vertex.push_back(QVector3D( 0, 0, 0));
vertex.push_back(QVector3D( 2,-2, 0));
vertex.push_back(QVector3D( 1, 0, 0));
vertex.push_back(QVector3D( 2, 2, 0));
vertex.push_back(QVector3D( 1, 1, 0));
vertex.push_back(QVector3D(-2, 2, 0));
vertex.push_back(QVector3D( 0, 1, 0));
glBindBuffer(GL_ARRAY_BUFFER,vboQuadId);
glBufferData(GL_ARRAY_BUFFER,vertex.size()*sizeof(QVector3D),vertex.data(),GL_STATIC_DRAW);
}
void CTAGLWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT);
QMatrix4x4 P(projection);
P.scale(zoom,zoom,zoom);
modelView.setToIdentity();
modelView.rotate(qNow.conjugate());
modelView.translate(-center);
program.bind();
program.setUniformValue("uPMat", P);
program.setUniformValue("uMVMat", modelView);
program.setUniformValue("uColor", QVector4D(1.0,0.0,0.0,1.0));
glBindBuffer(GL_ARRAY_BUFFER, vboQuadId);
int vertexLocation = program.attributeLocation("a_position");
program.enableAttributeArray(vertexLocation);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE,
2*sizeof(QVector3D), 0);
int texAttribLoc = program.attributeLocation("aTexCoord");
program.enableAttributeArray(texAttribLoc);
glVertexAttribPointer(texAttribLoc, 3, GL_FLOAT, GL_FALSE,
2*sizeof(QVector3D), (const void*) sizeof(QVector3D));
glDrawArrays(GL_QUADS,0,4);
}
这里的 3D 纹理是从 QByteArray 创建的 "texture":
void CTScanMain::setTexture() {
...
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8,
ctAnalyser->x(), ctAnalyser->y(), ctAnalyser->z(),
0, GL_RGB, GL_UNSIGNED_BYTE, texture);
...
}
程序中没有进一步的 OpenGL 调用。
查看 QGLWidget 的构造函数可以找到一个可能的解决方案:
QGLWidget ( QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0 )
将第一个 opengl 小部件对象作为 "shareWidget" 传递使更多小部件共享相同的纹理。
Qt 文档:
"If shareWidget is a valid QGLWidget, this widget will share OpenGL display lists and texture objects with shareWidget."
有人在以下位置提出了类似的问题:
http://qt-project.org/forums/viewthread/8265
我有一个关于 OpenGL 和 Qt 的问题。到目前为止,我还没有使用过 OpenGL,而是从其他人那里获得了代码。可惜我不能问他。
我创建了多个 CTAGLWidgets(参考 Constructor)来显示不同视角(矢状、轴向、冠状)的 CT 图像数据。因此,我希望所有 OpenGL 小部件都加载创建的 3D 纹理(请参阅源代码的最后一部分)。到目前为止,只有最后一个小部件加载纹理,其他小部件一直显示黑屏。
如有必要,我可以提供额外的代码(着色器,...),但我想我添加了所有相关部分。
我需要更改什么?或者你能提供一个可以帮助我解决问题的link吗?任何事情都会有所帮助!
.cpp 文件的代码片段:
CTAGLWidget::CTAGLWidget(QWidget* parent ) : QGLWidget (parent) {
}
void CTAGLWidget::initShaders() {
setlocale(LC_NUMERIC, "C");
if (!program.addShaderFromSourceFile(QGLShader::Vertex, ":/vshader.glsl"))
close();
if (!program.addShaderFromSourceFile(QGLShader::Fragment, ":/fshader.glsl"))
close();
if (!program.link())
close();
if (!program.bind())
close();
setlocale(LC_ALL, "");
}
void CTAGLWidget::initializeGL() {
initializeGLFunctions();
initShaders();
qglClearColor(Qt::black);
zoom = 1.0;
qNow = QQuaternion(1,0,0,0);
min = QVector3D( 1.0, 1.0, 1.0);
max = QVector3D(-1.0,-1.0,-1.0);
center = QVector3D(0,0,0);
glGenBuffers(1,&vboQuadId);
std::vector<QVector3D> vertex;
vertex.push_back(QVector3D(-2,-2, 0));
vertex.push_back(QVector3D( 0, 0, 0));
vertex.push_back(QVector3D( 2,-2, 0));
vertex.push_back(QVector3D( 1, 0, 0));
vertex.push_back(QVector3D( 2, 2, 0));
vertex.push_back(QVector3D( 1, 1, 0));
vertex.push_back(QVector3D(-2, 2, 0));
vertex.push_back(QVector3D( 0, 1, 0));
glBindBuffer(GL_ARRAY_BUFFER,vboQuadId);
glBufferData(GL_ARRAY_BUFFER,vertex.size()*sizeof(QVector3D),vertex.data(),GL_STATIC_DRAW);
}
void CTAGLWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT);
QMatrix4x4 P(projection);
P.scale(zoom,zoom,zoom);
modelView.setToIdentity();
modelView.rotate(qNow.conjugate());
modelView.translate(-center);
program.bind();
program.setUniformValue("uPMat", P);
program.setUniformValue("uMVMat", modelView);
program.setUniformValue("uColor", QVector4D(1.0,0.0,0.0,1.0));
glBindBuffer(GL_ARRAY_BUFFER, vboQuadId);
int vertexLocation = program.attributeLocation("a_position");
program.enableAttributeArray(vertexLocation);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE,
2*sizeof(QVector3D), 0);
int texAttribLoc = program.attributeLocation("aTexCoord");
program.enableAttributeArray(texAttribLoc);
glVertexAttribPointer(texAttribLoc, 3, GL_FLOAT, GL_FALSE,
2*sizeof(QVector3D), (const void*) sizeof(QVector3D));
glDrawArrays(GL_QUADS,0,4);
}
这里的 3D 纹理是从 QByteArray 创建的 "texture":
void CTScanMain::setTexture() {
...
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8,
ctAnalyser->x(), ctAnalyser->y(), ctAnalyser->z(),
0, GL_RGB, GL_UNSIGNED_BYTE, texture);
...
}
程序中没有进一步的 OpenGL 调用。
查看 QGLWidget 的构造函数可以找到一个可能的解决方案:
QGLWidget ( QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0 )
将第一个 opengl 小部件对象作为 "shareWidget" 传递使更多小部件共享相同的纹理。
Qt 文档: "If shareWidget is a valid QGLWidget, this widget will share OpenGL display lists and texture objects with shareWidget."
有人在以下位置提出了类似的问题: http://qt-project.org/forums/viewthread/8265