GLSL语言
以下两段代码为GLSL语言着色器代码。
顶点着色器:每个几何顶点执行一次。
attribute vec3 a_position;
void main(void){
gl_Position = vec4(a_position, 1.0);
}`
片元着色器:每个像素执行一次。
void main(void){
gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);
}
编译GLSL程序
生成Shader程序对象,获取其句柄。其中,type的取值可以为:context.VERTEX_SHADER(顶点着色器)、context.FRAGMENT_SHADER(片元着色器)。
let shader = context.createShader(type);
附加源代码,编译程序。
context.shaderSource(shader, source);
context.compileShader(shader);
完整代码如下:
function createShader(context, type, source){
let shader = context.createShader(type);
context.shaderSource(shader, source);
context.compileShader(shader);
// 查看程序是否报错
if (!context.getShaderParameter(shader, context.COMPILE_STATUS)) {
throw new Error('Shader程序编译出错!');
}
return shader;
}
链接GLSL程序
生成着色器程序对象:
let program = context.createProgram();
附加shader对象:
context.attachShader(program, shader);
链接GLSL程序:
context.linkProgram(program);
完整代码如下:
class ShaderProgram{
constructor(context, shaders){
let program = context.createProgram();
for(let shader of shaders){
context.attachShader(program, shader);
}
context.linkProgram(program);
if (!context.getProgramParameter(program, context.LINK_STATUS)) {
throw new Error('Shader程序链接出错!');
}
this.m_program = program;
this.m_context = context;
}
useProgram(){
this.m_context.useProgram(this.m_program);
}
bindAttribLocation(index, name){
this.m_context.bindAttribLocation(this.m_program, index, name);
}
}
应用案例
let shaderProgram = new ShaderProgram(context,
[createVertexShader(context,
`attribute vec3 a_position;
void main(void){
gl_Position = vec4(a_position, 1.0);
}`),
createFragmentShader(context,
`void main(void){
gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);
}`)
]);
shaderProgram.bindAttribLocation(a_position, "a_position");
shaderProgram.useProgram();