【WebGL初学系列之二】WebGL第一个程序,三角形
来源:互联网 发布:kingwear智能手表软件 编辑:程序博客网 时间:2024/06/12 01:29
开始WebGL程序之前,还是得进行一些理论上的知识,不然会让自己的代码写得不明不白。上一篇文章就是写得关于WebGL的一些基础知识http://nbcoders.com/detail/156
第一:首先获取WebGL上下文。
第二:编写顶点着色器
第三:开始一些自己的绘制工作(调用WebGL API)
这里我们就以画一个三角形为例子,开始我们的WegGL程序吧。
首先获取WebGL的上下文环境,也就是渲染环境,我们要利用HTML5的canvas元素。所以我们这里要新建一个Canvas元素,这里canvas可以对应一个WebGL的渲染环境,也可以对应一个canvas-2d的渲染环境。编写如下代码:
<html> <body> <canvas id="webglCanvas" style="border:1px solid blue;" width='600px' height='600px'></canvas> </body> </html>
可以简单运行试试效果,有个蓝色的细框。接下来我们要获取WebGL的渲染区域,然后操作WebGL渲染区域。这里通过canvas的getContext方法获取WebGL的上下文环境。
var webglContext = document.getElementById().getContex("experimental-webgl");
这里完整代码如下:
function initCanvas(canvasId) { var canvas = document.getElementById(canvasId); var context = null; try{ context = canvas.getContext("experimental-webgl"); }catch(ex) { alert(ex.toString()); } if(!context) { alert("我靠,你的浏览器不支持WebGL,换个浏览器吧!"); return null; } return context; }获取了绘图上下文之后,接下来就是要开始写shader程序和绘制相关代码了。在编写Shader代码前,先简单回顾介绍一下着色器。着色器有两种,顶点着色器和片段着色器。简单点的来说,顶点着色器就是负责处理顶点的位置,片段着色器就是用来处理顶点的颜色。前面已经介绍过顶点着色器和片段着色器,废话就不多说了,来点演示的。顶点着色器和片段着色器的shader代码如下:
<span style="white-space:pre"></span><script id="shader-vs" type="x-shader/x-vertex"> attribute vec3 v3Position; void main(void) { gl_Position = vec4(v3Position, 1.0); } </script> <script id="shader-fs" type="x-shader/x-fragment"> void main(void) { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); } </script>上面一段代码只是shader程序,要创建着色器还是要通过WebGL API,这里着色器用createShader函数创建,该函数的参数只有一个,用于控制创建着色器的类型,是一个枚举类型。顶点着色器用VERTEX_SHADER表示,片段着色器用FRAGMENT_SHADER表示,最后函数返回一个创建好的对象。再来解释一下上面那段shader代码。当我们创建好着色器之后,我们还需要将3d内容转换成要绘制显示的内容。Shader程序用字符串来表示的,所以,这里写了一个解析器来解析Shader代码,将其转换。
//解析Shader代码 function shaderSourceFromScript(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; }当然,这里我们并不能说就完事了,因为我们只是刚好解析好Shader代码,接下来的事情是要对Shader代码进行编译和链接。着色器的编译源码的WebGL Api是compileShader(shaderObject),链接API为attachShader(programObject, shaderObject),这里也不对这个函数进行细说了,查查就知道。编译和链接的代码如下:
//编译shader程序 function compileShader(context, shaderVertexCode, shaderFragmentCode, vertexShaderobject, fragmentShaderObject) { //将shader代码装载到shader Object中 context.shaderSource(vertexShaderobject, shaderVertexCode); context.shaderSource(fragmentShaderObject, shaderFragmentCode); //编译shader代码 context.compileShader(vertexShaderobject); context.compileShader(fragmentShaderObject); //检查是否编译成功 if (!context.getShaderParameter(vertexShaderobject, context.COMPILE_STATUS)) { alert("error:vertexShaderObject"); return; } if (!context.getShaderParameter(fragmentShaderObject, context.COMPILE_STATUS)) { alert("error:framentShaderObject"); return; } } //链接Shader程序 function linkShader(context, programObj, vertexShaderObj, fragmentShaderObj) { //一个程序对象只能并且必须附带一个顶点着色器和片段着色器 context.attachShader(programObj, vertexShaderObj); context.attachShader(programObj, fragmentShaderObj); //将着色器变量关联到一个属性索引 context.bindAttribLocation(programObj, v3PositionIndex, "v3Position"); context.linkProgram(programObj); //检查是否链接成功 if (!context.getProgramParameter(programObj, context.LINK_STATUS)) { alert("error:ProgramObject"); return; } return programObj; } //初始化Shader程序 function initShader(context) { //创建shaderobject vertexShaderObj = context.createShader(context.VERTEX_SHADER); fragmentShaderObj = context.createShader(context.FRAGMENT_SHADER); //编译shader compileShader(context, shaderSourceFromScript("shader-vs"), shaderSourceFromScript("shader-fs"), vertexShaderObj, fragmentShaderObj); //链接shader //创建一个程序对象 programObj = context.createProgram(); programObj = linkShader(context, programObj, vertexShaderObj, fragmentShaderObj); //context指定使用shader程序 context.useProgram(programObj); }经过这步之后,Shader程序就已经编译和链接好了。接下来,我们要想渲染出我们想要的图形来,我们还需要向WebGL提供我们相应的数据。所以我们接下来的操作是建立缓冲,用来保存顶点数据。这里的第一个程序,只需要保存一个三角形的顶点位置,因为基本每一句我都写了注释,所以,直接上代码:
//初始化顶点数据 function initVextexData(context) { //顶点坐标 var jsArrayData = [ 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 1.0, 0.0, 0.0 ] //创建一个webgl能够访问的缓冲 var triangleBuffer = context.createBuffer(); //绑定buffer context.bindBuffer(context.ARRAY_BUFFER, triangleBuffer); //将js数据拷贝到buffer上 context.bufferData(context.ARRAY_BUFFER, new Float32Array(jsArrayData), context.STATIC_DRAW); return triangleBuffer; }好吧,还有一步,绘制场景(即绘制所以对象)
function start() { //初始化webgl渲染区域 webglContext = initCanvas("webglCanvas"); //初始化shader程序 initShader(webglContext); //初始化顶点数据 triangleBuffer = initVextexData(webglContext); //开始绘制 //清空屏幕 webglContext.clearColor(0.0, 0.0, 0.0, 1.0); webglContext.clear(webglContext.COLOR_BUFFER_BIT); //webgl中顶点数组数据可能N个,我们这里需要告诉webgl我们用哪一个, //绑定一个顶点数组数据 webglContext.bindBuffer(webglContext.ARRAY_BUFFER, triangleBuffer); //启动关联索引上的数据 webglContext.enableVertexAttribArray(v3PositionIndex); //指定关联索引上的数据元素或者元素数据的正确信息 webglContext.vertexAttribPointer(v3PositionIndex, 3, webglContext.FLOAT, false, 0, 0); //绘制数据 webglContext.drawArrays(webglContext.TRIANGLES, 0, 3); }最后全部的代码如下:
<html><head> <script id="shader-vs" type="x-shader/x-vertex"> attribute vec3 v3Position; void main(void) { gl_Position = vec4(v3Position, 1.0); } </script> <script id="shader-fs" type="x-shader/x-fragment"> void main(void) { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); } </script><script type="text/javascript">var webglContext = null;var vertexShaderObj = null;var fragmentShaderObj = null;var programObj = null;var v3PositionIndex = null;var triangleBuffer = null; //解析Shader代码 function shaderSourceFromScript(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; } //编译shader程序 function compileShader(context, shaderVertexCode, shaderFragmentCode, vertexShaderobject, fragmentShaderObject) { //将shader代码装载到shader Object中 context.shaderSource(vertexShaderobject, shaderVertexCode); context.shaderSource(fragmentShaderObject, shaderFragmentCode); //编译shader代码 context.compileShader(vertexShaderobject); context.compileShader(fragmentShaderObject); //检查是否编译成功 if (!context.getShaderParameter(vertexShaderobject, context.COMPILE_STATUS)) { alert("error:vertexShaderObject"); return; } if (!context.getShaderParameter(fragmentShaderObject, context.COMPILE_STATUS)) { alert("error:framentShaderObject"); return; } } //链接Shader程序 function linkShader(context, programObj, vertexShaderObj, fragmentShaderObj) { //一个程序对象只能并且必须附带一个顶点着色器和片段着色器 context.attachShader(programObj, vertexShaderObj); context.attachShader(programObj, fragmentShaderObj); //将着色器变量关联到一个属性索引 context.bindAttribLocation(programObj, v3PositionIndex, "v3Position"); context.linkProgram(programObj); //检查是否链接成功 if (!context.getProgramParameter(programObj, context.LINK_STATUS)) { alert("error:ProgramObject"); return; } return programObj; } function initShader(context){//创建shaderobjectvertexShaderObj = context.createShader(context.VERTEX_SHADER);fragmentShaderObj = context.createShader(context.FRAGMENT_SHADER);//编译shadercompileShader(context, shaderSourceFromScript("shader-vs"), shaderSourceFromScript("shader-fs"), vertexShaderObj, fragmentShaderObj);//链接shader//创建一个程序对象programObj = context.createProgram();programObj = linkShader(context, programObj, vertexShaderObj, fragmentShaderObj);//context指定使用shader程序context.useProgram(programObj);} //初始化canvasfunction initCanvas(canvasId) {var canvas = document.getElementById(canvasId);var context = null;try{context = canvas.getContext("experimental-webgl");}catch(ex){alert(ex.toString());}if(!context){alert("我靠,你的浏览器不支持WebGL,换个浏览器吧!");return null;}//获得了绘图上下文之后,设置视口context.viewport(0, 0, canvas.width, canvas.height);return context;}//初始化顶点数据 function initVextexData(context) { //顶点坐标 var jsArrayData = [ 0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 1.0, 0.0, 0.0 ] //创建一个webgl能够访问的缓冲 var triangleBuffer = context.createBuffer(); //绑定buffer context.bindBuffer(context.ARRAY_BUFFER, triangleBuffer); //将js数据拷贝到buffer上 context.bufferData(context.ARRAY_BUFFER, new Float32Array(jsArrayData), context.STATIC_DRAW); return triangleBuffer; } function start(){//初始化webgl渲染区域webglContext = initCanvas("webglCanvas");//初始化shader程序initShader(webglContext); //初始化顶点数据 triangleBuffer = initVextexData(webglContext); //开始绘制 //清空屏幕 webglContext.clearColor(0.0, 0.0, 0.0, 1.0); webglContext.clear(webglContext.COLOR_BUFFER_BIT); //webgl中顶点数组数据可能N个,我们这里需要告诉webgl我们用哪一个, //绑定一个顶点数组数据 webglContext.bindBuffer(webglContext.ARRAY_BUFFER, triangleBuffer); //启动关联索引上的数据 webglContext.enableVertexAttribArray(v3PositionIndex); //指定关联索引上的数据元素或者元素数据的正确信息 webglContext.vertexAttribPointer(v3PositionIndex, 3, webglContext.FLOAT, false, 0, 0); //绘制数据 webglContext.drawArrays(webglContext.TRIANGLES, 0, 3);}</script>></head><body onload="start()"><canvas id = "webglCanvas" style = "border:1px solid blue" width = "600px" height = "600px"></canvas></body></html>运行效果如下:
地址:http://nbcoders.com/detail/164
0 0
- 【WebGL初学系列之二】WebGL第一个程序,三角形
- WebGL学习系列-第一个程序
- 【WebGL初学系列之三】闪烁的颜色三角形
- 第一个WEBGL脚本程序
- WebGL Tutorial 绘制第一个三角形
- 【WebGL初学系列之四】纹理三角
- 【WebGL初学系列之一】WebGl基础知识
- webGL第一个3d小程序
- WebGL之旋转三角形
- WebGL入门系列二
- 初学WebGL
- 【WebGL初学系列之五】旋转,平移,缩放
- WebGL学习系列-WebGL简介
- 我的第一个WebGL代码
- WebGL
- WebGL
- WebGL
- webGL
- 【2014/10/22】mysql 索引 视图
- zoj 3822 dp
- leetcode Sudoku Solver
- 软件本地化/国际化解决方案 - 多语种代码生成工具
- Android随笔——Activity生命周期
- 【WebGL初学系列之二】WebGL第一个程序,三角形
- 33个jQuery与CSS3实现的绚丽鼠标悬停效果
- ug871-vivado-high-level-synthesis-tutorial第二章lab2中文
- 简单编程(四)要求用户输入一个年份和一个月份,判断该年该月有多少天。
- Huffman Algorithm (i) 一次提取2个最小权重值的操作实现
- Android之Handler简单用法
- hdu 5074 Hatsune Miku
- Ubuntu中同时打开多个终端窗口:Terminator
- mysql在linux上的安装之二(mysql源码安装)