一、環(huán)境搭建
準(zhǔn)備資源
GLTools
glew?
libGLTools.a
鏈接: https://pan.baidu.com/s/1vL0WsvilTx9R6tGiNlo6gA 密碼: a3m8
1.新建一個(gè)macOS App罢缸。
2.下載下來(lái)的資源直接拖到項(xiàng)目中夺饲。
3.添加OpenGL.framework 和GLUT.framework兩個(gè)系統(tǒng)庫(kù)徘层。
路徑:TARGETS -> BuildPhases -> Link Binary With Libraries
4.添加GLTools流纹, glew.h
直接拖入項(xiàng)目中的 include 和libGLTool.a文件 到 Header Search path 中
路徑:TARGETS -> Build Setting -> 搜索(Header Search path?)
5.刪除無(wú)用文件畔师。
6.新建一個(gè)c++文件畔咧。
7. c++文件名稱(chēng) 為 main.app茎芭。
8. 簡(jiǎn)單的一個(gè)三角形,ok 完成了誓沸。
demo在鏈接中梅桩,可自行下載。
二拜隧、OpenGL專(zhuān)業(yè)名詞介紹
1.圖形API介紹:
OpenGL(Open Graphics Library: 開(kāi)放式圖形庫(kù)) ,是用于渲染2D, 3D矢量圖的跨編程, 跨平臺(tái)的編程圖形程序接口,它將計(jì)算機(jī)的資源抽象稱(chēng)為一個(gè)個(gè)OpenGL的對(duì)象, 對(duì)這些資源的操作抽象為一個(gè)個(gè)的OpenGL指令.常用于CAD, 虛擬現(xiàn)實(shí),科學(xué)可視化程序和電子游戲開(kāi)發(fā)宿百。
?OpenGL ES(OpenGL for Embedded systems)是OpenGL三維圖形API的子集, 針對(duì)手機(jī), PDA和游戲主機(jī)等嵌入式設(shè)備而設(shè)計(jì), 去除了許多不必要和性能較低的API接口。
DirectX和Metal: DirectX 是由很多API組成的, 并不是一個(gè)單純的圖形API, 且是屬于Windows, 不支持別的平臺(tái). Metal是Apple推出的一個(gè)新的平臺(tái)技術(shù), 該技術(shù)能夠?yàn)?D圖像提高10倍的渲染性能洪添。
2.專(zhuān)業(yè)名詞解釋?zhuān)?/h4>
上下文(Context):
? ? ?1.在應(yīng)用程序調(diào)用任何OpenGL的指令之前犀呼,首先需要?jiǎng)?chuàng)建一個(gè)上下文,這個(gè)上下文其實(shí)是一個(gè)龐大狀態(tài)機(jī)薇组,保存了OpenGL中的各種狀態(tài)外臂,比如顏色,紋理律胀,混合之類(lèi)的宋光,這也是OpenGL指令執(zhí)行的基礎(chǔ)。
? ? ?2.OpenGL的函數(shù)不管在哪個(gè)語(yǔ)言中炭菌,都是類(lèi)似C語(yǔ)言一樣的面向過(guò)程的函數(shù)罪佳,本質(zhì)上都是對(duì)OpenGL上下文這個(gè)龐大的狀態(tài)機(jī)中的某個(gè)狀態(tài)或者對(duì)象進(jìn)行操作,需要將這個(gè)對(duì)象設(shè)置為當(dāng)前對(duì)象黑低。
? ? ?3.由于OpenGL是一個(gè)非常龐大的狀態(tài)機(jī)赘艳,切換上下文會(huì)產(chǎn)生比較大的開(kāi)銷(xiāo)。 ?一般情況下克握, 不同的繪制模塊蕾管, 需要使用完全獨(dú)立的狀態(tài)管理。 因此菩暗, 可以再應(yīng)用程序中分別創(chuàng)建多個(gè)不同的上下文掰曾,在不同線程中使用不同的上下文。上下文之間共享紋理停团,緩沖區(qū)等資源旷坦,這樣比反復(fù)切換上下文掏熬, 或者大量修改渲染狀態(tài), 更加合理高效秒梅。
OpenGL狀態(tài)機(jī):
?狀態(tài)機(jī)是存在理論上的一種機(jī)器旗芬,直接解釋的話這個(gè)狀態(tài)機(jī)是描述了一個(gè)對(duì)象在其生命周期內(nèi)所經(jīng)歷的各種狀態(tài),狀態(tài)的改變捆蜀,以及狀態(tài)發(fā)生改變的原因岗屏,條件和狀態(tài)改變時(shí)的過(guò)程。它具有以下特點(diǎn):
1漱办、有記憶功能这刷,能記住當(dāng)前的狀態(tài)
2、可以接收輸入娩井,根據(jù)輸入的內(nèi)容和自己原先的狀態(tài)暇屋,修改自己當(dāng)前狀態(tài),并且可以有對(duì)應(yīng)輸出洞辣。
3咐刨、當(dāng)進(jìn)入特殊狀態(tài)(停機(jī)狀態(tài))的時(shí)候,便不再接收輸入扬霜,停止工作
OpenGL就可以當(dāng)做是這樣的一個(gè)機(jī)器定鸟,類(lèi)推過(guò)來(lái)理解:
?1、OpenGL可以記錄自己的狀態(tài)(比如當(dāng)前所使用的顏色著瓶,是否開(kāi)啟了混合功能等)
?2联予、OpenGL可以接收輸入(當(dāng)調(diào)用OpenGL函數(shù)的時(shí)候,實(shí)際上可以看成OpenGL在接收我們的輸入)材原,比如我們?cè)谡{(diào) ? ? ? ? ?用glColor3f沸久,則OpenGL接收到這個(gè)輸入后會(huì)修改自己的當(dāng)前顏色這個(gè)狀態(tài)
?3、OpenGL可以進(jìn)入停止?fàn)顟B(tài)余蟹,不再接收輸入卷胯。在程序退出前,OpenGL總會(huì)先停止工作的
渲染:
將圖形/圖像數(shù)據(jù)轉(zhuǎn)換成2D空間圖像操作叫渲染(Rendering)
頂點(diǎn)數(shù)組(VertexArray)和頂點(diǎn)緩沖區(qū)(VertexBuffer):
?畫(huà)圖一般是先畫(huà)好骨架威酒,然后再去填充顏色窑睁,這對(duì)于OpenGL來(lái)說(shuō)也是一樣的,頂點(diǎn)數(shù)據(jù)就是這個(gè)骨架葵孤。OpenGL中的圖像都是由圖元組成担钮。在OpenGL ES中,有3種類(lèi)型的圖元:點(diǎn)佛呻、線裳朋、三角形(所有圖形都是由這些組成)。這些圖形的頂點(diǎn)數(shù)據(jù)儲(chǔ)存的地方是存在內(nèi)存中的吓著,開(kāi)發(fā)者可以選擇設(shè)定函數(shù)指針鲤嫡,在調(diào)用繪制方法的時(shí)候,直接由內(nèi)存?zhèn)魅腠旤c(diǎn)數(shù)據(jù)绑莺,這個(gè)也就是頂點(diǎn)數(shù)組暖眼。而我們知道OpenGL是直接操作GPU的語(yǔ)言,所以有一個(gè)更加高效的做法纺裁,提前分配一塊顯存诫肠,將頂點(diǎn)數(shù)據(jù)提前傳入到顯存中,這部分的顯存就稱(chēng)為頂點(diǎn)緩沖區(qū)欺缘。
著色器程序Shader
1栋豫、就全?的將固定渲染管線架構(gòu)變?yōu)榱丝删幊啼秩竟芫€。因此谚殊,OpenGL在實(shí)際調(diào)?繪制函數(shù)之前丧鸯,還需要指定?個(gè)由shader編譯成的著?器程序。常?的著?器主要有頂點(diǎn)著?器(VertexShader)嫩絮,?段著?器(FragmentShader)/像素著?器(PixelShader)丛肢,?何著?器(GeometryShader),曲?細(xì)分著?器(TessellationShader)剿干。?段著?器和像素著?器只是在OpenGL和DX中的不同叫法?已蜂怎。可惜的是置尔,直到OpenGLES 3.0杠步,依然只?持了頂點(diǎn)著?器和?段著?器這兩個(gè)最基礎(chǔ)的著?器。
2榜轿、OpenGL在處理shader時(shí)篮愉,和其他編譯器一樣,通過(guò)編譯差导、鏈接等步驟试躏,生成了著色器程序(glProgram),著色器程序同時(shí)包含了頂點(diǎn)著色器和片元著色器的運(yùn)算邏輯设褐,在OpenGL進(jìn)行繪制的時(shí)候颠蕴,1.首先由頂點(diǎn)著色器對(duì)傳入的頂點(diǎn)數(shù)據(jù)進(jìn)行運(yùn)算。2.再通過(guò)圖元裝配助析,將頂點(diǎn)轉(zhuǎn)換為圖元犀被。3.最后將柵格化數(shù)據(jù)傳入片元著色器中進(jìn)行運(yùn)算,片元著色器會(huì)對(duì)柵格化數(shù)據(jù)中的每一個(gè)像素進(jìn)行運(yùn)算外冀,并決定像素顏色寡键。
管線
在OpenGL下渲染圖形,就會(huì)有經(jīng)歷一個(gè)一個(gè)節(jié)點(diǎn)雪隧。這個(gè)操作就可以理解為管線西轩。其實(shí)就是像流水線一樣员舵,任務(wù)是有先后順序,嚴(yán)格按著這個(gè)順序一步一步去執(zhí)行藕畔。管線是一個(gè)抽象的概念马僻,之所以稱(chēng)之為管線是因?yàn)轱@卡處理數(shù)據(jù)的時(shí)候是按照一個(gè)固定的順序來(lái)的,這個(gè)順序是不能被打破的注服。
固定管線/存儲(chǔ)著色器
早期的OpenGL版本韭邓,封裝了很多著色器程序塊內(nèi)置的一段包含了光照,坐標(biāo)變換溶弟,裁剪等諸多功能的固定shader程序女淑,來(lái)幫助開(kāi)發(fā)者完成對(duì)圖形的渲染, 開(kāi)發(fā)者只需要傳入相應(yīng)的參數(shù)就可以快速完成渲染辜御。類(lèi)似于使用工廠的模具只需要選擇不同的模具去生產(chǎn)鸭你,不需要知道怎么生產(chǎn)模具。 ?由于OpenGL使用場(chǎng)景非常豐富我抠,固定管線和shader無(wú)法滿足很多業(yè)務(wù)苇本,所以一些相關(guān)部分開(kāi)放為可編程。
頂點(diǎn)著色器 VertexShader
1菜拓、一般用來(lái)處理圖形每個(gè)頂點(diǎn)變換(旋轉(zhuǎn)瓣窄、平移、投影等)
2纳鼎、頂點(diǎn)著色器是OpenGL中用于計(jì)算頂點(diǎn)屬性的程序俺夕,且每個(gè)頂點(diǎn)數(shù)據(jù)都會(huì)執(zhí)行一次頂點(diǎn)著色器,是并發(fā)執(zhí)行的贱鄙。
3劝贸、一般來(lái)說(shuō)典型的需要計(jì)算的頂點(diǎn)屬性主要包括:頂點(diǎn)坐標(biāo)變換、逐頂點(diǎn)光照運(yùn)算等逗宁。頂點(diǎn)坐標(biāo)由自身坐標(biāo)系轉(zhuǎn)換到歸一化坐標(biāo)系的運(yùn)算映九,就是再這里發(fā)生的。
片元著色器
1瞎颗、一般用來(lái)處理圖形中每個(gè)像素點(diǎn)顏色計(jì)算和填充
2件甥、片元著色器是OpenGL中用于計(jì)算片段(像素)顏色的程序。片元著色器是逐像素運(yùn)算的程序哼拔,也就是說(shuō)每個(gè)像素都會(huì)執(zhí)行一次片元著色器引有,也是并發(fā)執(zhí)行的。
GLSL(OpenGL Shading Language)
OpenGL 著色語(yǔ)言倦逐。 是用來(lái)在OpenGL中著色編程的語(yǔ)言譬正。也即開(kāi)發(fā)?員寫(xiě)的短?的?定義程序,他們是在圖形卡的GPU (Graphic Processor Unit圖形處理單元)上執(zhí)?的,代替了固定的渲染管線的?部分曾我,使渲染管線中不同層次具有可編程性粉怕。?如:視圖轉(zhuǎn)換、投影轉(zhuǎn)換等您单。GLSL(GL Shading Language)的著?器代碼分成2個(gè)部分:Vertex Shader(頂點(diǎn)著?器)和Fragment(?元著?器)
光柵化Rasterization
1斋荞、是把頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換為?元的過(guò)程荞雏,具有將圖轉(zhuǎn)化為?個(gè)個(gè)柵格組成的圖象的作?虐秦,特點(diǎn)是每個(gè)元素對(duì)應(yīng)幀緩沖區(qū)中的?像素。
2凤优、光柵化就是把頂點(diǎn)數(shù)據(jù)轉(zhuǎn)換為?元的過(guò)程悦陋。?元中的每?個(gè)元素對(duì)應(yīng)于幀緩沖區(qū)中的?個(gè)像素。
3筑辨、光柵化其實(shí)是?種將?何圖元變?yōu)?維圖像的過(guò)程俺驶。該過(guò)程包含了兩部分的?作。第?部分?作:決定窗?坐標(biāo)中的哪些整型柵格區(qū)域被基本圖元占?棍辕;第?部分?作:分配?個(gè)顏?值和?個(gè)深度值到各個(gè)區(qū)域暮现。光柵化過(guò)程產(chǎn)?的是?元。
4楚昭、把物體的數(shù)學(xué)描述以及與物體相關(guān)的顏?信息轉(zhuǎn)換為屏幕上?于對(duì)應(yīng)位置的像素及?于填充像素的顏?栖袋,這個(gè)過(guò)程稱(chēng)為光柵化,這是?個(gè)將模擬信號(hào)轉(zhuǎn)化為離散信號(hào)的過(guò)程抚太。
紋理
紋理其實(shí)我們也叫做圖片塘幅,讓我們?cè)阡秩緢D形時(shí),需要在其編碼填充圖片尿贫,讓場(chǎng)景更加逼真电媳,在這里叫做紋理。
混合(Blending)
在測(cè)試階段之后庆亡,如果像素依然沒(méi)有被剔除匾乓,那么像素的顏?將會(huì)和幀緩沖區(qū)中顏?附著上的顏?進(jìn)?混合,混合的算法可以通過(guò)OpenGL的函數(shù)進(jìn)?指定又谋。但是OpenGL提供的混合算法是有限的拼缝,如果需要更加復(fù)雜的混合算法,?般可以通過(guò)像素著?器進(jìn)?實(shí)現(xiàn)搂根,當(dāng)然性能會(huì)?原?的混合算法差?些珍促。
變換矩陣(Transformation)
?例如圖形想發(fā)?平移,縮放剩愧,旋轉(zhuǎn)變換猪叙,就需要使?變換矩陣。
投影矩陣Projection?
?于將3D坐標(biāo)轉(zhuǎn)換為?維屏幕坐標(biāo),實(shí)際線條也將在?維坐標(biāo)下進(jìn)?繪制穴翩。
渲染上屏/交換緩沖區(qū)(SwaoBuffer)
1犬第、渲染緩沖區(qū)?般映射的是系統(tǒng)的資源?如窗?。如果將圖像直接渲染到窗?對(duì)應(yīng)的渲染緩沖區(qū)芒帕,則可以將圖像顯示到屏幕上歉嗓。
2、如果每個(gè)窗口只有一個(gè)緩沖區(qū)背蟆,那么在繪制過(guò)程中屏幕進(jìn)行了刷新鉴分,窗口可能顯示出不完整的圖像。
3带膀、由于顯示器的刷新一般是逐步進(jìn)行的志珍,因此為了防止交換緩沖區(qū)的時(shí)候屏幕上下區(qū)域的圖像分屬于兩個(gè)不同的幀,因此交換一般會(huì)等待顯示器刷新完成的信號(hào)垛叨,在顯示器兩次刷新的間隔中進(jìn)行交換伦糯,這個(gè)信號(hào)就被稱(chēng)為垂直同步信號(hào),這個(gè)技術(shù)被稱(chēng)為垂直同步嗽元。
4敛纲、使用了雙緩沖區(qū)和垂直同步技術(shù)后,由于要等待緩沖區(qū)交換之后再進(jìn)行下一陣的渲染剂癌,是的幀率無(wú)法完全達(dá)到硬件允許的最高水平淤翔。為了解決這個(gè)問(wèn)題,引入了三緩沖區(qū)技術(shù)珍手,在等待垂直同步時(shí)办铡,來(lái)回交替渲染兩個(gè)離屏的緩沖區(qū),而垂直同步發(fā)生時(shí)琳要,屏幕緩沖區(qū)和最近渲染完成的離屏緩沖區(qū)交換寡具,實(shí)現(xiàn)充分利用性能的目的。
著色器渲染流程