LineDraw.hx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package arm.render;
  2. import kha.graphics4.PipelineState;
  3. import kha.graphics4.VertexStructure;
  4. import kha.graphics4.VertexBuffer;
  5. import kha.graphics4.IndexBuffer;
  6. import kha.graphics4.VertexData;
  7. import kha.graphics4.Usage;
  8. import kha.graphics4.ConstantLocation;
  9. import kha.graphics4.CompareMode;
  10. import kha.graphics4.CullMode;
  11. import kha.graphics4.TextureFormat;
  12. import kha.graphics4.DepthStencilFormat;
  13. import iron.math.Vec4;
  14. import iron.math.Mat4;
  15. class LineDraw {
  16. public static var color: kha.Color = 0xffff0000;
  17. public static var strength = 0.005;
  18. public static var mat: iron.math.Mat4 = null;
  19. public static var dim: iron.math.Vec4 = null;
  20. static var vertexBuffer: VertexBuffer;
  21. static var indexBuffer: IndexBuffer;
  22. static var pipeline: PipelineState = null;
  23. static var vp: Mat4;
  24. static var vpID: ConstantLocation;
  25. static var vbData: kha.arrays.ByteArray;
  26. static var ibData: kha.arrays.Uint32Array;
  27. static inline var maxLines = 300;
  28. static inline var maxVertices = maxLines * 4;
  29. static inline var maxIndices = maxLines * 6;
  30. static var lines = 0;
  31. static var g: kha.graphics4.Graphics;
  32. public static function render(g4: kha.graphics4.Graphics, matrix: iron.math.Mat4) {
  33. g = g4;
  34. mat = matrix;
  35. dim = matrix.getScale();
  36. if (pipeline == null) {
  37. var structure = new VertexStructure();
  38. structure.add("pos", VertexData.Float3);
  39. structure.add("col", VertexData.Float3);
  40. pipeline = new PipelineState();
  41. pipeline.inputLayout = [structure];
  42. pipeline.fragmentShader = kha.Shaders.getFragment("line.frag");
  43. pipeline.vertexShader = kha.Shaders.getVertex("line.vert");
  44. pipeline.depthWrite = true;
  45. pipeline.depthMode = CompareMode.Less;
  46. pipeline.cullMode = CullMode.None;
  47. pipeline.colorAttachmentCount = 3;
  48. pipeline.colorAttachments[0] = TextureFormat.RGBA64;
  49. pipeline.colorAttachments[1] = TextureFormat.RGBA64;
  50. pipeline.colorAttachments[2] = TextureFormat.RGBA64;
  51. pipeline.depthStencilAttachment = DepthStencilFormat.DepthOnly;
  52. pipeline.compile();
  53. vpID = pipeline.getConstantLocation("VP");
  54. vp = Mat4.identity();
  55. vertexBuffer = new VertexBuffer(maxVertices, structure, Usage.DynamicUsage);
  56. indexBuffer = new IndexBuffer(maxIndices, Usage.DynamicUsage);
  57. }
  58. begin();
  59. bounds(mat, dim);
  60. end();
  61. }
  62. static var wpos: Vec4;
  63. static var vx = new Vec4();
  64. static var vy = new Vec4();
  65. static var vz = new Vec4();
  66. public static function bounds(mat: iron.math.Mat4, dim: iron.math.Vec4) {
  67. wpos = mat.getLoc();
  68. var dx = dim.x / 2;
  69. var dy = dim.y / 2;
  70. var dz = dim.z / 2;
  71. var up = mat.up();
  72. var look = mat.look();
  73. var right = mat.right();
  74. up.normalize();
  75. look.normalize();
  76. right.normalize();
  77. vx.setFrom(right);
  78. vx.mult(dx);
  79. vy.setFrom(look);
  80. vy.mult(dy);
  81. vz.setFrom(up);
  82. vz.mult(dz);
  83. lineb(-1, -1, -1, 1, -1, -1);
  84. lineb(-1, 1, -1, 1, 1, -1);
  85. lineb(-1, -1, 1, 1, -1, 1);
  86. lineb(-1, 1, 1, 1, 1, 1);
  87. lineb(-1, -1, -1, -1, 1, -1);
  88. lineb(-1, -1, 1, -1, 1, 1);
  89. lineb( 1, -1, -1, 1, 1, -1);
  90. lineb( 1, -1, 1, 1, 1, 1);
  91. lineb(-1, -1, -1, -1, -1, 1);
  92. lineb(-1, 1, -1, -1, 1, 1);
  93. lineb( 1, -1, -1, 1, -1, 1);
  94. lineb( 1, 1, -1, 1, 1, 1);
  95. }
  96. static var v1 = new Vec4();
  97. static var v2 = new Vec4();
  98. static var t = new Vec4();
  99. static function lineb(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {
  100. v1.setFrom(wpos);
  101. t.setFrom(vx); t.mult(a); v1.add(t);
  102. t.setFrom(vy); t.mult(b); v1.add(t);
  103. t.setFrom(vz); t.mult(c); v1.add(t);
  104. v2.setFrom(wpos);
  105. t.setFrom(vx); t.mult(d); v2.add(t);
  106. t.setFrom(vy); t.mult(e); v2.add(t);
  107. t.setFrom(vz); t.mult(f); v2.add(t);
  108. line(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z);
  109. }
  110. static var midPoint = new Vec4();
  111. static var midLine = new Vec4();
  112. static var corner1 = new Vec4();
  113. static var corner2 = new Vec4();
  114. static var corner3 = new Vec4();
  115. static var corner4 = new Vec4();
  116. static var cameraLook = new Vec4();
  117. public static function line(x1: Float, y1: Float, z1: Float, x2: Float, y2: Float, z2: Float) {
  118. if (lines >= maxLines) {
  119. end();
  120. begin();
  121. }
  122. midPoint.set(x1 + x2, y1 + y2, z1 + z2);
  123. midPoint.mult(0.5);
  124. midLine.set(x1, y1, z1);
  125. midLine.sub(midPoint);
  126. var camera = iron.Scene.active.camera;
  127. cameraLook = camera.transform.world.getLoc();
  128. cameraLook.sub(midPoint);
  129. var lineWidth = cameraLook.cross(midLine);
  130. lineWidth.normalize();
  131. lineWidth.mult(strength);
  132. corner1.set(x1, y1, z1).add(lineWidth);
  133. corner2.set(x1, y1, z1).sub(lineWidth);
  134. corner3.set(x2, y2, z2).sub(lineWidth);
  135. corner4.set(x2, y2, z2).add(lineWidth);
  136. var i = lines * 24; // 4 * 6 (structure len)
  137. addVbData(i, [corner1.x, corner1.y, corner1.z, color.R, color.G, color.B]);
  138. i += 6;
  139. addVbData(i, [corner2.x, corner2.y, corner2.z, color.R, color.G, color.B]);
  140. i += 6;
  141. addVbData(i, [corner3.x, corner3.y, corner3.z, color.R, color.G, color.B]);
  142. i += 6;
  143. addVbData(i, [corner4.x, corner4.y, corner4.z, color.R, color.G, color.B]);
  144. i = lines * 6;
  145. ibData[i ] = lines * 4;
  146. ibData[i + 1] = lines * 4 + 1;
  147. ibData[i + 2] = lines * 4 + 2;
  148. ibData[i + 3] = lines * 4 + 2;
  149. ibData[i + 4] = lines * 4 + 3;
  150. ibData[i + 5] = lines * 4;
  151. lines++;
  152. }
  153. static function begin() {
  154. lines = 0;
  155. vbData = vertexBuffer.lock();
  156. ibData = indexBuffer.lock();
  157. }
  158. static function end() {
  159. vertexBuffer.unlock();
  160. indexBuffer.unlock();
  161. g.setVertexBuffer(vertexBuffer);
  162. g.setIndexBuffer(indexBuffer);
  163. g.setPipeline(pipeline);
  164. var camera = iron.Scene.active.camera;
  165. vp.setFrom(camera.V);
  166. vp.multmat(camera.P);
  167. g.setMatrix(vpID, vp.self);
  168. g.drawIndexedVertices(0, lines * 6);
  169. }
  170. inline static function addVbData(i: Int, data: Array<Float>) {
  171. for (offset in 0...6) {
  172. vbData.setFloat32((i + offset) * 4, data[offset]);
  173. }
  174. }
  175. }