您的位置:首页 > 其它

webgl学习日志(1)——创建几何图形

2018-03-11 13:19 477 查看
webgl入门也挺麻烦的,需要了解JavaScript脚本编辑语言,需要会Html,需要懂点Opengl,还要有懂些计算机图形学的知识。做得精还需要会编写shader。
当然,这些都可以慢慢学,而且webgl看似难入门,其实把它各个部分割裂开,也挺简单的。当然,JavaScript和Html知识是必备的技能。
编辑器还是选择强大的visual studio。然后创建TypeScript的Html项目。这里创建这个项目就可以直接在chrome上查看结果,很方便,不用搞什么服务器什么的。
好,来看第一个部分,创建几何图形。
首先在index.html里写入主体代码。这里写了两个着色器,顶点着色器和片面着色器,当然也可以放在其他地方。然后,确定画布大小。<!DOCTYPE html>

<html lang="en">
<head>
<meta charset="utf-8" />
<title>TypeScript HTML App</title>
<link rel="stylesheet" href="app.css" type="text/css" />
<script src="app.js"></script>
<script id="shader-vs">
attribute vec3 v3Position;
void main(void)
{
gl_Position = vec4(v3Position, 1.0);
}
</script>

<script id="shader-fs">
precision mediump float;
void main(void)
{
gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);
}
</script>

<script type="text/javascript" src="Common/gl-matrix.js"></script>
<script type="text/javascript" src="Common/initShaders.js"></script>
<script type="text/javascript" src="Common/webgl_utils.js"></script>
<script type="text/javascript" src="Test/test001.js"></script>
<script>
function Init()
{
var canvas = document.getElementById('gl-canvas');
webgl = canvas.getContext("webgl");

webgl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight);
InitGeometry(webgl);
}
</script>
</head>
<body onload='Init()'>
<canvas id="gl-canvas" width="512" height="512"></canvas>
</body>
</html>接下来创建着色器,并应用着色器到程序中,这部分可以不用细究,后面再学。这部分是initshader.js.function initShaderToWebgl(webgl, v3PositionIndex)
{
vertexShaderObject = webgl.createShader(webgl.VERTEX_SHADER);
fragmentShaderObject = webgl.createShader(webgl.FRAGMENT_SHADER);

webgl.shaderSource(vertexShaderObject, getShaderSource("shader-vs"));
webgl.shaderSource(fragmentShaderObject, getShaderSource("shader-fs"));

webgl.compileShader(vertexShaderObject);
webgl.compileShader(fragmentShaderObject);

if (!webgl.getShaderParameter(vertexShaderObject, webgl.COMPILE_STATUS)) {
alert("error:vertexShaderObject");
return;
}
if (!webgl.getShaderParameter(fragmentShaderObject, webgl.COMPILE_STATUS)) {
alert("error:fragmentShaderObject");
return;
}

programObject = webgl.createProgram();

webgl.attachShader(programObject, vertexShaderObject);
webgl.attachShader(programObject, fragmentShaderObject);

webgl.bindAttribLocation(programObject, v3PositionIndex, "v3Position");

webgl.linkProgram(programObject);
if (!webgl.getProgramParameter(programObject, webgl.LINK_STATUS)) {
alert("error:programObject");
return;
}

webgl.useProgram(programObject);
}
//
// Initialize a shader program, so WebGL knows how to draw our data
//
function initShaderProgram(gl, vsSource, fsSource) {
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);

// Create the shader program

const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);

// If creating the shader program failed, alert

if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert('Unable to initialize the shader program: ' + gl.getProgramInfoLog(shaderProgram));
return null;
}

return shaderProgram;
}

//
// creates a shader of the given type, uploads the source and
// compiles it.
//
function loadShader(gl, type, source) {
const shader = gl.createShader(type);

// Send the source to the shader object

gl.shaderSource(shader, source);

// Compile the shader program

gl.compileShader(shader);

// See if it compiled successfully

if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {

alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}

return shader;
}

function getShaderSource(scriptID) {
var shaderScript = document.getElementById(scriptID);
if (shaderScript == null) return "";

var sourceCode = "";
var child = shaderScript.firstChild;
while (child) {
if (child.nodeType == child.TEXT_NODE) sourceCode += child.textContent;
child = child.nextSibling;
}

return sourceCode;
}最后就是他的几何部分,卸载test001.js中。var webgl = null;
var vertexShaderObject = null;
var fragmentShaderObject = null;
var programObject = null;
var triangleBuffer = null;
var v3PositionIndex = 0;

function InitGeometry(webgl) {

var jsArrayData =
[
0.0, 1.0, 0.0,//上顶点
-1.0, -1.0, 0.0,//左顶点
1.0, -1.0, 0.0
];//右顶点

render(webgl, v3PositionIndex, jsArrayData);

//开启着色器中的顶点属性
webgl.enableVertexAttribArray(v3PositionIndex);
//描述顶点数组中的数据形式
webgl.vertexAttribPointer(v3PositionIndex, 3, webgl.FLOAT, false, 0, 0);
//画三角形
webgl.drawArrays(webgl.TRIANGLES, 0, 3);

}

function render(webgl, v3PositionIndex, jsArrayData)
{
//初始化定义shader
initShaderToWebgl(webgl, v3PositionIndex);
initBuffer(webgl, jsArrayData);
webgl.clearColor(0.0, 0.0, 0.0, 1.0);
webgl.clear(webgl.COLOR_BUFFER_BIT);
}

//创建缓冲区并绑定顶点数据
function initBuffer(webgl, jsArrayData)
{
triangleBuffer = webgl.createBuffer();
webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData), webgl.STATIC_DRAW);
}webgl_utils.js用来写各种小工具。gl-matrix.js用来存放矩阵计算的方法。暂时用不上。
最后结果:



现在来画几条线,这个就简单了,直接在上面的InitGeometry()方法里修改,比如我要画四条直线,那就是8个点。只需要在jsArrayData里添加点即可,另外,需要把drawArray里的3改为8,另外用上webgl.LINES的模式。更多样式请参考:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawArrays
各个实例请参考:http://www.cocoachina.com/ios/20170710/19798.html
function InitGeometry(webgl) {

var jsArrayData =
[
-0.5, -0.5, 0.0,
-0.5, 0.5, 0.0,

-0.5, 0.5, 0.0,
0.5, 0.5, 0.0,

0.5, 0.5, 0.0,
0.5, -0.5, 0.0,

0.5, -0.5, 0.0,
-0.5, -0.5, 0.0,
];//右顶点

render(webgl, v3PositionIndex, jsArrayData);

//开启着色器中的顶点属性
webgl.enableVertexAttribArray(v3PositionIndex);
//描述顶点数组中的数据形式
webgl.vertexAttribPointer(v3PositionIndex, 3, webgl.FLOAT, false, 0, 0);
//画直线
webgl.drawArrays(webgl.LINES, 0, 8);

}


讲得比较简单,最好结合书和视频教程来看。但是把各个部分分隔开,还是很好理解的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: