
经过之前内容的学习,我们已经掌握了如何通过OpenGL在Qt提供的环境下绘制一个三角形,我们知道绘制一个三角形需要VAO,VBO,在一些场景还需要EBO,然后我们需要搞定着色器,最后我们绑定VAO,调用绘制接口就能绘制出想要的三角形。下面是时候来绘制一些有趣的进度条了。
设计实现
目录结构
先让我们看看完成后的目录结构:

文件很简单,因为在工程实现的角度,绘制有趣的进度条和绘制一个三角形基本是一样的。CMakeLists是CMake的构建配置文件,它帮我们将下面这些文件添加到构建体系。coolprogress.h/.cpp就是核心实现进度条绘制的文件,它提供了一个进度条的控件类,可以像使用Qt其它控件一样使用它。main.cpp是整个程序的入口函数,所有C++程序都有这样一个入口函数。progressexample.h/.cpp主要是构造一个控件去使用coolprogress.h/.cpp中提供的进度条。progressshader.h提供了绘制进度条所需要的着色器程序,这一部分十分复杂,需要很好的数学功底才能完全弄懂,可惜我还没有>-<,只能看懂一些简单的,但在工程实现的角度,我们不用太关心这其中的原理,抄过来也许是个不错的选择。最后是shaderprogram.h,这就是我们之前写的shader类,更换了命名防止后续会发生命名冲突,然后稍微做了一些修改。
需要哪些类
所需要的类也很简单,当然如果你有更好的设计完全可以按照自己的想法去写。

这里的ShaderProgram提供着色器构造、激活、Uniform变量设置等功能。CoolProgress是一个继承于QOpenGLWidget的控件类,对外提供接口。CoolProgressImpl类包含进度条实现过程中的数据集合,不对外暴露,该类的实例被CoolProgress类创建,并由智能指针管理生命周期。pImpl设计模式经常会在实际过程中用到,这样做的好处是能够保证一定的二进制兼容性。
接口设计
核心的接口都在coolprogress.h文件中:
#ifndef COOL_PROGRESS_H
#define COOL_PROGRESS_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <memory>
class CoolProgressImpl;
class CoolProgress : public QOpenGLWidget
{
Q_OBJECT
public:
enum ProgressStyle
{
Ring_1 = 0,
Ring_2,
Ring_3,
FlashDot_1,
FlashDot_2,
FlashDot_3,
FlashDot_4,
Rect_1,
Rect_2,
Rect_3,
Polygon_1,
WaterWave_1
};
public:
CoolProgress(bool bTransparent, ProgressStyle style, int width = 100, int height = 100, QWidget *parent = nullptr);
~CoolProgress();
void startProgress(float speed = 1.0);
void stopProgress();
void updateProgress();
// only valid in Ring style
void setRingRadius(float r1, float r2);
protected:
void initializeGL() override;
void paintGL() override;
void resizeGL(int w, int h) override;
private:
void initShader();
void setShaderUniform();
private:
std::unique_ptr<CoolProgressImpl> m_impl;
};
#endif
CoolProgressImpl是上面提到的数据类,m_impl指针指向该类实例,通过std::unique_ptr管理生命周期。ProgressStyle枚举表示进度条

最低0.47元/天 解锁文章
2605





