2019年在浏览器用原生js写WebGL,绘制图形;

您所在的位置:网站首页 星空js代码 2019年在浏览器用原生js写WebGL,绘制图形;

2019年在浏览器用原生js写WebGL,绘制图形;

2023-03-13 09:06| 来源: 网络整理| 查看: 265

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

使用WebGL上下文对象绘图 您的浏览器不支持canvas标签; #ifdef GL_ES precision mediump float; #endif attribute vec2 aVertexPosition; void main() { gl_Position = vec4(aVertexPosition, 0.0, 1.0); } #ifdef GL_ES precision mediump float; #endif uniform vec4 uColor; void main() { gl_FragColor = uColor; } 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画图;"); } }

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

WebGL Example Your browser doesn't suppor the canvas tag.(您的浏览器不支持canvas标签;) attribute vec2 aVertexPosition; void main() { gl_Position = vec4(aVertexPosition, 0.0, 1.0); } uniform vec4 uColor; void main() { gl_FragColor = uColor; } 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;"); } } };

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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3