mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-07-13 08:12:54 +02:00
feat: generate quad texture programmatically
This commit is contained in:
@@ -77,7 +77,7 @@ struct PipelineStates {
|
|||||||
let library = renderer.library
|
let library = renderer.library
|
||||||
let pipelineDescriptor = MTLRenderPipelineDescriptor()
|
let pipelineDescriptor = MTLRenderPipelineDescriptor()
|
||||||
pipelineDescriptor.vertexFunction = library.makeFunction(name: "vertex_stroke")
|
pipelineDescriptor.vertexFunction = library.makeFunction(name: "vertex_stroke")
|
||||||
pipelineDescriptor.fragmentFunction = library.makeFunction(name: "fragment_stroke")
|
pipelineDescriptor.fragmentFunction = library.makeFunction(name: "fragment_stroke_eraser")
|
||||||
pipelineDescriptor.colorAttachments[0].pixelFormat = pixelFormat ?? renderer.pixelFormat
|
pipelineDescriptor.colorAttachments[0].pixelFormat = pixelFormat ?? renderer.pixelFormat
|
||||||
pipelineDescriptor.label = "Eraser Pipeline State"
|
pipelineDescriptor.label = "Eraser Pipeline State"
|
||||||
|
|
||||||
|
|||||||
@@ -83,13 +83,17 @@ extension Stroke {
|
|||||||
extension Stroke {
|
extension Stroke {
|
||||||
func prepare(device: MTLDevice) {
|
func prepare(device: MTLDevice) {
|
||||||
guard texture == nil else { return }
|
guard texture == nil else { return }
|
||||||
texture = penStyle.loadTexture(on: device)
|
if penStyle.textureName != nil {
|
||||||
|
texture = penStyle.loadTexture(on: device)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func draw(device: MTLDevice, renderEncoder: MTLRenderCommandEncoder) {
|
func draw(device: MTLDevice, renderEncoder: MTLRenderCommandEncoder) {
|
||||||
guard !isEmpty, let indexBuffer else { return }
|
guard !isEmpty, let indexBuffer else { return }
|
||||||
prepare(device: device)
|
prepare(device: device)
|
||||||
renderEncoder.setFragmentTexture(texture, index: 0)
|
if penStyle.textureName != nil {
|
||||||
|
renderEncoder.setFragmentTexture(texture, index: 0)
|
||||||
|
}
|
||||||
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
|
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
|
||||||
renderEncoder.drawIndexedPrimitives(
|
renderEncoder.drawIndexedPrimitives(
|
||||||
type: .triangle,
|
type: .triangle,
|
||||||
|
|||||||
@@ -52,5 +52,6 @@ class PhotoBackgroundRenderPass: RenderPass {
|
|||||||
|
|
||||||
renderEncoder.endEncoding()
|
renderEncoder.endEncoding()
|
||||||
commandBuffer.commit()
|
commandBuffer.commit()
|
||||||
|
commandBuffer.waitUntilCompleted()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,5 +41,6 @@ class PhotoRenderPass: RenderPass {
|
|||||||
|
|
||||||
renderEncoder.endEncoding()
|
renderEncoder.endEncoding()
|
||||||
commandBuffer.commit()
|
commandBuffer.commit()
|
||||||
|
commandBuffer.waitUntilCompleted()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class ViewPortRenderPass: RenderPass {
|
|||||||
renderEncoder.setRenderPipelineState(viewPortUpdatePipelineState)
|
renderEncoder.setRenderPipelineState(viewPortUpdatePipelineState)
|
||||||
|
|
||||||
renderEncoder.setFragmentTexture(photoBackgroundTexture, index: 0)
|
renderEncoder.setFragmentTexture(photoBackgroundTexture, index: 0)
|
||||||
canvas.renderViewPort(device: renderer.device, renderEncoder: renderEncoder)
|
canvas.renderViewPortUpdate(device: renderer.device, renderEncoder: renderEncoder)
|
||||||
|
|
||||||
renderEncoder.setFragmentTexture(cacheTexture, index: 0)
|
renderEncoder.setFragmentTexture(cacheTexture, index: 0)
|
||||||
canvas.renderViewPortUpdate(device: renderer.device, renderEncoder: renderEncoder)
|
canvas.renderViewPortUpdate(device: renderer.device, renderEncoder: renderEncoder)
|
||||||
|
|||||||
@@ -53,3 +53,21 @@ fragment float4 fragment_stroke(
|
|||||||
float4 color = float4(texture.sample(textureSampler, out.textCoord));
|
float4 color = float4(texture.sample(textureSampler, out.textCoord));
|
||||||
return float4(1, 1, 1, color.a);
|
return float4(1, 1, 1, color.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fragment float4 fragment_stroke_eraser(
|
||||||
|
VertexOut out [[stage_in]],
|
||||||
|
texture2d<float> texture [[texture(0)]]
|
||||||
|
) {
|
||||||
|
float2 circleCenter = float2(0.5, 0.5);
|
||||||
|
float radius = 0.4;
|
||||||
|
float4 circleColor = float4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
float2 fragCoord = out.textCoord;
|
||||||
|
float distance = length(fragCoord - circleCenter);
|
||||||
|
|
||||||
|
if (distance < radius) {
|
||||||
|
return circleColor;
|
||||||
|
} else {
|
||||||
|
return float4(0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Foundation
|
|||||||
|
|
||||||
protocol PenStyle {
|
protocol PenStyle {
|
||||||
var icon: (base: String, tip: String?) { get }
|
var icon: (base: String, tip: String?) { get }
|
||||||
var textureName: String { get }
|
var textureName: String? { get }
|
||||||
var thickness: (min: CGFloat, max: CGFloat) { get }
|
var thickness: (min: CGFloat, max: CGFloat) { get }
|
||||||
var thicknessSteps: [CGFloat] { get }
|
var thicknessSteps: [CGFloat] { get }
|
||||||
var color: [CGFloat] { get }
|
var color: [CGFloat] { get }
|
||||||
@@ -22,6 +22,7 @@ protocol PenStyle {
|
|||||||
extension PenStyle {
|
extension PenStyle {
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func loadTexture(on device: MTLDevice) -> MTLTexture? {
|
func loadTexture(on device: MTLDevice) -> MTLTexture? {
|
||||||
Textures.createPenTexture(with: textureName, on: device)
|
guard let textureName else { return nil }
|
||||||
|
return Textures.createPenTexture(with: textureName, on: device)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Foundation
|
|||||||
struct EraserPenStyle: PenStyle {
|
struct EraserPenStyle: PenStyle {
|
||||||
var icon: (base: String, tip: String?) = ("eraser", nil)
|
var icon: (base: String, tip: String?) = ("eraser", nil)
|
||||||
|
|
||||||
var textureName: String = "point-texture"
|
var textureName: String? = nil
|
||||||
|
|
||||||
var thickness: (min: CGFloat, max: CGFloat) = (0.5, 30)
|
var thickness: (min: CGFloat, max: CGFloat) = (0.5, 30)
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Foundation
|
|||||||
struct MarkerPenStyle: PenStyle {
|
struct MarkerPenStyle: PenStyle {
|
||||||
var icon: (base: String, tip: String?) = ("marker-base", "marker-tip")
|
var icon: (base: String, tip: String?) = ("marker-base", "marker-tip")
|
||||||
|
|
||||||
var textureName: String = "point-texture"
|
var textureName: String? = "point-texture"
|
||||||
|
|
||||||
var thickness: (min: CGFloat, max: CGFloat) = (0.5, 30)
|
var thickness: (min: CGFloat, max: CGFloat) = (0.5, 30)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user