近來(lái)課程需要,跟著learnopengl.com學(xué)習(xí)了opengl,在此將要點(diǎn)記錄以下。
學(xué)習(xí)網(wǎng)站:learnopengl(英文)learnopengl(中文)
一、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ù)的開(kāi)發(fā)者自行決定(譯注:這里開(kāi)發(fā)者是指編寫(xiě)OpenGL庫(kù)的人)。
? ??????實(shí)際的OpenGL庫(kù)的開(kāi)發(fā)者通常是顯卡的生產(chǎn)商。
? ? ? ? 簡(jiǎn)言之,OpenGL只是一個(gè)標(biāo)準(zhǔn)/規(guī)范,具體的實(shí)現(xiàn)是由驅(qū)動(dòng)開(kāi)發(fā)商針對(duì)特定顯卡實(shí)現(xiàn)的
? ??????所有版本的OpenGL規(guī)范文檔都被公開(kāi)的寄存在Khronos那里。例如OpenGL3.3規(guī)范文檔
二、核心模式與立即渲染模式(Core-profile vs Immediate mode)
? ? ? ? 早期的OpenGL使用立即渲染模式(Immediate mode,也就是固定渲染管線),從OpenGL3.2開(kāi)始,規(guī)范文檔開(kāi)始廢棄立即渲染模式,并鼓勵(lì)開(kāi)發(fā)者在OpenGL的核心模式(Core-profile)下進(jìn)行開(kāi)發(fā),這個(gè)分支的規(guī)范完全移除了舊的特性。
三、擴(kuò)展
? ??????OpenGL的一大特性就是對(duì)擴(kuò)展(Extension)的支持,當(dāng)一個(gè)顯卡公司提出一個(gè)新特性或者渲染上的大優(yōu)化,通常會(huì)以擴(kuò)展的方式在驅(qū)動(dòng)中實(shí)現(xiàn)。
? ??????通過(guò)這種方式,開(kāi)發(fā)者不必等待一個(gè)新的OpenGL規(guī)范面世,就可以使用這些新的渲染特性了。
? ??????通常,當(dāng)一個(gè)擴(kuò)展非常流行或者非常有用的時(shí)候,它將最終成為未來(lái)的OpenGL規(guī)范的一部分。
四、狀態(tài)機(jī)
? ??????OpenGL本質(zhì)上是個(gè)大狀態(tài)機(jī)。
? ? ? ? 關(guān)于狀態(tài)機(jī)的解釋:一系列的變量描述OpenGL此刻應(yīng)當(dāng)如何運(yùn)行。OpenGL的狀態(tài)通常被稱為OpenGL上下文(Context)。
? ??????狀態(tài)設(shè)置函數(shù)(State-changing Function):這類函數(shù)將會(huì)改變上下文。
? ??????狀態(tài)使用函數(shù)(State-using Function):這類函數(shù)會(huì)根據(jù)當(dāng)前OpenGL的狀態(tài)執(zhí)行一些操作。
????????我們通常使用如下途徑去更改OpenGL狀態(tài):
? ? ? ? ①設(shè)置選項(xiàng)(setting some options)
? ? ? ? ②操作緩沖(manipulating some buffers)
????????最后,我們使用當(dāng)前OpenGL上下文來(lái)渲染(render using the current context)。
五、對(duì)象
? ??????OpenGL庫(kù)是用C語(yǔ)言寫(xiě)的,同時(shí)也支持多種語(yǔ)言的派生,但其內(nèi)核仍是一個(gè)C庫(kù)。
? ? ? ? 由于C的一些語(yǔ)言結(jié)構(gòu)不易被翻譯到其它的高級(jí)語(yǔ)言,因此OpenGL引入了一些抽象層。
????????“對(duì)象(Object)”就是其中一個(gè)抽象概念。
? ??????在OpenGL中一個(gè)對(duì)象是指一些選項(xiàng)的集合,它代表OpenGL狀態(tài)(即OpenGL上下文)的一個(gè)子集。
? ??????可以把對(duì)象看做一個(gè)C風(fēng)格的結(jié)構(gòu)體(Struct):

? ??????當(dāng)我們使用一個(gè)對(duì)象時(shí),通??雌饋?lái)像如下一樣(把OpenGL上下文看作一個(gè)大的結(jié)構(gòu)體):


? ??????使用OpenGL時(shí)常見(jiàn)的工作流:
? ? ? ? ①首先創(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)。設(shè)置的選項(xiàng)將被保存在objectId所引用的對(duì)象中
? ? ? ? ④最后我們將目標(biāo)位置的對(duì)象id設(shè)回0,解綁這個(gè)對(duì)象
? ? ? ?因?yàn)橹霸O(shè)置的選項(xiàng)被保存在objectId所引用的對(duì)象中, 一旦我們重新綁定這個(gè)對(duì)象到GL_WINDOW_TARGET位置,這些選項(xiàng)就會(huì)重新生效
? ??????使用對(duì)象的好處:
? ? ? ? 我們可以定義多個(gè)對(duì)象,每個(gè)對(duì)象都可以是不同的設(shè)置。在我們執(zhí)行一個(gè)使用OpenGL狀態(tài)的操作的時(shí)候,只需要綁定含有需要的設(shè)置的對(duì)象即可。