小八——WebGL心路历程(1),从一个原生的webGL程序粗放认识webGL_webgl有用mfc吗-程序员宅基地

技术标签: webgl  我的webgl  

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框架的代码,从中学到了很多,也写了自己的一个小框架,会在后面的学习中一点点引入。


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013231094/article/details/17456121

智能推荐

设备树(五) ——pinctrl子系统与GPIO子系统_设备树pinctrl和gpio子系统-程序员宅基地

文章浏览阅读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子系统

04-Foundation-NSSet、NSDictionary、block-程序员宅基地

文章浏览阅读117次。目录:一、NSSet集合二、NSDictionary字典三、block代码块回到顶部一、NSSet集合1 NSSet是一个无序的,管理对个对象的集合类,最大特点是集合中不允许出现重复对象,和数学上的集合含义是一样的。除了无序,不许重复,其他功能和NSArray是一样的。2 什么叫重复?* 同一个对象* 两个对象信息值一样计算机认为的一样是:..._nsdictionary block

Swift编程十七(可选链接)_swift 文件公开链接-程序员宅基地

文章浏览阅读247次。案例代码下载可选链接可选链接是一个查询和调用当前可能为nil的可选项的属性,方法和下标的过程。如果optional包含值,则属性,方法或下标调用成功; 如果optional是nil,则属性,方法或下标调用返回nil。多个查询可以链接在一起,如果链中的任何链接为nil,则整个链都会正常失败。注意: Swift中的可选链接类似于Objective-C中的nil消息传递,但其方式适用于任何类型,..._swift 文件公开链接

OpenSSL之ssl库_ssl_read_ex-程序员宅基地

文章浏览阅读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

285、基于51单片机的电子秤称重超重报警系统设计(程序+原理图+PCB图+参考论文+开题报告+设计资料+制作详解+程序流程图+元器件清单等)_超重报警电子秤总体设计方案-程序员宅基地

文章浏览阅读809次。方案一:AT89C52是美国ATMEL公司生产的低电压,高性能CMOS型8位单片机,器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器(CPU)和Flash存储单元,功能强大。其片内的8K程序存储器是FLASH工艺的,这种单片机对开发设备的要求很低,开发时间也大大缩短。写入单片机内的程序还可以进行加密,这又很好地保护我们的劳动成果。再者,AT89C52目前的售价比8031还低,市场供应也很充足。_超重报警电子秤总体设计方案

c语言编程题及答案汇总,c语言编程题及答案-程序员宅基地

文章浏览阅读248次。资源描述:C C 语言编程题及答案(三)语言编程题及答案(三) 1. 给小学生出加法考试题 编写一个程序,给学生出一道加法运算题,然后判断学生输入的答案对错与否,按下列 要求以循序渐进的方式编程。 程程序序 1 通过输入两个加数给学生出一道加法运算题,如果输入答案正确,则显示 “Right” , 否则显示“Not correct Try again” ,程序结束。 程程序序 2 通过输入两个加数给..._1)通过输入两个加数给学生出一道加法运算题,如果输入答案正确,则显示“right!”,

随便推点

基于博图TIA中SCL语言编写CRC校验功能块_博图crc校验程序-程序员宅基地

文章浏览阅读574次,点赞5次,收藏3次。在这里直接体现源码,感兴趣的可以提出修改建议,以及自己的一些想法。_博图crc校验程序

POE介绍-程序员宅基地

文章浏览阅读317次。POE是"Power over Ethernet"的缩写,它是一种通过以太网(Ethernet)网络传输电力的技术。POE的标准规定了不同供电能力的级别,从而适应不同设备的功耗需求。IEEE 802.3af(POE)提供最高15.4瓦的功率,而IEEE 802.3at(POE+)则提供最高30瓦的功率。POE技术的应用使得网络设备的安装和维护更加便利,特别是在需要灵活布置设备的情况下。有一些设备可以作为POE中继器,允许将POE信号传输到更远的距离,从而扩大了POE的应用范围。

信息系统项目管理师(2022年) —— 第 3 章 项目立项管理_论信息系统项目的立项管理-程序员宅基地

文章浏览阅读2.3k次。1、立项内容管理项目立项一般包括提交项目建议书、项目可行性研究、项目招标与投标等内容。1.1 项目建议书项目建议书(又称立项申请)是项目建设单位向上级主管部门提交项目申请时所必须的文件,是该项目建设筹建单位或项目法人,提出的某一具体项目的建议文件,是对拟建项目提出的框架性的总体设想。项目建议书是项目发展周期的初始阶段,也是可行性研究的依据,在项目建议书批准后,方可开展对外工作。1.1.1 项目建议书内容(1)项目的必要性。(2)项目的市场预测。(3)产品方案或服务的市场预测。(4)项_论信息系统项目的立项管理

【转】android获取所有安装的非系统应用_app读取应用列表怎么区分是否系统应用-程序员宅基地

文章浏览阅读5.3k次,点赞2次,收藏3次。程序大概分成三个部分:1.获取手机已安装的所有应用package的信息(其中包括用户自己安装的,还有系统自带的);2.滤除系统自带应用;3.通过列表显示出应用程序的图标(icon),和其他文字信息(应用名称,包名称package name,版本号等等)首先,我们定义一个数据结构,来保存应用程序信息(icon,name,packageName,versionName,_app读取应用列表怎么区分是否系统应用

wamp集成环境自己的项目访问时出现地址栏自动去掉localhost的问题-程序员宅基地

文章浏览阅读95次。这是在www目录下的index.php文件有参数没有设置好。然后修改里面查找$projectContents,或直接查看338行代码,修改'http://'为'http://localhost/'即可(再试应该就可以了) ..._php a herf 链接跳转外部页面 去掉开头的 localhost 目录信息

图象工具:可将SWING组件外观输出成图片的工具 - SWING组件_swing打印出组件的图片-程序员宅基地

文章浏览阅读1.8k次。图象工具:可将SWING组件外观输出成图片的工具---------------------------------------- 我的自定义SWING组件 !!! 王 晋 (Edward W.J.)Email:[email protected]:(0)13482058688_swing打印出组件的图片

推荐文章

热门文章

相关标签