一、QPainter绘制
在QOpenGLWidget中可以绘制,并且和OpenGL的内容叠在一起。paintGL里面绘制完视频后,解锁资源,再用QPainter绘制矩形框。这种方式灵活性最好。
void VideoGLWidget::paintGL() {glClear(GL_COLOR_BUFFER_BIT);m_program.bind();//绘制视频数据// 解绑VAOglBindVertexArray(0);m_program.release();// ----------------- 绘制矩形框 -----------------QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);painter.setPen(QPen(QColor(Qt::red), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));QRectF drawRect = QRectF(0, 0, width() * 0.5, height() * 0.5);painter.drawRect(drawRect);painter.end();
}
二、OpenGL绘制
通过不同的QOpenGLShaderProgram,可以指定不同的着色器程序来实现矩形的绘制。
1)边框颜色参数要通过Uniform传递给OpenGL的顶点着色器。
2)动态矩形顶点缓冲更新,坐标归一化到OpenGL坐标系,顶点数据更新VBO
void VideoGLWidget::updateRectBuffer() {
if (m_rects.isEmpty()) return; // 将 QRectF 转换为归一化坐标(-1 到 1)
QVector<float> vertices;
for (const QRectF &rect : m_rects) {
float x1 = (rect.x() / m_videoSize.width()) * 2 - 1;
float y1 = 1 - (rect.y() / m_videoSize.height()) * 2;
float x2 = ((rect.x() + rect.width()) / m_videoSize.width()) * 2 - 1;
float y2 = 1 - ((rect.y() + rect.height()) / m_videoSize.height()) * 2; // 每个矩形由 4 条线段组成(每条线段 2 个点)
vertices << x1 << y1 << x2 << y1; // 上边
vertices << x2 << y1 << x2 << y2; // 右边
vertices << x2 << y2 << x1 << y2; // 下边
vertices << x1 << y2 << x1 << y1; // 左边
} // 更新 VBO
glBindBuffer(GL_ARRAY_BUFFER, m_rectVBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float),
ver