44 WebGL通过点击获取到点击面的下标
来源:互联网 发布:淘宝上传生产许可证 编辑:程序博客网 时间:2024/05/16 07:30
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Title</title> <style> body { margin: 0; } #canvas { margin: 0; display: block; } </style></head><body onload="main()"><canvas id="canvas" height="800" width="1200"></canvas></body><script src="webgl/webgl-utils.js"></script><script src="webgl/webgl-debug.js"></script><script src="webgl/cuon-utils.js"></script><script src="webgl/cuon-matrix.js"></script><script> //设置WebGL全屏显示 var canvas = document.getElementById("canvas"); canvas.width = window.innerWidth; canvas.height = window.innerHeight; //顶点着色器 var vertexShaderSource = "" + "attribute vec4 a_Position;\n" + "attribute vec4 a_Color;\n" + "attribute float a_Face;\n" +//表面编号,不是用int类型 "uniform mat4 u_MvpMatrix;\n" + "uniform int u_PickedFace;\n" + //被选中的表面编号 "varying vec4 v_Color;\n" + "void main (){\n" + " gl_Position = u_MvpMatrix * a_Position;\n" + " int face = int(a_Face);\n" + " vec3 color = (face == u_PickedFace) ? vec3(1.0) : a_Color.rgb;\n" + " if(u_PickedFace == 0){\n" + " v_Color = vec4(color, a_Face/255.0);\n" + " }else{\n" + " v_Color = vec4(color, a_Color.a);\n" + " }\n" + "}\n"; //片元着色器 var fragmentShaderSource = "" + "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "varying vec4 v_Color;\n" + "void main(){\n" + " gl_FragColor = v_Color;\n" + "}\n"; function main() { //获取WebGL对象 var gl = getWebGLContext(canvas); //初始化着色器 initShaders(gl, vertexShaderSource, fragmentShaderSource); //将数据存入缓冲区 var n = initVertexBuffers(gl); if (n < 0) { console.log("数据存入缓冲区失败"); return; } //设置背景色和开启层级关系 gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.enable(gl.DEPTH_TEST); //获取uniform变量的存储位置 var u_MvpMatrix = gl.getUniformLocation(gl.program, "u_MvpMatrix"); var u_PickedFace = gl.getUniformLocation(gl.program, "u_PickedFace"); if (!u_MvpMatrix || !u_PickedFace) { console.log("无法获取相关的存储位置"); return; } //设置视点和投影矩阵 var viewProjectionMatrix = new Matrix4(); viewProjectionMatrix.setPerspective(30.0, canvas.width / canvas.height, 1.0, 100.0); viewProjectionMatrix.lookAt(0.0, 0.0, 7.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //设置一个自动转圈的变量 var currentAngle = 0.0; // 初始化被选中的表面的变量 gl.uniform1i(u_PickedFace, -1); canvas.onmousedown = function (e) { //鼠标按下时,将u_PickedFace修改为0,然后重新绘制场景 gl.uniform1i(u_PickedFace, 0); draw(gl, n, currentAngle, viewProjectionMatrix, u_MvpMatrix); //因为绘制的场景将代表下标的存入了a的值内,所以需要获取颜色来获取下标 var pixels = new Uint8Array(4); //存储获取的颜色的变量 gl.readPixels(e.offsetX, window.innerHeight - e.offsetY, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels); //给u_PickedFace赋值然后交给顶点着色器判断是否相同 gl.uniform1i(u_PickedFace, pixels[3]); draw(gl, n, currentAngle, viewProjectionMatrix, u_MvpMatrix); }; //定时绘制页面 var tick = function () { currentAngle = animate(currentAngle); draw(gl, n, currentAngle, viewProjectionMatrix, u_MvpMatrix); requestAnimationFrame(tick); }; tick(); } //修改currentAngle的值 var last = +new Date(); var angleStep = 20.0;//每次旋转的速度 function animate(currentAngle) { var now = +new Date(); var elapsed = now - last; last = now; //这里是为了保证旋转保证匀速旋转 var newAngle = currentAngle + (angleStep * elapsed) / 1000; return newAngle % 360; } //设置顶点数据和将数据存入缓冲区 function initVertexBuffers(gl) { // Create a cube // v6----- v5 // /| /| // v1------v0| // | | | | // | |v7---|-|v4 // |/ |/ // v2------v3 var vertices = new Float32Array([ // Vertex coordinates 顶点的位置数据 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, // v0-v1-v2-v3 front 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, // v0-v3-v4-v5 right 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, // v0-v5-v6-v1 up -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, // v1-v6-v7-v2 left -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, // v7-v4-v3-v2 down 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0 // v4-v7-v6-v5 back ]); var colors = new Float32Array([ // Colors 顶点的颜色数据 0.32, 0.18, 0.56, 0.32, 0.18, 0.56, 0.32, 0.18, 0.56, 0.32, 0.18, 0.56, // v0-v1-v2-v3 front 0.5, 0.41, 0.69, 0.5, 0.41, 0.69, 0.5, 0.41, 0.69, 0.5, 0.41, 0.69, // v0-v3-v4-v5 right 0.78, 0.69, 0.84, 0.78, 0.69, 0.84, 0.78, 0.69, 0.84, 0.78, 0.69, 0.84, // v0-v5-v6-v1 up 0.0, 0.32, 0.61, 0.0, 0.32, 0.61, 0.0, 0.32, 0.61, 0.0, 0.32, 0.61, // v1-v6-v7-v2 left 0.27, 0.58, 0.82, 0.27, 0.58, 0.82, 0.27, 0.58, 0.82, 0.27, 0.58, 0.82, // v7-v4-v3-v2 down 0.73, 0.82, 0.93, 0.73, 0.82, 0.93, 0.73, 0.82, 0.93, 0.73, 0.82, 0.93 // v4-v7-v6-v5 back ]); var faces = new Uint8Array([ // Faces 顶点的面的数据 1, 1, 1, 1, // v0-v1-v2-v3 front 2, 2, 2, 2, // v0-v3-v4-v5 right 3, 3, 3, 3, // v0-v5-v6-v1 up 4, 4, 4, 4, // v1-v6-v7-v2 left 5, 5, 5, 5, // v7-v4-v3-v2 down 6, 6, 6, 6 // v4-v7-v6-v5 back ]); var indices = new Uint8Array([ // Indices of the vertices 顶点的索引数据 0, 1, 2, 0, 2, 3, // front 4, 5, 6, 4, 6, 7, // right 8, 9, 10, 8, 10, 11, // up 12, 13, 14, 12, 14, 15, // left 16, 17, 18, 16, 18, 19, // down 20, 21, 22, 20, 22, 23 // back ]); //存入缓冲区 if (!initArrayBuffer(gl, vertices, gl.FLOAT, 3, "a_Position")) { return -1; } if (!initArrayBuffer(gl, colors, gl.FLOAT, 3, "a_Color")) { return -1; } if (!initArrayBuffer(gl, faces, gl.UNSIGNED_BYTE, 1, "a_Face")) { return -1; } //创建索引缓冲区 var indexBuffer = gl.createBuffer(); if (indexBuffer < 0) { console.log("无法创建缓冲区"); return -1; } //取消ARRAY_BUFFER中的绑定 gl.bindBuffer(gl.ARRAY_BUFFER, null); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); return indices.length; } function initArrayBuffer(gl, data, type, num, attribute) { var buffer = gl.createBuffer(); if (!buffer) { console.log("无法创建缓冲区对象"); return; } gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); var a_attribute = gl.getAttribLocation(gl.program, attribute); if (a_attribute < 0) { console.log("无法获取变量的存储位置" + attribute); return false; } gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0); gl.enableVertexAttribArray(a_attribute); return true; } //绘制 var matrix = new Matrix4(); function draw(gl, n, currentAngle, viewProjectionMatrix, u_MvpMatrix) { matrix.set(viewProjectionMatrix); matrix.rotate(currentAngle, 1.0, 0.0, 0.0); matrix.rotate(currentAngle, 0.0, 1.0, 0.0); matrix.rotate(currentAngle, 0.0, 0.0, 1.0); gl.uniformMatrix4fv(u_MvpMatrix, false, matrix.elements); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); }</script></html>
这是教程里面的一个案例,里面就是交给我们如何通过点击实现获取到哪个面。里面有趣的是有一个判断。
这里与上一节的案例代码区别不大,别的不再讲解。
我们直接从mousedown事件里面说起来。
触发mousedown事件以后,我们就把u_PickedFace变量改为了0. 然后让WebGL重新绘制页面。到了这里我们就去看顶点着色器,会发现有个if else的判断,在那里对u_PickedFace进行了判断。也就是说,在点击第一次绘制的时候,会把我们设置的当前面的index作为颜色的第四项传入到视图当中。等绘制完成,然后调用获取颜色的方法获取了一下当前下标,再次将u_PickedFace修改掉。然后通过顶点着色器里面的三元运算符运算,将处于相同面的点的颜色全部绘制成了白色。
阅读全文
0 0
- 44 WebGL通过点击获取到点击面的下标
- WebGL通过鼠标点击绘点
- 08 WebGL通过点击绘制点
- jquery如何获取当前点击的标签下标
- 43 WebGL绘制一个自动旋转的立方体盒子,点击获取点击位置颜色
- 点击li,输出对应li的下标
- 通过控件的点击事件获取其id
- 通过获取鼠标的点击位置来动态定位元素
- 获取点击的option
- Android实现通过浏览器点击链接打开本地应用(APP),并获取到传递的数据
- 点击body获取点击的对象
- 点击事件中获取点击的坐标
- Unity3d通过射线来实现点击地面,获取点击坐标
- Dialog的自定义view无法获取到点击事件
- jquery获取任意点击到的对象,绑定点击函数event.target 不能用this
- 通过添加点击手势获取当前坐标
- MFC通过点击获取文件路径名字
- 【笔记】《WebGL编程指南》学习-第2章WebGL入门(5-通过鼠标点击画点)
- 在github上创建一个静态网站
- linux 中mysql 四种启动方式
- 自制Java虚拟机(六)静态属性和静态方法(getstatic, putstatic, invokestatic, <clinit>)
- redis(一)--- 简单介绍redis
- 一个文科生的工程师之路
- 44 WebGL通过点击获取到点击面的下标
- Linux菜鸟笔记——磁盘管理与文件系统管理 之 磁盘的分割、格式化、检验
- Can you find it?(二分)
- MySQL数据库小技巧(持续更新)
- 【shell脚本】eval命令详解及命令代换
- Going from u to v or from v to u? 【判定弱连通】=【tarjan求scc+ 缩点+topo】
- Android Studio 使用第三方库的方法
- 215.m1-当服务器给的同类型图片大小不一致的时候的适配
- 登陆框居中问题