計算機圖形學實踐:結合Qt和OpenGL實現繪制彩色三角形

在Qt項目中結合OpenGL與CMake需要配置正確的依賴關系、鏈接庫以及代碼結構設計。以下是具體實現步驟和關鍵要點:


一、環境準備

  1. 安裝Qt
    確保安裝包含OpenGL模塊的Qt版本(如Qt OpenGLQt OpenGLWidgets組件)。
  2. 安裝CMake
    使用3.10及以上版本,并配置系統環境變量。

二、CMake配置

1. 基礎配置
cmake_minimum_required(VERSION 3.10)
project(Qt_OpenGL_Project)# 設置C++標準
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 查找Qt組件
find_package(Qt6 COMPONENTS Core Gui Widgets OpenGL OpenGLWidgets REQUIRED)# 添加可執行文件
add_executable(${PROJECT_NAME} main.cpp)
2. 鏈接OpenGL與Qt庫
# 鏈接Qt核心庫
target_link_libraries(${PROJECT_NAME}Qt6::CoreQt6::GuiQt6::WidgetsQt6::OpenGLQt6::OpenGLWidgets
)# 鏈接系統OpenGL庫(Windows需顯式鏈接)
if(WIN32)target_link_libraries(${PROJECT_NAME} opengl32 glu32)
endif()
3. 啟用OpenGL特性

若使用QCustomPlot等第三方庫需啟用OpenGL支持:

target_compile_definitions(${PROJECT_NAME} PRIVATE QCUSTOMPLOT_USE_OPENGL)

三、代碼實現

1. 繼承QOpenGLWidget
#include <QOpenGLWidget>
#include <QOpenGLFunctions>class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions {Q_OBJECT
public:explicit GLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {}protected:void initializeGL() override {initializeOpenGLFunctions(); // 初始化OpenGL函數glClearColor(0.2f, 0.3f, 0.3f, 1.0f); // 設置背景色}void paintGL() override {glClear(GL_COLOR_BUFFER_BIT); // 清空緩沖區// 添加OpenGL繪制代碼}void resizeGL(int w, int h) override {glViewport(0, 0, w, h); // 設置視口}
};
2. 主窗口集成
#include <QApplication>
#include <QMainWindow>int main(int argc, char *argv[]) {QApplication a(argc, argv);QMainWindow window;GLWidget glWidget;window.setCentralWidget(&glWidget);window.show();return a.exec();
}

四、常見問題解決

  1. OpenGL函數未識別

    • 確保繼承QOpenGLFunctions并調用initializeOpenGLFunctions()
    • 使用QOpenGLExtraFunctions獲取更高版本API支持。
  2. Qt版本兼容性

    • Qt6默認使用QOpenGLWidget替代舊版QGLWidget,推薦使用新API。
    • 若需兼容Qt5,修改CMake中Qt6Qt5并調整組件名稱。
  3. 第三方庫集成(如OpenCV)
    在CMake中啟用WITH_QTWITH_OPENGL選項,確保OpenCV編譯時支持Qt和OpenGL:

    find_package(OpenCV REQUIRED)
    target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
    

五、高級配置

  • 多平臺適配
    CMake自動處理不同平臺的庫依賴(如Linux下鏈接-lGL,macOS下鏈接-framework OpenGL)。
  • 調試工具
    使用qDebug()輸出OpenGL錯誤碼,或借助glGetError()檢查錯誤。

通過以上步驟,Qt與OpenGL可在CMake項目中無縫集成,實現跨平臺的圖形渲染功能。建議參考Qt官方文檔和OpenGL教程深入優化渲染邏輯。


下面利用QT和OpenGL畫一個三角形


一、創建OpenGL繪制組件

  1. 繼承QOpenGLWidget實現自定義繪制類:
// myopenglwidget.h
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShaderProgram>class MyOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{Q_OBJECT
public:explicit MyOpenGLWidget(QWidget *parent = nullptr);void setTriangleColor(const QColor &color);protected:void initializeGL() override;void paintGL() override;private:GLuint VAO, VBO;QOpenGLShaderProgram *shaderProgram;QVector3D triangleColor = QVector3D(1.0f, 0.0f, 0.0f); // 默認紅色
};

二、實現OpenGL初始化與繪制

// myopenglwidget.cpp
void MyOpenGLWidget::initializeGL()
{initializeOpenGLFunctions();glClearColor(0.1f, 0.1f, 0.1f, 1.0f);// 頂點數據(三角形位置)float vertices[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f};// 創建VAO/VBOglGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// 配置頂點屬性glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);// 創建著色器程序shaderProgram = new QOpenGLShaderProgram(this);shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex,"#version 330 core\n""layout (location = 0) in vec3 aPos;\n""void main() {\n""   gl_Position = vec4(aPos, 1.0);\n""}");shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment,"#version 330 core\n""out vec4 FragColor;\n""uniform vec3 ourColor;\n""void main() {\n""   FragColor = vec4(ourColor, 1.0);\n""}");shaderProgram->link();
}void MyOpenGLWidget::paintGL()
{glClear(GL_COLOR_BUFFER_BIT);shaderProgram->bind();shaderProgram->setUniformValue("ourColor", triangleColor);glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 3);shaderProgram->release();
}void MyOpenGLWidget::setTriangleColor(const QColor &color)
{triangleColor = QVector3D(color.redF(), color.greenF(), color.blueF());update(); // 觸發重繪
}

三、添加顏色選擇按鈕

// mainwindow.cpp
#include <QMainWindow>
#include <QPushButton>
#include <QColorDialog>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{MyOpenGLWidget *glWidget = new MyOpenGLWidget(this);setCentralWidget(glWidget);// 創建顏色選擇按鈕QPushButton *colorBtn = new QPushButton("選擇顏色", this);colorBtn->setGeometry(10, 10, 100, 30);connect(colorBtn, &QPushButton::clicked, [=](){QColor color = QColorDialog::getColor(Qt::red, this, "選擇三角形顏色");if (color.isValid()) {glWidget->setTriangleColor(color);}});
}

四、運行效果

  1. 窗口顯示灰色背景的紅色三角形
  2. 點擊"選擇顏色"按鈕彈出顏色選擇對話框
  3. 選擇顏色后三角形實時更新顏色

關鍵實現原理

  1. 著色器控制顏色:通過uniform變量傳遞顏色值到片段著色器
  2. 顏色轉換:將Qt的QColor轉換為OpenGL的歸一化顏色值(0.0-1.0)
  3. 實時更新:調用update()觸發OpenGL重繪

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77269.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77269.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77269.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

3:QT聯合HALCON編程—海康相機SDK二次程序開發

思路&#xff1a; 1.定義帶UI界面的主函數類 1.1在主函數中包含其它所有類頭文件&#xff0c;進行聲明和實例化&#xff1b;使用相機時&#xff0c;是用公共相機的接口在某一個具體函數中去實例化具體的海康相機對象。 1.2設計界面&#xff1a;連接相機&#xff0c;單次采集&a…

基于大模型底座重構司法信息系統

前置篇章&#xff1a;法律智能體所需的基礎知識 構建一個高效的法律智能體&#xff0c;特別是在基于RAG&#xff08;Retrieval-Augmented Generation&#xff09;架構的背景下&#xff0c;需要融合多種學科和領域的知識。以下是對法律智能體開發和應用所需核心基礎知識的簡要介…

類《雙人成行》3D動作益智冒險類雙人控制游戲開發

服務器端采用了基于開源Kbengine&#xff08;引擎使用C和Python編寫&#xff09;的多人在線游戲服務器&#xff0c;客戶端采用Unity3D。游戲支持線上的雙人聯機房間功能。 資源地址&#xff1a;類《雙人成行》3D動作益智冒險類雙人控制游戲開發教程 | Unity 中文課堂 一、游戲…

Spark--基本介紹

Spark是基于內存的快速&#xff0c;通農用&#xff0c;可拓展的大數據分析計算引擎&#xff0c;Hadoop是一個分布式系統基礎架構 Spark和Hadoop之間的對比和聯系 架構與組件&#xff1a; Hadoop&#xff1a; ■ HDFS&#xff1a;分布式文件系統&#xff0c;負責海量數據存儲。…

05-GPIO原理

一、概述 1、GPIO,即通用I/O(輸入/輸出)端口&#xff0c;是STM32可控制的引腳。STM32芯片的GPIO引腳與外部設備連接起來&#xff0c;可實現與外部通訊、控制外部硬件或者采集外部硬件數據的功能。 2、GPIO的復用:引腳復用是指將單個引腳配置為多個功能的能力。在 STM32 中&…

基于LangChain4J的AI Services實踐:用聲明式接口重構LLM應用開發

基于LangChain4J的AI Services實踐&#xff1a;用聲明式接口重構LLM應用開發 前言&#xff1a;當Java開發遇上LLM編程困境 在LLM應用開發領域&#xff0c;Java開發者常面臨兩大痛點&#xff1a;一是需要手動編排Prompt工程、記憶管理和結果解析等底層組件&#xff0c;二是復雜…

深入解析 Docker 容器進程的 cgroup 和命名空間信息

深入解析 Docker 容器進程的 cgroup 和命名空間信息 在現代 Linux 系統中&#xff0c;控制組&#xff08;cgroup&#xff09;和命名空間&#xff08;namespace&#xff09;是實現容器化技術的核心機制。cgroup 用于管理和限制進程的資源使用&#xff08;如 CPU、內存、I/O&…

【汽車ECU電控數據管理篇】S19文件格式解析篇章

一、S19格式是啥 在電控文件管理的初期階段&#xff0c;我首次接觸到的是 A2L 和 HEX 文件。其中&#xff0c;A2L 文件主要承擔著描述性功能&#xff0c;它詳細地描述了各種參數和配置等相關信息。而 HEX 文件則是一種刷寫文件&#xff0c;其內部明確記錄了具體的地址以及對應的…

python編程相關的單詞

the: 在編程中&#xff0c;“the” 是一個常見的英語單詞&#xff0c;用于指定特定的對象或變量。例如&#xff0c;“the function” 指的是某個特定的函數。 the的拼寫是t,h,e.再讀一次t,h,e and: 在編程中&#xff0c;“and” 是一個邏輯運算符&#xff0c;用于連接兩個條件&…

網絡原理 - 4(TCP - 1)

目錄 TCP 協議 TCP 協議段格式 可靠傳輸 幾個 TCP 協議中的機制 1. 確認應答 2. 超時重傳 完&#xff01; TCP 協議 TCP 全稱為 “傳輸控制協議”&#xff08;Transmission Control Protocol&#xff09;&#xff0c;要對數據的傳輸進行一個詳細的控制。 TCP 協議段格…

python博客爬蟲列表

我希望對指定網頁的&#xff0c;博客列表&#xff0c;獲取url&#xff0c;然后保存成本地文件&#xff0c;用python實現 step1: import requests from bs4 import BeautifulSoup import jsondef get_blog_links(url):headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win6…

軟件測試入門學習筆記

今天學習新知識&#xff0c;軟件測試。 什么是軟件測試&#xff1f; 使用人工和自動手段來運行或測試某個系統的過程&#xff0c;目的在于檢驗它是否滿足規定的需求或弄清實際結果與預期結果之間的差別。 軟件測試的目的&#xff1f; 1&#xff09;為了發現程序&#xff0…

uniapp開發2--uniapp中的條件編譯總結

以下是對 uni-app 中條件編譯的總結&#xff1a; 概念&#xff1a; 條件編譯是一種技術&#xff0c;允許你根據不同的平臺或環境&#xff0c;編譯不同的代碼。 在 uni-app 中&#xff0c;這意味著你可以編寫一套代碼&#xff0c;然后根據要編譯到的平臺&#xff08;例如微信小…

【k8s】sidecar邊車容器

一、Sidecar 模式簡介 Sidecar 模式是一種常見的微服務架構設計模式。它通過將附加功能或服務與主應用程序部署在同一容器或主機上&#xff0c;從而實現對主應用程序的增強和擴展。Sidecar 的名稱來源于摩托車的邊車&#xff0c;它與摩托車緊密相連&#xff0c;為主車提供額外…

MySQL索引使用一定有效嗎?如何排查索引效果?

MySQL索引使用一定有效嗎&#xff1f;如何排查索引效果&#xff1f; 1. 索引一定有效嗎&#xff1f; 不一定&#xff01; 即使你創建了索引&#xff0c;MySQL 也可能因為以下原因 不使用索引 或 索引效果不佳&#xff1a; 索引選擇錯誤&#xff1a;MySQL 優化器可能選擇了錯…

漏洞管理體系:從掃描評估到修復驗證的全生命周期實踐

漏洞管理體系&#xff1a;從掃描評估到修復驗證的全生命周期實踐 在網絡安全防御體系中&#xff0c;漏洞管理是“攻防博弈”的核心戰場。據NVD&#xff08;國家漏洞數據庫&#xff09;統計&#xff0c;2023年新增漏洞超21萬個&#xff0c;平均每天披露575個&#xff0c;其中32…

cdh平臺管理與運維最佳實踐

一、容量規劃:構建可持續擴展的數據湖底座 1.1 資源評估三維模型 #mermaid-svg-4Fd5JDKTgwqF1BUd {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-4Fd5JDKTgwqF1BUd .error-icon{fill:#552222;}#mermaid-svg-4Fd5J…

力扣347:前K個高頻元素

給你一個整數數組 nums 和一個整數 k &#xff0c;請你返回其中出現頻率前 k 高的元素。你可以按 任意順序 返回答案。 示例 1: 輸入: nums [1,1,1,2,2,3], k 2 輸出: [1,2]示例 2: 輸入: nums [1], k 1 輸出: [1]題解&#xff1a; 一、思路&#xff1a; 1.我希望將nu…

前饋神經網絡層

FeedForward Network 論文地址 https://arxiv.org/pdf/1706.03762 前饋網絡介紹 前饋網絡是Transformer模型中的關鍵組件&#xff0c;每個Transformer層包含一個多頭注意力模塊和一個前饋網絡模塊。該模塊通過兩次線性變換和激活函數&#xff0c;為模型提供非線性建模能力。其核…

如何將 sNp 文件導入并繪制到 AEDT (HFSS)

導入 sNp 文件 打開您的項目&#xff0c;右鍵單擊 “Result” 繪制結果 導入后&#xff0c;用戶可以選擇它進行打印。請參閱下面的示例。要點&#xff1a;確保從 Solution 中選擇它。