terrain.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. function Terrain(assets, atlas) {
  2. this.last = {
  3. center: [0,0],
  4. size: [0,0], // zero size will force an update on the first frame
  5. }
  6. this.prog = loadProgram2(assets.vertexShader.terrain, assets.fragmentShader.terrain);
  7. this.pos_ul = gl.getUniformLocation(this.prog, "position");
  8. this.vaoInfo = makeVAO([
  9. { buf: 0, name: 'vpos', loc: 0, count: 3, type: gl.FLOAT, norm: false },
  10. { buf: 0, name: 'vtex', loc: 1, count: 2, type: gl.FLOAT, norm: false },
  11. { buf: 1, name: 'pos_ind', loc: 2, count: 3, type: gl.FLOAT, norm: false, divisor: 1 },
  12. ]);
  13. this.meshVBO = this.makeTerrainMeshVBO();
  14. this.instVBO = this.makeInstVBO();
  15. this.instances = [];
  16. this.tiles = { /* fill with tile atlas info */};
  17. this.blocks = {
  18. };
  19. this.dataTex = makeTexArray(gl.R8, 64,64, 16);
  20. this.map = new Map();
  21. var map = this.map;
  22. map.fillRandom(pt(0,0), pt(63, 63), [0,0,1]);
  23. // main street
  24. map.placeRoad(pt(0,36), pt(63, 36), [3,2,2,2,3]);
  25. // side streets
  26. for(var i = 0; i < 3; i++) {
  27. map.placeRoad(pt(5 + i*15,36), pt(5 + i*15, 20), [3,2,2,2,3]);
  28. }
  29. // // clear the map first
  30. // for(var y = 0; y < 64; y++) {
  31. // for(var x = 0; x < 64; x++) {
  32. // var d = (Math.random() * 5) | 0;
  33. // //console.log(d);
  34. // map[x + (y * 64)] = d
  35. // }
  36. // }
  37. //
  38. this.dataTex.updateLayer(0, map.getBlock(0,0).tiles);
  39. this.tilesTex = assets.imageArray['terraintex'];
  40. return this;
  41. }
  42. Terrain.prototype.loadTiles = function(tiles) {
  43. for(var t in tiles) {
  44. }
  45. }
  46. Terrain.prototype.setTile = function(pos, tile) {
  47. }
  48. Terrain.prototype.makeBlock = function(tl) {
  49. var arr = new Uint16Array(64*64);
  50. arr.fill(0);
  51. return {
  52. aabb: [tl[0], tl[1], tl[0] + 64, tl[1] + 64],
  53. data: arr,
  54. meshVBO: this.makeTerrainVBO(arr),
  55. kids: {
  56. tl: null,
  57. tr: null,
  58. bl: null,
  59. br: null,
  60. },
  61. };
  62. };
  63. Terrain.prototype.makeTerrainMeshVBO = function(arr) {
  64. var buf = [];
  65. for(var y = 0; y < 64; y++) {
  66. for(var x = 0; x < 64; x++) {
  67. buf.push(x - 0.5);
  68. buf.push(y - 0.5);
  69. buf.push(1);
  70. buf.push(0);
  71. buf.push(0);
  72. buf.push(x - 0.5);
  73. buf.push(y + 0.5);
  74. buf.push(1);
  75. buf.push(0);
  76. buf.push(1);
  77. buf.push(x + 0.5);
  78. buf.push(y - 0.5);
  79. buf.push(1);
  80. buf.push(1);
  81. buf.push(0);
  82. // ------------------
  83. buf.push(x - 0.5);
  84. buf.push(y + 0.5);
  85. buf.push(1);
  86. buf.push(0);
  87. buf.push(1);
  88. buf.push(x + 0.5);
  89. buf.push(y - 0.5);
  90. buf.push(1);
  91. buf.push(1);
  92. buf.push(0);
  93. buf.push(x + 0.5);
  94. buf.push(y + 0.5);
  95. buf.push(1);
  96. buf.push(1);
  97. buf.push(1);
  98. }
  99. }
  100. // console.log("vbo len", buf.length);
  101. return makeVBO(new Float32Array(buf), this.vaoInfo, 0, gl.DYNAMIC_DRAW);
  102. }
  103. Terrain.prototype.makeInstVBO = function(arr) {
  104. var buf = [];
  105. // need to track which layers of the tile info texture are used and which map to what block
  106. // use sync objects to know when it's safe to use and recycle
  107. // TODO: need to get view area from matrices
  108. // var blocks = this.map.blocksInArea();
  109. buf.push(0);
  110. buf.push(0);
  111. buf.push(0);
  112. // console.log("vbo len", buf.length);
  113. return makeVBO(new Float32Array(buf), this.vaoInfo, 1, gl.DYNAMIC_DRAW);
  114. }
  115. /*
  116. Terrain.prototype.makeTerrainVBO = function(arr) {
  117. var buf = [];
  118. var sz = 10;
  119. for(var y = 0; y < 64; y++) {
  120. for(var x = 0; x < 64; x++) {
  121. var n = arr[x + (y * 64)];
  122. var t = this.tiles[n];
  123. // position
  124. buf.push(x * sz);
  125. buf.push(y * sz);
  126. buf.push(1);
  127. // quad size
  128. buf.push(sz);
  129. buf.push(sz);
  130. // tex array index
  131. buf.push(t.texIndex);
  132. // tex offset, size
  133. buf.push(t.normOffset[0]);
  134. buf.push(t.normOffset[1]);
  135. buf.push(t.normSize[0]);
  136. buf.push(t.normSize[1]);
  137. }
  138. }
  139. return makeVBO(buf, this.vaoInfo, 1, gl.DYNAMIC_DRAW);
  140. }*/
  141. Terrain.prototype.render = function(game) {
  142. gl.useProgram(this.prog);
  143. var vp_ul = gl.getUniformLocation(this.prog, "mViewProj");
  144. gl.uniformMatrix4fv(vp_ul, false, game.vp);
  145. gl.activeTexture(gl.TEXTURE0 + 0);
  146. gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.tilesTex.tex);
  147. // gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.dataTex.tex);
  148. var tex_ul = gl.getUniformLocation(this.prog, "sTex");
  149. gl.uniform1i(tex_ul, 0);
  150. gl.activeTexture(gl.TEXTURE0 + 1);
  151. gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.dataTex.tex);
  152. var lookup_tex_ul = gl.getUniformLocation(this.prog, "sTileLookup");
  153. gl.uniform1i(lookup_tex_ul, 1);
  154. gl.bindVertexArray(this.vaoInfo.vao);
  155. gl.bindBuffer(gl.ARRAY_BUFFER, this.meshVBO.vbo);
  156. gl.bindBuffer(gl.ARRAY_BUFFER, this.instVBO.vbo);
  157. // console.log(this.meshVBO, this.instVBO);
  158. var primitiveType = gl.TRIANGLES;
  159. var offset = 0;
  160. var count = 6 * 64 * 64;
  161. var instances = 1;
  162. gl.drawArraysInstanced(primitiveType, offset, count, instances);
  163. }