QOpenGLWidget类中的QPainter和OpenGL本机代码



我正在准备一个桌面应用程序来绘制一些2D绘图。我正在使用C++:Qt 5和visual studio 2013。我创建了一个简单的GUI,并将myQOpenGLWidget放入其中。我已经在使用自己的openGl着色器绘制绘图、轴和记号了。一切都很好,现在我想把描述添加到我的轴和记号中,使图形可以进行分析。由于OpenGL本身没有专门的功能来渲染文本,所以我想到使用QPainter对象只是为了将所需的描述添加到已经创建的绘图中。这里的问题开始了。。。

以下是我的QopenGLWidget实现的功能:

void GLWidget::initializeGL() {
initializeOpenGLFunctions();
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
vertexShad = new QOpenGLShader(QOpenGLShader::Vertex);
fragmentShad = new QOpenGLShader(QOpenGLShader::Fragment);
bool flag = vertexShad->compileSourceFile(QString("vs.glsl"));
if (flag) printf("compiled vertex Shadern");
flag = fragmentShad->compileSourceFile(QString("fs.glsl"));
if (flag) printf("compiled fragment Shadern");
flag = program.addShader(vertexShad);
if (flag) printf("linked vertex Shadern");
flag = false;
flag =program.addShader(fragmentShad);
if (flag) printf("linked fragment Shadern");
program.link();
program.bind();
}

paintGL:

void GLWidget::paintGL() {
painter = new QPainter(this);
painter->beginNativePainting();
glViewport(0, 0, this->width(), this->height());
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
drawAxes();
glViewport(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
glScissor(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
glEnable(GL_SCISSOR_TEST);
// here are the functions which use native openGL code
// ...
// disabling openGL settings
glDisable(GL_SCISSOR_TEST);
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glDisable(GL_BLEND);
painter->endNativePainting();
drawTicksValues(); // function that uses QPainter
painter->end();
}

drawTicks值:

void GLWidget::drawTicksValues() {
char * maxText = new char[4];
sprintf(maxText, "%d", maxY);
char * minText = new char[4];
sprintf(minText, "%d", minY);
painter->drawText(0, MARGIN, QString(maxText));
painter->drawText(0, height() - MARGIN, QString(minText));
painter->drawText(MARGIN, height() - MARGIN + 20, QString("0"));
painter->drawText(width() - MARGIN, height() - MARGIN + 20, QString(100));
}

main:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSurfaceFormat  format;
format.setSamples(4);
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
QSurfaceFormat::setDefaultFormat(format);
SymmGaitModels w;
w.show();
return a.exec();
}

不幸的是,当我用未注释的QPainter部分运行代码时,轴和绘图被清除,只显示我用QPainter绘制的数字。但如果我评论QPainter部分,则绘图和轴是正常绘制的。有什么建议我可以用QPainter将文本添加到我的绘图中,而不是清除它吗?

我终于把事情做好了。

首先,我必须更改和设置格式(你必须在显示小部件之前更改它),例如在主功能中,在我的应用程序显示之前

main:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SymmGaitModels w;
// GLWidget is my implemantation of QOpenGLWidget
GLWidget* gl = w.findChild<GLWidget*>("OpenGLWidget");
QSurfaceFormat  format;
//format.setSamples(4);
//format.setDepthBufferSize(24);
//format.setStencilBufferSize(8);
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile);
QSurfaceFormat::setDefaultFormat(format);
gl->setFormat(format);
w.show();
return a.exec();
}

此外,我不得不在之间移动我的所有openGL函数(甚至启用和禁用诸如blend、point_sprite等,这导致了我的问题)

QPainter-> beginNativePainting()
...
QPainter->endNativePainting();

我必须实现paintEvent函数。我只是把paintGL()表达式放在那里。现在我的函数是这样的:

void GLWidget::initializeGL() {
printf("autoFILL: %dn",this->autoFillBackground());
initializeOpenGLFunctions(); // this function has to stay in initializeGL
// commented functions below has to be removed and put after beginNativePainting
//glEnable(GL_POINT_SPRITE);
//glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// shaders may be compiled and added here, but program has to be linked and built after beginNativePainting()
vertexShad = new QOpenGLShader(QOpenGLShader::Vertex);
fragmentShad = new QOpenGLShader(QOpenGLShader::Fragment);
bool flag = vertexShad->compileSourceFile(QString("vs.glsl"));
//bool flag = vertexShad->compileSourceCode(vertexShadSrc);
if (flag) printf("compiled vertex Shadern");
flag = fragmentShad->compileSourceFile(QString("fs.glsl"));
//flag = fragmentShad->compileSourceCode(fragmentShadSrc);
if (flag) printf("compiled fragment Shadern");
flag = program.addShader(vertexShad);
if (flag) printf("linked vertex Shadern");
flag = false;
flag =program.addShader(fragmentShad);
if (flag) printf("linked fragment Shadern");
}
void GLWidget::paintEvent(QPaintEvent *e) {
paintGL(); // still this, widget has to be now refreshed by widget->update()
}
void GLWidget::paintGL() {
painter = new QPainter(this);
painter->beginNativePainting();
//
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
program.link();
program.bind();
//
glViewport(0, 0, this->width(), this->height());
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
drawAxes();
glViewport(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
glScissor(MARGIN, MARGIN, this->width() - MARGIN * 2, this->height() - MARGIN * 2);
glEnable(GL_SCISSOR_TEST);
// methods using native openGL functions here
glDisable(GL_SCISSOR_TEST);
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glDisable(GL_BLEND);
program.disconnect();
painter->endNativePainting();
drawTicksValues();
painter->end();
}

添加paintEvent实现后,现在必须使用widget->update()刷新openGL小部件。

希望它能对其他正在努力使用QPainter和原生openGL函数的人有所帮助,因为Qt-doc在这个话题上似乎有点肤浅。

谢谢!Adam

相关内容

  • 没有找到相关文章

最新更新