如果这不准确,我深表歉意。我正在尽我所能手动将代码从一台计算机复制到另一台计算机,而目标计算机没有编译器(不要问(。
头文件
#ifndef MYOPENGLWIDGET_H
#define MYOPENGLWIDGET_H
#include <qopenglwidget.h>
class MyOpenGlWidget : public QOpenGLWidget
{
Q_OBJECT
public:
explicit MyOpenGlWidget(QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags());
virtual ~MyOpenGlWidget();
protected:
// these are supposed to be overridden, so use the "override" keyword to compiler check yourself
virtual void initializeGL() override;
virtual void resizeGL(int w, int h) override;
virtual void paintGL() override;
private:
QPixmap *_foregroundPixmap;
}
#endif
源文件
QOpenGLFunctions_2_1 *f = 0;
MyOpenGlWidget::MyOpenGlWidget(QWidget *parent, Qt::WindowFlags f) :
QOpenGLWidget(parent, f)
{
_foregroundPixmap = 0;
QPixmap *p = new QPixmap("beveled_texture.tiff");
if (!p->isNull())
{
_foregroundPixmap = p;
}
}
MyOpenGlWidget::~MyOpenGlWidget()
{
delete _foregroundPixmap;
}
void MyOpenGlWidget::initializeGL()
{
// getting a deprecated set of functions because such is my work environment
// Note: Also, QOpenGLWidget doesn't support these natively.
f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_2_1>();
f->glClearColor(0.0f, 1.0f, 0.0f, 1.0f); // clearing to green
f->glEnable(GL_DEPTH_TEST);
f->glEnable(GL_CULL_FACE); // implicitly culling front face
f->glEnable(GL_SCISSOR_TEST);
// it is either copy the matrix and viewport code from resizeGL or just call the method
this->resizeGL(this->width(), this->height());
}
void MyOpenGlWidget::resizeGL(int w, int h)
{
// make the viewport square
int sideLen = qMin(w, h);
int x = (w - side) / 2;
int y = (h - side) / 2;
// the widget is 400x400, so this random demonstration square will show up inside it
f->glViewport(50, 50, 100, 100);
f->glMatrixMode(GL_PROJECTION);
f->glLoadIdentity();
f->glOrtho(-2.0f, +2.0f, -2.0f, +2.0f, 1.0f, 15.0f); // magic numbers left over from a demo
f->glMatrixMode(GL_MODELVIEW);
// queue up a paint event
// Note: QGLWidget used updateGL(), but QOpenGLWidget uses update().
this->update();
}
void MyOpenGlWidget::paintGL()
{
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// I want to draw a texture with beveled edges the size of this widget, so I can't
// have the background clearing all the way to the edges
f->glScissor(50, 50, 200, 200); // more magic numbers just for demonstration
// clears to green in just scissored area (unless QPainter is created)
f->glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
// loading identity matrix, doing f->glTranslatef(...) and f->glRotatef(...)
// pixmap loaded earlier in another function
if (_foregroundPixmap != 0)
{
// QPixmap apparently draws such that culling the back face will cull the entire
// pixmap, so have to switch culling for duration of pixmap drawing
f->glCullFace(GL_FRONT);
QPainter(this);
painter.drawPixmap(0, 0, _foregroundPixmap->scaled(this->size()));
// done, so switch back to culling the front face
f->glCullFace(GL_BACK);
}
QOpenGLFunctions_2_1 *f = 0;
void MyOpenGlWidget::initializeGL()
{
// getting a deprecated set of functions because such is my work environment
// Note: Also, QOpenGLWidget doesn't support these natively.
f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_2_1>();
f->glClearColor(0.0f, 1.0f, 0.0f, 1.0f); // clearing to green
f->glEnable(GL_DEPTH_TEST);
f->glEnable(GL_CULL_FACE); // implicitly culling front face
f->glEnable(GL_SCISSOR_TEST);
// it is either copy the matrix and viewport code from resizeGL or just call it directly
this->resizeGL(this->width(), this->height());
}
void MyOpenGlWidget::resizeGL(int w, int h)
{
// make the viewport square
int sideLen = qMin(w, h);
int x = (w - side) / 2;
int y = (h - side) / 2;
// the widget is 400x400, so this random demonstration square will show up inside it
f->glViewport(50, 50, 100, 100);
f->glMatrixMode(GL_PROJECTION);
f->glLoadIdentity();
f->glOrtho(-2.0f, +2.0f, -2.0f, +2.0f, 1.0f, 15.0f); // magic numbers left over from a demo
f->glMatrixMode(GL_MODELVIEW);
// queue up a paint event
// Note: QGLWidget used updateGL(), but QOpenGLWidget uses update().
this->update();
}
void MyOpenGlWidget::paintGL()
{
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// I want to draw a texture with beveled edges the size of this widget, so I can't
// have the background clearing all the way to the edges
f->glScissor(50, 50, 200, 200); // more magic numbers just for demonstration
// clears to green in just scissored area (unless QPainter is created)
f->glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
// loading identity matrix, doing f->glTranslatef(...) and f->glRotatef(...), drawing triangles
// done drawing, so now draw the beveled foreground
if (_foregroundPixmap != 0)
{
// QPixmap apparently draws such that culling the back face will cull the entire
// pixmap, so have to switch culling for duration of pixmap drawing
f->glCullFace(GL_FRONT);
QPainter(this);
painter.drawPixmap(0, 0, _foregroundPixmap->scaled(this->size()));
// done, so switch back to culling the front face
f->glCullFace(GL_BACK);
}
}
问题是来自paintGL()
:的此代码
QPainter(this);
一旦创建了QPainter对象,我在函数前面进行的glScissor(...)
调用就会被溢出,并进行某种glClearColor(...)
调用(可能来自QPainter的构造函数(,将整个视口清除为我在glScissor(...)
之后设置的背景色。然后像素图把我的斜面纹理画得很好。
我不希望QPainter超过我的剪刀。
我得到的最接近解释是两种QPainter方法,beginNativePainting()
和endNativePainting()
。根据文档,剪刀测试在这两者之间是禁用的,但在他们的例子中,他们重新启用了它。我尝试使用这个"原生绘画"代码,但我无法阻止QPainter的存在,因为它忽略了GL的剪刀测试并清除了我的整个视口。
为什么会发生这种情况,我该如何阻止这种情况
注意:这台工作电脑有网络策略,禁止我去imgur等娱乐网站上传"我想要的"one_answers"我得到的"图片,所以我必须通过文本进行支付。
为什么会发生这种情况
OpenGL上下文是一个共享资源,您必须与其他玩家共享它。
我该如何阻止这种情况?
你不能。只要做正确的事情,在右侧时刻设置视口、剪刀矩形和所有其他与绘图相关的状态:就在您要绘制依赖于这些设置的东西之前。不要在某个"初始化"或整形处理程序的某个位置之前(用计算机术语来说(设置它们。在绘图代码中,任何使用OpenGL调用的函数都会留下一些垃圾。