Advertisement
Guest User

WebGL Lesson 10 (demo with jump)

a guest
Sep 2nd, 2012
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.76 KB | None | 0 0
  1.  
  2. <!-- saved from url=(0052)http://learningwebgl.com/lessons/lesson10/index.html -->
  3. <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  4. <title>Learning WebGL — lesson 10</title>
  5.  
  6.  
  7. <script type="text/javascript" src="./Learning WebGL — lesson 10_files/glMatrix-0.9.5.min.js"></script>
  8. <script type="text/javascript" src="./Learning WebGL — lesson 10_files/webgl-utils.js"></script>
  9.  
  10. <script id="shader-fs" type="x-shader/x-fragment">
  11. precision mediump float;
  12.  
  13. varying vec2 vTextureCoord;
  14.  
  15. uniform sampler2D uSampler;
  16.  
  17. void main(void) {
  18. gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
  19. }
  20. </script>
  21.  
  22. <script id="shader-vs" type="x-shader/x-vertex">
  23. attribute vec3 aVertexPosition;
  24. attribute vec2 aTextureCoord;
  25.  
  26. uniform mat4 uMVMatrix;
  27. uniform mat4 uPMatrix;
  28.  
  29. varying vec2 vTextureCoord;
  30.  
  31. void main(void) {
  32. gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
  33. vTextureCoord = aTextureCoord;
  34. }
  35. </script>
  36.  
  37.  
  38. <script type="text/javascript">
  39.  
  40. var jump = {
  41. isPerforming : false,
  42. hPos : 0,
  43. startSpeed : 3,
  44. accel : 9.8,
  45. timePoint : 0
  46. }
  47.  
  48. var gl;
  49.  
  50. function initGL(canvas) {
  51. try {
  52. gl = canvas.getContext("experimental-webgl");
  53. gl.viewportWidth = canvas.width;
  54. gl.viewportHeight = canvas.height;
  55. } catch (e) {
  56. }
  57. if (!gl) {
  58. alert("Could not initialise WebGL, sorry :-(");
  59. }
  60. }
  61.  
  62.  
  63. function getShader(gl, id) {
  64. var shaderScript = document.getElementById(id);
  65. if (!shaderScript) {
  66. return null;
  67. }
  68.  
  69. var str = "";
  70. var k = shaderScript.firstChild;
  71. while (k) {
  72. if (k.nodeType == 3) {
  73. str += k.textContent;
  74. }
  75. k = k.nextSibling;
  76. }
  77.  
  78. var shader;
  79. if (shaderScript.type == "x-shader/x-fragment") {
  80. shader = gl.createShader(gl.FRAGMENT_SHADER);
  81. } else if (shaderScript.type == "x-shader/x-vertex") {
  82. shader = gl.createShader(gl.VERTEX_SHADER);
  83. } else {
  84. return null;
  85. }
  86.  
  87. gl.shaderSource(shader, str);
  88. gl.compileShader(shader);
  89.  
  90. if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
  91. alert(gl.getShaderInfoLog(shader));
  92. return null;
  93. }
  94.  
  95. return shader;
  96. }
  97.  
  98.  
  99. var shaderProgram;
  100.  
  101. function initShaders() {
  102. var fragmentShader = getShader(gl, "shader-fs");
  103. var vertexShader = getShader(gl, "shader-vs");
  104.  
  105. shaderProgram = gl.createProgram();
  106. gl.attachShader(shaderProgram, vertexShader);
  107. gl.attachShader(shaderProgram, fragmentShader);
  108. gl.linkProgram(shaderProgram);
  109.  
  110. if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
  111. alert("Could not initialise shaders");
  112. }
  113.  
  114. gl.useProgram(shaderProgram);
  115.  
  116. shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
  117. gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
  118.  
  119. shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
  120. gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
  121.  
  122. shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
  123. shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
  124. shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
  125. }
  126.  
  127.  
  128. function handleLoadedTexture(texture) {
  129. gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
  130. gl.bindTexture(gl.TEXTURE_2D, texture);
  131. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
  132. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  133. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  134.  
  135. gl.bindTexture(gl.TEXTURE_2D, null);
  136. }
  137.  
  138.  
  139. var mudTexture;
  140.  
  141. function initTexture() {
  142. mudTexture = gl.createTexture();
  143. mudTexture.image = new Image();
  144. mudTexture.image.onload = function () {
  145. handleLoadedTexture(mudTexture)
  146. }
  147.  
  148. mudTexture.image.src = "mud.gif";
  149. }
  150.  
  151.  
  152. var mvMatrix = mat4.create();
  153. var mvMatrixStack = [];
  154. var pMatrix = mat4.create();
  155.  
  156. function mvPushMatrix() {
  157. var copy = mat4.create();
  158. mat4.set(mvMatrix, copy);
  159. mvMatrixStack.push(copy);
  160. }
  161.  
  162. function mvPopMatrix() {
  163. if (mvMatrixStack.length == 0) {
  164. throw "Invalid popMatrix!";
  165. }
  166. mvMatrix = mvMatrixStack.pop();
  167. }
  168.  
  169.  
  170. function setMatrixUniforms() {
  171. gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
  172. gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
  173. }
  174.  
  175.  
  176. function degToRad(degrees) {
  177. return degrees * Math.PI / 180;
  178. }
  179.  
  180.  
  181. var currentlyPressedKeys = {};
  182.  
  183. function handleKeyDown(event) {
  184. currentlyPressedKeys[event.keyCode] = true;
  185. if (event.keyCode==32) jump.isPerforming = true;
  186. }
  187.  
  188.  
  189. function handleKeyUp(event) {
  190. currentlyPressedKeys[event.keyCode] = false;
  191. }
  192.  
  193.  
  194. var pitch = 0;
  195. var pitchRate = 0;
  196.  
  197. var yaw = 0;
  198. var yawRate = 0;
  199.  
  200. var xPos = 0;
  201. var yPos = 0.4;
  202. var zPos = 0;
  203.  
  204. var speed = 0;
  205.  
  206. function handleKeys() {
  207. if (currentlyPressedKeys[33]) {
  208. // Page Up
  209. pitchRate = 0.1;
  210. } else if (currentlyPressedKeys[34]) {
  211. // Page Down
  212. pitchRate = -0.1;
  213. } else {
  214. pitchRate = 0;
  215. }
  216.  
  217. if (currentlyPressedKeys[37] || currentlyPressedKeys[65]) {
  218. // Left cursor key or A
  219. yawRate = 0.1;
  220. } else if (currentlyPressedKeys[39] || currentlyPressedKeys[68]) {
  221. // Right cursor key or D
  222. yawRate = -0.1;
  223. } else {
  224. yawRate = 0;
  225. }
  226.  
  227. if (currentlyPressedKeys[38] || currentlyPressedKeys[87]) {
  228. // Up cursor key or W
  229. speed = 0.003;
  230. } else if (currentlyPressedKeys[40] || currentlyPressedKeys[83]) {
  231. // Down cursor key
  232. speed = -0.003;
  233. } else {
  234. speed = 0;
  235. }
  236.  
  237. }
  238.  
  239.  
  240. var worldVertexPositionBuffer = null;
  241. var worldVertexTextureCoordBuffer = null;
  242.  
  243. function handleLoadedWorld(data) {
  244. var lines = data.split("\n");
  245. var vertexCount = 0;
  246. var vertexPositions = [];
  247. var vertexTextureCoords = [];
  248. for (var i in lines) {
  249. var vals = lines[i].replace(/^\s+/, "").split(/\s+/);
  250. if (vals.length == 5 && vals[0] != "//") {
  251. // It is a line describing a vertex; get X, Y and Z first
  252. vertexPositions.push(parseFloat(vals[0]));
  253. vertexPositions.push(parseFloat(vals[1]));
  254. vertexPositions.push(parseFloat(vals[2]));
  255.  
  256. // And then the texture coords
  257. vertexTextureCoords.push(parseFloat(vals[3]));
  258. vertexTextureCoords.push(parseFloat(vals[4]));
  259.  
  260. vertexCount += 1;
  261. }
  262. }
  263.  
  264. worldVertexPositionBuffer = gl.createBuffer();
  265. gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexPositionBuffer);
  266. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositions), gl.STATIC_DRAW);
  267. worldVertexPositionBuffer.itemSize = 3;
  268. worldVertexPositionBuffer.numItems = vertexCount;
  269.  
  270. worldVertexTextureCoordBuffer = gl.createBuffer();
  271. gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexTextureCoordBuffer);
  272. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexTextureCoords), gl.STATIC_DRAW);
  273. worldVertexTextureCoordBuffer.itemSize = 2;
  274. worldVertexTextureCoordBuffer.numItems = vertexCount;
  275.  
  276. document.getElementById("loadingtext").textContent = "";
  277. }
  278.  
  279.  
  280. function loadWorld() {
  281. /*var request = new XMLHttpRequest();
  282. //request.open("GET", "world.txt");
  283. request.onreadystatechange = function () {
  284. if (request.readyState == 4) {
  285. handleLoadedWorld(request.responseText);
  286. }
  287. }
  288. request.send();*/
  289. handleLoadedWorld("\nNUMPOLLIES 36\n\n// Floor 1\n-3.0 0.0 -3.0 0.0 6.0\n-3.0 0.0 3.0 0.0 0.0\n 3.0 0.0 3.0 6.0 0.0\n\n-3.0 0.0 -3.0 0.0 6.0\n 3.0 0.0 -3.0 6.0 6.0\n 3.0 0.0 3.0 6.0 0.0\n\n// Ceiling 1\n-3.0 1.0 -3.0 0.0 6.0\n-3.0 1.0 3.0 0.0 0.0\n 3.0 1.0 3.0 6.0 0.0\n-3.0 1.0 -3.0 0.0 6.0\n 3.0 1.0 -3.0 6.0 6.0\n 3.0 1.0 3.0 6.0 0.0\n\n// A1\n\n-2.0 1.0 -2.0 0.0 1.0\n-2.0 0.0 -2.0 0.0 0.0\n-0.5 0.0 -2.0 1.5 0.0\n-2.0 1.0 -2.0 0.0 1.0\n-0.5 1.0 -2.0 1.5 1.0\n-0.5 0.0 -2.0 1.5 0.0\n\n// A2\n\n 2.0 1.0 -2.0 2.0 1.0\n 2.0 0.0 -2.0 2.0 0.0\n 0.5 0.0 -2.0 0.5 0.0\n 2.0 1.0 -2.0 2.0 1.0\n 0.5 1.0 -2.0 0.5 1.0\n 0.5 0.0 -2.0 0.5 0.0\n\n// B1\n\n-2.0 1.0 2.0 2.0 1.0\n-2.0 0.0 2.0 2.0 0.0\n-0.5 0.0 2.0 0.5 0.0\n-2.0 1.0 2.0 2.0 1.0\n-0.5 1.0 2.0 0.5 1.0\n-0.5 0.0 2.0 0.5 0.0\n\n// B2\n\n 2.0 1.0 2.0 2.0 1.0\n 2.0 0.0 2.0 2.0 0.0\n 0.5 0.0 2.0 0.5 0.0\n 2.0 1.0 2.0 2.0 1.0\n 0.5 1.0 2.0 0.5 1.0\n 0.5 0.0 2.0 0.5 0.0\n\n// C1\n\n-2.0 1.0 -2.0 0.0 1.0\n-2.0 0.0 -2.0 0.0 0.0\n-2.0 0.0 -0.5 1.5 0.0\n-2.0 1.0 -2.0 0.0 1.0\n-2.0 1.0 -0.5 1.5 1.0\n-2.0 0.0 -0.5 1.5 0.0\n\n// C2\n\n-2.0 1.0 2.0 2.0 1.0\n-2.0 0.0 2.0 2.0 0.0\n-2.0 0.0 0.5 0.5 0.0\n-2.0 1.0 2.0 2.0 1.0\n-2.0 1.0 0.5 0.5 1.0\n-2.0 0.0 0.5 0.5 0.0\n\n// D1\n\n2.0 1.0 -2.0 0.0 1.0\n2.0 0.0 -2.0 0.0 0.0\n2.0 0.0 -0.5 1.5 0.0\n2.0 1.0 -2.0 0.0 1.0\n2.0 1.0 -0.5 1.5 1.0\n2.0 0.0 -0.5 1.5 0.0\n\n// D2\n\n2.0 1.0 2.0 2.0 1.0\n2.0 0.0 2.0 2.0 0.0\n2.0 0.0 0.5 0.5 0.0\n2.0 1.0 2.0 2.0 1.0\n2.0 1.0 0.5 0.5 1.0\n2.0 0.0 0.5 0.5 0.0\n\n// Upper hallway - L\n-0.5 1.0 -3.0 0.0 1.0\n-0.5 0.0 -3.0 0.0 0.0\n-0.5 0.0 -2.0 1.0 0.0\n-0.5 1.0 -3.0 0.0 1.0\n-0.5 1.0 -2.0 1.0 1.0\n-0.5 0.0 -2.0 1.0 0.0\n\n// Upper hallway - R\n0.5 1.0 -3.0 0.0 1.0\n0.5 0.0 -3.0 0.0 0.0\n0.5 0.0 -2.0 1.0 0.0\n0.5 1.0 -3.0 0.0 1.0\n0.5 1.0 -2.0 1.0 1.0\n0.5 0.0 -2.0 1.0 0.0\n\n// Lower hallway - L\n-0.5 1.0 3.0 0.0 1.0\n-0.5 0.0 3.0 0.0 0.0\n-0.5 0.0 2.0 1.0 0.0\n-0.5 1.0 3.0 0.0 1.0\n-0.5 1.0 2.0 1.0 1.0\n-0.5 0.0 2.0 1.0 0.0\n\n// Lower hallway - R\n0.5 1.0 3.0 0.0 1.0\n0.5 0.0 3.0 0.0 0.0\n0.5 0.0 2.0 1.0 0.0\n0.5 1.0 3.0 0.0 1.0\n0.5 1.0 2.0 1.0 1.0\n0.5 0.0 2.0 1.0 0.0\n\n\n// Left hallway - Lw\n\n-3.0 1.0 0.5 1.0 1.0\n-3.0 0.0 0.5 1.0 0.0\n-2.0 0.0 0.5 0.0 0.0\n-3.0 1.0 0.5 1.0 1.0\n-2.0 1.0 0.5 0.0 1.0\n-2.0 0.0 0.5 0.0 0.0\n\n// Left hallway - Hi\n\n-3.0 1.0 -0.5 1.0 1.0\n-3.0 0.0 -0.5 1.0 0.0\n-2.0 0.0 -0.5 0.0 0.0\n-3.0 1.0 -0.5 1.0 1.0\n-2.0 1.0 -0.5 0.0 1.0\n-2.0 0.0 -0.5 0.0 0.0\n\n// Right hallway - Lw\n\n3.0 1.0 0.5 1.0 1.0\n3.0 0.0 0.5 1.0 0.0\n2.0 0.0 0.5 0.0 0.0\n3.0 1.0 0.5 1.0 1.0\n2.0 1.0 0.5 0.0 1.0\n2.0 0.0 0.5 0.0 0.0\n\n// Right hallway - Hi\n\n3.0 1.0 -0.5 1.0 1.0\n3.0 0.0 -0.5 1.0 0.0\n2.0 0.0 -0.5 0.0 0.0\n3.0 1.0 -0.5 1.0 1.0\n2.0 1.0 -0.5 0.0 1.0\n2.0 0.0 -0.5 0.0 0.0\n")
  290. }
  291.  
  292.  
  293.  
  294. function drawScene() {
  295. gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
  296. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  297.  
  298. if (worldVertexTextureCoordBuffer == null || worldVertexPositionBuffer == null) {
  299. return;
  300. }
  301.  
  302. mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
  303.  
  304. mat4.identity(mvMatrix);
  305.  
  306. mat4.rotate(mvMatrix, degToRad(-pitch), [1, 0, 0]);
  307. mat4.rotate(mvMatrix, degToRad(-yaw), [0, 1, 0]);
  308. mat4.translate(mvMatrix, [-xPos, -yPos-jump.hPos, -zPos]);
  309.  
  310. gl.activeTexture(gl.TEXTURE0);
  311. gl.bindTexture(gl.TEXTURE_2D, mudTexture);
  312. gl.uniform1i(shaderProgram.samplerUniform, 0);
  313.  
  314. gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexTextureCoordBuffer);
  315. gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, worldVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
  316.  
  317. gl.bindBuffer(gl.ARRAY_BUFFER, worldVertexPositionBuffer);
  318. gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, worldVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
  319.  
  320. setMatrixUniforms();
  321. gl.drawArrays(gl.TRIANGLES, 0, worldVertexPositionBuffer.numItems);
  322. }
  323.  
  324.  
  325. var lastTime = 0;
  326. // Used to make us "jog" up and down as we move forward.
  327. var joggingAngle = 0;
  328.  
  329. function animate() {
  330. var timeNow = new Date().getTime();
  331. if (lastTime != 0) {
  332. var elapsed = timeNow - lastTime;
  333.  
  334. if (speed != 0) {
  335. xPos -= Math.sin(degToRad(yaw)) * speed * elapsed;
  336. zPos -= Math.cos(degToRad(yaw)) * speed * elapsed;
  337.  
  338. joggingAngle += elapsed * 0.6; // 0.6 "fiddle factor" - makes it feel more realistic :-)
  339. yPos = Math.sin(degToRad(joggingAngle)) / 20 + 0.4
  340. }
  341.  
  342. yaw += yawRate * elapsed;
  343. pitch += pitchRate * elapsed;
  344.  
  345. if (jump.isPerforming)
  346. {
  347. jump.timePoint += elapsed*0.001;
  348. jump.hPos = jump.startSpeed * jump.timePoint - jump.accel * jump.timePoint * jump.timePoint / 2;
  349. if (jump.hPos<0.0)
  350. {
  351. jump.timePoint = 0;
  352. jump.hPos = 0;
  353. jump.isPerforming = false;
  354. }
  355. }
  356.  
  357. }
  358. lastTime = timeNow;
  359. }
  360.  
  361.  
  362. function tick() {
  363. requestAnimFrame(tick);
  364. handleKeys();
  365. drawScene();
  366. animate();
  367. }
  368.  
  369.  
  370.  
  371. function webGLStart() {
  372. var canvas = document.getElementById("lesson10-canvas");
  373. initGL(canvas);
  374. initShaders();
  375. initTexture();
  376. loadWorld();
  377.  
  378. gl.clearColor(0.0, 0.0, 0.0, 1.0);
  379. gl.enable(gl.DEPTH_TEST);
  380.  
  381. document.onkeydown = handleKeyDown;
  382. document.onkeyup = handleKeyUp;
  383.  
  384. tick();
  385. }
  386.  
  387.  
  388.  
  389. </script>
  390.  
  391. <style type="text/css">
  392. #loadingtext {
  393. position:absolute;
  394. top:250px;
  395. left:150px;
  396. font-size:2em;
  397. color: white;
  398. }
  399. </style>
  400.  
  401.  
  402.  
  403. </head>
  404.  
  405.  
  406. <body onload="webGLStart();">
  407. <a href="http://learningwebgl.com/blog/?p=1067">&lt;&lt; Back to Lesson 10</a><br>
  408.  
  409. <canvas id="lesson10-canvas" style="border: none;" width="500" height="500"></canvas>
  410.  
  411. <div id="loadingtext"></div>
  412.  
  413. <br>
  414. Use the cursor keys or WASD to run around, and <code>Page Up</code>/<code>Page Down</code> to
  415. look up and down.
  416.  
  417. <br>
  418. <br>
  419. <a href="http://learningwebgl.com/blog/?p=1067">&lt;&lt; Back to Lesson 10</a>
  420.  
  421. <!-- Google Analytics stuff, please ignore - nothing to do with WebGL :-) -->
  422. <script type="text/javascript">
  423. var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
  424. document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
  425. </script><script src="./Learning WebGL — lesson 10_files/ga.js" type="text/javascript"></script>
  426. <script type="text/javascript">
  427. try {
  428. var pageTracker = _gat._getTracker("UA-2240015-5");
  429. pageTracker._trackPageview();
  430. } catch(err) {
  431. }
  432. </script>
  433.  
  434.  
  435.  
  436.  
  437. </body></html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement