Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在指定的时间在qglwidget上绘制一个rect 我在Ubuntu 16.04上用C++使用Qt 5.7。我试图实现一个继承qglwidget的类,它以给定的速率(3-10 Hz)将图像渲染到屏幕上_C++_Qt_Opengl_Rendering - Fatal编程技术网

在指定的时间在qglwidget上绘制一个rect 我在Ubuntu 16.04上用C++使用Qt 5.7。我试图实现一个继承qglwidget的类,它以给定的速率(3-10 Hz)将图像渲染到屏幕上

在指定的时间在qglwidget上绘制一个rect 我在Ubuntu 16.04上用C++使用Qt 5.7。我试图实现一个继承qglwidget的类,它以给定的速率(3-10 Hz)将图像渲染到屏幕上,c++,qt,opengl,rendering,C++,Qt,Opengl,Rendering,除此之外,我想在屏幕上的某个地方画一个小矩形,它的颜色从黑色变为白色,反之亦然。当图像出现时,它应该从白色切换到黑色,并在下一个图像出现之前的某个预定义时间切换回黑色。 现在我正在使用纹理加载图像(来自QImage对象),使用 这是我的paintGL()重载: glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); drawTexture(QRect(0,0,1,1),texture,GL_TEXTUR

除此之外,我想在屏幕上的某个地方画一个小矩形,它的颜色从黑色变为白色,反之亦然。当图像出现时,它应该从白色切换到黑色,并在下一个图像出现之前的某个预定义时间切换回黑色。 现在我正在使用纹理加载图像(来自QImage对象),使用

这是我的paintGL()重载:

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
drawTexture(QRect(0,0,1,1),texture,GL_TEXTURE_2D);
swapBuffers();
glDisable(GL_TEXTURE_2D);
我想知道是否有可能在这个小部件上画图,让它同时呈现rect和image。我尝试过使用QPainter,但一直得到这样的结论:绘制矩形会使图像消失(矩形不应该出现在图像上,而是在小部件的某个角落,现在什么都没有绘制)


非常感谢您的帮助

这是一个最小的示例应用程序,它在paint handler中混合了OpenGL代码和
QPaint

#include <QtWidgets>
#include <QOpenGLFunctions_1_1>

// manually added types (normally provided by glib)
typedef unsigned guint;
typedef unsigned char guint8;

extern const struct Image {
  guint      width;
  guint      height;
  guint      bytes_per_pixel; /* 3:RGB, 4:RGBA */
  guint8     pixel_data[1];
} fluffyCat;

class GLWidget: public QOpenGLWidget, protected QOpenGLFunctions_1_1 {
  private:
    float _step;
    GLuint _idTex;
    QTimer _qTimer;
  public:
    GLWidget(QWidget *parent = 0):
      QOpenGLWidget(parent),
      _step(0.0f), _idTex(0)
    {
      _qTimer.setInterval(100); // 100 ms -> 10 Hz
      QObject::connect(&_qTimer, &QTimer::timeout,
        this, &GLWidget::timeout);
    }
  protected:
    virtual void initializeGL();
    virtual void paintGL();
  private:
    void timeout();
};

void GLWidget::initializeGL()
{
  initializeOpenGLFunctions();
  glClearColor(0.525, 0.733f, 0.851, 1.0);
  glGenTextures(1, &_idTex);
  glBindTexture(GL_TEXTURE_2D, _idTex);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, fluffyCat.width, fluffyCat.height, 0,
    GL_RGB, GL_UNSIGNED_BYTE, fluffyCat.pixel_data);
  glBindTexture(GL_TEXTURE_2D, 0);
  _qTimer.start();
}

void GLWidget::paintGL()
{
  // prepare OpenGL rendering
  QPainter qPainter(this);
  qPainter.beginNativePainting();
  // do OpenGL rendering
  glColor3f(1.0f, 1.0f, 1.0f);
  bool tex2dOld = glIsEnabled(GL_TEXTURE_2D);
  glEnable(GL_TEXTURE_2D);
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  static GLfloat envColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor);
  glBindTexture(GL_TEXTURE_2D, _idTex);
  float x = sin(_step) * 0.5f, y = cos(_step) * 0.5f;
#if 0 // does not work (no tex-coords)
  glRectf(x - 0.5f, y - 0.5f, x + 0.5f, y + 0.5f);
#else // (not) 0
  glBegin(GL_QUADS);
  glColor3f(1.0f, 1.0f, 1.0f);
  glTexCoord2i(0, 1);
  glVertex2f(x - 0.5f, y - 0.5f);
  glTexCoord2i(1, 1);
  glVertex2f(x + 0.5f, y - 0.5f);
  glTexCoord2i(1, 0);
  glVertex2f(x + 0.5f, y + 0.5f);
  glTexCoord2i(0, 0);
  glVertex2f(x - 0.5f, y + 0.5f);
  glEnd();
#endif // 0
  glBindTexture(GL_TEXTURE_2D, 0);
  //if (!tex2dOld) glDisable(GL_TEXTURE_2D);
  // prepare Qt painting
  qPainter.endNativePainting();
  // do Qt painting (HUD)
  QPen qPen;
  qPen.setWidth(1);
  qPen.setColor(QColor(Qt::black));
  qPen.setStyle(Qt::SolidLine);
  qPainter.resetMatrix();
  qPainter.setPen(qPen);
  qPainter.drawLine(0, 0, width(), height());
  qPainter.drawLine(0, height(), width(), 0);
}

void GLWidget::timeout()
{
  _step = fmod(_step + 0.1, 2 * 3.141);
  update(); // force redraw
}

int main(int argc, char **argv)
{
  QApplication app(argc, argv);
  QMainWindow win;
  GLWidget view3d;
  win.setCentralWidget(&view3d);
  win.show();
  return app.exec();
}

顺便说一下,我没有意识到OP要求的是
QGLWidget
。该示例使用新的
QOpenGLWidget
,这是自Qt5+以来推荐的

QTimer
用于制作非常简单的动画(表示已完成定期绘制)

顺便说一句,我偶然发现了一个错误(这不是第一次击中我…)
设置
GL\u TEXTURE\u MIN\u FILTER
GL\u TEXTURE\u MAG\u FILTER
非常重要,因为这是两种罕见的OpenGL状态,如果保留默认值则无法工作。

这是一个最小的示例应用程序,它在paint handler中混合了OpenGL代码和
qPaint

#include <QtWidgets>
#include <QOpenGLFunctions_1_1>

// manually added types (normally provided by glib)
typedef unsigned guint;
typedef unsigned char guint8;

extern const struct Image {
  guint      width;
  guint      height;
  guint      bytes_per_pixel; /* 3:RGB, 4:RGBA */
  guint8     pixel_data[1];
} fluffyCat;

class GLWidget: public QOpenGLWidget, protected QOpenGLFunctions_1_1 {
  private:
    float _step;
    GLuint _idTex;
    QTimer _qTimer;
  public:
    GLWidget(QWidget *parent = 0):
      QOpenGLWidget(parent),
      _step(0.0f), _idTex(0)
    {
      _qTimer.setInterval(100); // 100 ms -> 10 Hz
      QObject::connect(&_qTimer, &QTimer::timeout,
        this, &GLWidget::timeout);
    }
  protected:
    virtual void initializeGL();
    virtual void paintGL();
  private:
    void timeout();
};

void GLWidget::initializeGL()
{
  initializeOpenGLFunctions();
  glClearColor(0.525, 0.733f, 0.851, 1.0);
  glGenTextures(1, &_idTex);
  glBindTexture(GL_TEXTURE_2D, _idTex);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, fluffyCat.width, fluffyCat.height, 0,
    GL_RGB, GL_UNSIGNED_BYTE, fluffyCat.pixel_data);
  glBindTexture(GL_TEXTURE_2D, 0);
  _qTimer.start();
}

void GLWidget::paintGL()
{
  // prepare OpenGL rendering
  QPainter qPainter(this);
  qPainter.beginNativePainting();
  // do OpenGL rendering
  glColor3f(1.0f, 1.0f, 1.0f);
  bool tex2dOld = glIsEnabled(GL_TEXTURE_2D);
  glEnable(GL_TEXTURE_2D);
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  static GLfloat envColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor);
  glBindTexture(GL_TEXTURE_2D, _idTex);
  float x = sin(_step) * 0.5f, y = cos(_step) * 0.5f;
#if 0 // does not work (no tex-coords)
  glRectf(x - 0.5f, y - 0.5f, x + 0.5f, y + 0.5f);
#else // (not) 0
  glBegin(GL_QUADS);
  glColor3f(1.0f, 1.0f, 1.0f);
  glTexCoord2i(0, 1);
  glVertex2f(x - 0.5f, y - 0.5f);
  glTexCoord2i(1, 1);
  glVertex2f(x + 0.5f, y - 0.5f);
  glTexCoord2i(1, 0);
  glVertex2f(x + 0.5f, y + 0.5f);
  glTexCoord2i(0, 0);
  glVertex2f(x - 0.5f, y + 0.5f);
  glEnd();
#endif // 0
  glBindTexture(GL_TEXTURE_2D, 0);
  //if (!tex2dOld) glDisable(GL_TEXTURE_2D);
  // prepare Qt painting
  qPainter.endNativePainting();
  // do Qt painting (HUD)
  QPen qPen;
  qPen.setWidth(1);
  qPen.setColor(QColor(Qt::black));
  qPen.setStyle(Qt::SolidLine);
  qPainter.resetMatrix();
  qPainter.setPen(qPen);
  qPainter.drawLine(0, 0, width(), height());
  qPainter.drawLine(0, height(), width(), 0);
}

void GLWidget::timeout()
{
  _step = fmod(_step + 0.1, 2 * 3.141);
  update(); // force redraw
}

int main(int argc, char **argv)
{
  QApplication app(argc, argv);
  QMainWindow win;
  GLWidget view3d;
  win.setCentralWidget(&view3d);
  win.show();
  return app.exec();
}

顺便说一下,我没有意识到OP要求的是
QGLWidget
。该示例使用新的
QOpenGLWidget
,这是自Qt5+以来推荐的

QTimer
用于制作非常简单的动画(表示已完成定期绘制)

顺便说一句,我偶然发现了一个错误(这不是第一次击中我…)
设置
GL\u TEXTURE\u MIN\u FILTER
GL\u TEXTURE\u MAG\u FILTER
非常重要,因为这是两种罕见的OpenGL状态,如果保留默认值则无法工作。

好吧,最后这对于添加一个小的rect-

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
QPainter qPainter(this);
QPainterPath path;
path.addRect(10, 10, 30,30);
QPen pen(Qt::black, 1);
qPainter.setPen(pen);
qPainter.fillPath(path, Qt::black);
qPainter.drawPath(path);
qPainter.end();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glShadeModel( GL_FLAT );
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D);
glColor3f(0.5, 0.5, 0);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.5f, -0.5f);  // vertex 1
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.5f, 0.5f); // vertex 2
glTexCoord2f(1.0f, 0.0f); glVertex2f(-0.5f, 0.5f); // vertex 3
glTexCoord2f(1.0f, 1.0f); glVertex2f(-0.5f, -0.5f); // vertex 4
glEnd();
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);

好的,最后这对添加一个小的rect-

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
QPainter qPainter(this);
QPainterPath path;
path.addRect(10, 10, 30,30);
QPen pen(Qt::black, 1);
qPainter.setPen(pen);
qPainter.fillPath(path, Qt::black);
qPainter.drawPath(path);
qPainter.end();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glShadeModel( GL_FLAT );
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D);
glColor3f(0.5, 0.5, 0);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.5f, -0.5f);  // vertex 1
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.5f, 0.5f); // vertex 2
glTexCoord2f(1.0f, 0.0f); glVertex2f(-0.5f, 0.5f); // vertex 3
glTexCoord2f(1.0f, 1.0f); glVertex2f(-0.5f, -0.5f); // vertex 4
glEnd();
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);


如果使用了
QPainter
,则假定它具有对OpenGL状态的独占访问权限。如果直接使用OpenGL API,则必须在调用
QPainter
-API之前恢复某些状态。通过这种方式,我解决了在使用OpenGL渲染3d场景后使用
qPaint
渲染HUD的问题QGLWidget完成。(我必须查看我的源代码以提供更多细节。)您必须知道
QOpenGLFunctions
方法的使用和调用GL函数(从任何非Qt库)是不同的。这是可能的,尤其是在文件中。例如。如果调用“非Qt”OpenGL函数,这可能会绕过Qt中的内部状态跟踪。您是否注意到我在回答末尾添加的关于
GL_纹理_MIN_过滤器
GL_纹理_MAG_过滤器
的提示?如果使用
QPainter
,则假定对OpenGL状态具有独占访问权限。如果直接使用OpenGL API,则必须在调用
QPainter
-API之前恢复某些状态。通过这种方式,我解决了在使用OpenGL渲染3d场景后使用
qPaint
渲染HUD的问题QGLWidget完成。(我必须查看我的源代码以提供更多细节。)您必须知道
QOpenGLFunctions
方法的使用和调用GL函数(从任何非Qt库)是不同的。这是可能的,尤其是在文件中。例如。如果调用“非Qt”OpenGL函数,这可能会绕过Qt中的内部状态跟踪。您是否注意到关于
GL_TEXTURE\u MIN_FILTER
GL_TEXTURE\u MAG_FILTER
的提示,这是我在回答末尾添加的?当我刚刚创建Qpainter(使用Qpainter Qpainter(this)),它会覆盖我正在绘制的纹理,即使我没有打电话给其他绘画指导。你知道为什么吗?我还尝试了整个代码块,但它不起作用,只是画对角线。@JLev我明确要求
QOpenGLFunctions\u 1\u 1
像您那样使用OpenGL 1.1。默认的
QOpenGLFunctions
不再提供
glColor3f()
glRectf()
。(它在OpenGL 3+中被弃用)也许,您的OpenGL驱动程序不支持请求的OpenGL 1.1函数(尽管-这很难相信…@JLev我试图记住如果
QOpenGLFunctions
xx无法绑定请求的OpenGL函数会发生什么。我在Qt
qopengelfunctions
doc中找不到任何成功的检索函数。我想,在这种情况下,它简直崩溃了。(我曾经在一个colaborator的Windows计算机上的驱动程序更新失败时看到过这种情况,并在没有适当的OpenGL支持的情况下退回到通用驱动程序。关于Linux我不知道。)我尝试切换到QopenGlwidget,但无法初始化QOpenGLFunctions。我不需要它,你在哪里看到我在使用它?
QOpenGLFunctions
是属于Qt的openglapi。Qt建议使用它,但这不是必须的。在我们(公司)的项目中,我们从
QOpenGLFunctions
开始,但后来切换到自己的OpenGL C绑定,因为我们希望使用独立于Qt的GL渲染代码。它确实有效,但不需要额外的努力。正如我已经说过的,如果GL状态发生更改,Qt可能会在内部跟踪这些状态,如果在执行“非Qt”OpenGL渲染代码后这些状态没有恢复,Qt代码可能会崩溃。顺便说一句,你可以吗