一、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