HTML5时代的到来,让WebGL这个重磅核武器渐渐被大多人所熟悉并且使用。笔者最近两周左右的时间因为项目的原因,一直在看WebGL相关的文章。
说说我的基础吧:计算机本科毕业生水平,大学本科用MFC编写图形学的基础,除此之外在使用WebGL之前自己偷摸着用了一阵子的opengl以及jogl,也就是写几个小例子的水平。写网页的话有点HTML的小基础,写javascript基本每次都是现学的。本人眼高手低,心想着WebGL肯定api也跟这两者差不多,应该很快就入门。没想到入门就吃了闭门羹。终于静下心来买了一本《WebGL入门指南》慢慢研读,研读下来感悟不少,一本不到两百多页的书硬是被我越读越厚。利用这个博客将我这一段时间的所得写下来吧。第一次在CSDN写博客,有什么不足的地方见谅以及指出。本人的联系邮箱是:[email protected]
大学时候有位老师对我说,什么事情都得从小事开始做起。那么我的心路历程也用原生的一个WebGL例子作为引子开始介绍WebGL
例子引自WebGL高级编程
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Listing 2-1, A First WebGL Example</title>
<meta charset="utf-8">
<script type="text/javascript">
var gl;
var canvas;
var shaderProgram;
var vertexBuffer;
function createGLContext(canvas) {
var names = ["webgl", "experimental-webgl"];
var context = null;
for (var i=0; i < names.length; i++) {
try {
context = canvas.getContext(names[i]);
} catch(e) {}
if (context) {
break;
}
}
if (context) {
context.viewportWidth = canvas.width;
context.viewportHeight = canvas.height;
} else {
alert("Failed to create WebGL context!");
}
return context;
}
function loadShader(type, shaderSource) {
var shader = gl.createShader(type);
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert("Error compiling shader" + gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
function setupShaders() {
var vertexShaderSource =
"attribute vec3 aVertexPosition; \n" +
"void main() { \n" +
" gl_Position = vec4(aVertexPosition, 1.0); \n" +
"} \n";
var fragmentShaderSource =
"precision mediump float; \n"+
"void main() { \n"+
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); \n"+
"} \n";
var vertexShader = loadShader(gl.VERTEX_SHADER, vertexShaderSource);
var fragmentShader = loadShader(gl.FRAGMENT_SHADER, fragmentShaderSource);
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Failed to setup shaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
}
function setupBuffers() {
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
var triangleVertices = [
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW);
vertexBuffer.itemSize = 3;
vertexBuffer.numberOfItems = 3;
}
function draw() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
gl.drawArrays(gl.TRIANGLES, 0, vertexBuffer.numberOfItems);
}
function startup() {
canvas = document.getElementById("myGLCanvas");
gl = createGLContext(canvas);
setupShaders();
setupBuffers();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
draw();
}
</script>
</head>
<body οnlοad="startup();">
<canvas id="myGLCanvas" width="500" height="500"></canvas>
</body>
</html>
很不幸地说,这个例子看似代码很长,出来的效果,如下图:
有点失望是吧,这么一大段的代码,出来的结果却是这样的。
我在这里说说自己对这个例子的几点感悟,希望对于想要学WebGL的同学有所帮助(有关HTML以及JS一些基础的内容,自行百度脑补XD)
1. 这个例子是最基础的webGL程序,你甚至可以把它当成一个模板应用在你后面的一些例子当中。当然了,如果对于只是使用webGL来快速开发而不是研究webGL的朋友来说,你会有更好的方法来达到你的目的。比如使用一些成熟的WebGL框架。
2. createGLContext函数判断浏览器是否支持支持WebGL,如果支持的话返回一个context对象,我对这个context对象的理解就相当于opengl里面的gl,事实证明例子中把该函数的返回值也赋给了一个名为gl的变量。对于这个函数,您大可不必大费周章,因为很多时候您对它的操作也就是copy+paste。
3. 来到关键的setupShaders函数,对于webGL来说,个人认为最最关键的技术就在于顶点着色器和片段着色器了。为什么要使用这两个东西呢?这么来说吧,如果我只用CPU来完成绘图工作的话,效率已经很慢了,如果我再用效率更低的js来绘图的话,可想而知效率会怎么样?那么webGL是将点的渲染交给GPU,采用GLSL的类C语言的语法编写这一部分的代码,将代码传入CPU编译连接,这样就提高了效率。这一部分的代码主要有两种:顶点着色器和片段着色器。关于这两个知识点,我会在后面的文章中说明。
4. setupBuffers函数定义了图形的顶点,你还可以在这里面定义图形的颜色等等信息。
5. 最后的draw函数,利用之前做好的准备和数据画出图形
整个过程就是这样了,我的建议是,对于这一大段代码,您大可不必大费周章每行都明白。现在,你只需要知道每一步是干什么的,以及能大概在脑子里面有个大体的流程,知道WebGL的程序的流程就好。
后面的内容我将以Three.js这个框架为基础,谈谈自己最近的感受。等最后,再回来看看这个程序,就会很明白每一步的细节了。需要说明的是,《webGL入门指南》这本书虽然讲的很好,而且基于Three.js这个框架,但是在中间又引入本书作者自己的Sim.js框架让我很不习惯。因为本来Three.js已经封装了一层代码的情况下,我不太喜欢有人再给我封装一层不符合我的学习习惯,这就是导致我这本书越读越厚的原因了。另外,我在很纠结的情况下也去拜读了一下Sim.js框架的代码,从中学到了很多,也写了自己的一个小框架,会在后面的学习中一点点引入。
文章浏览阅读1.1k次,点赞40次,收藏27次。(2) 设置pinctrl-names="default"与pinctrl-0 = <πnctrl节点名称>(2)在内核/arch/arm/boot/dts/imx6ulpinfunc.h中寻找对应的引脚复用宏定义。这里只是对引脚复用宏定义进行解释,实际不会去修改这个文件,只会对其进行应用,所以我们的重点在PAD(引脚属性)值。引脚复用宏定义:在其内核文件下的 arch/arm/boot/dts/imx6ul-pinfunc.h。编译成功后会在“./arch/arm/boot/dts。_设备树pinctrl和gpio子系统
文章浏览阅读117次。目录:一、NSSet集合二、NSDictionary字典三、block代码块回到顶部一、NSSet集合1 NSSet是一个无序的,管理对个对象的集合类,最大特点是集合中不允许出现重复对象,和数学上的集合含义是一样的。除了无序,不许重复,其他功能和NSArray是一样的。2 什么叫重复?* 同一个对象* 两个对象信息值一样计算机认为的一样是:..._nsdictionary block
文章浏览阅读247次。案例代码下载可选链接可选链接是一个查询和调用当前可能为nil的可选项的属性,方法和下标的过程。如果optional包含值,则属性,方法或下标调用成功; 如果optional是nil,则属性,方法或下标调用返回nil。多个查询可以链接在一起,如果链中的任何链接为nil,则整个链都会正常失败。注意: Swift中的可选链接类似于Objective-C中的nil消息传递,但其方式适用于任何类型,..._swift 文件公开链接
文章浏览阅读4.6k次。sslOpenSSL的SSL/TLS库,实现了SSL(Secur)/TLS(Transport Layer Security)/DTLS(Datagram Transport Layer Security)协议的多个版本。SSL_CTX对象包含证书、算法等信息,用于建立TLS/SSL连接。网络连接建立后可以赋值给SSL对象,然后可以使用SSL对象完成握手操作(SSL_accept或SSL_connect或SSL_do_handshake),握手完成后就可以读写了。关闭网络连接前先调用SSL_shutd_ssl_read_ex
文章浏览阅读809次。方案一:AT89C52是美国ATMEL公司生产的低电压,高性能CMOS型8位单片机,器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器(CPU)和Flash存储单元,功能强大。其片内的8K程序存储器是FLASH工艺的,这种单片机对开发设备的要求很低,开发时间也大大缩短。写入单片机内的程序还可以进行加密,这又很好地保护我们的劳动成果。再者,AT89C52目前的售价比8031还低,市场供应也很充足。_超重报警电子秤总体设计方案
文章浏览阅读248次。资源描述:C C 语言编程题及答案(三)语言编程题及答案(三) 1. 给小学生出加法考试题 编写一个程序,给学生出一道加法运算题,然后判断学生输入的答案对错与否,按下列 要求以循序渐进的方式编程。 程程序序 1 通过输入两个加数给学生出一道加法运算题,如果输入答案正确,则显示 “Right” , 否则显示“Not correct Try again” ,程序结束。 程程序序 2 通过输入两个加数给..._1)通过输入两个加数给学生出一道加法运算题,如果输入答案正确,则显示“right!”,
文章浏览阅读574次,点赞5次,收藏3次。在这里直接体现源码,感兴趣的可以提出修改建议,以及自己的一些想法。_博图crc校验程序
文章浏览阅读317次。POE是"Power over Ethernet"的缩写,它是一种通过以太网(Ethernet)网络传输电力的技术。POE的标准规定了不同供电能力的级别,从而适应不同设备的功耗需求。IEEE 802.3af(POE)提供最高15.4瓦的功率,而IEEE 802.3at(POE+)则提供最高30瓦的功率。POE技术的应用使得网络设备的安装和维护更加便利,特别是在需要灵活布置设备的情况下。有一些设备可以作为POE中继器,允许将POE信号传输到更远的距离,从而扩大了POE的应用范围。
文章浏览阅读2.3k次。1、立项内容管理项目立项一般包括提交项目建议书、项目可行性研究、项目招标与投标等内容。1.1 项目建议书项目建议书(又称立项申请)是项目建设单位向上级主管部门提交项目申请时所必须的文件,是该项目建设筹建单位或项目法人,提出的某一具体项目的建议文件,是对拟建项目提出的框架性的总体设想。项目建议书是项目发展周期的初始阶段,也是可行性研究的依据,在项目建议书批准后,方可开展对外工作。1.1.1 项目建议书内容(1)项目的必要性。(2)项目的市场预测。(3)产品方案或服务的市场预测。(4)项_论信息系统项目的立项管理
文章浏览阅读5.3k次,点赞2次,收藏3次。程序大概分成三个部分:1.获取手机已安装的所有应用package的信息(其中包括用户自己安装的,还有系统自带的);2.滤除系统自带应用;3.通过列表显示出应用程序的图标(icon),和其他文字信息(应用名称,包名称package name,版本号等等)首先,我们定义一个数据结构,来保存应用程序信息(icon,name,packageName,versionName,_app读取应用列表怎么区分是否系统应用
文章浏览阅读95次。这是在www目录下的index.php文件有参数没有设置好。然后修改里面查找$projectContents,或直接查看338行代码,修改'http://'为'http://localhost/'即可(再试应该就可以了) ..._php a herf 链接跳转外部页面 去掉开头的 localhost 目录信息
文章浏览阅读1.8k次。图象工具:可将SWING组件外观输出成图片的工具---------------------------------------- 我的自定义SWING组件 !!! 王 晋 (Edward W.J.)Email:[email protected]:(0)13482058688_swing打印出组件的图片