步骤三:创建/加载模型数据 - initBuffers
这些小例子中,模型数据基本都是直接生成的,实际的程序中,这些数据应该都是从模型加载得到的:
vartriangleVertexPositionBuffer;
vartriangleVertexColorBuffer;
functioninitBuffers(){
triangleVertexPositionBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,triangleVertexPositionBuffer);
varvertices=[
0.0,1.0,0.0,
-1.0,-1.0,0.0,
1.0,-1.0,0.0
];
gl.bufferData(gl.ARRAY_BUFFER,newFloat32Array(vertices),gl.STATIC_DRAW);
triangleVertexPositionBuffer.itemSize=3;
triangleVertexPositionBuffer.numItems=3;
triangleVertexColorBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,triangleVertexColorBuffer);
varcolors=[
1.0,0.0,0.0,1.0,
0.0,1.0,0.0,1.0,
0.0,0.0,1.0,1.0
];
gl.bufferData(gl.ARRAY_BUFFER,newFloat32Array(colors),gl.STATIC_DRAW);
triangleVertexColorBuffer.itemSize=4;
triangleVertexColorBuffer.numItems=3;
}
上面这段代码创建了三角形的顶点和顶点的颜色数据并放在缓冲区中。
步骤四:渲染 - drawScene
准备好了数据以后,交给WebGL去渲染就好了,这里调用的是gl.drawArrays方法。看代码:
functiondrawScene(){
gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
pMatrix=okMat4Proj(45.0,gl.viewportWidth/gl.viewportHeight,0.1,100.0);
mvMatrix=okMat4Trans(-1.5,0.0,-7.0);
gl.bindBuffer(gl.ARRAY_BUFFER,triangleVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,triangleVertexPositionBuffer.itemSize,gl.FLOAT,false,0,0);
gl.bindBuffer(gl.ARRAY_BUFFER,triangleVertexColorBuffer);
gl.vertexAttribPointer(shaderProgram.vertexColorAttribute,triangleVertexColorBuffer.itemSize,gl.FLOAT,false,0,0);
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLES,0,triangleVertexPositionBuffer.numItems);
}
这个函数首先设置了3D世界的背景为黑色,然后设置投影矩阵,设置待绘制对象的位置,然后根据缓冲中的顶点和颜色数据,绘制对象。这里还有一些生成投影矩阵和模型视图矩形的辅助方法(使用了Oak3D图形库中的矩阵辅助方法)与主题关系不大,这里就不详细解释了。
基本上流程就是这么多了,更复杂的纹理,光线等都是在这些基础上加入一些WegGL的特性实现的,这个请参看后面的中文教程,里面有详细的例子。
怎么样?使用原生的WebGL开发是一种什么感受?不仅需要有深厚的3D知识,还需要知道各种实现细节。WebGL这样做是为了灵活的适应各种应用场景,但是对于大多数像我这样非专业人士来说,很多细节是不需要知道的。这样就催生了各种辅助开发的类库,例如这节用到的Oak3D库(为了演示WebGL开发,例子中只用到了矩阵辅助方法)。下一节会介绍一个用的比较多的Three.js图形库。