opengl es3.0學習篇二:着色器和程序

opengl es學習篇二:着色器和程序

學習資料來源:java

OpenGL ES 3.0編程指南android

OpenGL ES 2 for Android —a Quick-Start Guidec++

https://developer.android.com/guide/topics/graphics/opengl編程

上一節中學習了opengl es的大致執行過程,這一節學習一下着色器這塊內容。數組

若是要使用着色器進行渲染的時候,須要建立兩個基本對象:着色器和程序對象。着色器對象和程序對象能夠理解爲c中的編譯器和連接程序:ide

在c中將一段代碼編譯成目標代碼,在建立目標文件後,c連接程序會將對象文件連接爲最後的程序函數

着色器對象是包含的歌着色器的對象。源代碼提供給着色器對象,而後着色器對象被編譯成一個目標形式。學習

得到連接後的桌而起對象通常6個步驟:ui

  • 建立一個頂點着色器對象和一個片斷着色器對象
  • 將源代碼鏈接到每一個着色器對象
  • 編譯着色器對象
  • 建立一個程序對象
  • 將編譯後的着色器對象鏈接到程序對象
  • 連接程序對象

建立和編譯着色器對象

注意:居於Android系統code

//GL_VERTEX_SHADER or GL_FRAGMENT_SHADER 建立對應的着色器,返回着色器句柄
int shader1= GLES30.glCreateShader(type);
//刪除對應的着色器對象句柄
GLES30.glDeleteShader(shader1);
//爲着色器對象提供源代碼,參數依次:shader句柄,shader代碼
GLES30.glShaderSource(shader,shaderSourceCode);
//編譯着色器對象
GLES30.glCompileShader(shader);

上述描述瞭如何去建立和編譯一個着色器對象。

建立和連接程序

建立程序對象代碼以下:

//建立程序對象
mProgram = GLES30.glCreateProgram();
//與着色器進行連接,每一個程序對象須要連接一個頂點着色器和一個片斷着色器
GLES30.glAttachShader(mProgram, vertexShader);
GLES30.glAttachShader(mProgram, fragmentShader);
//連接程序對象
GLES30.glLinkProgram(mProgram);

上面寫好後能夠看到對應着上方的六個步驟。全部步驟完成後須要在執行以下代碼:

GLES30.glUseProgram(mProgram);

該代碼代表激活程序對象,而後就能夠渲染了。


###opengl es 着色語言

在計算機圖形中,兩個基本數據類型組成變換基礎:向量和矩陣。這兩種數據在opengl es的着色語言中也是核心(ps:學很差線性代數就流淚...)。opengl es着色語言數據類型以下:

變量分類 類型 描述
標量 float,int,uint,bool 與c對應變量解釋一致
浮點向量 float,vec2,vec3,vec4 有1,2,3,4個份量的基於浮點的向量類型
整數向量 int,,ivec2,ivec3,ivec4 有1,2,3,4個份量的基於整數的向量類型
無符號向量 uint,,uvec2,uvec3,uvec4 有1,2,3,4個份量的基於無符號整數的向量類型
布爾變量 bool,bvec2,bvec3,bvec4 有1,2,3,4個份量的基於布爾值的向量類型
矩陣 mat2(mat2x2底下類推),mat2x3,mat3x2,mat3,mat3x4,mat4x2,mat4x3,mat4 2x2,2x3,3x2,3x3,3x4,4x2,4x3,4x4的基於浮點的矩陣

聲明例子,與c語法相近:

float a;
vec4 v;
mat4 m;
ivec2 iv;

變量構造器

標量

float mm=1.0;
float mm=1;//不正確,語法很是嚴格
bool ll=true;
int kk=0;
int ka=0.0;//error
float sd=float(ll) //轉換成float

向量

vec4 myVec4=vec4(1.0);//myVec4={1.0,1.0,1.0,1.0}
vec3 myVec3=vec3(1.0,1.0,1.0);
vec3 temp=vec3(myVec3);//賦值操做
vec2 myVec2=vec2(myVec3);//myVec2={1.0,1.0}即取x,y點
vec4 myVec4=vec4(myVec2,temp);//myVec4={myVec2.x,myVec2.y,temp.x,temp.y}

向量和矩陣份量

向量的單獨份量能夠用兩種方式訪問,**"."運算符號和數組下標的形式。**根據組成向量 的份量數量,每一個份量可使用{x,y,z,w}或{r,g,b,a}或者{s,t,p,q}來訪問。使用"."運算符號售後,能夠再操做中從新排列響亮的份量,如:

vec3 my3=vec3(1.0,0.0,3.0);
vec3 temp;
temp=my3.xyz;//(1.0,0.0,3.0)
temp=my3.yzx;//(0.0,3.0,1.0)

矩陣有向量組成,如mat2能夠當作兩個vec2等,例子:

mat4 m=mat4(1.0);
vec4 v4=m[0];
float k=mat4[0][1];

常量

const float zrto=0.0;

結構體

struct ff{
    vec4 volor;
    float end;
} fo;
//初始化能夠跟c相同,也能夠以下
fo=ff(vec4(0.0,0.0,0.0,0.0),4.0);

數組

float fl[4];
vec4 vec[2];

函數

函數聲明跟c語言的相同,惟一不一樣在於函數參數的傳遞方法,opengl es有特殊的限定符,定義函數是否能夠修改可變參數:

限定符 描述
in 指定參數按值傳送,函數不能修改
inout 規定變量按引用傳入函數,若是該值被修改,他將在函數退出後變化
out 表示該變量不被傳入函數,但在函數返回時候被修改

關於opengl es着色語言中的函數還要注意一點,**函數不能遞歸。**這一限制的緣由是某些實現經過吧函數代碼真正內嵌到GPU生成的最終程序實施函數調用。着色語言有意構造這種內嵌式實現,以支持沒有堆棧的GPU。

頂點着色器的輸入和輸出

定點輸入變量用於指定頂點着色器中每一個頂點的輸入,用in關鍵字指定。他們一般存儲位置,發現,紋理座標和顏色這樣的數據。(能夠理解爲從咱們程序中寫的代碼中去讀取對應變量的值)

in vec4 a_Position;
in vec3 a_color;
out vec3 v_color;
void main()[
    v_color=a_color;
]

這個着色器的兩個頂點輸入變量a_position和a_color的數據由應用程序加載。相對應的有in就有out,out表明着來自頂點着色器的輸出變量。基本上來講,從頂點着色器out的值由片斷着色器接收,這些out出去的變量在片斷着色器中會經過in的形式進行接收。

控制流語句(if else)跟c同樣,不展開。

相關文章
相關標籤/搜索