diff --git a/Shaders/debug/line.frag.glsl b/Shaders/debug/line.frag.glsl deleted file mode 100644 index 2c8b9f98..00000000 --- a/Shaders/debug/line.frag.glsl +++ /dev/null @@ -1,8 +0,0 @@ -#version 450 - -in vec3 color; -out vec4 fragColor; - -void main() { - fragColor = vec4(color, 1.0); -} diff --git a/Shaders/debug/line_deferred.frag.glsl b/Shaders/painter/line.frag.glsl similarity index 100% rename from Shaders/debug/line_deferred.frag.glsl rename to Shaders/painter/line.frag.glsl diff --git a/Shaders/debug/line.vert.glsl b/Shaders/painter/line.vert.glsl similarity index 100% rename from Shaders/debug/line.vert.glsl rename to Shaders/painter/line.vert.glsl diff --git a/Sources/arm/data/LayerSlot.hx b/Sources/arm/data/LayerSlot.hx index 4dd771df..e8cbd7c4 100644 --- a/Sources/arm/data/LayerSlot.hx +++ b/Sources/arm/data/LayerSlot.hx @@ -43,9 +43,8 @@ class LayerSlot { public var paintEmis = true; public var paintSubs = true; - public var projectX = 0.0; // Decal layer - public var projectY = 0.0; - public var projectZ = 0.0; + public var decalMat = iron.math.Mat4.identity(); // Decal layer + public var decalDim = new iron.math.Vec4(1, 1, 1); var createMaskColor: Int; var createMaskImage: Image; diff --git a/Sources/arm/plugin/Gizmo.hx b/Sources/arm/plugin/Gizmo.hx index b6219b54..93cfbd56 100644 --- a/Sources/arm/plugin/Gizmo.hx +++ b/Sources/arm/plugin/Gizmo.hx @@ -32,7 +32,7 @@ class Gizmo { gizmo.transform.loc.setFrom(Context.object.transform.loc); } else if (isDecal) { - gizmo.transform.loc.set(Context.layer.projectX, Context.layer.projectY, Context.layer.projectZ); + gizmo.transform.loc.set(Context.layer.decalMat._30, Context.layer.decalMat._31, Context.layer.decalMat._32); } var cam = Scene.active.camera; var dist = Vec4.distance(cam.transform.loc, gizmo.transform.loc) / 10; @@ -128,13 +128,13 @@ class Gizmo { else if (isDecal) { if (Context.axisX || Context.axisY || Context.axisZ) { if (Context.axisX) { - Context.layer.projectX = Context.axisLoc; + Context.layer.decalMat._30 = Context.axisLoc; } else if (Context.axisY) { - Context.layer.projectY = Context.axisLoc; + Context.layer.decalMat._31 = Context.axisLoc; } else if (Context.axisZ) { - Context.layer.projectZ = Context.axisLoc; + Context.layer.decalMat._32 = Context.axisLoc; } Layers.updateFillLayer(); } @@ -163,7 +163,7 @@ class Gizmo { v.set(t.worldx(), t.worldy(), t.worldz()); } else if (isDecal) { - v.set(Context.layer.projectX, Context.layer.projectY, Context.layer.projectZ); + v.set(Context.layer.decalMat._30, Context.layer.decalMat._31, Context.layer.decalMat._32); } if (Context.axisX) { diff --git a/Sources/arm/render/LineDraw.hx b/Sources/arm/render/LineDraw.hx new file mode 100644 index 00000000..3fff5fe3 --- /dev/null +++ b/Sources/arm/render/LineDraw.hx @@ -0,0 +1,214 @@ +package arm.render; + +import kha.graphics4.PipelineState; +import kha.graphics4.VertexStructure; +import kha.graphics4.VertexBuffer; +import kha.graphics4.IndexBuffer; +import kha.graphics4.VertexData; +import kha.graphics4.Usage; +import kha.graphics4.ConstantLocation; +import kha.graphics4.CompareMode; +import kha.graphics4.CullMode; +import kha.graphics4.TextureFormat; +import kha.graphics4.DepthStencilFormat; +import iron.math.Vec4; +import iron.math.Mat4; +import arm.ui.UIHeader; +import arm.Enums; + +class LineDraw { + + public static var color: kha.Color = 0xffff0000; + public static var strength = 0.02; + public static var mat: iron.math.Mat4 = null; + public static var dim: iron.math.Vec4 = null; + + static var vertexBuffer: VertexBuffer; + static var indexBuffer: IndexBuffer; + static var pipeline: PipelineState = null; + + static var vp: Mat4; + static var vpID: ConstantLocation; + + static var vbData: kha.arrays.Float32Array; + static var ibData: kha.arrays.Uint32Array; + + static inline var maxLines = 300; + static inline var maxVertices = maxLines * 4; + static inline var maxIndices = maxLines * 6; + static var lines = 0; + + static var g: kha.graphics4.Graphics; + + public static function render(g4: kha.graphics4.Graphics) { + + var isPaint = UIHeader.inst.worktab.position == SpacePaint; + var isDecal = isPaint && Context.layer.material_mask != null && Context.layer.uvType == UVProject; + if (!isDecal) return; + + mat = Context.layer.decalMat; + dim = Context.layer.decalDim; + + g = g4; + + if (pipeline == null) { + var structure = new VertexStructure(); + structure.add("pos", VertexData.Float3); + structure.add("col", VertexData.Float3); + pipeline = new PipelineState(); + pipeline.inputLayout = [structure]; + pipeline.fragmentShader = kha.Shaders.line_frag; + pipeline.vertexShader = kha.Shaders.line_vert; + pipeline.depthWrite = true; + pipeline.depthMode = CompareMode.Less; + pipeline.cullMode = CullMode.None; + pipeline.colorAttachmentCount = 3; + pipeline.colorAttachments[0] = TextureFormat.RGBA64; + pipeline.colorAttachments[1] = TextureFormat.RGBA64; + pipeline.colorAttachments[2] = TextureFormat.RGBA64; + pipeline.depthStencilAttachment = DepthStencilFormat.DepthOnly; + pipeline.compile(); + vpID = pipeline.getConstantLocation("VP"); + vp = Mat4.identity(); + vertexBuffer = new VertexBuffer(maxVertices, structure, Usage.DynamicUsage); + indexBuffer = new IndexBuffer(maxIndices, Usage.DynamicUsage); + } + + begin(); + bounds(mat, dim); + end(); + } + + static var wpos: Vec4; + static var vx = new Vec4(); + static var vy = new Vec4(); + static var vz = new Vec4(); + public static function bounds(mat: iron.math.Mat4, dim: iron.math.Vec4) { + wpos = mat.getLoc(); + var dx = dim.x / 2; + var dy = dim.y / 2; + var dz = dim.z / 2; + + var up = mat.up(); + var look = mat.look(); + var right = mat.right(); + up.normalize(); + look.normalize(); + right.normalize(); + + vx.setFrom(right); + vx.mult(dx); + vy.setFrom(look); + vy.mult(dy); + vz.setFrom(up); + vz.mult(dz); + + lineb(-1, -1, -1, 1, -1, -1); + lineb(-1, 1, -1, 1, 1, -1); + lineb(-1, -1, 1, 1, -1, 1); + lineb(-1, 1, 1, 1, 1, 1); + + lineb(-1, -1, -1, -1, 1, -1); + lineb(-1, -1, 1, -1, 1, 1); + lineb( 1, -1, -1, 1, 1, -1); + lineb( 1, -1, 1, 1, 1, 1); + + lineb(-1, -1, -1, -1, -1, 1); + lineb(-1, 1, -1, -1, 1, 1); + lineb( 1, -1, -1, 1, -1, 1); + lineb( 1, 1, -1, 1, 1, 1); + } + + static var v1 = new Vec4(); + static var v2 = new Vec4(); + static var t = new Vec4(); + static function lineb(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) { + v1.setFrom(wpos); + t.setFrom(vx); t.mult(a); v1.add(t); + t.setFrom(vy); t.mult(b); v1.add(t); + t.setFrom(vz); t.mult(c); v1.add(t); + + v2.setFrom(wpos); + t.setFrom(vx); t.mult(d); v2.add(t); + t.setFrom(vy); t.mult(e); v2.add(t); + t.setFrom(vz); t.mult(f); v2.add(t); + + line(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z); + } + + static var midPoint = new Vec4(); + static var midLine = new Vec4(); + static var corner1 = new Vec4(); + static var corner2 = new Vec4(); + static var corner3 = new Vec4(); + static var corner4 = new Vec4(); + static var cameraLook = new Vec4(); + public static function line(x1: Float, y1: Float, z1: Float, x2: Float, y2: Float, z2: Float) { + + if (lines >= maxLines) { end(); begin(); } + + midPoint.set(x1 + x2, y1 + y2, z1 + z2); + midPoint.mult(0.5); + + midLine.set(x1, y1, z1); + midLine.sub(midPoint); + + var camera = iron.Scene.active.camera; + cameraLook = camera.transform.world.getLoc(); + cameraLook.sub(midPoint); + + var lineWidth = cameraLook.cross(midLine); + lineWidth.normalize(); + lineWidth.mult(strength); + + corner1.set(x1, y1, z1).add(lineWidth); + corner2.set(x1, y1, z1).sub(lineWidth); + corner3.set(x2, y2, z2).sub(lineWidth); + corner4.set(x2, y2, z2).add(lineWidth); + + var i = lines * 24; // 4 * 6 (structure len) + addVbData(i, [corner1.x, corner1.y, corner1.z, color.R, color.G, color.B]); + i += 6; + addVbData(i, [corner2.x, corner2.y, corner2.z, color.R, color.G, color.B]); + i += 6; + addVbData(i, [corner3.x, corner3.y, corner3.z, color.R, color.G, color.B]); + i += 6; + addVbData(i, [corner4.x, corner4.y, corner4.z, color.R, color.G, color.B]); + + i = lines * 6; + ibData[i ] = lines * 4; + ibData[i + 1] = lines * 4 + 1; + ibData[i + 2] = lines * 4 + 2; + ibData[i + 3] = lines * 4 + 2; + ibData[i + 4] = lines * 4 + 3; + ibData[i + 5] = lines * 4; + + lines++; + } + + static function begin() { + lines = 0; + vbData = vertexBuffer.lock(); + ibData = indexBuffer.lock(); + } + + static function end() { + vertexBuffer.unlock(); + indexBuffer.unlock(); + + g.setVertexBuffer(vertexBuffer); + g.setIndexBuffer(indexBuffer); + g.setPipeline(pipeline); + var camera = iron.Scene.active.camera; + vp.setFrom(camera.V); + vp.multmat(camera.P); + g.setMatrix(vpID, vp.self); + g.drawIndexedVertices(0, lines * 6); + } + + inline static function addVbData(i: Int, data: Array) { + for (offset in 0...6) { + vbData.set(i + offset, data[offset]); + } + } +} diff --git a/Sources/arm/render/RenderPathDeferred.hx b/Sources/arm/render/RenderPathDeferred.hx index 469b629c..2058b02c 100644 --- a/Sources/arm/render/RenderPathDeferred.hx +++ b/Sources/arm/render/RenderPathDeferred.hx @@ -616,6 +616,7 @@ class RenderPathDeferred { path.setTarget("gbuffer2"); path.clearTarget(0xff000000); path.setTarget("gbuffer0", ["gbuffer1", "gbuffer2"]); + var currentG = path.currentG; #if arm_painter RenderPathPaint.bindLayers(); #end @@ -623,6 +624,7 @@ class RenderPathDeferred { #if arm_painter RenderPathPaint.unbindLayers(); #end + LineDraw.render(currentG); } static function drawSplit() { diff --git a/Sources/arm/render/RenderPathForward.hx b/Sources/arm/render/RenderPathForward.hx index 1cb04b03..72637be2 100644 --- a/Sources/arm/render/RenderPathForward.hx +++ b/Sources/arm/render/RenderPathForward.hx @@ -69,6 +69,7 @@ class RenderPathForward { path.setTarget("gbuffer2"); path.clearTarget(0xff000000); path.setTarget("gbuffer0", ["gbuffer1", "gbuffer2"]); + var currentG = path.currentG; #if arm_painter RenderPathPaint.bindLayers(); #end @@ -76,6 +77,7 @@ class RenderPathForward { #if arm_painter RenderPathPaint.unbindLayers(); #end + LineDraw.render(path.currentG); } static function drawForward() { diff --git a/Sources/arm/render/Uniforms.hx b/Sources/arm/render/Uniforms.hx index 2a9360a5..80d0e628 100644 --- a/Sources/arm/render/Uniforms.hx +++ b/Sources/arm/render/Uniforms.hx @@ -333,10 +333,8 @@ class Uniforms { if (link == "_decalLayerMatrix") { // Decal layer var camera = Scene.active.camera; var m = iron.object.Uniforms.helpMat; - m.setFrom(object.transform.worldUnpack); - var V = Mat4.identity(); - V.setLookAt(new Vec4(Context.layer.projectX, -5, Context.layer.projectZ), new Vec4(Context.layer.projectX, 0, Context.layer.projectZ), new Vec4(0, 0, 1)); - m.multmat(V); + m.setFrom(Context.layer.decalMat); + m.getInverse(m); m.multmat(camera.P); return m; } diff --git a/khafile.js b/khafile.js index 69ee72ab..c8a190e6 100644 --- a/khafile.js +++ b/khafile.js @@ -57,7 +57,6 @@ else if (process.platform === "darwin") { if (debug) { project.addDefine("arm_debug"); - project.addShaders("Shaders/debug/*.glsl"); project.addParameter("--times"); // project.addParameter("--no-inline"); }