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同样,不展开。

相关文章
相关标签/搜索