OpenGL/GLES Notes

@(Graphics)[OpenGL, OpenGLES]

OpenGL/GLES Notes

EGL

opengl和host app window system之間的glue層

使用egl進(jìn)行綁定例程中, 主要創(chuàng)建的對象包括

  • display device: eglGetDisplay 使用default即可
  • config object: 包含了當(dāng)前render相關(guān)的所有參數(shù), 包括target的buffer格式, frame組成, onscreen/offscreen等, 通過eglGetConfigseglChooseConfig進(jìn)行查詢, 獲取一個合適的config
  • rendering surface: 根據(jù)onscreen/offscreen區(qū)分, 使用eglCreateWindowSurfaceeglCreatePbufferSurface. 前者需要傳入一個平臺相關(guān)的window對象(例如Windows上就是HWND). 需要額外指定surface的模式參數(shù), 例如單/雙緩沖, frame的大小等
  • rendering context: 包含了所有的gl state. eglCreateContext. 可以實現(xiàn)context共享, 但是一般用不到. 需要額外的context參數(shù), 主要是opengl/es的版本
  • 把context和surface綁定: eglMakeCurrent

iOS Apple自己有提供context: EAGLContext, 創(chuàng)建非常簡單, 不需要使用到EGL.

Program Object & Shaders

從Host app向Shader傳遞數(shù)據(jù)有2種主要形式

  • attribute
  • uniform

Attributes

attribute的數(shù)據(jù)處理時是per vertex的, 但我們可以給所有vertex賦予不同, 也可以給相同的值. (后者在OpenGLES3.0 PG這本書中稱為 constant vertex attribute)

當(dāng)program編譯并完成之后, 其attribute入?yún)⒌南嚓P(guān)meta data都確定了, 可以通過一些列query方法抽取.

  • 調(diào)用glGetProgram提供GL_ACTIVE_ATTRIBUTESGL_ACTIVE_ATTRIBUTE_MAX_LENGTH, 可以獲知indexCount和max name length
  • 調(diào)用glGetActiveAttrib可以一次性獲取到attribute的name, type, size等參數(shù). 調(diào)用時的index一定是屬于0..<indexCountrange內(nèi)

注意: OpenGL里對類似GL_MAX_VERTEX_ATTRIBS這類state限制的解釋: 都是以vec4為單位的, 如果出現(xiàn)數(shù)組或者struct或者mat4, 是按復(fù)數(shù)倍來計算的. 因此最終programmer真正能使用的active attribute的參數(shù)個數(shù)可能會少于GL_MAX_VERTEX_ATTRIBS. 即: 仍然是從0開始遞增計數(shù), 但上限會更小.

但一般host app在給shader提供具體data時, 并不會從program從頭開始query參數(shù)來決定如何提供data, 而是根據(jù)先驗的知識(例如location, name等)來決定提供data的方式.

  • attribute的layout location和index不是一個概念, index一定從0開始以step為1遞增, 但location可以在shader中, 用layout(location = x)指定. 同時當(dāng)一個attribute的size較大時, 相鄰index的attribute的location差大于1, 具體規(guī)則可以理解成一個vec4會加1, array中的每個元素一定按vec4的stride進(jìn)行align
  • 如果知道attribute名, 也可以通過glGetAttribLocation進(jìn)行獲取
  • 也可以在program link之前, 預(yù)先用glBindAttribLocation指定某個name的location(但不可以和layout qualifier沖突)
  • 獲取location后, 調(diào)用glVertexAttribglVertexAttribPointer傳遞數(shù)據(jù). 后者可以進(jìn)一步把將對應(yīng)的data buffer綁定到GL_ARRAY_BUFFER/GL_ELEMENT_ARRAY_BUFFER. 對同一個location, constant/array(包含VBO)這2種模式可以同時指定, 通過glEnableVertexAttribArray啟用后者

VAO: vertex array pointer

如上所述, 在GLES3.0前, 有三種提供vertex attributes的方式

  1. constant vertex attribute glVertexAttrib
  2. client vertex array glVertexAttribPointer withglEnableVertexAttribArray
  3. VBO, glVertexAttribPointer with buffer bound to GL_ARRAY_BUFFER / GL_ELEMENT_ARRAY_BUFFER

事實上, 上述API更改的是當(dāng)前active的VAO對象. 通過預(yù)先配置好不同的VAO, 并且實時切換, 可以快速提供一組新的對象給GPU繪制.
默認(rèn)有一個VAO(id是0), glGenVertexArrays可以生成額外的, 不同的VAO用glBindVertexArray切換

Uniforms

Uniforms是全局constant, vertex shader和fragment shader中每次執(zhí)行都獲取相同的值. 但uniform有2種定義方式.

  • 使用uniform Type identifier;定義的uniform, 位于匿名的default uniform group
  • 也可以通過uniform Name{ Type identifier; }方式定義一個實名為Name的uniform group.
    • 使用layout(std140)可以使用標(biāo)準(zhǔn)化的布局, 便于在host app中準(zhǔn)備數(shù)據(jù)

和vertex attributes一樣, 可以從program中獲取大量信息

  • 調(diào)用glGetProgram提供GL_ACTIVE_UNIFORMSGL_ACTIVE_UNIFORM_MAX_LENGTH, 可以獲知indexCount和max name length. 這邊獲取的param是所有包含于任何default/named uniform group的uniforms的值.
  • 以index為0..<indexCount范圍內(nèi)的值調(diào)用glGetActiveUniform可以一次性獲取uniform的name, type, size等參數(shù), 這一點和attribute類似. 除此之外, 還可以調(diào)用glGetActiveUniformsiv批量獲取一組index的信息, 這個方法主要支援的是隸屬于named uniform block的uniforms, 可以額外獲取該uniform隸屬的uniform block的index, 以及其在block中的offset/stride等屬性; 如果對default uniform block中的uniform調(diào)用此方法, 上面這些參數(shù)值只能取到-1.

named uniform block是gles 3.0新增概念, 對于uniform block本身也有metadata可以獲取

  • 調(diào)用glGetProgram提供GL_ACTIVE_UNIFORM_BLOCKSGL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, 可以獲取block的indexCount和max name Length. 不包括default uniform block.
  • 提供0..<indexCount范圍內(nèi)的值, 給glGetActiveUniformBlockName可以獲取到block的name, 而glGetActiveUniformBlockiv可以獲取到更多param, 包括buffer binding, size; 最終要的屬性是該bblock所包含的uniform列表, 可以按uniform的global index進(jìn)行索引.

Host app提供uniform data和attribute也有兩種方式, trivial value/buffer. 同樣我們一般擁有先驗知識: uniform的name. 而想要提供數(shù)據(jù), 無論如何, 也都需要首先獲取到shader中uniform的位置.

  • 對于default uniform block中的uniform, 和attribute類似, 需要獲取location, 該值和index不是一個概念:
    • glGetUniformLocation可以根據(jù)uniform的name查詢location
    • 獲取到location后, 使用glUniform傳遞data即可
  • 對于named uniform block, 即使已經(jīng)獲取到了成員的index(無論是通過glGetUniformIndices直接由name獲取, 還是通過獲取到block index后, 使用glGetActiveUniformBlock間接獲取), 也無法通過glGetUniformLocation獲取location.
    • 必須在通過glGetActiveUniformBlock獲取到uniform block的index后, 調(diào)用glUniformBlockBinding將該block和一個user-defined的binding point聯(lián)系起來.
    • 緊接著, 將一個bind到GL_UNIFORM_BUFFERtarget的data buffer, 通過glBindBufferBase/glBindBufferRange和該binding point進(jìn)行關(guān)聯(lián). 此時buffer中的data即可傳遞. (事實上這2個方法可以同時bind到這個index binding point, 同時bind到這個target; 因此有時可以省去一次單獨的glBindBuffer)

Buffers

in gpu/ opengl controlled

Types

  • uniform (block )buffer
  • vertex array buffer
  • vertex element buffer

Copy

gpu memory 1 -> gpu memory 2

Map

gpu memory -> client

DrawCalls

  • drawArrays
  • drawElements
  • instanced drawing
  • drawing query object
    • Q: if we enable instance divisor on an indexed per-vertex attribute, what will happen?
      A: it will behavior as per-instance, ignoring indexing

Shaders

Vertex Shader

Fragment Shader

  • gl_PointCoord, 用于GL_POINTS繪制時, 如果VS輸出的gl_PointSize大于1, 則每個fragment會指示自己位于整個point的哪個位置.
    • 注意: 左上角為0, 0, 右下角為1, 1. 此坐標(biāo)系為OpenGL特例! .
    • 可以方便用來實現(xiàn)point sprite的紋理渲染
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蠕搜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岖沛,死亡現(xiàn)場離奇詭異钠怯,居然都是意外死亡玻驻,警方通過查閱死者的電腦和手機(jī)供常,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門摊聋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人栈暇,你說我怎么就攤上這事麻裁。” “怎么了源祈?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵煎源,是天一觀的道長。 經(jīng)常有香客問我香缺,道長手销,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任图张,我火速辦了婚禮锋拖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘埂淮。我一直安慰自己姑隅,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布倔撞。 她就那樣靜靜地躺著讲仰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪痪蝇。 梳的紋絲不亂的頭發(fā)上鄙陡,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天,我揣著相機(jī)與錄音躏啰,去河邊找鬼趁矾。 笑死,一個胖子當(dāng)著我的面吹牛给僵,可吹牛的內(nèi)容都是我干的毫捣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼帝际,長吁一口氣:“原來是場噩夢啊……” “哼蔓同!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蹲诀,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤斑粱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后脯爪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體则北,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡矿微,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了尚揣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涌矢。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖惑艇,靈堂內(nèi)的尸體忽然破棺而出蒿辙,到底是詐尸還是另有隱情,我是刑警寧澤滨巴,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布思灌,位于F島的核電站,受9級特大地震影響恭取,放射性物質(zhì)發(fā)生泄漏泰偿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一蜈垮、第九天 我趴在偏房一處隱蔽的房頂上張望耗跛。 院中可真熱鬧,春花似錦攒发、人聲如沸调塌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽羔砾。三九已至,卻和暖如春偶妖,著一層夾襖步出監(jiān)牢的瞬間姜凄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工趾访, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留态秧,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓扼鞋,卻偏偏與公主長得像申鱼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子云头,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354