1. <!--探讨WEBGL中不同图形的绘制方法:[待测试2017.11.6]-->
  2. <!DOCTYPE HTML>
  3. <html lang="en">
  4. <head>
  5. <title>WEBGL高级编程----绘制三维场景(变换矩阵)</title>
  6. <meta charset="utf-8">
  7. <!--顶点着色器-->
  8. <script id="shader-vs" type="x-shader/x-vertex">
  9. attribute vec3 aVertexPosition;
  10. attribute vec4 aVertexColor;
  11.  
  12. uniform mat4 uMVMatrix;
  13. uniform mat4 uPMatrix;
  14.  
  15. varying vec4 vColor;
  16.  
  17. void main() {
  18. vColor = aVertexColor;
  19. gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
  20. }
  21.  
  22. </script>
  23.  
  24. <!--片元着色器-->
  25. <script id="shader-fs" type="x-shader/x-fragment">
  26. precision mediump float;
  27.  
  28. varying vec4 vColor;
  29. void main() {
  30. gl_FragColor = vColor;
  31. }
  32.  
  33. </script>
  34.  
  35. <!--引入我的库文件-->
  36. <script src="./lib/webgl-debug.js"></script>
  37.  
  38. <script type="text/javascript">
  39. var gl;
  40. var canvas;
  41. var shaderProgram;
  42.  
  43. //绘制桌子的场景模型
  44. //地板的顶点位置和索引
  45. var floorVertexPositionBuffer;
  46. var floorVertexIndexBuffer;
  47.  
  48. //立方体的顶点位置和索引
  49. var cubeVertexPositionBuffer;
  50. var cubeVertexIndexBuffer;
  51.  
  52. //我的模型 视图 投影矩阵
  53. var modelViewMatrix;
  54. var projectionMatrix;
  55.  
  56. //模型视图的矩阵栈
  57. var modelViewMatrixStack;
  58.  
  59. //创建我的上下文句柄
  60. function createGLContext(canvas) {
  61. var names = ["webgl", "experimental-webgl"];
  62. var context = null;
  63. for (var i = 0; i < names.length; i++) {
  64. try {
  65. context = canvas.getContext(names[i]);
  66. } catch (e) {
  67. }
  68. if (context) {
  69. break;
  70. }
  71. }
  72. if (context) {
  73. context.viewportWidth = canvas.width;
  74. context.viewportHeight = canvas.height;
  75. } else {
  76. alert("Failed to create WebGL context!");
  77. }
  78. return context;
  79. }
  80.  
  81. //从JavaScript代码中通过DOM加载着色器
  82. function loadShaderFromDOM(id) {
  83. var shaderScript = document.getElementById(id);
  84.  
  85. // If we don't find an element with the specified id
  86. // we do an early exit
  87. if (!shaderScript) {
  88. return null;
  89. }
  90.  
  91. // Loop through the children for the found DOM element and
  92. // build up the shader source code as a string
  93. var shaderSource = "";
  94. var currentChild = shaderScript.firstChild;
  95. while (currentChild) {
  96. if (currentChild.nodeType == 3) { // 3 corresponds to TEXT_NODE
  97. shaderSource += currentChild.textContent;
  98. }
  99. currentChild = currentChild.nextSibling;
  100. }
  101.  
  102. var shader;
  103. if (shaderScript.type == "x-shader/x-fragment") {
  104. shader = gl.createShader(gl.FRAGMENT_SHADER);
  105. } else if (shaderScript.type == "x-shader/x-vertex") {
  106. shader = gl.createShader(gl.VERTEX_SHADER);
  107. } else {
  108. return null;
  109. }
  110.  
  111. gl.shaderSource(shader, shaderSource);
  112. gl.compileShader(shader);
  113.  
  114. if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
  115. alert(gl.getShaderInfoLog(shader));
  116. return null;
  117. }
  118. return shader;
  119. }
  120.  
  121. //设置我的着色器(完成着色器的部分初始化操作)
  122. function setupShaders() {
  123. var vertexShader = loadShaderFromDOM("shader-vs");
  124. var fragmentShader = loadShaderFromDOM("shader-fs");
  125.  
  126. shaderProgram = gl.createProgram();
  127. gl.attachShader(shaderProgram, vertexShader);
  128. gl.attachShader(shaderProgram, fragmentShader);
  129. gl.linkProgram(shaderProgram);
  130.  
  131. if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
  132. alert("Failed to setup shaders");
  133. }
  134.  
  135. gl.useProgram(shaderProgram);
  136.  
  137. //获取顶点的位置和颜色的存储地址
  138. shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
  139. shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
  140.  
  141. //回去模型视图矩阵的存储地址
  142. shaderProgram.uniformMVMatrix = gl.getUniformLocation(shaderProgram, "uMVMatrix");
  143. shaderProgram.uniformProjMatrix = gl.getUniformLocation(shaderProgram, "uPMatrix");
  144.  
  145. gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
  146.  
  147. //开始创建我的模型视图矩阵
  148. modelViewMatrix = mat4.create();
  149. projectionMatrix = mat4.create();
  150. modelViewMatrixStack = [];
  151. }
  152.  
  153. //定义两个辅助函数(矩阵的入栈和出栈操作)
  154. function pushModelViewMatrix() {
  155. //把当前的模型视图矩阵存储在一个JavaScript数组中去
  156. var copyToPush = mat4.create(modelViewMatrix);
  157. modelViewMatrixStack.push(copyToPush);
  158. }
  159.  
  160. function popModelViewMatrix() {
  161. if (modelViewMatrixStack.length == 0) {
  162. throw "Error popModelViewMatrix() - Stack was empty";
  163. }
  164. //把我自己保存的模型视图矩阵弹出去
  165. modelViewMatrix = modelViewMatrixStack.pop();
  166. }
  167.  
  168. //处理物体运动的一些基本参数
  169. var xRot = 0;
  170. var xSpeed = 3;
  171.  
  172. var yRot = 0;
  173. var ySpeed = -3;
  174.  
  175. var z = -5.0;
  176.  
  177. //可以处理多个按键同时按下的情形
  178. var currentlyPressedKeys = {};
  179.  
  180. function handleKeyDown(event) {
  181. currentlyPressedKeys[event.keyCode] = true;
  182. }
  183.  
  184. function handleKeyUp(event) {
  185. currentlyPressedKeys[event.keyCode] = false;
  186. }
  187.  
  188. //根据不同的按键做出不同的反应
  189. function handleKeys() {
  190. if (currentlyPressedKeys[33]) {
  191. // Page Up
  192. z -= 0.05;
  193. }
  194. if (currentlyPressedKeys[34]) {
  195. // Page Down
  196. z += 0.05;
  197. }
  198. if (currentlyPressedKeys[37]) {
  199. // Left cursor key
  200. ySpeed -= 1;
  201. }
  202. if (currentlyPressedKeys[39]) {
  203. // Right cursor key
  204. ySpeed += 1;
  205. }
  206. if (currentlyPressedKeys[38]) {
  207. // Up cursor key
  208. xSpeed -= 1;
  209. }
  210. if (currentlyPressedKeys[40]) {
  211. // Down cursor key
  212. xSpeed += 1;
  213. }
  214. }
  215.  
  216. //地板的顶点位置参数
  217. function setupFloorBuffers() {
  218. /****第一步****/
  219. //1.创建地板顶点缓冲区
  220. floorVertexPositionBuffer = gl.createBuffer();
  221. //2.绑定缓冲区到目标对象
  222. gl.bindBuffer(gl.ARRAY_BUFFER, floorVertexPositionBuffer);
  223. var floorVertexPosition = [
  224. // Plane in y=0
  225. 5.0, 0.0, 5.0, //v0
  226. 5.0, 0.0, -5.0, //v1
  227. -5.0, 0.0, -5.0, //v2
  228. -5.0, 0.0, 5.0 //v3
  229. ];
  230. //3.向缓冲区对象中写入数据
  231. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(floorVertexPosition), gl.STATIC_DRAW);
  232.  
  233. floorVertexPositionBuffer.itemSize = 3;
  234. floorVertexPositionBuffer.numberOfItems = 4;
  235.  
  236. /****第二步***/
  237. //1.创建地板顶点索引缓冲区.
  238. floorVertexIndexBuffer = gl.createBuffer();
  239. //2.绑定缓冲区到目标对象
  240. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, floorVertexIndexBuffer);
  241. var floorVertexIndices = [
  242. 0, 1, 2, 3
  243. ];
  244. //3.向缓冲区对象中写入数据(16为无符号整型数字)
  245. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(floorVertexIndices), gl.STATIC_DRAW);
  246.  
  247. floorVertexIndexBuffer.itemSize = 1;
  248. floorVertexIndexBuffer.numberOfItems = 4;
  249.  
  250. }
  251.  
  252. //立方体的顶点位置参数
  253. function setupCubeBuffers() {
  254. /*****立方体的顶点位置*****/
  255. //1.创建立方体的顶点缓冲区
  256. cubeVertexPositionBuffer = gl.createBuffer();
  257. //2.绑定缓冲区到目标对象
  258. gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
  259. var cubeVertexPosition = [
  260. // Front face
  261. 1.0, 1.0, 1.0, //v0
  262. -1.0, 1.0, 1.0, //v1
  263. -1.0, -1.0, 1.0, //v2
  264. 1.0, -1.0, 1.0, //v3
  265.  
  266. // Back face
  267. 1.0, 1.0, -1.0, //v4
  268. -1.0, 1.0, -1.0, //v5
  269. -1.0, -1.0, -1.0, //v6
  270. 1.0, -1.0, -1.0, //v7
  271.  
  272. // Left face
  273. -1.0, 1.0, 1.0, //v8
  274. -1.0, 1.0, -1.0, //v9
  275. -1.0, -1.0, -1.0, //v10
  276. -1.0, -1.0, 1.0, //v11
  277.  
  278. // Right face
  279. 1.0, 1.0, 1.0, //12
  280. 1.0, -1.0, 1.0, //13
  281. 1.0, -1.0, -1.0, //14
  282. 1.0, 1.0, -1.0, //15
  283.  
  284. // Top face
  285. 1.0, 1.0, 1.0, //v16
  286. 1.0, 1.0, -1.0, //v17
  287. -1.0, 1.0, -1.0, //v18
  288. -1.0, 1.0, 1.0, //v19
  289.  
  290. // Bottom face
  291. 1.0, -1.0, 1.0, //v20
  292. 1.0, -1.0, -1.0, //v21
  293. -1.0, -1.0, -1.0, //v22
  294. -1.0, -1.0, 1.0, //v23
  295. ];
  296. //3.向缓冲区对象中写入数据
  297. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cubeVertexPosition), gl.STATIC_DRAW);
  298.  
  299. //错误提示:Uncaught TypeError: Cannot read property 'toString' of undefined!
  300. /*cubeVertexPosition.itemSize = 3;
  301. cubeVertexPosition.numberOfItems = 24;*/
  302. /*
  303. * 【经验话语】:如果控制台提示toString()类型的错误,多半原因是由于调用该函数的语句中的某一个变量没有正确定义,或者没有正确初始化操作
  304. * 【解决方案】:通常检查出错语句中的变量,是否正确赋值!
  305. * */
  306. cubeVertexPositionBuffer.itemSize = 3;
  307. cubeVertexPositionBuffer.numberOfItems = 24;
  308.  
  309. /*****立方体的顶点位置索引信息****/
  310. //1.创建立方体顶点位置索引缓冲区
  311. cubeVertexIndexBuffer = gl.createBuffer();
  312. //2.绑定缓冲区到目标对象
  313. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
  314. var cubeVertexIndices = [
  315. 0, 1, 2, 0, 2, 3, // Front face
  316. 4, 6, 5, 4, 7, 6, // Back face
  317. 8, 9, 10, 8, 10, 11, // Left face
  318. 12, 13, 14, 12, 14, 15, // Right face
  319. 16, 17, 18, 16, 18, 19, // Top face
  320. 20, 22, 21, 20, 23, 22 // Bottom face
  321. ];
  322. //3.向缓冲区对象中写入数据
  323. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
  324.  
  325. //索引之间互相独立, 共计有36个索引点的信息
  326. cubeVertexIndexBuffer.itemSize = 1;
  327. cubeVertexIndexBuffer.numberOfItems = 36;
  328. }
  329.  
  330. //设置我的缓冲区
  331. function setupBuffers() {
  332. //设置缓冲区分解为两个部分
  333. //1.设置地板的顶点缓冲区
  334. setupFloorBuffers();
  335. //2.设置立方体的顶点缓冲区
  336. setupCubeBuffers();
  337. }
  338.  
  339. //把我的模型视图矩阵传给顶点着色器
  340. function uploadModelViewMatrixToShader() {
  341. gl.uniformMatrix4fv(shaderProgram.uniformMVMatrix, false, modelViewMatrix);
  342. }
  343. //把我的投影矩阵传给顶点着色器
  344. function uploadProjectionMatrixToShader() {
  345. gl.uniformMatrix4fv(shaderProgram.uniformProjMatrix, false, projectionMatrix);
  346. }
  347.  
  348. //绘制地板
  349. function drawFloor(r, g, b, a) {
  350. //指定一个常量颜色
  351. gl.disableVertexAttribArray(shaderProgram.vertexColorAttribute);
  352. gl.vertexAttrib4f(shaderProgram.vertexColorAttribute, r, g, b, a);
  353.  
  354. //开始绘制(先把地板顶点位置信息传给顶点着色器)
  355. gl.bindBuffer(gl.ARRAY_BUFFER, floorVertexPositionBuffer);
  356. gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
  357. floorVertexPositionBuffer.itemSize,
  358. gl.FLOAT, false, 0, 0);
  359. //利用顶点索引信息开始绘图
  360. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, floorVertexIndexBuffer);
  361. gl.drawElements(gl.TRIANGLE_FAN, floorVertexIndexBuffer.numberOfItems, gl.UNSIGNED_SHORT, 0);
  362.  
  363. }
  364.  
  365. //绘制立方体
  366. function drawCube(r, g, b, a) {
  367. //设置指定的颜色
  368. gl.disableVertexAttribArray(shaderProgram.vertexColorAttribute);
  369. gl.vertexAttrib4f(shaderProgram.vertexColorAttribute, r, g, b, a);
  370.  
  371. //开始绘制
  372. gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
  373. gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, cubeVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
  374.  
  375. //开始利用索引坐标绘制立方体
  376. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
  377. gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numberOfItems,
  378. gl.UNSIGNED_SHORT, 0);
  379.  
  380. }
  381.  
  382. //绘制卓子
  383. function drawTable() {
  384. //绘制之前先保存当前的模型视图矩阵
  385. pushModelViewMatrix();//最初的模型视图矩阵
  386. //alert(modelViewMatrixStack.length); 此时这里面存放了两个模型视图矩阵
  387. //向上移动1个单位
  388. mat4.translate(modelViewMatrix, [0.0, 1.0, 0.0], modelViewMatrix);
  389. //开始缩放
  390. mat4.scale(modelViewMatrix, [2.0, 0.1, 2.0], modelViewMatrix);
  391. //把平移并且缩放后的矩阵(此时的模型视图矩阵)传到顶点着色器
  392. uploadModelViewMatrixToShader();
  393.  
  394. //开始绘制立方体(主要是把立方体的顶点位置传给顶点着色器,然后顶点着色器就会对这个顶点位置向量进行矩阵变换)
  395. drawCube(0.72, 0.53, 0.04, 1.0);
  396. popModelViewMatrix();
  397.  
  398. //绘制桌子腿
  399. for (var i=-1; i<=1; i+=2) {
  400. for (var j= -1; j<=1; j+=2) {
  401. pushModelViewMatrix();
  402. mat4.translate(modelViewMatrix, [i*1.9, -0.1, j*1.9], modelViewMatrix);
  403. mat4.scale(modelViewMatrix, [0.1, 1.0, 0.1], modelViewMatrix);
  404. uploadModelViewMatrixToShader();
  405. //绘制立方体(会把立方体的顶点坐标,进行矩阵变换)
  406. drawCube(0.72, 0.53, 0.04, 1.0); // argument sets brown color
  407. popModelViewMatrix();
  408. }
  409. }
  410. }
  411.  
  412. //绘图函数
  413. function draw() {
  414. //设置视口,清空深度缓存(左下角坐标, 宽度, 高度)
  415. gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
  416. gl.clear(gl.COLOR_BUFFER_BIT);
  417.  
  418. //设置我的透视投影矩阵
  419. mat4.perspective(60, gl.viewportWidth/gl.viewportHeight, 0.1, 100, projectionMatrix);
  420. //重置模型视图矩阵
  421. mat4.identity(modelViewMatrix);
  422. mat4.lookAt([8, 5, -10], [0, 0, 0], [0, 1, 0], modelViewMatrix);
  423.  
  424. //在这里设置转动整个场景
  425. mat4.translate(modelViewMatrix, [0, 0, z], modelViewMatrix);
  426. mat4.rotateY(modelViewMatrix, yRot, modelViewMatrix);
  427.  
  428. //把当前的模型视图投影矩阵传递给顶点着色器(到这里顶点的坐标已经转换为了裁剪坐标系)
  429. uploadModelViewMatrixToShader();
  430. uploadProjectionMatrixToShader();
  431.  
  432. //开始绘制地板
  433. drawFloor(1.0, 0.0, 0.0, 1.0);
  434.  
  435. //绘制桌子
  436. //绘制之前先把我当前的WEBGL坐标系统的矩阵保存起来【相当于是桌子腿的最下面位置】
  437. pushModelViewMatrix();
  438. //此时物体的坐标系到达桌子的最上表面(注意物体自身的坐标系和WEBGL坐标系的区别)
  439. //这里实际上是把WEBGL坐标系移动到物体坐标系的原点位置
  440. mat4.translate(modelViewMatrix, [0.0, 1.1, 0.0], modelViewMatrix);
  441. uploadModelViewMatrixToShader();
  442. drawTable();
  443. popModelViewMatrix();
  444.  
  445. //开始绘制桌子上面的一个物体
  446. pushModelViewMatrix();
  447. mat4.translate(modelViewMatrix, [0.0, 2.7, 0.0], modelViewMatrix);
  448. //把原来的立方体2*2*2变换为1*1*1的立方体,相当于把长宽高都缩减为原来的一半
  449. mat4.scale(modelViewMatrix, [0.5, 0.5, 0.5], modelViewMatrix);
  450. uploadModelViewMatrixToShader();
  451. drawCube(0.0, 0.0, 1.0, 1.0);
  452. popModelViewMatrix();
  453.  
  454. //在绘制一个图形
  455. pushModelViewMatrix();
  456. mat4.translate(modelViewMatrix, [0.0, 3.7, 0.0], modelViewMatrix);
  457. mat4.scale(modelViewMatrix, [0.5, 0.5, 0.5], modelViewMatrix);
  458. uploadModelViewMatrixToShader();
  459. drawCube(0.0, 1.0, 0.0, 1.0);
  460. popModelViewMatrix();
  461.  
  462. pushModelViewMatrix();
  463. mat4.translate(modelViewMatrix, [0.0, 4.7, 0.0], modelViewMatrix);
  464. mat4.scale(modelViewMatrix, [0.5, 0.5, 0.5], modelViewMatrix);
  465. //mat4.rotateY(modelViewMatrix, yRot, modelViewMatrix);
  466. uploadModelViewMatrixToShader();
  467. drawCube(1.0, 1.0, 0.0, 1.0);
  468. popModelViewMatrix();
  469.  
  470. //开始转动场景
  471. /*mat4.rotate(modelViewMatrix, xRot, [1, 0, 0], modelViewMatrix);
  472. mat4.rotateY(modelViewMatrix, yRot, modelViewMatrix);
  473. uploadModelViewMatrixToShader();
  474. uploadProjectionMatrixToShader();*/
  475.  
  476. }
  477.  
  478. var lastTime = 0;
  479. //实时更新旋转角度
  480. function animate() {
  481. var timeNow = new Date().getTime();
  482. if (lastTime != 0) {
  483. var elapsed = timeNow - lastTime;
  484.  
  485. xRot += (xSpeed * elapsed) / 1000.0;
  486. yRot += (ySpeed * elapsed) / 1000.0;
  487. }
  488. lastTime = timeNow;
  489. }
  490.  
  491. //不断重绘场景
  492. function tick() {
  493. requestAnimationFrame(tick);
  494. handleKeys();
  495. draw();
  496. animate();
  497. }
  498.  
  499. function startup() {
  500. canvas = document.getElementById("myGLCanvas");
  501. gl = WebGLDebugUtils.makeDebugContext(createGLContext(canvas));
  502. setupShaders();
  503. setupBuffers();
  504. gl.clearColor(1.0, 1.0, 1.0, 1.0);
  505.  
  506. //逆时针方向是前面
  507. gl.frontFace(gl.CW);
  508. //激活背面剔除功能
  509. gl.enable(gl.CULL_FACE);
  510. //WEBGL剔除背面三角形
  511. gl.cullFace(gl.FRONT);
  512.  
  513. //draw();
  514.  
  515. document.onkeydown = handleKeyDown;
  516. document.onkeyup = handleKeyUp;
  517.  
  518. tick();
  519. }
  520. </script>
  521. <script src="./lib/glMatrix.js"></script>
  522.  
  523. </head>
  524.  
  525. <body onload="startup();">
  526. <canvas id="myGLCanvas" width="500" height="500" style="border: 2px solid springgreen;"></canvas>
  527. </body>
  528.  
  529. </html>
  1.  

WEBGL学习【八】模型视图投影矩阵的更多相关文章

  1. OpenGL 模型视图投影矩阵 仿射矩阵

    矩阵基础知识 要对矩阵进行运算,必须先要了解矩阵的计算公式,这个知识的内容涉及到了线性代数. 我们知道在Cocos2dx中,有关于平移,旋转,缩放等等操作,都必须要进行矩阵的乘法. 只需要一张图就能理 ...

  2. 【GISER&&Painter】Chapter02:WebGL中的模型视图变换

    上一节我们提到了如何在一张画布上画一个简单几何图形,通过创建画布,获取WebGLRendering上下文,创建一个简单的着色器,然后将一些顶点数据绑定到gl的Buffer中,最后通过绑定buffer数 ...

  3. WEBGL学习【四】模型视图矩阵

    <html lang="zh-CN"> <!--服务器运行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWe ...

  4. WebGL或OpenGL关于模型视图投影变换的设置技巧

    目录 1. 具体实例 2. 解决方案 1) Cube.html 2) Cube.js 3) 运行结果 3. 详细讲解 1) 模型变换 2) 视图变换 3) 投影变换 4) 模型视图投影矩阵 4. 存在 ...

  5. three.js中的矩阵变换(模型视图投影变换)

    目录 1. 概述 2. 基本变换 2.1. 矩阵运算 2.2. 模型变换矩阵 2.2.1. 平移矩阵 2.2.2. 旋转矩阵 2.2.2.1. 绕X轴旋转矩阵 2.2.2.2. 绕Y轴旋转矩阵 2.2 ...

  6. WEBGL学习【十五】利用WEBGL实现三维场景的一般思路总结

    实现三维场景载入操作的实现步骤: 主要知识点:着色器,纹理贴图,文件载入 实现思路: 获取canvas,初始化WEBGL上下文信息. 主要是实现WEBGL上下文的获取,设置视的大小,此时gl存储了WE ...

  7. WEBGL学习【十三】鼠标点击立方体改变颜色的原理与实现

    // PickFace.js (c) 2012 matsuda and kanda // Vertex shader program var VSHADER_SOURCE = 'attribute v ...

  8. WEBGL学习【十】运动模型

    <!DOCTYPE HTML> <html lang="en"> <head> <title>LWEBGL6.2, Animated ...

  9. WEBGL学习【九】立方体贴不同的纹理

    <html> <!--开始实现一个三维街景的渲染效果--> <head> <meta http-equiv="Content-Type" ...

随机推荐

  1. Redis参数

    phpredis是php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系 很有用;以下是redis官方提供的命令使用技巧: Redis::__construct构造函数$redis ...

  2. Apache vs. Nginx

    精简版 Apache:出名比较早,09年左右是最流行的时期,功能强大,可以根据需求配置为基于进程,基于线程或者基于事件的,但是消耗内存较多,对硬件需求较高,内存是影响服务器性能的最关键因素,在VPS上 ...

  3. 我要带徒弟学JAVA架构 ( 写架构,非用架构 )

    80元,当然我不觉得我带的徒弟比花了1万多在培训班学习的学生差,你努力了.会比他们出色的多.等你学有所成.相同能够成为jeecg核心成员之中的一个.一起构建Java学习平台.你也能够成为非常好的师傅. ...

  4. Thread和ThreadGroup

    Thread和ThreadGroup 学习了:https://www.cnblogs.com/yiwangzhibujian/p/6212104.html  这个里面有Thread的基本内容: htt ...

  5. OpenCV学习笔记(六十二)——《OpenCV Computer Version with Python》阅读摘要

    如今python火啊.每次OpenCV自带的ml模块都让我直呼坑爹,索性准备用python来做OpenCV后期的机器学习算法的处理.于是赶紧拿起这本书读读. 适合OpenCV和python都有一定基础 ...

  6. JeeCG团队招聘啦!

    JeeCG团队招聘啦! 小团队攻坚,创业氛围浓厚.盼望有激情的你增加. 岗位描写叙述: 1,负责Jeecg.jeewx 微信管理系统相关的研发工作.2,高度參与整个产品设计.參与微信相关项目开发.3. ...

  7. 设计一部iphone手机用面向对象的方法

    main.m //编辑字体大小command + < //编译执行快捷键 com + R #import <Foundation/Foundation.h> #import &quo ...

  8. Spring JDBC数据库开发

    针对数据库操作,Spring框架提供了JdbcTemplate类. 1.Spring JDBC的配置 创建配置文件applicationContext.xml,添加如下代码: <!--配置数据源 ...

  9. cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第0步---知识点总结&amp;效果预览&amp;设计思路

    /* 说明: **1.本次游戏实例是<cocos2d-x游戏开发之旅>上的最后一个游戏.这里用3.0重写并做下笔记 **2.我也问过木头本人啦,他说:随便写.第一别全然照搬代码:第二能够说 ...

  10. 《转》Ceilometer Alarm API 參数具体解释 及 举例说明

    Ceilometer Alarm是H版新加入的功能,监控报警是云平台必不可少的部分,Ceilometer已经实现了比較完好的监控体系.报警怎么能缺少呢?用过AWS CloudWatch Alarm的人 ...