04 绘制正方体和位移矩阵

我们首先绘制一个正方体,它有8个顶点,6个面。每个面由2个三角形组成,一共12个三角形,所以顶点索引是12个。为了保证所有的面向外,三角形顶点顺序由前面介绍的右手定则确定。

生成正方体后,我们给它加一个位移矩阵。使用矩阵表示位移是非常不直观的,所以我们借助THREEJS,将欧拉角转换为矩阵,然后传递给着色器程序。着色器程序只要简单左乘顶点坐标就好了。借助上一节贴图的知识,我们可以给正方体六个面贴图,这里为了程序简洁明了,就不示范了。

  1 <!DOCTYPE html>
  2
  3 <html lang="zh-CN">
  4
  5 <head>
  6     <meta charset="UTF-8" />
  7     <title>04_绘制正方体和位移矩阵</title>
  8     <script src="../js/three.js"></script>
  9
 10     <!-- 顶点着色器 -->
 11     <script id="shader-vs" type="x-shader/x-vertex">
 12         attribute vec3 aVertexPosition; // 顶点坐标
 13         uniform mat4 uMVMatrix; // 位移矩阵
 14
 15         void main(void) {
 16         gl_Position = uMVMatrix * vec4(aVertexPosition, 1.0);
 17         }
 18     </script>
 19
 20     <!-- 片源着色器 -->
 21     <script id="shader-fs" type="x-shader/x-fragment">
 22         precision mediump float;
 23         varying vec4 vColor;
 24
 25         void main(void) {
 26         gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
 27         }
 28     </script>
 29
 30     <script type="text/javascript">
 31         var start = function () {
 32             // 上下文环境
 33             var canvas = document.getElementById("mycanvas");
 34             var gl = canvas.getContext("experimental-webgl");
 35             gl.viewportWidth = canvas.width;
 36             gl.viewportHeight = canvas.height;
 37             gl.viewport(0, 0, gl.viewportWidth, gl.viewportWidth);
 38             gl.clearColor(0.0, 0.0, 0.0, 1.0);
 39             gl.enable(gl.DEPTH_TEST);
 40
 41             // 顶点着色器
 42             var shader = gl.createShader(gl.VERTEX_SHADER);
 43             gl.shaderSource(shader, document.getElementById(‘shader-vs‘).innerHTML);
 44             gl.compileShader(shader);
 45             var vertexShader = shader;
 46
 47             // 片源着色器
 48             var shader = gl.createShader(gl.FRAGMENT_SHADER);
 49             gl.shaderSource(shader, document.getElementById(‘shader-fs‘).innerHTML);
 50             gl.compileShader(shader);
 51             var fragmentShader = shader;
 52
 53             // 着色器程序
 54             var shaderProgram = gl.createProgram();
 55             gl.attachShader(shaderProgram, vertexShader);
 56             gl.attachShader(shaderProgram, fragmentShader);
 57             gl.linkProgram(shaderProgram);
 58             gl.useProgram(shaderProgram);
 59
 60             // 获取参数地址
 61             var vertexPositionAttr = gl.getAttribLocation(shaderProgram, ‘aVertexPosition‘);
 62             gl.enableVertexAttribArray(vertexPositionAttr);
 63             var mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
 64
 65             // 顶点
 66             var vertices = [
 67                 // 前面四个顶点
 68                  -0.5, -0.5, -0.5,
 69                  0.5, -0.5, -0.5,
 70                  0.5, 0.5, -0.5,
 71                  -0.5, 0.5, -0.5,
 72
 73                  // 后面四个顶点
 74                  -0.5, -0.5, 0.5,
 75                  0.5, -0.5, 0.5,
 76                  0.5, 0.5, 0.5,
 77                  -0.5, 0.5, 0.5,
 78             ];
 79             var vertexPositionBuffer = gl.createBuffer();
 80             gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
 81             gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
 82
 83             // 索引
 84             var vertexIndices = [
 85                 // 前面
 86                 0, 1, 2,
 87                 0, 2, 3,
 88
 89                 // 后面
 90                 4, 5, 6,
 91                 4, 6, 7,
 92
 93                 // 左面
 94                 4, 0, 3,
 95                 4, 3, 7,
 96
 97                 // 右面
 98                 1, 5, 6,
 99                 1, 6, 2,
100
101                 // 上面
102                 3, 2, 6,
103                 3, 6, 7,
104
105                 // 下面
106                 0, 1, 5,
107                 0, 5, 4
108             ];
109             var vertexIndexBuffer = gl.createBuffer();
110             gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
111             gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertexIndices), gl.STATIC_DRAW);
112
113             // 渲染循环
114             var x = 0, y = 0, z = 0;
115             var render = function () {
116                 // 清屏
117                 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
118
119                 // 顶点
120                 gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
121                 gl.vertexAttribPointer(vertexPositionAttr, 3, gl.FLOAT, false, 0, 0);
122
123                 // 位移矩阵
124                 var euler = new THREE.Euler(x, y, z);
125                 var mat = new THREE.Matrix4();
126                 mat.makeRotationFromEuler(euler);
127                 gl.uniformMatrix4fv(mvMatrixUniform, false, mat.toArray());
128
129                 // 绘制
130                 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
131                 gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
132
133                 x += 0.01;
134                 y += 0.01;
135                 z += 0.01;
136                 requestAnimationFrame(render);
137             }
138             render();
139         }
140     </script>
141 </head>
142
143 <body onload="start();">
144     <canvas id="mycanvas" style="border: none;" width="500" height="500"></canvas>
145 </body>
146
147 </html>

效果图:

参考资料:

Lesson4 真正的3D物体:http://www.hiwebgl.com/?p=186

THREEJS官网:https://threejs.org/

时间: 2024-08-09 03:46:05

04 绘制正方体和位移矩阵的相关文章

基于OpenGL编写一个简易的2D渲染框架-04 绘制图片

阅读文章前需要了解的知识,纹理:https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/ 过程简述:利用 FreeImage 库加载图像数据,再创建 OpenGL 纹理,通过 Canvas2D 画布绘制,最后又 Renderer 渲染器渲染 本来想用 soil 库加载图像数据的,虽然方便,但是加载有些格式的图像文件时会出现一些问题.最后,改用 FreeImage 库来加载图像了. 添加 FreeImage 库到工

dx11 入门 Tutorial 04: DX、HLSL中矩阵的内存存储和数学计算方式 DirectXSampleBrowser(June 2010)

主要是两方面: 1.shader数据和dx的通信,使用constant Buffer 2.矩阵的数学计算方式和内存存储方式再DX和HLSL中的异同 先说第一个: dx中的常量数据matrix等传入shader中流程: The first thing that we need to do is declare three constant buffer variables. Constant buffers are used to store data that the application n

OpenGL绘制简单场景,实现旋转缩放平移和灯光效果

本项目实现了用OpenGL绘制一个简单场景,包含正方体.球体和网格,实现了物体的旋转.缩放.平移和灯光效果.附有项目完整代码,有详细注释.适合初学者熟悉opengl使用. 开发情况 开发环境VS2012+OpenGL 开发平台 Intel core i5,Intel HD Graphics Family 本项目实现了绘制一个场景(包括立方体.球体.网格),对各物体实现平移.旋转.缩放功能,添加了光源并简单设置了物体材质. 本项目示例代码下载(里面有详细注释) 感谢nehe的框架! 场景介绍 初始

51 Nod 1013 3的幂的和 矩阵链乘法||逆元+快速幂

这道题我写了两种写法 一种利用逆元 a/b%mod=a*c%mod; (c是b的逆元)易得2的逆元就是5~~~04: 一种是矩阵快速幂 利用递推式得出结论 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int mod=1000000007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c&

利用canvas绘制图形

绘制图有很多种方法,可以借助flash实现,也可以使用SVG和VML来绘图.本章将要学习一种新的绘图方法--使用Canvas元素,它是基于HTML5原生的绘图功能.使用Canvas元素,可以绘制图形,也可以实现动画.它方便了使用Javascript脚本的前端开发人员,寥寥的竖行代码,就可以在Canvas元素中实现各种图形及动画.本章将介绍如何使用Canvas元素来绘制一些简单的图形.本章主要知识点如下:·认识Canvas元素·使用Canvas绘图·Canvas与JavaScript之间的互动·利

opengl矩阵向量

如何创建一个物体.着色.加入纹理,给它们一些细节的表现,但因为它们都还是静态的物体,仍是不够有趣.我们可以尝试着在每一帧改变物体的顶点并且重配置缓冲区从而使它们移动,但这太繁琐了,而且会消耗很多的处理时间.我们现在有一个更好的解决方案,使用(多个)矩阵(Matrix)对象可以更好的变换(Transform)一个物体. 向量 向量最基本的定义就是一个方向.或者更正式的说,向量有一个方向(Direction)和大小(Magnitude,也叫做强度或长度).你可以把向量想像成一个藏宝图上的指示:"向左

[从头学数学] 第172节 直线与方程

剧情提要: [机器小伟]在[project师阿伟]的陪同下进入了结丹初期的修炼. 这次要修炼的目标是[直线与方程]. 正剧開始: 星历2016年04月11日 09:30:00, 银河系厄尔斯星球中华帝国江南行省. [project师阿伟]正在和[机器小伟]一起研究[直线与方程]. 開始今天的修炼之前,小伟先整理了一下这件法器: <span style="font-size:18px;"> if (1) { var r = 20; config.setSector(1,1,1

第三章:初始化 OpenGL 4.0

原文地址: http://www.rastertek.com/gl40tut03.html Tutorial 3: Initializing OpenGL 4.0 This tutorial will be the first real introduction to working with OpenGL 4.0. We will address three main things which are initializing OpenGL 4.0, shutting it down, and

图解css3 -- 笔记2

text-shadow text-shadow:none|[color  x-offset  y-offset  blur-radius] 注意: 在ie下,可以使用滤镜filter:shadow(Color=颜色值, Direction=数值, Strength=数值) 其中:Direction用来设置投影的方向,0度在文本的上面,45度在文本的右上角,依次 Strength用来设置阴影的强度 text-overflow 有两个值:clip不显示省略标记(…),只剪裁 ellipsis文本溢出