QOpenGLWidget QPainter::drawRect 只画四个箭头
Posted
技术标签:
【中文标题】QOpenGLWidget QPainter::drawRect 只画四个箭头【英文标题】:QOpenGLWidget QPainter::drawRect only draws four arrows 【发布时间】:2016-08-26 16:47:46 【问题描述】:我现在正在尝试对我创建的 QOpenGLWidget 进行文本/图形覆盖。正如你所看到的,我已经把 3D 压得很紧,但是使用 QPainter 的 2D 覆盖不能正常工作。使用 QPainter 的 drawRect 函数,我希望看到一个矩形。相反,我得到了四个箭头。
相关代码如下:
main.cpp
QApplication a(argc, argv);
QSurfaceFormat format;
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile);
QSurfaceFormat::setDefaultFormat(format);
HSIOpenGLQuadViewWidget qvwidget;
qvwidget.setFormat(format);
qvwidget.init();
qvwidget.addPoint(QVector3D(-1, 1, 1), Qt::red);
qvwidget.addPoint(QVector3D( 1, 1, 1), Qt::red);
qvwidget.addPoint(QVector3D( 1, -1, 1), Qt::red);
qvwidget.addPoint(QVector3D(-1, -1, 1), Qt::red);
qvwidget.addPoint(QVector3D( 0, 0, 0), Qt::red);
qvwidget.addPoint(QVector3D(-1, 1, -1), Qt::red);
qvwidget.addPoint(QVector3D( 1, 1, -1), Qt::red);
qvwidget.addPoint(QVector3D( 1, -1, -1), Qt::red);
qvwidget.addPoint(QVector3D(-1, -1, -1), Qt::red);
qvwidget.generateSphere(0.5);
qvwidget.show();
return a.exec();
MyQOpenGLWidget.cpp
void HSIOpenGLQuadViewWidget::initializeGL()
// Required by Qt
initializeOpenGLFunctions();
// Creates a 24 bit depth mask
glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width(), height());
// Sets the OpenGL screen clear color
glClearColor(0, 0, 0, 0);
glEnable(GL_POLYGON_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
// Enables face culling
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glColorMaterial(GL_FRONT, GL_SPECULAR);
// Somewhere in the initialization part of your program…
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_SMOOTH);
// Create light components
//GLfloat ambientLight[] = 0.2f, 0.2f, 0.2f, 1.0f ;
GLfloat ambientLight[] = 2.0f, 2.0f, 2.0f, 1.0f ;
GLfloat diffuseLight[] = 0.8f, 0.8f, 0.8f, 1.0f ;
GLfloat specularLight[] = 0.5f, 0.5f, 0.5f, 1.0f ;
GLfloat position[] = 0.0f, -10.0f, 0.0f, 1.0f ;
// Assign created components to GL_LIGHT0
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);
//glDisable(GL_DEPTH_TEST);
glEnable(GL_PROGRAM_POINT_SIZE);
glPointSize(5);
void HSIOpenGLQuadViewWidget::paintGL()
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// Set the depth test and clear the depth field
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glClearDepth(1.0);
glDepthFunc(GL_LEQUAL);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawPoints();
drawSphere();
glPopMatrix();
QPainter painter(this);
QRect rect = this->rect();
float top = rect.y() + (rect.height() * 0.8);
float height = rect.height() * 0.15;
float left = rect.x() + (rect.width() * 0.8);
float width = rect.width() * 0.15;
QPen pen;
pen.setColor(Qt::red);
pen.setWidth(10);
painter.setPen(pen);
painter.setBrush(QBrush(Qt::red));
painter.drawRect(left, top, width, height);
QString textYaw = QString(" Yaw : ") + QString::number(100) + QString("\n");
QString textPitch = QString("Pitch : ") + QString::number(200) + QString("\n");
QString textRoll = QString(" Roll : ") + QString::number(300) + QString("\n");
painter.drawText(left, top + 10, textYaw);
painter.drawText(left, top + 25, textPitch);
painter.drawText(left, top + 40, textRoll);
那么,问题是,是什么导致 QOpenGLWidget 绘制四个箭头而不是一个实心红色矩形?有人有线索吗?谢谢。
【问题讨论】:
【参考方案1】:见this answer。你需要先启动一个painter,然后通知它native绘画,push状态,使用GL调用做native绘画,pop state,结束native绘画,最后使用painter进行绘画。
【讨论】:
两种方法我都试过了。有或没有 begin/endNativePainter() 我得到相同的结果。 您的上下文预初始化正在破坏它。请参阅其他答案的详细信息和 cmets。以零碎的方式做:首先做一些非常简单的工作 - 例如。根本没有OpenGL调用,只有画家,然后开始一一添加简单的绘图调用,看看它在哪里中断。它显然不起作用,因为画家期望上下文的状态与其所处的状态不同。 kuba ober 我会试一试。真的不敢相信我什至没有想过这样做。 :) 即使它不起作用,它仍然是一个愚蠢的新手错误。 出于某种原因,删除了 'glEnable(GL_CULL_FACE)' 和 'glCullFace(GL_BACK)' 行解决了这个问题。将其移至 gl 命令的开头并在命令解决问题后将其关闭。所以,把这归结为另一个菜鸟错误。谢谢!编辑:我也尝试打开正面剔除,这也有效。可能只是我,但这没有任何意义。哦,好吧。以上是关于QOpenGLWidget QPainter::drawRect 只画四个箭头的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 QOpenGLWidget 读取 GL_DEPTH_COMPONENT
使用 QOpenGLWidget 优于普通 QWidget 的好处