频道栏目
首页 > 资讯 > HTML/CSS > 正文

WebGL绘制鼠标与键盘交互的代码实例

17-11-16        来源:[db:作者]  
收藏   我要投稿

下面,就从一个实例开始讲解,这个实例绘制了一个彩色立方体,且实现了键盘与鼠标的交互,shift+鼠标左键或中建是旋转立方体,shift+鼠标右键是平移立方体,shift+鼠标滚轮缩放立方体,其效果图如下:

这里写图片描述
这里写图片描述

接下来就详细地附上程序和注释。

1 HTML文档

其中,MV.js与cuon-matrix.js是相关地矩阵运算库,button用于添加底部地交互按。

interactiveCube.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webgl-interactive-cube</title>
    <script type="text/javascript" src="libs/initShader.js"></script>
    <script type="text/javascript" src="libs/webgl-utils.js"></script>
    <script type="text/javascript" src="libs/MV.js"></script>
    <script type="text/javascript" src="libs/cuon-matrix.js"></script>
    <script type="text/javascript" src="js/cube/interactiveCube.js"></script>
</head>
<body>
<canvas id="WebGL-mouseCube" width="1000" height="680"></canvas>

<br/>
<p><strong>鼠标操作: “shift+左键和中键旋转” “shift+右键平移” “shift+滚轮缩放”</strong></p>
<button id ="xRotate">绕x轴旋转</button>
<button id ="yRotate">绕y轴旋转</button>
<button id ="zRotate">绕z轴旋转</button>
<button id ="sRotate">开始/停止旋转</button>
</body>
</html>

2 interactiveCube.js文件

/**
 * Created by wjh on 2017/10/31.
 */

//定义变量

//用于绘制模型
var canvas, gl;
var numVertices = 36;
var points = [], colors = [];

//用于HTML按钮交互
var xAixs = 0;
var yAixs = 1;
var zAixs = 2;
var axis = 0;
var theta = [0,0,0];
var currentAngle = [0.0, 0.0];
var rotate = false;
var thetaLoc;


//鼠标键盘交互
var isShiftDown = false;//用于shift+鼠标键交互
var vRotateMatrix, rotateMatrix, u_rotateMatrix;//旋转
var vTranslateMatrix, translateMatrix, u_translateMatrix, Tx = 0, Ty = 0;//平移
var vScalingMatrix, scalingMatrix, u_scalingMatrix, factor = 0, Sx = 1, Sy = 1, Sz = 1;//缩放



window.onload = function cube (){

    canvas = document.getElementById('WebGL-mouseCube');
    // gl = WebGLUtils.setupWebGL(canvas);
    gl = canvas.getContext('experimental-webgl',{antialias:true});

    colorCube();

    if(!gl){
        console.log('浏览器不支持WebGL');
    }

    //设置视口大小
    gl.viewport(0,0,canvas.width,canvas.height);
    //清除canvas
    gl.clearColor(0, 0, 0, 1.0);
    //消除隐藏面
    gl.enable(gl.DEPTH_TEST);

    //初始化着色器
    var program = initShaders(gl,"shader/cube/mouseCubeVshader.glsl","shader/cube/fragmentShader.glsl");
    gl.useProgram(program);//将着色器程序设置为有效


    //颜色数据
    var cBuffer = gl.createBuffer();//创建缓冲区对象
    gl.bindBuffer(gl.ARRAY_BUFFER,cBuffer);//绑定对象
    gl.bufferData(gl.ARRAY_BUFFER,flatten(colors),gl.STATIC_DRAW);//向缓冲区对象写入数据

    var vColor = gl.getAttribLocation(program, 'vColor');//获取着色器中的Attribute变量
    gl.vertexAttribPointer(vColor, 4, gl.FLOAT,false,0,0);//将缓冲区对象分配给attribute变量
    gl.enableVertexAttribArray(vColor);//建立attribute变量与缓冲区之间的连接

    //顶点数据
    var vBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER,vBuffer);
    gl.bufferData(gl.ARRAY_BUFFER,flatten(points),gl.STATIC_DRAW);

    var vPosition = gl.getAttribLocation(program, 'vPosition');
    gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false,0,0);
    gl.enableVertexAttribArray(vPosition);

    //旋转变换矩阵
    vRotateMatrix = gl.getUniformLocation(program,'vRotateMatrix');
    rotateMatrix =  new Matrix4();
    rotateMatrix.setPerspective(45,canvas.width/canvas.height,1.0,10000);
    rotateMatrix.lookAt(1.0,1.0,2.0, 0.0,0.0,0.0, 0.0,1.0,0.0);
    initMouseControl(canvas,currentAngle);

    //平移矩阵
    vTranslateMatrix = gl.getUniformLocation(program, 'vTranslateMatrix');
    translateMatrix = new Matrix4();

    //缩放矩阵
    vScalingMatrix = gl.getUniformLocation(program,'vScalingMatrix');
    scalingMatrix = new Matrix4();






    thetaLoc = gl.getUniformLocation(program, 'theta');

    //添加交互按钮的函数功能
    document.getElementById('xRotate').onclick = function (){
        axis = xAixs;
    };//绕x轴
    document.getElementById('yRotate').onclick = function (){
        axis = yAixs;
    };//绕y轴
    document.getElementById('zRotate').onclick = function (){
        axis = zAixs;
    };//绕z轴
    document.getElementById('sRotate').onclick = function (){
      rotate = !rotate;
    };//控制是否旋转

    //添加键盘监听事件
    document.addEventListener('keydown',onDocumentKeyDown,false);
    document.addEventListener('keyup',onDocumentKeyUp,false);

    //绘制渲染
    render();
};

//立方体与的顶点索引和面
function colorCube(){

    quad( 1, 0, 3, 2 );
    quad( 2, 3, 7, 6 );
    quad( 3, 0, 4, 7 );
    quad( 6, 5, 1, 2 );
    quad( 4, 5, 6, 7 );
    quad( 5, 4, 0, 1 );
}

function quad(a, b, c, d)
{
    var vertices = [
        vec4( -0.25, -0.25,  0.25, 1.0 ),
        vec4( -0.25,  0.25,  0.25, 1.0 ),
        vec4(  0.25,  0.25,  0.25, 1.0 ),
        vec4(  0.25, -0.25,  0.25, 1.0 ),
        vec4( -0.25, -0.25, -0.25, 1.0 ),
        vec4( -0.25,  0.25, -0.25, 1.0 ),
        vec4(  0.25,  0.25, -0.25, 1.0 ),
        vec4(  0.25, -0.25, -0.25, 1.0 )
    ];

    var vertexColors = [
        [ 0.0, 0.0, 0.0, 1.0 ],  // black
        [ 1.0, 0.0, 0.0, 1.0 ],  // red
        [ 1.0, 1.0, 0.0, 1.0 ],  // yellow
        [ 0.0, 1.0, 0.0, 1.0 ],  // green
        [ 0.0, 0.0, 1.0, 1.0 ],  // blue
        [ 1.0, 0.0, 1.0, 1.0 ],  // magenta
        [ 0.0, 1.0, 1.0, 1.0 ],  // cyan
        [ 1.0, 1.0, 1.0, 1.0 ]   // white
    ];


    var indices = [a,b,c,a,c,d];
    for (var i=0; i=0&&Sy>=0&&Sz>=0) {
        u_scalingMatrix = new Matrix4();
        u_scalingMatrix.set(scalingMatrix);
        u_scalingMatrix.scale(Sx, Sy, Sz);
        gl.uniformMatrix4fv(vScalingMatrix, false, u_scalingMatrix.elements);
    }
    gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
    if(rotate)theta[axis] += 0.8;//绕坐标轴运动的旋转角
    gl.uniform3fv(thetaLoc, theta);
    gl.drawArrays(gl.TRIANGLES, 0, numVertices);//绘制图形
    requestAnimFrame( render );//动画
}

3 着色器文件代码

(1).顶点着色器mouseCubeVshader.glsl

attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 fColor;
uniform mat4 vRotateMatrix;
uniform mat4 vTranslateMatrix;
uniform mat4 vScalingMatrix;
uniform vec3 theta;
void main() {

vec3 angles = radians( theta );
vec3 c = cos( angles );
vec3 s = sin( angles );

mat4 rx = mat4(1.0, 0.0, 0.0, 0.0,
          0.0, c.x, s.x, 0.0,
          0.0, -s.x, c.x, 0.0,
          0.0, 0.0, 0.0, 1.0
          );

mat4 ry = mat4(c.y, 0.0, -s.y, 0.0,
          0.0, 1.0, 0.0, 0.0,
          s.y, 0.0, c.y, 0.0,
          0.0, 0.0, 0.0, 1.0
          );

mat4 rz = mat4(c.z, s.z, 0.0, 0.0,
          -s.z, c.z, 0.0, 0.0,
          0.0, 0.0, 1.0, 0.0,
          0.0, 0.0, 0.0, 1.0
          );
 fColor = vColor;
 gl_Position = vScalingMatrix * vTranslateMatrix * vRotateMatrix * rz * ry * rx * vPosition;
// gl_Position.x = -gl_Position.x;
// gl_Position.y = -gl_Position.y;
// gl_Position.z = -gl_Position.z;
}

(2) 片元着色器fragmentShader.glsl

precision mediump float;
varying vec4 fColor;
void main() {
gl_FragColor = fColor;
}

以上正式一个可交互地旋转立方体地完整代码实例。

相关TAG标签
上一篇:Http Proxy的创建
下一篇:Android移动开发项目里集成调用微信支付开发的实现
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站