LineDraw.hx 5.9 KB

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