cocos-shader---1.了解

一、着色器语言

先看一段代码:

attribute vec4 a_position;
attribute vec4 a_color;

varying vec4 v_fragmentColor;

void main()
{
    gl_Position = CC_MVPMatrix * a_position;
    v_fragmentColor = a_color;
}

再来解释这段代码:

varying:在vertex shader和fragment shader之间传递数据用的
attribute:从外部传进来的,每一个顶点都会有这两个属性,所以它也叫做vertex attribute(顶点属性)
gl开头的变量名:是系统内置的变量,所以大家在定义自己的变量名时,请不要以gl开头
CC_MVPMatrix:是一个mat4类型的变量,它是在cocos2d-x内部设置进来的,它其实是一个uniform,每一个cocos2d-x预定义的shader都包含有这个uniform,但是如果你在shader里面不使用这个变量的话,OpenGL底层会把它优化掉。
uniform:shader里面的一种变量,它是由外部程序设置进来的,它不像vertex的attribute,每个顶点都有一份数据。除非你显式地调用glUniformXXX函数来修改这个uniform的值,否则它的值恒定不变。

二、如何传递顶点数据

每一个attribute在vertex shader里面有一个location,它是用来传递数据的入口。我们可以通过下列代码获取这个入口值:

GLuint positionLocation = glGetAttribLocation(program->getProgram(), "a_position");
glEnableVertexAttribArray(positionLocation);

glGetAttribLocation是用来获得vertex attribute的入口的,
在我们要传递数据之前,首先要告诉OpenGL,所以要调用glEnableVertexAttribArray。
最后的数据通过glVertexAttribPointer传进来。它的第一个参数就是glGetAttribLocation返回的值。

三、如何使用uniform:

varying vec4 v_fragmentColor;
uniform vec4 u_color;
void main()
{
    gl_FragColor = v_fragmentColor * u_color;
}

此时,我们需要在程序里面给这个u_color传值。它的基本做法与attribute的传值是一样的。
首先,我们需要获得这个uniform在shader里面的位置。

GLuint uColorLocation = glGetUniformLocation(glProgram->getProgram(), "u_color");

然后,我们可以通过glUniformXXX函数给这个uniform赋值:

float uColor[] = {1.0, 0.0, 0.0, 1.0};
glUniform4fv(uColorLocation,1, uColor);

四、初识CC_MVPMatrix

CC_MVPMatrix是一个mat4类型的uniform,在shader代码被编译之前,它由cocos2d-x框架插入进来的。
CCGLProgram这个文件中:

static const char * COCOS2D_SHADER_UNIFORMS =
    "uniform mat4 CC_PMatrix;\n"
    "uniform mat4 CC_MVMatrix;\n"
    "uniform mat4 CC_MVPMatrix;\n"
    "uniform mat3 CC_NormalMatrix;\n"
    "uniform vec4 CC_Time;\n"
    "uniform vec4 CC_SinTime;\n"
    "uniform vec4 CC_CosTime;\n"
    "uniform vec4 CC_Random01;\n"
    "uniform sampler2D CC_Texture0;\n"
    "uniform sampler2D CC_Texture1;\n"
    "uniform sampler2D CC_Texture2;\n"
    "uniform sampler2D CC_Texture3;\n"
    "//CC INCLUDES END\n\n";

我们可以看到, 这里除了插入CC_MVPMatrix以外,还插入了其它一些uniform。只要你在后面的main函数里面不使用这些变量,最终shader program里面是看不到它们的。(被优化掉了)

CC_MVPMatrix 的作用
CC_MVPMatrix本质上是一个变换矩阵,用来把一个世界坐标系中的点转换到Clipping space。当然,如果学过OpenGL的人都知道,3D物体从建模到最终显示到屏幕上面要经历以下几个阶段:

对象空间(Object Space)
世界空间(World Space)
照相机空间(Camera Space/Eye Space)
裁剪空间(Clipping Space)
设备空间(normalized device space)
视口空间(Viewport)

从对象空间到世界空间的变换通常叫做Model-To-World变换,从世界空间到照相机空间的变换叫做World-To-View变换,而从照相机空间到裁剪空间的变换叫做View-To-Projection。合起来,就是我们常常提到的MVP变换。这里面每一个变换都是乘以一个矩阵,3个矩阵相乘最后还是一个矩阵,也就是cocos2d-x里面的CC_MVPMatrix啦。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页