本文主要内容是关于QOpenGLWidget的使用。此控件用于代替旧的QGLWidget类。关于此类的使用方法可以参考Qt帮助相关内容。
- glDrawArrays(...)函数参数说明:OpenGL 理解GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN等绘制三角形序列的三种方式_匆忙拥挤repeat的博客-CSDN博客
- 变量修饰符说明:shader三种变量类型修饰(uniform,attribute和varying) - 知乎 (zhihu.com)。除此之外还有其它修饰符,如:highp,mediump,lowp,in,out等,读者可以自行查找相关资料
下面将从简到繁给出3个例子带读者入门Qt3D的世界。以下代码开发平台是VS2017和Qt5.9。
一、绘制曲面和颜色
本代码实现了一个沿着x轴旋转的彩色曲面。头文件:
class QOpenGLShaderProgram; //--------------------------------------------------------------------------------------- // 显示彩虹色 //--------------------------------------------------------------------------------------- class MyOpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions { Q_OBJECT public: MyOpenGLWidget(QWidget* parent = 0); private: void initializeGL() override; void paintGL() override; void resizeGL(int w, int h) override; private: QOpenGLShaderProgram* program; int iter; };
CPP文件:
MyOpenGLWidget::MyOpenGLWidget(QWidget* parent) : QOpenGLWidget(parent), iter(0) { QSurfaceFormat surface; surface.setSamples(4); setFormat(surface); QTimer* timer = new QTimer(this); connect(timer, &QTimer::timeout, this, QOverload<>::of(&MyOpenGLWidget::update)); timer->setInterval(100); timer->start(); } void MyOpenGLWidget::initializeGL() { initializeOpenGLFunctions(); glEnable(GL_DEPTH_TEST); QOpenGLShader* vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); const char* vsrc = R"( in vec4 vposition; in vec4 vcolor; out vec4 ocolor; uniform mat4 trans; void main() { gl_Position = trans * vposition; ocolor = vcolor; })"; vshader->compileSourceCode(vsrc); QOpenGLShader* fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); const char* fsrc = R"( in vec4 ocolor; void main() { gl_FragColor = ocolor; })"; fshader->compileSourceCode(fsrc); program = new QOpenGLShaderProgram(this); program->addShader(vshader); program->addShader(fshader); program->link(); program->bind(); delete vshader; delete fshader; } void MyOpenGLWidget::paintGL() { GLfloat vertices[] = { -0.8f, 0.8f, 0.2f, -0.8f, -0.8f, -0.3f, 0.8f, 0.8f, 0.0f, 0.8f, -0.8f, 0.5f, }; GLfloat colors[] = { 0.9f, 0.7f, 0.1f, 0.2f, 0.7f, 0.3f, 0.8f, 0.0f, 0.5f, 0.1f, 0.1f, 0.9f, }; QMatrix4x4 matrix; matrix.perspective(60.0f, 1.0f, 1.0f, 100.0f); matrix.translate(0, 0, -3); matrix.rotate(iter * 1.0f, 1, 0, 0); program->setUniformValue("trans", matrix); program->enableAttributeArray("trans"); iter++; program->setAttributeArray("vposition", vertices, 3); program->enableAttributeArray("vposition"); program->setAttributeArray("vcolor", colors, 3); program->enableAttributeArray("vcolor"); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } void MyOpenGLWidget::resizeGL(int w, int h) { }
程序运行效果如下图:
二、绘制曲面和贴图
本代码实现了一个沿着z轴旋转的曲面,曲面上贴了图片。头文件:
class QOpenGLTexture; //--------------------------------------------------------------------------------------- // 显示图片 //--------------------------------------------------------------------------------------- class MzOpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions { Q_OBJECT public: MzOpenGLWidget(QWidget* parent = 0); private: void initializeGL() override; void paintGL() override; void resizeGL(int w, int h) override; private: QOpenGLShaderProgram* program; QOpenGLTexture *texture; int iter; };
CPP文件:
MzOpenGLWidget::MzOpenGLWidget(QWidget* parent) : QOpenGLWidget(parent), iter(0) { QSurfaceFormat surface; surface.setSamples(4); setFormat(surface); QTimer* timer = new QTimer(this); connect(timer, &QTimer::timeout, this, QOverload<>::of(&MyOpenGLWidget::update)); timer->setInterval(100); timer->start(); } void MzOpenGLWidget::initializeGL() { initializeOpenGLFunctions(); glEnable(GL_DEPTH_TEST); program = new QOpenGLShaderProgram(this); const char* vsrc = R"( in vec4 pos; in vec2 itextCoor; out vec2 otextCoor; uniform mat4 trans; void main() { gl_Position = trans * pos; otextCoor = itextCoor; })"; program->addShaderFromSourceCode(QOpenGLShader::Vertex, vsrc); const char* fsrc = R"( uniform sampler2D image; in vec2 otextCoor; void main() { gl_FragColor = texture2D(image, otextCoor); })"; program->addShaderFromSourceCode(QOpenGLShader::Fragment, fsrc); texture = new QOpenGLTexture(QImage(u8"F:/Mr.Duu/ProjectM/QtTest/QtTest/1.bmp")); texture->setMinificationFilter(QOpenGLTexture::LinearMipMapNearest); /* 缩小图片插值方法 */ texture->setMagnificationFilter(QOpenGLTexture::LinearMipMapLinear); /* 放大图片插值方法 */ texture->setWrapMode(QOpenGLTexture::Repeat); program->link(); program->bind(); } void MzOpenGLWidget::paintGL() { GLfloat vertices[] = { -0.8f, 0.8f, 0.2f, -0.8f, -0.8f, -0.3f, 0.8f, 0.8f, 0.0f, 0.8f, -0.8f, 0.5f, }; GLfloat coors[] = /* 此数组和vertices数组一一对应 */ { 0.0f, 0.0f, 0.0f, 2.2f, 2.2f, 0.0f, 2.2f, 2.2f, }; QMatrix4x4 matrix; matrix.perspective(60.0f, 1.0f, 1.0f, 100.0f); matrix.translate(0, 0, -3); matrix.rotate(iter * 1.0f, 0, 1, 0); program->setUniformValue("trans", matrix); program->enableAttributeArray("trans"); iter++; program->setAttributeArray("pos", vertices, 3); program->enableAttributeArray("pos"); program->setAttributeArray("itextCoor", coors, 2); program->enableAttributeArray("itextCoor"); program->setUniformValue("image", 0); texture->bind(0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } void MzOpenGLWidget::resizeGL(int w, int h) { }
程序运行效果如下:
三、绘制立体图形和颜色
立体图形其实也是曲面,只不过首尾点相同把曲面连接成了封闭的图形。下面给出一个绘制三棱锥的例子。头文件:
class QOpenGLTexture; //--------------------------------------------------------------------------------------- // 显示图片 //--------------------------------------------------------------------------------------- class MxOpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions { Q_OBJECT public: MxOpenGLWidget(QWidget* parent = 0); private: void initializeGL() override; void paintGL() override; void resizeGL(int w, int h) override; private: QOpenGLShaderProgram* program; int iter; };
CPP文件:
MxOpenGLWidget::MxOpenGLWidget(QWidget* parent) : QOpenGLWidget(parent), iter(0) { QSurfaceFormat surface; surface.setSamples(4); setFormat(surface); QTimer* timer = new QTimer(this); connect(timer, &QTimer::timeout, this, QOverload<>::of(&MyOpenGLWidget::update)); timer->setInterval(100); timer->start(); } void MxOpenGLWidget::initializeGL() { initializeOpenGLFunctions(); glEnable(GL_DEPTH_TEST); program = new QOpenGLShaderProgram(this); const char* vsrc = R"( in vec4 pos; in vec4 itextCoor; out vec4 otextCoor; uniform mat4 trans; void main() { gl_Position = trans * pos; otextCoor = itextCoor; })"; program->addShaderFromSourceCode(QOpenGLShader::Vertex, vsrc); const char* fsrc = R"( in vec4 otextCoor; void main() { gl_FragColor = otextCoor; })"; program->addShaderFromSourceCode(QOpenGLShader::Fragment, fsrc); program->link(); program->bind(); } void MxOpenGLWidget::paintGL() { GLfloat vertices[] = { -0.8f, -0.4f, 0.3f, 0.8f, -0.4f, 0.3f, 0.0f, 0.8f, 0.0f, 0.0f, -0.4f, -0.5f, -0.8f, -0.4f, 0.3f, 0.8f, -0.4f, 0.3f, }; GLfloat colors[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, }; QMatrix4x4 matrix; matrix.perspective(60.0f, 1.0f, 1.0f, 100.0f); matrix.translate(0, 0, -2); matrix.rotate(iter * 1.0f, 0, 1, 0); program->setUniformValue("trans", matrix); program->enableAttributeArray("trans"); iter++; program->setAttributeArray("pos", vertices, 3); program->enableAttributeArray("pos"); program->setAttributeArray("itextCoor", colors, 3); program->enableAttributeArray("itextCoor"); glDrawArrays(GL_TRIANGLE_STRIP, 0, 6); } void MxOpenGLWidget::resizeGL(int w, int h) { }
程序运行效果如下图:
标签:0.8,1.0,Qt,例程,0.0,void,int,program,3D From: https://www.cnblogs.com/mengxiangdu/p/17672585.html