41 WebGL绘制一个具有交互的立方体
来源:互联网 发布:c语言头文件是什么 编辑:程序博客网 时间:2024/05/21 07:06
增加交互事件,鼠标拖拽立方体上下左右旋转,鼠标滚轮放大缩小立方体。
<!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> //顶点着色器 var vertexShaderSource = "" + "attribute vec4 a_Position;\n" + "attribute vec2 a_TextCoord;\n" + "uniform mat4 u_MvpMatrix;\n" + "varying vec2 v_TexCoord;\n" + "void main(){\n" + " gl_Position = u_MvpMatrix * a_Position;\n" + " v_TexCoord = a_TextCoord;\n" + "}\n"; //片元着色器 var fragmentShaderSource = "" + "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "uniform sampler2D u_Sampler;\n" + "varying vec2 v_TexCoord;\n" + "void main(){\n" + " gl_FragColor = texture2D(u_Sampler,v_TexCoord);\n" + "}\n"; function main() { var canvas = document.getElementById("canvas"); setCss(); window.onresize = function () { setCss(); }; function setCss() { canvas.height = window.innerHeight; canvas.width = window.innerWidth; canvas.style.width = canvas.width+"px"; canvas.style.height = canvas.height+"px"; } var gl = getWebGLContext(canvas); //初始化着色器 initShaders(gl, vertexShaderSource, fragmentShaderSource); gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.enable(gl.DEPTH_TEST); var u_MvpMatrix = gl.getUniformLocation(gl.program, "u_MvpMatrix"); if (!u_MvpMatrix) { console.log("无法获取变量相关的存储位置"); return; } //获取需要绘制图形的次数 var n = initVertexBuffers(gl); if (n < 0) { console.log("创建缓冲区失败"); return; } //定义一个保存现在角度的数组[x,y,z] var currentAngle = [0.0,0.0,10.0]; //添加交互的方法 initEventHandlers(canvas,currentAngle); //将纹理存入着色器 if(!initTextures(gl)){ console.log("无法获取到纹理"); return; } //设置一个定时绘制的函数 var tick = function() { // Start drawing draw(gl, n, u_MvpMatrix,currentAngle); requestAnimationFrame(tick); }; tick(); } function initEventHandlers(canvas, currentAngle) { //添加拖拽事件 canvas.onmousedown = function (e) { var downX = e.clientX; var downY = e.clientY; var factorX = 0.3; var factorY = 0.2; var beforeAngle = []; beforeAngle[0] = currentAngle[0]; beforeAngle[1] = currentAngle[1]; beforeAngle[2] = currentAngle[2]; document.onmousemove = function (e) { var moveX = e.clientX; var moveY = e.clientY; var x = factorX * (moveX - downX); var y = factorY * (moveY - downY); currentAngle[0] = Math.max(Math.min(beforeAngle[0] + y, 90.0), -90.0); currentAngle[1] = beforeAngle[1] + x; }; document.onmouseup = function () { document.onmousemove = null; document.onmouseup = null; } }; function wheel(e) { console.log(e); if (e.wheelDelta) { //除了firfox浏览器,别的浏览器的处理 changeZ(-e.wheelDelta / 120, e); } else if (e.detail) { //firefox浏览器的测试 if (e.detail === -3) { changeZ(-1, e); } else if (e.detail === 3) { changeZ(1, e); } else { console.log("鼠标滚轮事件改了?", e); } } } function changeZ(index) { console.log(currentAngle[2]); currentAngle[2] = Math.max(Math.min(currentAngle[2] += index/5,20.0),1.0); } //添加鼠标滚轮事件 canvas.addEventListener("mousewheel",wheel); canvas.addEventListener("DOMMouseScroll",wheel);//兼容火狐 } 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 texCoords = new Float32Array([ // Texture coordinates 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // v0-v1-v2-v3 front 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, // v0-v3-v4-v5 right 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, // v0-v5-v6-v1 up 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // v1-v6-v7-v2 left 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, // v7-v4-v3-v2 down 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0 // v4-v7-v6-v5 back ]); // Indices of the vertices var indices = new Uint8Array([ 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, 3, gl.FLOAT, "a_Position")) { return -1; } if (!initArrayBuffer(gl, texCoords, 2, gl.FLOAT, "a_TextCoord")) { return -1; } //处理下标 var indexBuffer = gl.createBuffer(); if (!indexBuffer) { console.log("无法创建缓冲区"); return -1; } gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); return indices.length; } function initArrayBuffer(gl, data, num, type, 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; } function initTextures(gl) { var texture = gl.createTexture(); if(!texture){ console.log("无法创建纹理对象"); return false; } var u_Sampler = gl.getUniformLocation(gl.program, "u_Sampler"); if(!u_Sampler){ console.log("无法获取到变量的存储位置"); return false; } var image = new Image(); image.onload = function () { loadTexture(gl,texture,u_Sampler,image); }; image.src = "./resources/sky_cloud.jpg"; return true; } /* 设置纹理相关信息供WebGL使用,并进行绘制*/ function loadTexture(gl,texture,u_Sampler,image) { //对纹理图像进行y轴反转 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,1); //开启0号纹理单元 gl.activeTexture(gl.TEXTURE0); //向target绑定纹理对象 gl.bindTexture(gl.TEXTURE_2D,texture); //配置纹理参数 gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR); //配置纹理图像 gl.texImage2D(gl.TEXTURE_2D,0,gl.RGB,gl.RGB,gl.UNSIGNED_BYTE,image); //将0号纹理传递给着色器 gl.uniform1i(u_Sampler,0); } function draw(gl, n, u_MvpMatrix,currentAngle) { //设置视点位置 var viewProjectionMatrix = new Matrix4(); viewProjectionMatrix.setPerspective(30.0, canvas.width / canvas.height, 1.0, 100.0); console.log(30.0, canvas.width / canvas.height, 1.0, 100.0); viewProjectionMatrix.lookAt(0.0, 0.0, currentAngle[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); var mvpMatrix = new Matrix4(); mvpMatrix.set(viewProjectionMatrix); mvpMatrix.rotate(currentAngle[0], 1.0, 0.0, 0.0); mvpMatrix.rotate(currentAngle[1], 0.0, 1.0, 0.0); gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); }</script></html>
阅读全文
0 0
- 41 WebGL绘制一个具有交互的立方体
- 用webgl绘制一个彩色旋转立方体
- 28 WebGL绘制立方体
- 43 WebGL绘制一个自动旋转的立方体盒子,点击获取点击位置颜色
- 36 WebGL两个简单模型组合成一个具有交互效果的模型
- 优化的立方体绘制
- WebGL之旅(十二)IBO绘制立方体
- 使用opengl绘制一个立方体
- 从“绘制一个立方体”来看OpenGL的进化过程
- 从“绘制一个立方体”来看OpenGL的进化过程
- 29 WebGL绘制立方体并为立方体每个表面指定颜色
- WPF3D学习,立方体的绘制
- OpenGL4-绘制旋转的立方体
- webgl+three.js,学习笔记,画一个立方体+解析
- unity与webGL的交互
- webGL第八课-绘制一个三维图形
- 【WebGL】绘制一个点(版本1)
- WebGL Learning (二)绘制一个点
- gym I. Painting the natural numbers
- 线程简介
- JS之连接数组方法concat
- MySQL 5.6.14 win32 zip版安装
- Python基础(一)
- 41 WebGL绘制一个具有交互的立方体
- Android 微博打开指定用户界面
- Android Studio更新后打开老项目报错,但是能运行
- java日期操作
- 基础dp
- HEVC代码学习17:m_filteredBlockTmp[]和m_filteredBlock[][]
- 获取指定路径下的文件类型及数量
- pandas 数据合并与重塑(concat篇)
- 创建maven项目