赞
踩
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../lib/index.js"></script> <style> *{ margin: 0; padding: 0; } canvas{ margin: 50px auto 0; display: block; background: yellow; } </style> </head> <body> <canvas id="cancas" width="400" height="400"></canvas> </body> <script> const ctx = document.getElementById('cancas') const gl = ctx.getContext('webgl') //着色器 //创建着色器源码 const VERTEX_SHADER_SOURCE = ` //必须要存在 main 函数 attribute vec4 aPosition; void main() { //要绘制的点的坐标 gl_Position = aPosition; //默认为 vec4(0.0,0.0,0.0,1.0); //点的大小 gl_PointSize=40.0; } `; //顶点着色器 const FRAGMENT_SHADER_SOURCE = ` void main(){ gl_FragColor=vec4(1.0,0.0,0.0,1.0); } `; //片元着色器 //执行绘画 const program=initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE) // 获取attribute变量 const aPosition=gl.getAttribLocation(program,'aPosition') gl.vertexAttrib1f(aPosition,0.0) gl.drawArrays(gl.POINTS, 0, 1);//重新绘制 // onmousemove 鼠标跟随效果 ctx.onmousemove=function(ev){ //坐标 const x =ev.clientX const y=ev.clientY const domPosition= ev.target.getBoundingClientRect() console.log(domPosition,ctx.offsetTop,ctx.offsetLeft) const domx=x-domPosition.left; const domy=y-domPosition.top; /* 画布的宽度是400,对应的画布坐标系 0 200 400 webgl对应的X坐标系 -1 0 1 把画布X坐标系转化成webgl对应的坐标系 需要先 -200 (当前画布的宽度)然后再除以200 画布的高度是400,对应的画布坐标系 0 200 400 webgl对应的Y坐标系 1 0 -1 把画布Y坐标系转化成webgl对应的坐标系 需要先让200(当前画布的高度) 减这个数,然后再/200 */ const halfWidth=ctx.offsetWidth/2 const halfHeight=ctx.offsetHeight/2 const clickX=(domx-halfWidth)/halfWidth const clickY=(halfHeight-domy) / halfHeight gl.vertexAttrib2f(aPosition,clickX,clickY) gl.drawArrays(gl.POINTS, 0, 1); } </script> </html>
提示:需要把画布坐标转换成webgl坐标才能进行绘画
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../lib/index.js"></script> <style> *{ margin: 0; padding: 0; } canvas{ margin: 50px auto 0; display: block; background: yellow; } </style> </head> <body> <canvas id="cancas" width="400" height="400"></canvas> </body> <script> const ctx = document.getElementById('cancas') const gl = ctx.getContext('webgl') //着色器 //创建着色器源码 const VERTEX_SHADER_SOURCE = ` //必须要存在 main 函数 attribute vec4 aPosition; void main() { //要绘制的点的坐标 gl_Position = aPosition; //默认为 vec4(0.0,0.0,0.0,1.0); //点的大小 gl_PointSize=10.0; } `; //顶点着色器 const FRAGMENT_SHADER_SOURCE = ` void main(){ gl_FragColor=vec4(1.0,0.0,0.0,1.0); } `; //片元着色器 //执行绘画 const program=initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE) // 获取attribute变量 const aPosition=gl.getAttribLocation(program,'aPosition') const points=[]; gl.vertexAttrib1f(aPosition,0.0) gl.drawArrays(gl.POINTS, 0, 1);//重新绘制 // 绘画效果 ctx.onmousemove=function(ev){ //坐标 const x =ev.clientX const y=ev.clientY const domPosition= ev.target.getBoundingClientRect() console.log(domPosition,ctx.offsetTop,ctx.offsetLeft) const domx=x-domPosition.left; const domy=y-domPosition.top; /* 画布的宽度是400,对应的画布坐标系 0 200 400 webgl对应的X坐标系 -1 0 1 把画布X坐标系转化成webgl对应的坐标系 需要先 -200 (当前画布的宽度)然后再除以200 画布的高度是400,对应的画布坐标系 0 200 400 webgl对应的Y坐标系 1 0 -1 把画布Y坐标系转化成webgl对应的坐标系 需要先让200(当前画布的高度) 减这个数,然后再/200 */ const halfWidth=ctx.offsetWidth/2 const halfHeight=ctx.offsetHeight/2 const clickX=(domx-halfWidth)/halfWidth const clickY=(halfHeight-domy) / halfHeight points.push({clickX,clickY}) for(let i=0;i<points.length;i++) { gl.vertexAttrib2f(aPosition,points[i].clickX,points[i].clickY) gl.drawArrays(gl.POINTS, 0, 1); } } </script> </html>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="../lib/index.js"></script> <style> *{ margin: 0; padding: 0; } canvas{ margin: 50px auto 0; display: block; background: yellow; } </style> </head> <body> <canvas id="cancas" width="400" height="400"></canvas> </body> <script> const ctx = document.getElementById('cancas') const gl = ctx.getContext('webgl') //着色器 //创建着色器源码 const VERTEX_SHADER_SOURCE = ` //必须要存在 main 函数 attribute vec4 aPosition; void main() { //要绘制的点的坐标 gl_Position = aPosition; //默认为 vec4(0.0,0.0,0.0,1.0); //点的大小 gl_PointSize=10.0; } `; //顶点着色器 const FRAGMENT_SHADER_SOURCE = ` void main(){ gl_FragColor=vec4(1.0,0.0,0.0,1.0); } `; //片元着色器 //执行绘画 const program=initShader(gl,VERTEX_SHADER_SOURCE,FRAGMENT_SHADER_SOURCE) // 获取attribute变量 const aPosition=gl.getAttribLocation(program,'aPosition') const points=[]; gl.vertexAttrib1f(aPosition,0.0) gl.drawArrays(gl.POINTS, 0, 1);//重新绘制 // 通过点击绘制多个点 ctx.onclick=function(ev){ //坐标 const x =ev.clientX const y=ev.clientY const domPosition= ev.target.getBoundingClientRect() console.log(domPosition,ctx.offsetTop,ctx.offsetLeft) const domx=x-domPosition.left; const domy=y-domPosition.top; /* 画布的宽度是400,对应的画布坐标系 0 200 400 webgl对应的X坐标系 -1 0 1 把画布X坐标系转化成webgl对应的坐标系 需要先 -200 (当前画布的宽度)然后再除以200 画布的高度是400,对应的画布坐标系 0 200 400 webgl对应的Y坐标系 1 0 -1 把画布Y坐标系转化成webgl对应的坐标系 需要先让200(当前画布的高度) 减这个数,然后再/200 */ const halfWidth=ctx.offsetWidth/2 const halfHeight=ctx.offsetHeight/2 const clickX=(domx-halfWidth)/halfWidth const clickY=(halfHeight-domy) / halfHeight points.push({clickX,clickY}) for(let i=0;i<points.length;i++) { gl.vertexAttrib2f(aPosition,points[i].clickX,points[i].clickY) gl.drawArrays(gl.POINTS, 0, 1); } } </script> </html>
代码中的initShader方法是自己封装好的方法
请参考https://blog.csdn.net/qq_45013951/article/details/134637108
下面是WebGL+Three.js入门与实战的总体链接
1.1 绘制一个点
1.2 webgl坐标系
1.3 学习使用attribute变量-绘制一个水平移动的点
1.4 通过鼠标控制绘制
1.5 修改点的颜色
1.6 实现贪吃蛇游戏
2.1 使用缓冲区对象-绘制多个点
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。