因为JavaScript高级程序设计(第三版)中的运行书上15.3WebGL部分的代码时在chrome和firefox浏览器下报错,在后面我网上初步找了一圈,好像没人做出真正可以用的代码;所以我就自己重写了一下:
书上代码有些错误,错误原因应该是书出了太久,WebGL的规则已经有些改变了.并且,可能浏览器也有一些相关的规则改变了;
新的代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>使用WebGL上下文对象绘图</title>
</head>
<body>
<canvas id="drawing" width="800" height="800">您的浏览器不支持canvas标签;</canvas> <!--开始04.使用脚本script标签编写着色器文本;-->
<!--开始使用脚本script标签编写顶点着色器文本;-->
<script type="x-webgl/x-shader" id="vertex-shader">
#ifdef GL_ES
precision mediump float;
#endif
attribute vec2 aVertexPosition;
void main() {
gl_Position = vec4(aVertexPosition, 0.0, 1.0);
} </script>
<!--结束使用脚本script标签编写顶点着色器文本;-->
<!--开始使用脚本script标签编写片段着色器文本;-->
<script type="x-webgl/x-shader" id="fragment-shader">
#ifdef GL_ES
precision mediump float;
#endif
uniform vec4 uColor;
void main() {
gl_FragColor = uColor;
} </script>
<!--结束使用脚本script标签编写片段着色器文本;-->
<!--结束04.使用脚本script标签编写着色器文本;-->
<script>
var drawing = document.getElementById("drawing");
var theContextSetting;
var gl;
var buffer;
var vertices;
var thisProgram;
var vertexShader;
var fragmentShader;
var node; if (drawing.getContext){ try {
theContextSetting = {
alpha: true,
depth: true,
stencil: false,
antialias: true,
premultipliedAlpha: true,
preserveDrawingBuffer: false
} gl = drawing.getContext("experimental-webgl",theContextSetting);
} catch (ex) {
console.log("浏览器无法创建WebGL上下文并抛出错误,此时抛出的错误参数ex--->",ex);
} if (gl){ //开始01.准备绘图;
gl.clearColor(1.0,0.0,1.0,1.0); //首先必须使用clearColor()方法来指定要使用的颜色值,该方法接收4个参数: 红、绿、蓝和透明度;每个参数必须是一个0到1之间的数值,表示每种分量在最终颜色中的强度;
gl.clear(gl.COLOR_BUFFER_BIT); //调用了clear()方法,传入的参数gl.COLOR_BUFFER_BIT告诉WebGL上下文对象使用之前定义的颜色来填充相应区域;
//结束01.准备绘图; //开始02.定义WebGL上下文对象的视口;
gl.viewport(0,0,drawing.width,drawing.height);
//结束02.定义WebGL上下文对象的视口; //开始03.设置缓冲区;
buffer = gl.createBuffer();
vertices = new Float32Array([0,1,1,-1,-1,-1]);
//开始将数据放入缓冲区;
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
//结束将数据放入缓冲区;
//结束03.设置缓冲区; //开始05.编写着色器对象并链接到着色器程序中;
//开始编写顶点着色器对象;
node = document.getElementById("vertex-shader");
vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, node.text);
gl.compileShader(vertexShader);
//结束编写顶点着色器对象; //开始编写片段着色器对象;
node = document.getElementById("fragment-shader");
fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, node.text);
gl.compileShader(fragmentShader);
//结束编写片段着色器对象; //开始创建着色器程序并把两个着色器对象链接到到着色器程序中;
thisProgram = gl.createProgram();
gl.attachShader(thisProgram, vertexShader);
gl.attachShader(thisProgram, fragmentShader);
gl.linkProgram(thisProgram);
gl.useProgram(thisProgram);
//结束创建着色器程序并把两个着色器对象链接到到着色器程序中;
//结束05.编写着色器对象并链接到着色器程序中; //开始06.为着色器传入值; var vertexSetSize = 2;
var vertexSetCount = vertices.length/vertexSetSize;
var uColor;
var aVertexPosition; //开始为片段着色器进行赋值;
uColor = gl.getUniformLocation(thisProgram, "uColor");
var uColorValue = [1.0,1.0,0.0,1.0];
gl.uniform4fv(uColor,uColorValue);
//结束为片段着色器进行赋值; //开始为顶点着色器进行赋值;
aVertexPosition = gl.getAttribLocation(thisProgram, "aVertexPosition");
gl.enableVertexAttribArray(aVertexPosition);
gl.vertexAttribPointer(aVertexPosition, vertexSetSize, gl.FLOAT, false, 0, 0);
//结束为顶点着色器进行赋值;
//结束06.为着色器传入值; //开始07.绘图;
gl.drawArrays(gl.TRIANGLES,0,vertexSetCount);
//结束07.绘图; } else {
console.log("您的浏览器不支持WebGL画图;");
}
}
</script>
</body>
</html>

如果有兴趣,可以自己对比两者代码,了解到底有那些部份改变了;了解原书作者在写那书时,可能没考虑到那些东西;
原书代码如下:

<!DOCTYPE html>
<html>
<head>
<title>WebGL Example</title>
</head>
<body>
<canvas id="drawing" width="1200" height="1200">Your browser doesn't suppor the canvas tag.(您的浏览器不支持canvas标签;)</canvas>
<script type="x-webgl/x-shader" id="vertex-shader">
attribute vec2 aVertexPosition; void main() {
gl_Position = vec4(aVertexPosition, 0.0, 1.0);
}
</script>
<script type="x-webgl/x-shader" id="fragment-shader">
uniform vec4 uColor; void main() {
gl_FragColor = uColor;
}
</script>
<script>
window.onload = function(){
var drawing = document.getElementById("drawing");
var gl;
var program;
var vertexShader;
var fragmentShader;
var node; if (drawing.getContext){ try { var theContextSetting = {
alpha: true,
depth: true,
stencil: false,
antialias: true,
premultipliedAlpha: true,
preserveDrawingBuffer: false
} gl = drawing.getContext("experimental-webgl",theContextSetting);
*/
} catch (ex) {
//noop;
} if (gl){
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.viewport(0, drawing.height, drawing.width, drawing.height); //create the vertex shader
node = document.getElementById("vertex-shader");
vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, node.text);
gl.compileShader(vertexShader); //create the fragment shader
node = document.getElementById("fragment-shader");
fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, node.text);
gl.compileShader(fragmentShader); //create the shader program
program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program); //debugging
if(!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)){
console.log(gl.getShaderInfoLog(vertexShader));
} if(!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)){
console.log(gl.getShaderInfoLog(fragmentShader));
} if(!gl.getProgramParameter(program, gl.LINK_STATUS)){
console.log(gl.getProgramInfoLog(program));
} //define three vertices, x and y for each
var vertices = new Float32Array([ 0, 1, 1, -1, -1, -1 ]),
buffer = gl.createBuffer(),
vertexSetSize = 2,
vertexSetCount = vertices.length/vertexSetSize,
uColor, aVertexPosition; //put data into the buffer
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); //pass color to fragment shader
uColor = gl.getUniformLocation(program, "uColor");
gl.uniform4fv(uColor, [ 0, 0, 0, 1 ]); //pass vertex information to shader
aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
gl.enableVertexAttribArray(aVertexPosition);
gl.vertexAttribPointer(aVertexPosition, vertexSetSize, gl.FLOAT, false, 0, 0); //draw the triangle
gl.drawArrays(gl.TRIANGLES, 0, vertexSetCount); } else {
alert("Your browser doesn't support WebGL;");
}
}
};
</script>
</body>
</html>

注:以上代码我修改过,但没多大改变,和原书作者的意思差不多;如果有兴趣,可以结合两份代码进行对比;不懂的话,到2019年6年前可以问我,有时间尽量回答;过了时间,可能我就不作回答了;

2019年在浏览器用原生js写WebGL,绘制图形;的更多相关文章

  1. 原生 js 写分页

    欢迎留言或者加本人QQ172360937咨询 这段代码是用原生 js 写的一个分页的效果 <!doctype html> <html lang="en"> ...

  2. 原生js写Ajax

    //原生js写ajax就像打电话 //打电话分下面4步//1.拿出手机//2.拨号//3.说话//4.挺对方说话 //ajax也分下面4步//1.创建ajax对象//2.连接到服务器//3.发送请求( ...

  3. 原生js写的贪吃蛇网页版游戏特效

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <bo ...

  4. 用原生JS写移动动画案例及实际应用

    js很强大 相信很多人都知道,那么它有哪些强大之处呢?有兴趣的人可以去查查,这里就不赘述了,因为不在本片文章讨论的范围. 我们要讲的是怎么用原生JS写移动动画?我们先举一个最简单的动画例子,很多网站的 ...

  5. 原生JS写的ajax函数

    参照JQuery中的ajax功能,用原生JS写了一个ajax,功能相对JQuery要少很多,不过基本功能都有,包括JSONP. 调用的方式分为两种: 1. ajax(url, {}); 2. ajax ...

  6. 用原生js写一个"多动症"的简历

    用原生js写一个"多动症"的简历 预览地址源码地址 最近在知乎上看到@方应杭用vue写了一个会动的简历,觉得挺好玩的,研究一下其实现思路,决定试试用原生js来实现. 会动的简历实现 ...

  7. 用原生JS写一个网页版的2048小游戏(兼容移动端)

    这个游戏JS部分全都是用原生JS代码写的,加有少量的CSS3动画,并简单的兼容了一下移动端. 先看一下在线的demo:https://yuan-yiming.github.io/2048-online ...

  8. 使用原生js写ajax

    // 使用原生js 封装ajax // 兼容xhr对象 function createXHR(){ if(typeof XMLHttpRequest != "undefined") ...

  9. 原生js写的一个弧形菜单插件

    弧形菜单是一种半弧式或者全弧形菜单,是一种不同于传统横向或者竖向菜单形式的菜单.最近在网上看到好多人写出了这种效果,于是也尝试自己写了一个. 实现方式:原生态js 主要结构: 1.参数合并 var d ...

  10. 自己用原生JS写的轮播图,支持移动端触屏滑动,面向对象思路。分页器圆点支持click和mouseover。

    自己用原生javascript写的轮播图,面向对象思路,支持移动端手指触屏滑动.分页器圆点可以选择click点击或mouseover鼠标移入时触发.图片滚动用的setInterval,感觉setInt ...

随机推荐

  1. [转帖]AlertManager 配置邮箱告警

    http://www.mydlq.club/article/126/ 2022-12-02 13:17:00KUBERNETESPROMETHEUSALERTMANAGER 文章目录 一.邮箱告警说明 ...

  2. [转帖]深入理解mysql-第十一章 mysql查询优化-Explain 详解(中)

    一.执行计划-type属性 执行计划的一条记录就代表着MySQL对某个表的执行查询时的访问方法,其中的type列就表明了这个访问这个单表的方法具体是什么,比方说下边这个查询: mysql> EX ...

  3. 浅析大促备战过程中出现的fullGc,我们能做什么?

    作者:京东科技 白洋 前言: 背景: 为应对618.双11大促,消费金融侧会根据零售侧大促节奏进行整体系统备战.对核心流量入口承载的系统进行加固优化,排除系统风险,保证大促期间系统稳定. 由于大促期间 ...

  4. 结论&定理大全

    定理 1:包含 \(0\) 与 \(2^k-1\) 的按位与或空间和 \(k\) 个点的有传递性的有向图形成双射 证明: 空间->传递闭包:对于任意两个位 \(i,j\),若某个数包含 \(i\ ...

  5. Ant Design Vue数字输入框InputNumber 有值但是验证却不能够通过

    InputNumber 有值但是验证却不能够通过 今天遇见这样一个问题,InputNumber 输入框中有值 但是却却提示验证不能够通过 后来经过分析,怀疑是数据类型不正确, 后面经过验证,果然是数据 ...

  6. svn把文件日期设置为最后提交的时间

    在使用svn进行checkout或update时,我想让文件的日期为提交那时的日期,这要怎样做? 说明:我是在windows下使用TortoiseSVN进行操作的 方法1.修改config [misc ...

  7. centos6.5安装MongoDB4.4.23

    前言 1.目前MongoDB最新稳定版本是:6.0.8 2.MongoDB 5+和6+版本已不支持centos6.2+系统,参考https://docs.mongoing.com/install-mo ...

  8. vue + elementui 分页切换页面,缓存页码

    问题场景 列表页面输入查询条件,选择第3页,点击详情进入详情页,从详情页返回时,默认列表页面页码重置为1:此时想要缓存该页码,有两种方式:可按业务场景使用 方式一:用vue自带的 keep-alive ...

  9. 神经网络优化篇:详解如何训练一个 Softmax 分类器(Training a Softmax classifier)

    如何训练一个 Softmax 分类器 回忆一下之前举的的例子,输出层计算出的\(z^{[l]}\)如下,\(z^{[l]} = \begin{bmatrix} 5 \\ 2 \\ - 1 \\ 3 \ ...

  10. ABC306 A - F

    ABC306 A - F 代码不提供 A 题意:吧字符串的每个字符连续输出两遍,记得不要快读,不要忘记输入 $ n $ 纪念 Qinzh A 题 WA 掉 B 题意:给定长度为 $ 64 $ 的数组 ...