自學(xué) openGL(一)-理論基礎(chǔ)

核心渲染模式與立即渲染模式

立即渲染模式

早期 openGL 使用的渲染模式,也稱固定渲染管線,這個(gè)模式下繪制圖形很方便。openGL的大多數(shù)功能都被隱藏起來(lái),開(kāi)發(fā)者很好有控制openGL如何進(jìn)行計(jì)算的自由。openGL 3.2 開(kāi)始,規(guī)范文檔開(kāi)始廢棄立即渲染模式,并鼓勵(lì)開(kāi)發(fā)者在 openGL的核心模式下開(kāi)發(fā),這個(gè)分之規(guī)范完全移出就的特性。

核心渲染模式

當(dāng)使用 OpenGL 核心模式時(shí),OpenGL 迫使我們使用現(xiàn)代函數(shù)。當(dāng)我們視圖使用一個(gè)已被廢棄的函數(shù)時(shí),OpenGL會(huì)跑出一個(gè)錯(cuò)誤并終止繪圖?,F(xiàn)代函數(shù)的優(yōu)勢(shì)時(shí)靈活性和效率,然而也更難學(xué)習(xí)。理解渲染模式從OpenGL 世紀(jì)運(yùn)作中抽象掉很多細(xì)節(jié),因此易學(xué)習(xí),也很難讓人去把我OpenGL具體時(shí)如何運(yùn)作的?,F(xiàn)代函數(shù)要求使用者真正理解 OpenGL 和圖形編程

我學(xué)習(xí)的是 OpenGL 3.3 版本,雖然上手更加困難,但這份努力一定值得。

擴(kuò)展

OpenGL 的一大特性就是對(duì)擴(kuò)展的支持,當(dāng)顯卡工時(shí)提出一個(gè)新特性或者渲染上的優(yōu)化,通常以擴(kuò)展的方式在驅(qū)動(dòng)中實(shí)現(xiàn)。如果一個(gè)程序在支持這個(gè)擴(kuò)展的顯卡上運(yùn)行,開(kāi)發(fā)者可以使用這個(gè)擴(kuò)展提供一些更優(yōu)先更有效的圖形功能。通過(guò)這種方式開(kāi)發(fā)者不必等待新的OpenGL規(guī)范面試就可以使用這些新的渲染特性,只需要簡(jiǎn)單地檢查一下顯卡是否支持此擴(kuò)展。通常,當(dāng)一個(gè)擴(kuò)展非常流行或者非常游泳的時(shí)候,它將最終成為未來(lái)的OpenGL 規(guī)范的一部分。

使用擴(kuò)展的代碼大多看上去如下:

if(GL_ARB_extension_name)
{
    // 使用硬件支持的全新的現(xiàn)代特性
}
else
{
    // 不支持此擴(kuò)展: 用舊的方式去做
}

狀態(tài)機(jī)

OpenGL 自身是一個(gè)巨大的狀態(tài)機(jī):一系列的變量描述OpenGL 此刻應(yīng)當(dāng)如何運(yùn)行。OpenGL 的狀態(tài)通常被稱為OpenGL 上下文。我們同城使用如下途徑去更改OpenGL 狀態(tài):設(shè)置選項(xiàng),曹祖緩沖。最后,我們使用當(dāng)前OpenGL上下文來(lái)渲染。

假設(shè)當(dāng)我們想告訴OpenGL去畫線段而不是三角形的時(shí)候,我們通過(guò)改變上下文變量來(lái)改變OpenGL 狀態(tài),從而告訴OpenGL如何去繪制。一旦我們改變了OpenGL的狀態(tài)為繪制線段,下一個(gè)繪制命令就會(huì)畫出現(xiàn)斷而不是三角形。

當(dāng)使用OpenGL的時(shí)候我們會(huì)遇到一些狀態(tài)設(shè)置函數(shù),這類函數(shù)將會(huì)改變上下文。以及狀態(tài)使用函數(shù),這類函數(shù)會(huì)根據(jù)當(dāng)前OpenGL的狀態(tài)執(zhí)行操作。只要你記住OpenGL本質(zhì)是一個(gè)巨大的狀態(tài)及,就能更容易理解它的大部分特性。

對(duì)象

OpenGL庫(kù)是用c語(yǔ)言寫的,同時(shí)支持多種語(yǔ)言的派生,但其內(nèi)核認(rèn)識(shí)一個(gè)c庫(kù)。由于c的一些語(yǔ)言結(jié)構(gòu)不易被翻譯到其他高級(jí)語(yǔ)言,因此OpenGL開(kāi)發(fā)的時(shí)候引入一些抽象層?!皩?duì)象”就是其中一個(gè)。

在OpenGL中一對(duì)象是指一些選項(xiàng)的集合,它代表OpenGL狀態(tài)的子集,比如,我們可以用一個(gè)對(duì)象來(lái)代表繪圖窗口的設(shè)置,之后我們就可以設(shè)置他的大小、支持的顏色位數(shù)等等??梢园蓪?duì)象看做一個(gè)c風(fēng)格的結(jié)構(gòu)體:

struct object_name {
    float  option1;
    int    option2;
    char[] name;
};

當(dāng)我們使用一個(gè)對(duì)象時(shí),通??雌饋?lái)像如下一樣:

// OpenGL的狀態(tài)
struct OpenGL_Context {
    ...
    object* object_Window_Target;
    ...     
};
//------------------------
// 創(chuàng)建對(duì)象
unsigned int 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í)常見(jiàn)的工作流。我們首先常見(jiàn)一個(gè)對(duì)象,然后使用一個(gè)id保存引用。然后我們將對(duì)象綁定至上下文的目標(biāo)位置。接下來(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è)對(duì)象并設(shè)置它們的選項(xiàng),每個(gè)對(duì)象都可以不同的設(shè)置。在我們執(zhí)行一個(gè)使用OpenGL狀態(tài)操作的時(shí)候,只需要綁定含有需要的設(shè)置對(duì)象即可。比如說(shuō)我們有一些作為3D模型數(shù)據(jù)的容器對(duì)象,在我們想繪制其中任何一個(gè)模型的時(shí)候,只需綁定一個(gè)對(duì)象模型數(shù)據(jù)對(duì)象就可以了。擁有數(shù)個(gè)這樣的對(duì)象允許我們指定多個(gè)模型,在想畫其中任何一個(gè)的時(shí)候,直接將對(duì)應(yīng)的對(duì)象想綁定上去,便不需要再重復(fù)設(shè)置選項(xiàng)了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容