OpenGL ES 框架詳細(xì)解析(十二) —— 采用OpenGL ES 3.0

版本記錄

版本號 時(shí)間
V1.0 2017.10.03

前言

OpenGL ES是一個(gè)強(qiáng)大的圖形庫,是跨平臺的圖形API,屬于OpenGL的一個(gè)簡化版本。iOS系統(tǒng)可以利用OpenGL ES將圖像數(shù)據(jù)直接送入到GPU進(jìn)行渲染,這樣避免了從CPU進(jìn)行計(jì)算再送到顯卡渲染帶來的性能的高消耗,能帶來來更好的視頻效果和用戶體驗(yàn)。接下來幾篇就介紹下iOS 系統(tǒng)的 OpenGL ES框架。感興趣的可以看上面幾篇。
1. OpenGL ES 框架詳細(xì)解析(一) —— 基本概覽
2. OpenGL ES 框架詳細(xì)解析(二) —— 關(guān)于OpenGL ES
3. OpenGL ES 框架詳細(xì)解析(三) —— 構(gòu)建用于iOS的OpenGL ES應(yīng)用程序的清單
4. OpenGL ES 框架詳細(xì)解析(四) —— 配置OpenGL ES的上下文
5. OpenGL ES 框架詳細(xì)解析(五) —— 使用OpenGL ES和GLKit進(jìn)行繪制
6. OpenGL ES 框架詳細(xì)解析(六) —— 繪制到其他渲染目的地
7. OpenGL ES 框架詳細(xì)解析(七) —— 多任務(wù),高分辨率和其他iOS功能
8. OpenGL ES 框架詳細(xì)解析(八) —— OpenGL ES 設(shè)計(jì)指南
9. OpenGL ES 框架詳細(xì)解析(九) —— 調(diào)整您的OpenGL ES應(yīng)用程序
10. OpenGL ES 框架詳細(xì)解析(十) —— 使用頂點(diǎn)數(shù)據(jù)的最佳做法
11. OpenGL ES 框架詳細(xì)解析(十一) —— 并發(fā)和OpenGL ES

Adopting OpenGL ES 3.0 - 采用OpenGL ES 3.0

OpenGL ES 3.0OpenGL ES 2.0規(guī)范的超集,因此在您的應(yīng)用程序中采用它是容易的。 您可以繼續(xù)使用OpenGL ES 2.0代碼,同時(shí)利用兼容設(shè)備上OpenGL ES 3.0上下文的更高資源限制,并增加對OpenGL ES 3.0特定功能的支持,使您的應(yīng)用程序的設(shè)計(jì)變得有意義。


Checklist for Adopting OpenGL ES 3.0 - 采用OpenGL ES 3.0的清單

在您的應(yīng)用程序中使用OpenGL ES 3.0:

EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];

如果您打算將應(yīng)用程序提供給不支持OpenGL ES 3.0的設(shè)備,請按照 Listing 2-1中的步驟在必要時(shí)退回到OpenGL ES 2.0。

  • 在使用OpenGL ES 3.0 API的源文件中包含或?qū)隣penGL ES 3.0 API頭文件:
#import <OpenGLES/ES3/gl.h>
#import <OpenGLES/ES3/glext.h>
  • 更新代碼,使用OpenGL ES 2.0擴(kuò)展并入或更改OpenGL ES 3.0規(guī)范,如下面更新擴(kuò)展代碼中所述。
  • (可選)您可以在OpenGL ES 2.0和3.0中使用相同的著色器程序。 但是,如果您選擇將著色器移植到GLSL ES 3.0以使用新功能,請參閱采用OpenGL ES著色語言版本3.0中的注意事項(xiàng)。
  • OpenGL ES 3.0兼容設(shè)備上測試您的應(yīng)用程序,以驗(yàn)證其行為是否正確。

Updating Extension Code - 更新擴(kuò)展碼

OpenGL ES 3.0是OpenGL ES 2.0規(guī)范的超集,所以僅使用核心OpenGL ES 2.0功能的應(yīng)用程序可以在OpenGL ES 3.0上下文中使用,無需更改。 然而,一些應(yīng)用程序也使用OpenGL ES 2.0擴(kuò)展。 這些擴(kuò)展提供的功能也可在OpenGL ES 3.0中使用,但是在OpenGL ES 3.0上下文中使用它們可能需要至少進(jìn)行較小的代碼更改。

1. Remove Extension Suffixes - 刪除擴(kuò)展名后綴

下面列出的OpenGL ES 2.0擴(kuò)展定義了將API并入到OpenGL ES 3.0核心規(guī)范中。 要在OpenGL ES 3.0上下文中使用這些功能,只需從函數(shù)和常量名稱中刪除擴(kuò)展名后綴即可。 例如,glMapBufferRangeEXT函數(shù)的名稱為glMapBufferRange,并且DEPTH_COMPONENT24_OES常量(在glRenderbufferStorage函數(shù)的internalformat參數(shù)中使用)變?yōu)?code>DEPTH_COMPONENT24。

2. Modify Use of Extension APIs - 修改使用擴(kuò)展API

OpenGL ES 2.0擴(kuò)展定義的一些功能是OpenGL ES 3.0的核心規(guī)范,但是對它們的API定義進(jìn)行了更改。 要在OpenGL ES 3.0上下文中使用這些功能,請進(jìn)行以下更改。

Working with Texture Formats - 使用紋理格式

OES_depth_texture, OES_packed_depth_stencil, OES_texture_float, OES_texture_half_float, EXT_texture_rgEXT_sRGB擴(kuò)展定義了在glTexImage系列函數(shù)的internalformat和type參數(shù)中使用的常量。 這些擴(kuò)展定義的功能在OpenGL ES 3.0內(nèi)核API中可用,但有一些注意事項(xiàng):

  • glTexImage函數(shù)不支持沒有顯式大小的internalformat常量。 改為使用顯式大小的常量:
// Replace this OpenGL ES 2.0 code:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_HALF_FLOAT_OES, data);
// With this OpenGL ES 3.0 code:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_HALF_FLOAT, data);
  • OpenGL ES 3.0未定義LUMINANCELUMINANCE_ALPHA數(shù)據(jù)的浮點(diǎn)數(shù)或半浮點(diǎn)數(shù)。 請改用相應(yīng)的RED或RG格式。
  • 由深度和深度/模板紋理采樣器返回的向量不再重復(fù)OpenGL ES 3.0中前三個(gè)組件的深度值。 只能在著色器代碼中使用第一個(gè)(.r)組件來對這些紋理進(jìn)行采樣。
  • sRGB格式僅在OpenGL ES 3.0中用于internalformat參數(shù)時(shí)有效。 使用GL_RGBGL_RGBA作為sRGB紋理的格式參數(shù)。

或者,通過調(diào)用glTexStorage函數(shù)替換對glTexImage函數(shù)的調(diào)用。 紋理存儲功能可用作OpenGL ES 3.0中的核心API,以及OpenGL ES 1.1和2.0中的EXT_texture_storage擴(kuò)展。 這些函數(shù)提供了一個(gè)額外的好處:使用glTexStorage函數(shù)在一次調(diào)用中完全指定一個(gè)不可變的紋理對象; 它會立即執(zhí)行所有一致性檢查和內(nèi)存分配,保證紋理對象永遠(yuǎn)不會因?yàn)槿鄙?code>mipmap級別或不一致的多維數(shù)據(jù)集地圖面而不完整。

Mapping Buffer Objects into Client Memory - 將緩沖區(qū)對象映射到客戶端內(nèi)存中

OES_mapbuffer擴(kuò)展定義了用于將緩沖區(qū)對象的整個(gè)數(shù)據(jù)存儲映射到客戶端內(nèi)存中的glMapBuffer函數(shù)。 OpenGL ES 3.0則定義了glMapBufferRange函數(shù),該函數(shù)提供了額外的功能:它允許映射緩沖區(qū)對象的數(shù)據(jù)存儲的子集,并包含用于異步映射的選項(xiàng)。 glMapBufferRange函數(shù)也可以通過EXT_map_buffer_range擴(kuò)展名在OpenGL ES 1.12.0上下文中使用。

Discarding Framebuffers - 丟棄幀緩沖區(qū)

OpenGL ES 3.0中的glInvalidateFramebuffer函數(shù)將替換由EXT_discard_framebuffer擴(kuò)展名提供的glDiscardFramebufferEXT函數(shù)。 兩個(gè)功能的參數(shù)和行為是相同的。

Using Multisampling - 使用多重采樣

OpenGL ES 3.0包含了APPLE_framebuffer_multisample擴(kuò)展的所有功能,但glResolveMultisampleFramebufferAPPLE函數(shù)除外。 相反,glBlitFramebuffer函數(shù)提供了這個(gè)和其他其他幀緩沖區(qū)復(fù)制選項(xiàng)。 要解決多采樣緩沖區(qū),請?jiān)O(shè)置讀取和繪制幀緩沖區(qū)(如Using Multisampling to Improve Image Quality),然后使用glBlitFramebuffer將整個(gè)讀取幀緩沖區(qū)復(fù)制到整個(gè)繪圖幀緩沖區(qū)中:

glBlitFramebuffer(0,0,w,h, 0,0,w,h, GL_COLOR_BUFFER_BIT, GL_NEAREST);

3. Continue Using Most Other Extensions in OpenGL ES 3.0 - 繼續(xù)使用OpenGL ES 3.0中的其他擴(kuò)展

iOS設(shè)備圖形硬件的幾個(gè)主要功能不是OpenGL ES 3.0核心內(nèi)容的一部分,但仍可作為OpenGL ES 3.0擴(kuò)展使用。 要使用這些功能,請繼續(xù)使用Verifying OpenGL ES Capabilities中描述的步驟檢查擴(kuò)展支持。 (另請參閱 iOS Device Compatibility Reference以確定哪些設(shè)備可用哪些功能。)

為OpenGL ES 2.0擴(kuò)展編寫的大多數(shù)代碼也可作為OpenGL ES 3.0擴(kuò)展使用,可在OpenGL ES 3.0上下文中進(jìn)行操作,無需更改。 但是,有關(guān)修改頂點(diǎn)和片段著色器語言的擴(kuò)展,另請注意,有關(guān)詳細(xì)信息,請參閱下一節(jié)。


Adopting OpenGL ES Shading Language version 3.0 - 采用OpenGL ES著色語言3.0版

OpenGL ES 3.0包括一個(gè)新版本的OpenGL ES著色語言(GLSL ES)。 OpenGL ES 3.0上下文可以使用編寫在版本1.0或版本3.0的GLSL ES中的著色器程序,但3.0版著色器(在著色器源代碼中標(biāo)有#version 300 es指令)需要訪問某些新功能,例如統(tǒng)一塊 ,32位整數(shù)和其他整數(shù)運(yùn)算。

GLSL ES版本1.0和3.0之間的某些語言習(xí)慣已經(jīng)發(fā)生變化。 這些更改使得Shader源代碼在OpenGL ES 3.0和桌面OpenGL ES 3.3或更高版本之間更加便攜,但是當(dāng)移植到GLSL ES 3.0時(shí),它們也需要對現(xiàn)有著色器源代碼進(jìn)行微小的更改:

  • attributevarying限定符在GLSL ES 3.0中被關(guān)鍵字in和out代替。 在頂點(diǎn)著色器中,使用in限定符中的頂點(diǎn)屬性和out限定符來改變輸出。 在片段著色器中,使用in限定符來改變輸入。
  • GLSL ES 3.0刪除了gl_FragDatagl_FragColor內(nèi)置的片段輸出變量。 相反,您使用out限定符聲明自己的片段輸出變量。
  • 紋理采樣函數(shù)已在GLSL ES 3.0中重命名,所有采樣器類型都使用相同的紋理函數(shù)名稱。 例如,您可以使用具有sampler2DsamplerCube參數(shù)的新texture函數(shù)(從GLSL ES 1.0替換texture2DtextureCube函數(shù))。
  • EXT_shader_texture_lod, EXT_shadow_samplersOES_standard_derivatives擴(kuò)展添加到GLSL ES 1.0中的功能是GLSL ES規(guī)范的核心部分。 將使用這些功能的著色器移植到GLSL ES 3.0時(shí),請使用相應(yīng)的GLSL ES 3.0功能。
  • EXT_shader_framebuffer_fetch擴(kuò)展名的作用不同。 GLSL ES 3.0刪除gl_FragDatagl_FragColor內(nèi)置片段輸出變量,有利于要求在著色器中聲明片段輸出。 相應(yīng)地,gl_LastFragData內(nèi)置變量不存在于GLSL ES 3.0片段著色器中。 相反,您使用inout限定符聲明的任何片段輸出變量在著色器運(yùn)行時(shí)都包含以前的片段數(shù)據(jù)。 有關(guān)更多詳細(xì)信息,請參閱Fetch Framebuffer Data for Programmable Blending

有關(guān)GLSL ES 3.0的完整概述,請參閱OpenGL ES著色語言3.0規(guī)范,可從OpenGL ES API Registry獲取。

后記

未完,待續(xù)~~~

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

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

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