【WebGL连载教程六】H5开发3D引擎:你好,三角形!HelloTriangles

由于从本篇开始,代码量会逐渐增多。每行代码都尽量做到中文注释。

如有疑问可以在下方留言。本示例基于typescript语言开发,是前几篇的连载。

本篇代码主要学习利用WebGL在Canvas上画一个三角形。成果如下图所示:


创建一个 HelloTriangles.ts 然后在 Main.ts 中调用它,全部代码如下:

namespace sunnyboxs { //namespace命名空间

export class HelloTriangles { //类名

constructor() //构造函数
{
//通过元素id来获取对象
var canvas: HTMLCanvasElement = < HTMLCanvasElement> document. getElementById( 'my-canvas');
if (! canvas) {
console. log( "错误:无法获取到 Canvas 元素!");
return;
}

//获取一个3d绘图上下文,表明我们将使用webgl相关的api
var gl: WebGLRenderingContext = this. create3DContext( canvas);
if ( gl == null) {
console. log( "错误:无法获取到 WebGL 上下文!");
return;
}

//设置WebGL渲染区域尺寸
gl. viewport( 0, 0, canvas. clientWidth, canvas. clientHeight);

//顶点着色器
var vertexShaderSource: string = `
attribute vec4 a_Position;
void main()
{
gl_Position = vec4(a_Position.x, a_Position.y, a_Position.z, 1.0);
}
`;

//片段着色器
var fragmentShaderSource: string = `
precision mediump float;
void main()
{
gl_FragColor = vec4(1.0, 0.5, 0.2, 1.0);
}
`;


// 生成并编译顶点着色器和片段着色器
// =========================================================================
// 首先是创建和编译顶点着色器
var vertexShader: WebGLShader | null = gl. createShader( gl. VERTEX_SHADER);
gl. shaderSource( vertexShader, vertexShaderSource);
gl. compileShader( vertexShader); //编译
// 检查着色器代码是否发生编译错误
if (! gl. getShaderParameter( vertexShader, gl. COMPILE_STATUS)) {
var log: string | null = gl. getShaderInfoLog( vertexShader);
gl. deleteShader( vertexShader);
console. log( "错误:编译vertex顶点着色器发生错误:" + log);
return;
}

// 片段着色器
var fragmentShader: WebGLShader | null = gl. createShader( gl. FRAGMENT_SHADER);
gl. shaderSource( fragmentShader, fragmentShaderSource);
gl. compileShader( fragmentShader); //编译
// 检查着色器代码是否发生编译错误
if (! gl. getShaderParameter( fragmentShader, gl. COMPILE_STATUS)) {
var log: string | null = gl. getShaderInfoLog( fragmentShader);
gl. deleteShader( fragmentShader);
console. log( "错误:编译fragment片段着色器发生错误:" + log);
return;
}
// 链接到着色器
var shaderProgram: WebGLProgram | null = gl. createProgram();
gl. attachShader( shaderProgram, vertexShader); //导入顶点着色器
gl. attachShader( shaderProgram, fragmentShader); //导入片断着色器
gl. linkProgram( shaderProgram); //链接到着色器
// 检查链接时,是否发生错误
if (! gl. getProgramParameter( shaderProgram, gl. LINK_STATUS)) {
var log: string | null = gl. getProgramInfoLog( shaderProgram);
console. log( "错误:链接到着色器时发生错误:" + log);
return;
}
//链接完成后可以释放源
gl. deleteShader( vertexShader);
gl. deleteShader( fragmentShader);



// 创建一个三角形的顶点数据
// =========================================================================
var vertices: number[] = [
- 0.5, - 0.5, 0.0, // left
0.5, - 0.5, 0.0, // right
0.0, 0.5, 0.0 // top
];

// 创建并绑定一个VBO对象
var VBO: WebGLBuffer | null = gl. createBuffer(); //创建一个VBO顶点Buffer
gl. bindBuffer( gl. ARRAY_BUFFER, VBO); //绑定
gl. bufferData( gl. ARRAY_BUFFER, new Float32Array( vertices), gl. STATIC_DRAW); //填充数据

//给指定的着色器变量a_Position赋值
var a_Position = gl. getAttribLocation( shaderProgram, 'a_Position'); //获取地址
//参数:着色器中的位置,顶点大小,数据类型,是否标准化,步长,偏移量
gl. vertexAttribPointer( a_Position, 3, gl. FLOAT, false, 0, 0);
gl. enableVertexAttribArray( a_Position); //激活



//开始渲染
// =========================================================================
//清空指定<canvas>的颜色
gl. clearColor( 0.2, 0.3, 0.3, 1.0);
//清空<canvas>
gl. clear( gl. COLOR_BUFFER_BIT);


// 画出三角形
gl. useProgram( shaderProgram);
gl. bindBuffer( gl. ARRAY_BUFFER, VBO);
gl. drawArrays( gl. TRIANGLES, 0, 3);

//渲染结束

}

//获取一个兼容的webgl上下文
private create3DContext( canvas: HTMLCanvasElement): WebGLRenderingContext | any {
var names: string[] = [ "webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
for ( var i = 0; i < names. length; i++) {
try {
var context: WebGLRenderingContext = < WebGLRenderingContext> canvas. getContext( names[ i]);
if ( context) {
return context;
}
} catch ( e) { }
}
return null;
}
}
}


另外,Main.ts 修改为调用 HelloTriangles.ts 编译就可以了。Main.ts 代码如下:

import HelloCanvas = sunnyboxs. HelloCanvas;
import HelloTriangles = sunnyboxs. HelloTriangles;

//new HelloCanvas();
new HelloTriangles();


整个工程目录结构如下,请参见前几篇的教程:


如有错误之处欢迎指正。


下一节,我们继续一步一步学习WebGL!

欢迎关注~~


结尾:推荐一个写glsl的vscode插件,写着色器会有代码提示和代码着色:

Shader languages support for VS Code




猜你喜欢

转载自blog.csdn.net/sjt223857130/article/details/80127071