OpenGL(QT平台)学习与实战(一)
參考資料:
LearnOpenGL CN
《現(xiàn)代OpenGL:1入門篇,2021 Qt實(shí)現(xiàn)版》
OpenGL
我們先了解一下OpenGL到底是什么。一般它被認(rèn)為是一個(gè)API(Application Programming Interface, 應(yīng)用程序編程接口),包含了一系列可以操作圖形、圖像的函數(shù)。然而,OpenGL本身并不是一個(gè)API,它僅僅是一個(gè)由Khronos組織制定并維護(hù)的規(guī)范(Specification)。
OpenGL規(guī)范嚴(yán)格規(guī)定了每個(gè)函數(shù)該如何執(zhí)行,以及它們的輸出值。至于內(nèi)部具體每個(gè)函數(shù)是如何實(shí)現(xiàn)(Implement)的,將由OpenGL庫(kù)的開發(fā)者自行決定(注:這里開發(fā)者是指編寫OpenGL庫(kù)的人)。因?yàn)镺penGL規(guī)范并沒有規(guī)定實(shí)現(xiàn)的細(xì)節(jié),具體的OpenGL庫(kù)允許使用不同的實(shí)現(xiàn),只要其功能和結(jié)果與規(guī)范相匹配(亦即,作為用戶不會(huì)感受到功能上的差異)。
實(shí)際的OpenGL庫(kù)的開發(fā)者通常是顯卡的生產(chǎn)商。你購(gòu)買的顯卡所支持的OpenGL版本都為這個(gè)系列的顯卡專門開發(fā)的。當(dāng)你使用Apple系統(tǒng)的時(shí)候,OpenGL庫(kù)是由Apple自身維護(hù)的。在Linux下,有顯卡生產(chǎn)商提供的OpenGL庫(kù),也有一些愛好者改編的版本。這也意味著任何時(shí)候OpenGL庫(kù)表現(xiàn)的行為與規(guī)范規(guī)定的不一致時(shí),基本都是庫(kù)的開發(fā)者留下的bug。
所有版本的OpenGL規(guī)范文檔都被公開的寄存在Khronos那里。有興趣的讀者可以找到OpenGL3.3(我們將要使用的版本)的規(guī)范文檔。如果你想深入到OpenGL的細(xì)節(jié)(只關(guān)心函數(shù)功能的描述而不是函數(shù)的實(shí)現(xiàn)),這是個(gè)很好的選擇。如果你想知道每個(gè)函數(shù)具體的運(yùn)作方式,這個(gè)規(guī)范也是一個(gè)很棒的參考。
狀態(tài)機(jī)
OpenGL自身是一個(gè)巨大的狀態(tài)機(jī)(State Machine):一系列的變量描述OpenGL此刻應(yīng)當(dāng)如何運(yùn)行。OpenGL的狀態(tài)通常被稱為OpenGL上下文(Context)。我們通常使用如下途徑去更改OpenGL狀態(tài):設(shè)置選項(xiàng),操作緩沖。最后,我們使用當(dāng)前OpenGL上下文來(lái)渲染。
假設(shè)當(dāng)我們想告訴OpenGL去畫線段而不是三角形的時(shí)候,我們通過改變一些上下文變量來(lái)改變OpenGL狀態(tài),從而告訴OpenGL如何去繪圖。一旦我們改變了OpenGL的狀態(tài)為繪制線段,下一個(gè)繪制命令就會(huì)畫出線段而不是三角形。
當(dāng)使用OpenGL的時(shí)候,我們會(huì)遇到一些狀態(tài)設(shè)置函數(shù)(State-changing Function),這類函數(shù)將會(huì)改變上下文。以及狀態(tài)應(yīng)用函數(shù)(State-using Function),這類函數(shù)會(huì)根據(jù)當(dāng)前OpenGL的狀態(tài)執(zhí)行一些操作。只要你記住OpenGL本質(zhì)上是個(gè)大狀態(tài)機(jī),就能更容易理解它的大部分特性。
對(duì)象
OpenGL庫(kù)是用C語(yǔ)言寫的,同時(shí)也支持多種語(yǔ)言的派生,但其內(nèi)核仍是一個(gè)C庫(kù)。由于C的一些語(yǔ)言結(jié)構(gòu)不易被翻譯到其它的高級(jí)語(yǔ)言,因此OpenGL開發(fā)的時(shí)候引入了一些抽象層。“對(duì)象(Object)”就是其中一個(gè)。
在OpenGL中一個(gè)對(duì)象是指一些選項(xiàng)的集合,它代表OpenGL狀態(tài)的一個(gè)子集。比如,我們可以用一個(gè)對(duì)象來(lái)代表繪圖窗口的設(shè)置,之后我們就可以設(shè)置它的大小、支持的顏色位數(shù)等等。可以把對(duì)象看做一個(gè)C風(fēng)格的結(jié)構(gòu)體(Struct):
struct object_name {GLfloat option1;GLuint option2;GLchar[] name; };基元類型(Primitive Type)
使用OpenGL時(shí),建議使用OpenGL定義的基元類型。比如使用float時(shí)我們加上前綴GL(因此寫作GLfloat)。int、uint、char、bool等等也類似。OpenGL定義的這些GL基元類型的內(nèi)存布局是與平臺(tái)無(wú)關(guān)的,而int等基元類型在不同操作系統(tǒng)上可能有不同的內(nèi)存布局。使用GL基元類型可以保證你的程序在不同的平臺(tái)上工作一致。
當(dāng)我們使用一個(gè)對(duì)象時(shí),通常看起來(lái)像如下一樣(把OpenGL上下文看作一個(gè)大的結(jié)構(gòu)體):
// OpenGL的狀態(tài) struct OpenGL_Context {...object* object_Window_Target;... }; // 創(chuàng)建對(duì)象 GLuint objectId = 0; glGenObject(1, &objectId); // 綁定對(duì)象至上下文 glBindObject(GL_WINDOW_TARGET, objectId); // 設(shè)置當(dāng)前綁定到 GL_WINDOW_TARGET 的對(duì)象的一些選項(xiàng) glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800); glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600); // 將上下文對(duì)象設(shè)回默認(rèn) glBindObject(GL_WINDOW_TARGET, 0);這一小段代碼展現(xiàn)了你以后使用OpenGL時(shí)常見的工作流。我們首先創(chuàng)建一個(gè)對(duì)象,然后用一個(gè)id保存它的引用(實(shí)際數(shù)據(jù)被儲(chǔ)存在后臺(tái))。然后我們將對(duì)象綁定至上下文的目標(biāo)位置(例子中窗口對(duì)象目標(biāo)的位置被定義成GL_WINDOW_TARGET)。接下來(lái)我們?cè)O(shè)置窗口的選項(xiàng)。最后我們將目標(biāo)位置的對(duì)象id設(shè)回0,解綁這個(gè)對(duì)象。設(shè)置的選項(xiàng)將被保存在objectId所引用的對(duì)象中,一旦我們重新綁定這個(gè)對(duì)象到GL_WINDOW_TARGET位置,這些選項(xiàng)就會(huì)重新生效。
使用對(duì)象的一個(gè)好處是在程序中,我們不止可以定義一個(gè)對(duì)象,并設(shè)置它們的選項(xiàng),每個(gè)對(duì)象都可以是不同的設(shè)置。在我們執(zhí)行一個(gè)使用OpenGL狀態(tài)的操作的時(shí)候,只需要綁定含有需要的設(shè)置的對(duì)象即可。比如說我們有一些作為3D模型數(shù)據(jù)(一棟房子或一個(gè)人物)的容器對(duì)象,在我們想繪制其中任何一個(gè)模型的時(shí)候,只需綁定一個(gè)包含對(duì)應(yīng)模型數(shù)據(jù)的對(duì)象就可以了(當(dāng)然,我們需要先創(chuàng)建并設(shè)置對(duì)象的選項(xiàng))。擁有數(shù)個(gè)這樣的對(duì)象允許我們指定多個(gè)模型,在想畫其中任何一個(gè)的時(shí)候,直接將對(duì)應(yīng)的對(duì)象綁定上去,便不需要再重復(fù)設(shè)置選項(xiàng)了。
QT簡(jiǎn)介
QT是一套應(yīng)用程序開發(fā)庫(kù),但與MFC不同,QT是跨平臺(tái)的開發(fā)類庫(kù)。其中,跨平臺(tái)意味著只需要編寫一次程序,在不同平臺(tái)上無(wú)需改動(dòng)或只需少許改動(dòng)后再編譯,就可以形成在不同平臺(tái)上運(yùn)行的版本。
使用QT的原因
優(yōu)勢(shì):
什么是第三方庫(kù)呢? ——GLFW+GLAD
GLFW解決操作系統(tǒng)層面的不同:
GLAD使得代碼可以用于不同的OpenGL驅(qū)動(dòng)
總結(jié)
以上是生活随笔為你收集整理的OpenGL(QT平台)学习与实战(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MAC OS下编译tensorflow
- 下一篇: 信息搜集简介