本篇文章讲述如何利用GpenGL ES来来实现分屏特效,话不多说,先上效果图一睹为快。
1.项目架构
项目代码放在了github上了,可以下载下来,对照下面的方法架构图来理解整个的流程。
2.着色器实现
2.1 Normal
顶点着色器,有两个属性,Position顶点坐标和TextureCoords纹理坐标属性。Position赋值给内建变量gl_Position。TextureCoords赋值给varying``修饰的TextureCoordsVarying,传递到纹理着色器,以供使用。
attribute vec4 Position;
attribute vec2 TextureCoords;
varying vec2 TextureCoordsVarying;
void main (void) {
gl_Position = Position;
TextureCoordsVarying = TextureCoords;
}
片元着色器,TextureCoordsVarying用来接收顶点着色器传进来的纹理坐标。Texture是传进来的纹理对象。main函数实现中,通过texture2D函数,获取与纹理坐标一一对应纹素,来进行纹理着色。
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
void main (void) {
gl_FragColor = texture2D(Texture, TextureCoordsVarying);
}
2.2 SplitScreen_2
效果图如下:
通过效果图我们可以看出,这时纹理的显示,不再与纹理坐标一一对应。而是以水平中轴线为标记,进行了上下的便宜。当y小于0.5时,纹理坐标向下便宜了0.25个位置。当y>0.5是,纹理坐标又向上偏移了0.25。使得最终的显示效果是显示了两个红框位置处的纹理图像。
片元着色器实现如下:
precision highp float;
uniform sampler2D Texture;
varying highp vec2 TextureCoordsVarying;
void main(){
vec2 uv = TextureCoordsVarying.xy;
float y;
if (uv.y>0.0 && uv.y<=0.5) {
y = uv.y+0.25;
} else {
y = uv.y-0.25;
}
gl_FragColor = texture2D(Texture, vec2(uv.x, y));
}
2.3 SplitScreen_3
三分屏实现与二分屏实现类似,同样是向上或向下偏了1/3的位置。当然,中间的1/3部分就不好用偏移啦。
precision highp float;
uniform sampler2D Texture;
varying highp vec2 TextureCoordsVarying;
void main(){
vec2 uv = TextureCoordsVarying.xy;
if (uv.y < 1.0/3.0) {
uv.y = uv.y + 1.0/3.0;
} else if (uv.y > 2.0/3.0){
uv.y = uv.y - 1.0/3.0;
}
gl_FragColor = texture2D(Texture, uv);
}
2.4 SplitScreen_4
四分屏是一个田字形的显示。相当于占用屏幕1/4的面积大小,来显示原来的整个纹理大小。相当于将坐标的x,y进行了放大2倍的操作。
代码如下:
precision highp float;
uniform sampler2D Texture;
varying highp vec2 TextureCoordsVarying;
void main(){
vec2 uv = TextureCoordsVarying.xy;
if(uv.x <= 0.5){
uv.x = uv.x * 2.0;
}else{
uv.x = (uv.x - 0.5) * 2.0;
}
if (uv.y<= 0.5) {
uv.y = uv.y * 2.0;
}else{
uv.y = (uv.y - 0.5) * 2.0;
}
gl_FragColor = texture2D(Texture, uv);
}
2.5 SplitScreen_6
六分屏的效果如下:
结合前面的分析,是在x轴上了取了原来的三分之一大小,y轴上去了和原来的二分之一大小。
precision highp float;
uniform sampler2D Texture;
varying highp vec2 TextureCoordsVarying;
void main(){
vec2 uv = TextureCoordsVarying.xy;
if (uv.x < 1.0/3.0) {
uv.x = uv.x + 1.0/3.0;
} else if (uv.x > 2.0/3.0){
uv.x = uv.x - 1.0/3.0;
}
if (uv.y < 0.5) {
uv.y = uv.y + 0.25;
}else{
uv.y = uv.y - 0.25;
}
gl_FragColor = texture2D(Texture, uv);
}
2.6 SplitScreen_9
九分屏的实现与四分屏的实现相类似,无非就是将原来的放大2倍变为了放大3倍。
precision highp float;
uniform sampler2D Texture;
varying highp vec2 TextureCoordsVarying;
void main(){
vec2 uv = TextureCoordsVarying.xy;
if(uv.x <= 1.0/3.0){
uv.x = uv.x * 3.0;
}
else if (uv.x <= 2.0/3.0){
uv.x = (uv.x - 1.0/3.0) * 3.0;
}
else{
uv.x = (uv.x - 2.0/3.0) * 3.0;
}
if(uv.y <= 1.0/3.0){
uv.y = uv.y * 3.0;
}
else if (uv.y <= 2.0/3.0){
uv.y = (uv.y - 1.0/3.0) * 3.0;
}
else{
uv.y = (uv.y - 2.0/3.0) * 3.0;
}
gl_FragColor = texture2D(Texture, uv);
}