opengl es3.0学习篇二:着色器和程序

opengl es学习篇二:着色器和程序

学习资料来源:

OpenGL ES 3.0编程指南

OpenGL ES 2 for Android —a Quick-Start Guide

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

上一节中学习了opengl es的大体执行过程,这一节学习一下着色器这块内容。

如果要使用着色器进行渲染的时候,需要创建两个基本对象:着色器和程序对象。着色器对象和程序对象可以理解为c中的编译器和链接程序:

在c中将一段代码编译成目标代码,在创建目标文件后,c链接程序会将对象文件链接为最后的程序

着色器对象是包含的歌着色器的对象。源代码提供给着色器对象,然后着色器对象被编译成一个目标形式。

获得链接后的桌而起对象一般6个步骤:

  • 创建一个顶点着色器对象和一个片段着色器对象
  • 将源代码连接到每个着色器对象
  • 编译着色器对象
  • 创建一个程序对象
  • 将编译后的着色器对象连接到程序对象
  • 链接程序对象
创建和编译着色器对象

注意:居于Android系统

//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,mat42x2,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一样,不展开。

转载于:https://my.oschina.net/u/3863980/blog/1829183

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值