3. 绘制四边形
任务目标
在Qt窗口中通过OpenGL绘制一个四边形。核心实现方式是将四边形拆分为两个三角形进行渲染,并为每个顶点赋予不同的颜色,使四边形表面产生平滑的颜色渐变效果。
环境依赖
本案例基于 Qt 5.12+(含OpenGL模块)与 OpenGL 3.3 Core Profile。在项目文件 .pro 中添加:
QT += openglwidgets
LIBS += -lopengl32 -lglu32 # Windows下需链接OpenGL库
完整实现代码
创建 QuadWidget 类,继承自 QOpenGLWidget 并实现核心渲染逻辑。着色器使用GLSL 330 core语法。
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShaderProgram>
#include <QVector>
class QuadWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{
Q_OBJECT
public:
explicit QuadWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {}
protected:
void initializeGL() override {
initializeOpenGLFunctions();
// 1. 顶点数据:两个三角形组成四边形(逆时针顺序)
// 三角形1: v0-v1-v2, 三角形2: v0-v2-v3
GLfloat vertices[] = {
// 位置(x,y) // 颜色(R,G,B)
-0.8f, -0.8f, 1.0f, 0.0f, 0.0f, // v0 左下-红
0.8f, -0.8f, 0.0f, 1.0f, 0.0f, // v1 右下-绿
0.8f, 0.8f, 0.0f, 0.0f, 1.0f, // v2 右上-蓝
-0.8f, -0.8f, 1.0f, 0.0f, 0.0f, // v0 重复(三角形2)
0.8f, 0.8f, 0.0f, 0.0f, 1.0f, // v2 重复(三角形2)
-0.8f, 0.8f, 1.0f, 1.0f, 0.0f // v3 左上-黄
};
// 2. 创建并绑定VBO
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. 创建并绑定VAO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// 4. 配置顶点属性
// 位置属性(location=0): 每2个float
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(0);
// 颜色属性(location=1): 每3个float,偏移2个float
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// 5. 编译着色器
program = new QOpenGLShaderProgram(this);
program->addShaderFromSourceCode(QOpenGLShader::Vertex,
"#version 330 core\n"
"layout(location=0) in vec2 aPos;\n"
"layout(location=1) in vec3 aColor;\n"
"out vec3 vColor;\n"
"void main() {\n"
" gl_Position = vec4(aPos, 0.0, 1.0);\n"
" vColor = aColor;\n"
"}\n");
program->addShaderFromSourceCode(QOpenGLShader::Fragment,
"#version 330 core\n"
"in vec3 vColor;\n"
"out vec4 fragColor;\n"
"void main() {\n"
" fragColor = vec4(vColor, 1.0);\n"
"}\n");
program->link();
program->bind();
glBindVertexArray(0); // 解绑VAO
}
void paintGL() override {
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
program->bind();
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6); // 6个顶点 = 2个三角形
glBindVertexArray(0);
}
void resizeGL(int w, int h) override {
glViewport(0, 0, w, h);
}
private:
GLuint vao;
QOpenGLShaderProgram *program;
};
运行与验证
主函数入口(main.cpp):
#include <QApplication>
#include "QuadWidget.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QuadWidget w;
w.resize(600, 600);
w.show();
return app.exec();
}
验证步骤:
- 在Qt Creator中打开项目,构建并运行。
- 观察窗口中央是否出现一个四边形,其四个顶点颜色分别为:左下红色、右下绿色、右上蓝色、左上黄色。
- 四边形内部颜色应呈现平滑渐变过渡(非突变分界线),说明两个三角形共享边上的颜色插值正确。
- 若四边形中间出现明显对角线色差,说明顶点顺序或颜色配置有误,需检查顶点数据。
通过条件:窗口显示完整四边形,且颜色从红→绿→蓝→黄连续渐变,无撕裂或闪烁。
上图展示了四边形顶点颜色布局与两个三角形的拆分方式。渲染时OpenGL对每个三角形内部进行逐像素颜色插值,由于两个三角形共享对角线(v0-v2),整条对角线上颜色连续,因此四边形整体呈现无缝渐变效果。