在 Widget 类中添加如下代码:
class Widget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
protected:
void initializeGL() override;
void resizeGL(int w, int h) override;
void paintGL() override;
private:
GLuint m_vao; // 顶点数组对象
GLuint m_vbo; // 顶点缓冲对象
GLsizei m_pointCount; // 点的数量
GLsizei m_faceCount; // 面的数量
};
Widget::Widget(QWidget *parent)
: QOpenGLWidget(parent)
{
}
void Widget::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
// 顶点数据
GLfloat pointData[] = {
// x, y, z
0.0f, 0.0f, 0.0f
};
// 面数据
GLushort faceData[] = {
0
};
m_pointCount = 1;
m_faceCount = 1;
// 创建 VAO 和 VBO
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(pointData), pointData, GL_STATIC_DRAW);
// 设置顶点属性指针
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// 解绑 VAO 和 VBO
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Widget::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
void Widget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(10.0f);
glEnable(GL_POINT_SMOOTH);
// 绘制点
glBindVertexArray(m_vao);
glDrawArrays(GL_POINTS, 0, m_pointCount);
glBindVertexArray(0);
// 绘制面
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.5f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
glEnd();
}
在 initializeGL() 方法中,首先初始化 OpenGL 函数,并设置清空颜色为白色。然后定义一个顶点数据和一个面数据,并创建 VAO 和 VBO,将顶点数据绑定到 VBO 上,并设置顶点属性指针。最后解绑 VAO 和 VBO。
在 paintGL() 中,首先清空颜色缓冲区,然后绘制点,先绑定 VAO,再调用 glDrawArrays() 方法绘制。接下来绘制面,使用 glBegin(GL_TRIANGLES) 开始绘制三角形,设置颜色和顶点坐标,最后使用 glEnd() 结束绘制。
需要注意的是,OpenGL 中的绘制操作都必须在一个合法的上下文中进行,所以在 Widget 构造函数中必须调用 setFormat() 方法设置 OpenGL 的版本和配置。