29 WebGL绘制立方体并为立方体每个表面指定颜色
来源:互联网 发布:安卓手机数据迁移软件 编辑:程序博客网 时间:2024/06/05 20:11
顶点着色器进行的是逐顶点的计算,接收的是逐顶点的信息。如果我们要指定表面的颜色,需要将颜色定义给顶点。比如,我们要定义一个三角形为一种颜色,必须三个顶点的颜色都为一种颜色。
但是你会发现,立方体的一个顶点会在三个面中被使用,定义了一种颜色肯定会对别的面造成影响。为了解决这个问题,我们需要创建多个具有相同顶点坐标的顶点(虽然这样会造成一些冗余)。
此时的三角形列表,也就是顶点索引值序列,对每个面都指向一组不同的顶点,不在有前表面和上表面同享一个顶点的情况。这样一来,就可以实现前述的效果,为每个表面涂上不同的单色了。
<!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; text-align: center; } #canvas { margin: 0; } </style></head><body onload="main()"><canvas id="canvas" height="800" width="1200"></canvas></body><script src="lib/webgl-utils.js"></script><script src="lib/webgl-debug.js"></script><script src="lib/cuon-utils.js"></script><script src="lib/cuon-matrix.js"></script><script> //顶点着色器 var VSHADER_SOURCE = "" + "attribute vec4 a_Position;\n" + "attribute vec4 a_Color;\n" + "uniform mat4 u_ModelViewMatrix;\n" + "varying vec4 v_Color;\n" + "void main(){" + " gl_Position = u_ModelViewMatrix * a_Position;\n" + " v_Color = a_Color;\n" + "}\n"; //片元着色器 var FSHADER_SOURCE = "" + "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "varying vec4 v_Color;\n" + "void main(){" + " gl_FragColor = v_Color;\n" + "}\n"; //声明js需要的相关变量 var canvas = document.getElementById("canvas"); var gl = getWebGLContext(canvas); function main() { if (!gl) { console.log("你的浏览器不支持WebGL"); return; } //初始化着色器 if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) { console.log("无法初始化着色器"); return; } var n = initVertexBuffers(gl); if (n < 0) { console.log("无法创建缓冲区"); return; } //设置视角矩阵的相关信息 var u_ModelViewMatrix = gl.getUniformLocation(gl.program, "u_ModelViewMatrix"); if (u_ModelViewMatrix < 0) { console.log("无法获取矩阵变量的存储位置"); return; } //设置底色 gl.clearColor(0.0, 0.0, 0.0, 1.0); //进入场景初始化 draw(gl, n, u_ModelViewMatrix); } function draw(gl, n, u_ModelViewMatrix) { //设置视角矩阵的相关信息(视点,视线,上方向) var viewMatrix = new Matrix4(); viewMatrix.setLookAt(3,3,7,0,0,0,0,1,0); //设置模型矩阵的相关信息 var modelMatrix = new Matrix4(); modelMatrix.setRotate(0, 0, 0, 1); //设置透视投影矩阵 var projMatrix = new Matrix4(); projMatrix.setPerspective(30,canvas.width/canvas.height,1,100); //计算出模型视图矩阵 viewMatrix.multiply(modelMatrix)相当于在着色器里面u_ViewMatrix * u_ModelMatrix var modeViewMatrix = projMatrix.multiply(viewMatrix.multiply(modelMatrix)); //将试图矩阵传给u_ViewMatrix变量 gl.uniformMatrix4fv(u_ModelViewMatrix, false, modeViewMatrix.elements); //开启隐藏面清除 gl.enable(gl.DEPTH_TEST); //清空颜色和深度缓冲区 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); //绘制图形 gl.drawElements(gl.TRIANGLES,n,gl.UNSIGNED_BYTE,0); } function initVertexBuffers(gl) { // 创建一个立方体 // v6----- v5 // /| /| // v1------v0| // | | | | // | |v7---|-|v4 // |/ |/ // v2------v3 var vertices = new Float32Array([ // 顶点的位置坐标数据 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([ // 顶点的颜色 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, // v0-v1-v2-v3 front(blue) 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, // v0-v3-v4-v5 right(green) 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, // v0-v5-v6-v1 up(red) 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, // v1-v6-v7-v2 left 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, // v7-v4-v3-v2 down 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8 // v4-v7-v6-v5 back ]); 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 ]); //创建缓冲区对象 initArrayBuffer(gl,vertices,3,gl.FLOAT,"a_Position"); initArrayBuffer(gl,colors,3,gl.FLOAT,"a_Color"); //将顶点索引数据写入缓冲区对象 var indexBuffer = gl.createBuffer(); 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 -1; } //绑定缓冲区对象并写入数据 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); //获取顶点位置变量位置 var a_attribue = gl.getAttribLocation(gl.program, attribute); if (a_attribue < 0) { console.log("无法获取顶点位置的存储变量"); return -1; } //对位置的顶点数据进行分配,并开启 gl.vertexAttribPointer(a_attribue, num, type, false, 0, 0); gl.enableVertexAttribArray(a_attribue); }</script></html>虽然本例使用的是gl.drawElements(),使用了24个顶点。而使用gl.drawArrays()绘图也就使用36个顶点。看上去没有省多少的内存开销。但是,在实际生产当中,使用gl.drawElements()还是值得的。
就这样,我们实现了绘制相同颜色的面。
阅读全文
0 0
- 29 WebGL绘制立方体并为立方体每个表面指定颜色
- 28 WebGL绘制立方体
- OpenGL ES 绘制颜色立方体
- 用webgl绘制一个彩色旋转立方体
- 43 WebGL绘制一个自动旋转的立方体盒子,点击获取点击位置颜色
- 41 WebGL绘制一个具有交互的立方体
- WebGL之旅(十二)IBO绘制立方体
- 立方体
- 优化的立方体绘制
- DirectX3D中绘制立方体
- opengl绘制立方体
- D3D绘制彩色立方体
- opengles绘制立方体
- opengl绘制纹理立方体
- Ogre 绘制立方体
- OpenGL-绘制旋转立方体
- python3绘制超立方体
- opengl: 颜色立方体
- 正则删除HTML标签
- java nio 基础之Select 用法
- Null Byte Injection
- 博文测试
- 剑指offer-面试题67-机器人的运动范围
- 29 WebGL绘制立方体并为立方体每个表面指定颜色
- 博弈论之威佐夫博奕
- Ubuntu 14.04.5 LTS安装mongodb3.4
- 软件项目开发一般流程
- mysql忘记密码了1045,解决MySql 数据库 提示:1045 access denied for user 'root'@'localhost' using password yes
- 190.m1-Fragment显示界面
- 543. Diameter of Binary Tree
- android 弹性ScrollView(已优化)
- Android 屏幕适配方案