目錄
- 一.嵌入式設備的 OpenGL ES 版本
- 二.兼容性
- 三.著色器腳本
- 1.OpenGL ES shader 2.0
- 2.OpenGL ES shader 3.0
- 3.版本宣告
- 4. 默認精度修飾符 precision
- 4.輸入輸出
- 5.變數賦值
- 四.關于頂點緩沖區物件 VBO 與頂點陣列物件 VAO
- 五.PBO
- 六.猜你喜歡
零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 基礎
零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 特效
零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 轉場
零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 函式
零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES GPUImage 使用
零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES GLSL 編程
一.嵌入式設備的 OpenGL ES 版本
OpenGL ES 1.x 支持 初代 iPhone 和 Android;
OpenGL ES 2.0 支持 Android 2.2 以后的平臺,支持 iPad , iPhone3GS 和后續版本,以及 iPodTouch3 代和后續版本,
OpenGL ES 3.0 支持 Android 4.3 以后的平臺,支持 iPhone 5s ,iPad Air ,iPad mini 2 及后續版本,
二.兼容性
OpenGL ES 3.0 是向下兼容 OpenGL ES 2.0 的,也就是說使用 2.0 撰寫的應用程式是可以在 3.0 中繼續使用的,
三.著色器腳本
1.OpenGL ES shader 2.0
//頂點著色器
attribute vec4 aPosition; // 應用程式傳入頂點著色器的頂點位置
attribute vec2 aTextureCoord; // 應用程式傳入頂點著色器的頂點紋理坐標
varying vec2 vTextureCoord; // 用于傳遞給片元著色器的頂點紋理資料
void main()
{
gl_Position = aPosition; // 此次繪制此頂點位置
vTextureCoord = aTextureCoord; // 將接收的紋理坐標傳遞給片元著色器
}
//片元著色器
precision mediump float; // 設定作業精度
varying vec2 vTextureCoord; // 接收從頂點著色器過來的紋理坐標
uniform sampler2D sTexture; // 紋理采樣器,代表一幅紋理
void main()
{
gl_FragColor = texture2D(sTexture, vTextureCoord);// 進行紋理采樣
}
2.OpenGL ES shader 3.0
//頂點著色器
#version es 300
uniform mat4 u_matViewProj;
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec3 a_color;
out vec3 v_color;
void main() {
gl_Position = u_matViewProj * a_position;
v_color = a_color;
}
//片元著色器
#version es 300
precision mediump float;
in vec3 v_color; // input form vertex shader
layout(location = 0) out vec4 o_fragColor;
void main() {
o_fragColor = vec4(v_color, 1.0);
}
3.版本宣告
在 OpenGL ES 3.0 中,頂點著色器和片段著色器的第一行必須宣告著色器版本,否則編譯報錯:
ERROR: 0:1: '' : syntax error: #version directive must occur in a shader before anything
在 OpenGL ES 3.0 中,可以必須宣告著色器版本:
#version es 300
在 OpenGL ES 2.0 中,可以不用宣告著色器版本,默認為:
#version es 100
備注: 以往 2.0 剛剛出來可編程的圖形管線,所以版本宣告為 #version 100 es ,后來為了使版本號相匹配,OpenGL ES 3.0 的 shader 版本直接從 1.0 跳到了 3.0 ,
#version 300 es 指定使用OpenGL3.0
#version 100 es 指定使用OpenGL2.0 (不指定version 默認為OpenGL2.0)
4. 默認精度修飾符 precision
在頂點語言中有如下預定義的全域默認精度陳述句:
precision highp float;
precision highp int;
precision lowp sampler2D;
precision lowp samplerCube;
在片元語言中有如下預定義的全域默認精度陳述句:
precision mediump int;
precision lowp sampler2D;
precision lowp samplerCube;
片元語言沒有默認的浮點數精度修飾符,因此,對于浮點數,浮點數向量和矩陣變數宣告,要么宣告必須包含一個精度修飾符,要不默認的精度修飾符在之前已經被宣告過了
precision highp float;
4.輸入輸出
OpenGL ES 3.0 中新增了** in,out,inout **關鍵字,用來取代 **attribute 和 varying **關鍵字,
同時 gl_FragColor 和 gl_FragData 也洗掉了,片段著色器可以使用 out 宣告欄位輸出,
5.變數賦值
OpenGL ES 3.0 中可以直接使用 layout 對指定位置的變數賦值,例如:
shader腳本中
layout (location = 1) uniform float a;
代碼中,直接寫上對應的 layout 的值就可以賦值
GLES30.glUniform1f(1, 1f);
而 OpenGL ES 2.0 中必須使用如下形式賦值:
GLES20.glUniform1f(GLES20.glGetAttribLocation(program, "a"), 1f)
四.關于頂點緩沖區物件 VBO 與頂點陣列物件 VAO
VAO (頂點陣列物件:Vertex Array Object)是指頂點陣列物件,主要用于管理 VBO 或 EBO ,減少 glBindBuffer 、glEnableVertexAttribArray、 glVertexAttribPointer 這些呼叫操作,高效地實作在頂點陣列配置之間切換,
**VBO(頂點緩沖區物件: Vertex Buffer Object)是指把頂點資料保存在顯存中,繪制時直接從顯存中取資料,減少了資料傳輸的開銷,**因為頂點資料多了,就是坐標的資料多了很多的很多組,切換的時候很麻煩,就出現了這個 VAO,系結對應的頂點資料
OpenGL 2.0 有 VBO,沒有 VAO,VAO 是 OpenGL 3.0 才開始支持的,并且在 OpenGL 3.0 中,強制要求系結一個 VAO 才能開始繪制,
例如:在 OpenGL 3.0 中,不使用 VAO ,呼叫完 glVertexAttribPointer, glGetError 報錯 GL_INVALID_OPERATION,
int pos_location = glGetAttribLocation(ProgramId, "position");
glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
查看 OpenGL 官方檔案 http://docs.gl/gl3/glVertexAttribPointer
GL_INVALID_OPERATION is generated in the core context if there is no Vertex Array Object bound
在 OpenGL 3.0 中,強制要求系結一個 VAO 才能開始繪制,因此,需要在程式初始化的時候,創建并系結一個 VAO
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
此外,OpenGL 3.0 中也不允許在 glVertexAttribPointer 直接傳陣列了,因此要把頂點先傳入 vbo 中
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices, GL_STATIC_DRAW);
系結 VBO 之后,glVertexAttribPointer 后面的 pointer 引數就要填 0 了,
glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
五.PBO
OpenGL 2.0 不支持 PBO ,3.0 支持 PBO , PBO 設計的目的就是快速地向顯卡傳輸資料,或者從顯卡讀取資料,我們可以使用它更加高效的讀取螢屏資料,
單個 PBO 讀取螢屏資料效率大概和 glReadPixels 差不多,雙 PBO 交換讀取效率會很高,
原因是使用 PBO 時,螢屏上的資料不是讀取到記憶體,而是從顯卡讀到 PBO 中,或者如果內部機制是讀取到記憶體中,但這也是由 DMA 控制器來完成的,而不是 cpu 指令來做的,再加上兩個 PBO 交換使用,所以讀取效率很高,
PBO 快速地從記憶體 CPU 向顯卡 GPU 傳輸資料 —> GL_PIXEL_PACK_BUFFER
**PBO 快速地從顯卡 GPU 讀取資料到記憶體 CPU** —> GL_PIXEL_UNPACK_BUFFER
六.猜你喜歡
- OpenGL ES 簡介
- OpenGL ES 版本介紹
- OpenGL ES 2.0 和 3.0 區別
- OpenGL ES 名詞解釋(一)
- OpenGL ES 名詞解釋(二)
本文由博客 - 猿說編程 猿說編程 發布!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/508041.html
標籤:C
上一篇:第7章 函式-C++的編程模塊
下一篇:清源正本,鑒往知來,Go lang1.18入門精煉教程,由白丁入鴻儒,Golang中參考型別是否進行參考傳遞EP18