版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.10.03 |
前言
OpenGL ES是一個強大的圖形庫,是跨平臺的圖形API,屬于OpenGL的一個簡化版本。iOS系統可以利用OpenGL ES將圖像數據直接送入到GPU進行渲染,這樣避免了從CPU進行計算再送到顯卡渲染帶來的性能的高消耗,能帶來來更好的視頻效果和用戶體驗。接下來幾篇就介紹下iOS 系統的 OpenGL ES框架。感興趣的可以看上面幾篇。
1. OpenGL ES 框架詳細解析(一) —— 基本概覽
2. OpenGL ES 框架詳細解析(二) —— 關于OpenGL ES
3. OpenGL ES 框架詳細解析(三) —— 構建用于iOS的OpenGL ES應用程序的清單
4. OpenGL ES 框架詳細解析(四) —— 配置OpenGL ES的上下文
5. OpenGL ES 框架詳細解析(五) —— 使用OpenGL ES和GLKit進行繪制
6. OpenGL ES 框架詳細解析(六) —— 繪制到其他渲染目的地
7. OpenGL ES 框架詳細解析(七) —— 多任務,高分辨率和其他iOS功能
8. OpenGL ES 框架詳細解析(八) —— OpenGL ES 設計指南
9. OpenGL ES 框架詳細解析(九) —— 調整您的OpenGL ES應用程序
10. OpenGL ES 框架詳細解析(十) —— 使用頂點數據的最佳做法
11. OpenGL ES 框架詳細解析(十一) —— 并發和OpenGL ES
Adopting OpenGL ES 3.0 - 采用OpenGL ES 3.0
OpenGL ES 3.0
是OpenGL ES 2.0
規范的超集,因此在您的應用程序中采用它是容易的。 您可以繼續使用OpenGL ES 2.0代碼,同時利用兼容設備上OpenGL ES 3.0上下文的更高資源限制,并增加對OpenGL ES 3.0特定功能的支持,使您的應用程序的設計變得有意義。
Checklist for Adopting OpenGL ES 3.0 - 采用OpenGL ES 3.0的清單
在您的應用程序中使用OpenGL ES 3.0:
- 創建OpenGL ES上下文(如Configuring OpenGL ES Contexts中所述),并為OpenGL ES 3.0指定API版本常量:
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
如果您打算將應用程序提供給不支持OpenGL ES 3.0的設備,請按照 Listing 2-1中的步驟在必要時退回到OpenGL ES 2.0。
- 在使用OpenGL ES 3.0 API的源文件中包含或導入OpenGL ES 3.0 API頭文件:
#import <OpenGLES/ES3/gl.h>
#import <OpenGLES/ES3/glext.h>
- 更新代碼,使用OpenGL ES 2.0擴展并入或更改OpenGL ES 3.0規范,如下面更新擴展代碼中所述。
- (可選)您可以在
OpenGL ES 2.0
和3.0中使用相同的著色器程序。 但是,如果您選擇將著色器移植到GLSL ES 3.0以使用新功能,請參閱采用OpenGL ES著色語言版本3.0中的注意事項。 - 在
OpenGL ES 3.0
兼容設備上測試您的應用程序,以驗證其行為是否正確。
Updating Extension Code - 更新擴展碼
OpenGL ES 3.0是OpenGL ES 2.0規范的超集,所以僅使用核心OpenGL ES 2.0功能的應用程序可以在OpenGL ES 3.0上下文中使用,無需更改。 然而,一些應用程序也使用OpenGL ES 2.0擴展。 這些擴展提供的功能也可在OpenGL ES 3.0中使用,但是在OpenGL ES 3.0上下文中使用它們可能需要至少進行較小的代碼更改。
1. Remove Extension Suffixes - 刪除擴展名后綴
下面列出的OpenGL ES 2.0擴展定義了將API并入到OpenGL ES 3.0核心規范中。 要在OpenGL ES 3.0上下文中使用這些功能,只需從函數和常量名稱中刪除擴展名后綴即可。 例如,glMapBufferRangeEXT
函數的名稱為glMapBufferRange
,并且DEPTH_COMPONENT24_OES
常量(在glRenderbufferStorage
函數的internalformat
參數中使用)變為DEPTH_COMPONENT24
。
- OES_depth24
- OES_element_index_uint
- OES_fbo_render_mipmap
- OES_rgb8_rgba8
- OES_texture_half_float_linear
- OES_vertex_array_object
- EXT_blend_minmax
- EXT_draw_instanced
- EXT_instanced_arrays
- EXT_map_buffer_range
- EXT_occlusion_query_boolean
- EXT_texture_storage
- APPLE_sync
- APPLE_texture_max_level
2. Modify Use of Extension APIs - 修改使用擴展API
OpenGL ES 2.0擴展定義的一些功能是OpenGL ES 3.0的核心規范,但是對它們的API定義進行了更改。 要在OpenGL ES 3.0上下文中使用這些功能,請進行以下更改。
Working with Texture Formats - 使用紋理格式
OES_depth_texture, OES_packed_depth_stencil, OES_texture_float, OES_texture_half_float, EXT_texture_rg和EXT_sRGB擴展定義了在glTexImage系列函數的internalformat和type參數中使用的常量。 這些擴展定義的功能在OpenGL ES 3.0內核API中可用,但有一些注意事項:
-
glTexImage
函數不支持沒有顯式大小的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未定義
LUMINANCE
或LUMINANCE_ALPHA
數據的浮點數或半浮點數。 請改用相應的RED或RG格式。 - 由深度和深度/模板紋理采樣器返回的向量不再重復OpenGL ES 3.0中前三個組件的深度值。 只能在著色器代碼中使用第一個(.r)組件來對這些紋理進行采樣。
-
sRGB
格式僅在OpenGL ES 3.0中用于internalformat
參數時有效。 使用GL_RGB
或GL_RGBA
作為sRGB
紋理的格式參數。
或者,通過調用glTexStorage
函數替換對glTexImage
函數的調用。 紋理存儲功能可用作OpenGL ES 3.0中的核心API,以及OpenGL ES 1.1和2.0中的EXT_texture_storage擴展。 這些函數提供了一個額外的好處:使用glTexStorage
函數在一次調用中完全指定一個不可變的紋理對象; 它會立即執行所有一致性檢查和內存分配,保證紋理對象永遠不會因為缺少mipmap
級別或不一致的多維數據集地圖面而不完整。
Mapping Buffer Objects into Client Memory - 將緩沖區對象映射到客戶端內存中
OES_mapbuffer擴展定義了用于將緩沖區對象的整個數據存儲映射到客戶端內存中的glMapBuffer
函數。 OpenGL ES 3.0則定義了glMapBufferRange
函數,該函數提供了額外的功能:它允許映射緩沖區對象的數據存儲的子集,并包含用于異步映射的選項。 glMapBufferRange
函數也可以通過EXT_map_buffer_range
擴展名在OpenGL ES 1.1
和2.0
上下文中使用。
Discarding Framebuffers - 丟棄幀緩沖區
OpenGL ES 3.0中的glInvalidateFramebuffer
函數將替換由EXT_discard_framebuffer擴展名提供的glDiscardFramebufferEXT
函數。 兩個功能的參數和行為是相同的。
Using Multisampling - 使用多重采樣
OpenGL ES 3.0包含了APPLE_framebuffer_multisample擴展的所有功能,但glResolveMultisampleFramebufferAPPLE
函數除外。 相反,glBlitFramebuffer
函數提供了這個和其他其他幀緩沖區復制選項。 要解決多采樣緩沖區,請設置讀取和繪制幀緩沖區(如Using Multisampling to Improve Image Quality),然后使用glBlitFramebuffer
將整個讀取幀緩沖區復制到整個繪圖幀緩沖區中:
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 - 繼續使用OpenGL ES 3.0中的其他擴展
iOS設備圖形硬件的幾個主要功能不是OpenGL ES 3.0核心內容的一部分,但仍可作為OpenGL ES 3.0擴展使用。 要使用這些功能,請繼續使用Verifying OpenGL ES Capabilities中描述的步驟檢查擴展支持。 (另請參閱 iOS Device Compatibility Reference以確定哪些設備可用哪些功能。)
為OpenGL ES 2.0擴展編寫的大多數代碼也可作為OpenGL ES 3.0擴展使用,可在OpenGL ES 3.0上下文中進行操作,無需更改。 但是,有關修改頂點和片段著色器語言的擴展,另請注意,有關詳細信息,請參閱下一節。
Adopting OpenGL ES Shading Language version 3.0 - 采用OpenGL ES著色語言3.0版
OpenGL ES 3.0
包括一個新版本的OpenGL ES著色語言(GLSL ES)。 OpenGL ES 3.0上下文可以使用編寫在版本1.0或版本3.0的GLSL ES中的著色器程序,但3.0版著色器(在著色器源代碼中標有#version 300 es
指令)需要訪問某些新功能,例如統一塊 ,32位整數和其他整數運算。
GLSL ES
版本1.0和3.0之間的某些語言習慣已經發生變化。 這些更改使得Shader源代碼在OpenGL ES 3.0和桌面OpenGL ES 3.3或更高版本之間更加便攜,但是當移植到GLSL ES 3.0時,它們也需要對現有著色器源代碼進行微小的更改:
-
attribute
和varying
限定符在GLSL ES 3.0中被關鍵字in和out代替。 在頂點著色器中,使用in
限定符中的頂點屬性和out
限定符來改變輸出。 在片段著色器中,使用in
限定符來改變輸入。 - GLSL ES 3.0刪除了
gl_FragData
和gl_FragColor
內置的片段輸出變量。 相反,您使用out
限定符聲明自己的片段輸出變量。 - 紋理采樣函數已在GLSL ES 3.0中重命名,所有采樣器類型都使用相同的紋理函數名稱。 例如,您可以使用具有
sampler2D
或samplerCube
參數的新texture
函數(從GLSL ES 1.0替換texture2D
和textureCube
函數)。 - 由EXT_shader_texture_lod, EXT_shadow_samplers和OES_standard_derivatives擴展添加到GLSL ES 1.0中的功能是GLSL ES規范的核心部分。 將使用這些功能的著色器移植到GLSL ES 3.0時,請使用相應的GLSL ES 3.0功能。
-
EXT_shader_framebuffer_fetch擴展名的作用不同。 GLSL ES 3.0刪除
gl_FragData
和gl_FragColor
內置片段輸出變量,有利于要求在著色器中聲明片段輸出。 相應地,gl_LastFragData
內置變量不存在于GLSL ES 3.0片段著色器中。 相反,您使用inout
限定符聲明的任何片段輸出變量在著色器運行時都包含以前的片段數據。 有關更多詳細信息,請參閱Fetch Framebuffer Data for Programmable Blending。
有關GLSL ES 3.0的完整概述,請參閱OpenGL ES著色語言3.0規范,可從OpenGL ES API Registry獲取。
后記
未完,待續~~~