CG实验6 交互与动画
来源:互联网 发布:linux tcpdump 编辑:程序博客网 时间:2024/06/05 18:05
1.实验目的和要求
- 目的:了解交互与动画的基本思想,掌握交互与动画的常见实现方法;
- 要求:读懂WebGL交互与动画示范代码,实现简单的交互与动画程序。
2. 实验过程
(1) 示范代码1为交互实例:在鼠标点击的位置上绘制出点;示范代码2为动画实例:三角形按照恒定的速度(45度/秒)旋转。结合示范代码,学习理解交互与动画的基本思想与实现;
(2) 结合示范代码1,将示范代码2改为根据鼠标来控制三角形的旋转;
3.实验结果
示范代码1的结果如下图所示:
示范代码2如下图所示:
4.实验分析
请根据教材内容、网络资源及示范代码,简单分析下交互与动画的实现原理与方法。
5.实验代码
gl-matrix.js 下载地址:http://oty0nwcbq.bkt.clouddn.com/gl-matrix.js
(1) 鼠标点击交互绘点
(i) ClickedPoints.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Draw a point with a mouse click</title> </head> <script id="vertex-shader" type="x-shader/x-vertex"> attribute vec4 a_Position; void main() { gl_Position = a_Position ; gl_PointSize = 10.0; } </script> <script id="fragment-shader" type="x-shader/x-fragment"> void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } </script> <body onload="startup()"> <canvas id="myGLCanvas" width="600" height="600"> </canvas> </body> <script type="text/javascript" src="gl-matrix.js"></script> <script type="text/javascript" src="ClickedPoints.js"></script></html>
(ii) ClickedPoints.js
var gl;function startup(){ var canvas = document.getElementById('myGLCanvas');//获取<canvas>元素 gl = createGLContext(canvas); setupShaders(); // // Get the storage location of a_Position var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); if (a_Position < 0) { console.log('Failed to get the storage location of a_Position'); return; } // Register function (event handler) to be called on a mouse press canvas.onmousedown = function(ev){ click(ev, gl, canvas, a_Position); }; // Specify the color for clearing <canvas> gl.clearColor(0.0, 0.0, 0.0, 1.0); // Clear <canvas> gl.clear(gl.COLOR_BUFFER_BIT); } var g_points = []; // The array for the position of a mouse press function click(ev, gl, canvas, a_Position) { var x = ev.clientX; // x coordinate of a mouse pointer var y = ev.clientY; // y coordinate of a mouse pointer var rect = ev.target.getBoundingClientRect() ; x = ((x - rect.left) - canvas.width/2)/(canvas.width/2); y = (canvas.height/2 - (y - rect.top))/(canvas.height/2); // Store the coordinates to g_points array g_points.push(x); g_points.push(y); // Clear <canvas> gl.clear(gl.COLOR_BUFFER_BIT); var len = g_points.length; for(var i = 0; i < len; i += 2) { // Pass the position of a point to a_Position variable gl.vertexAttrib3f(a_Position, g_points[i], g_points[i+1], 0.0); // Draw gl.drawArrays(gl.POINTS, 0, 1); } }function createGLContext(canvas) { var names = ["webgl", "experimental-webgl"]; var context = null; for (var i=0; i < names.length; i++) { try { context = canvas.getContext(names[i]); //获取webgl context绘图上下文 } catch(e) {} if (context) { break; } } if (context) { context.viewportWidth = canvas.width; context.viewportHeight = canvas.height; } else { alert("Failed to create WebGL context!"); } return context;}function setupShaders() { var vertexShader = loadShader(gl.VERTEX_SHADER, "vertex-shader"); var fragmentShader = loadShader(gl.FRAGMENT_SHADER, "fragment-shader"); var shaderProgram = gl.createProgram(); gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); gl.linkProgram(shaderProgram); if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Failed to setup shaders"); } gl.useProgram(shaderProgram); gl.program= shaderProgram;}function loadShader(type, ShaderId) { var shaderScript = document.getElementById( ShaderId ); var shader = gl.createShader(type); gl.shaderSource( shader, shaderScript.text ); gl.compileShader( shader ); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { alert("Error compiling shader" + gl.getShaderInfoLog(shader)); gl.deleteShader(shader); return null; } return shader; }
(2) 三角形旋转动画
(i) RotatingTriangle.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Continually Rotate A Triangle</title> </head> <script id="vertex-shader" type="x-shader/x-vertex"> attribute vec4 a_Position; uniform mat4 u_ModelMatrix; void main() { gl_Position = u_ModelMatrix * a_Position; } </script> <script id="fragment-shader" type="x-shader/x-fragment"> void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } </script> <body onload="startup()"> <canvas id="myGLCanvas" width="600" height="600"> </canvas> </body> <script type="text/javascript" src="gl-matrix.js"></script> <script type="text/javascript" src="RotatingTriangle.js"> </script></html>
(ii) RotatingTriangle.js
var gl;// Rotation angle (degrees/second)var ANGLE_STEP = 45.0;var modelMatrixI = mat4.create();function startup(){ var canvas = document.getElementById('myGLCanvas');//获取<canvas>元素 gl = createGLContext(canvas); setupShaders(); // Write the positions of vertices to a vertex shader var n = initVertexBuffers(gl); if (n < 0) { console.log('Failed to set the positions of the vertices'); return; } // Specify the color for clearing <canvas> gl.clearColor(0.0, 0.0, 0.0, 1.0); // Get storage location of u_ModelMatrix var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix'); if (!u_ModelMatrix) { console.log('Failed to get the storage location of u_ModelMatrix'); return; } // Current rotation angle var currentAngle = 0.0; // Model matrix var modelMatrix = mat4.create(); // Start drawing var tick = function() { currentAngle = animate(currentAngle); // Update the rotation angle draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix); // Draw the triangle requestAnimationFrame(tick, canvas); // Request that the browser calls tick }; tick(); } function initVertexBuffers(gl) { var vertices = new Float32Array ([ 0, 0.5, -0.5, -0.5, 0.5, -0.5 ]); var n = 3; // The number of vertices // Create a buffer object var vertexBuffer = gl.createBuffer(); if (!vertexBuffer) { console.log('Failed to create the buffer object'); return -1; } // Bind the buffer object to target gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); // Write date into the buffer object gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); // Assign the buffer object to a_Position variable var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); if(a_Position < 0) { console.log('Failed to get the storage location of a_Position'); return -1; } gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0); // Enable the assignment to a_Position variable gl.enableVertexAttribArray(a_Position); return n; } function draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix) { // Set the rotation matrix //modelMatrix.setRotate(currentAngle, 0, 0, 1); // Rotation angle, rotation axis (0, 0, 1) var radian = Math.PI * currentAngle / 180.0; // Convert to radians mat4.rotate(modelMatrix, modelMatrixI, radian, [0, 0 , 1]); // Pass the rotation matrix to the vertex shader gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix); // Clear <canvas> gl.clear(gl.COLOR_BUFFER_BIT); // Draw the rectangle gl.drawArrays(gl.TRIANGLES, 0, n); } // Last time that this function was called var g_last = Date.now(); function animate(angle) { // Calculate the elapsed time var now = Date.now(); var elapsed = now - g_last; g_last = now; // Update the current rotation angle (adjusted by the elapsed time) var newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0; return newAngle %= 360; }function createGLContext(canvas) { var names = ["webgl", "experimental-webgl"]; var context = null; for (var i=0; i < names.length; i++) { try { context = canvas.getContext(names[i]); //获取webgl context绘图上下文 } catch(e) {} if (context) { break; } } if (context) { context.viewportWidth = canvas.width; context.viewportHeight = canvas.height; } else { alert("Failed to create WebGL context!"); } return context;}function setupShaders() { var vertexShader = loadShader(gl.VERTEX_SHADER, "vertex-shader"); var fragmentShader = loadShader(gl.FRAGMENT_SHADER, "fragment-shader"); var shaderProgram = gl.createProgram(); gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); gl.linkProgram(shaderProgram); if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Failed to setup shaders"); } gl.useProgram(shaderProgram); gl.program= shaderProgram; } function loadShader(type, ShaderId) { var shaderScript = document.getElementById( ShaderId ); var shader = gl.createShader(type); gl.shaderSource( shader, shaderScript.text ); gl.compileShader( shader ); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { alert("Error compiling shader" + gl.getShaderInfoLog(shader)); gl.deleteShader(shader); return null; } return shader; }
阅读全文
0 0
- CG实验6 交互与动画
- AE制作CG拍摄场景与动画合成教程
- CG实验2nd&3rd:二维几何变换、裁减、动画、三维透视
- 机械版CG 实验6 简单光照明模型实现
- CG实验4th:消隐
- CG实验1 三角形绘制
- Android通过javascript与flash动画交互
- 用户交互(3-过渡与动画)
- 动画交互设计与技术实现
- 交互动画
- CG资源与教程
- CG资源与教程
- shader与cg简介
- iOS 平板与 Android 平板的交互与动画
- iOS 平板与 Android 平板的交互与动画
- CG实验4th:Bezier曲线
- 机械版CG 实验3 变换
- 机械版CG 实验4 裁剪
- 点亮细胞211-220
- IntelliJ Idea 2017 免费激活方法
- 6. 矩阵的快速转置算法
- spring管理事务失效的原因和No mapping found for HTTP request with URI []DispatcherServlet with name 'sprinmvc错误
- Visual Studio 2013 + Qt + FFMPEG开发环境配置,手把手详细图文
- CG实验6 交互与动画
- React-Native 知识点小结
- 前端模块化
- 点亮细胞221-230
- 链式栈
- Linux 部署thinkphp 遇到的file_put_contents failed to open stream: Permission denied
- java 之 IO 转换流
- 6个编写优质干净代码的技巧
- 点亮细胞231-240