Пример взят из https://medium.com/@s1ddok / comb-the-power-of-coregraphics-and-metal-by-sharing-resource-memory-eabb4c1be615 . Просто изменил цветовое пространство с r8unorm на rgba8unorm.
// CGContext created with aligned data, which shared with MTLTexture
let cgContext = textureContext.cgContext
let clearRect = CGRect(
origin: .zero,
size: CGSize(width: cgContext.width, height: cgContext.height)
)
cgContext.setAllowsAntialiasing(true)
cgContext.setShouldAntialias(true)
cgContext.clear(clearRect)
cgContext.addPath(path)
cgContext.setFillColor(fillColor ?? UIColor.clear.cgColor)
cgContext.fillPath(using: fillRule.cgFillRuleValue())
Отображаемый путь к общему блоку данных, а затем используется в качестве текстуры для четырехугольного примитива, отображаемого на текстуре MTKView. Но есть проблема - сглаживание будет смешивать цвет заливки пути с прозрачным (черным) цветом на краях, как это (надеюсь, если разница между этими изображениями заметна) -
Это нормально перекрытие, когда я предварительно заполняю область контекста красным цветом
Если сглаживание отключено для контекста - края будут явно белыми, но резкими
Есть ли способ для перекрытия двух текстур с четкими и гладкими краями без рендеринга соответствующего фрагмента перекрывающейся текстуры в перекрывающуюся текстуру перед рисованием контура?
UPD: как создается контекст
func createCGMTLContext(withSize size: CGSize) -> CGMTLContext? {
let width = Int(size.width)
let height = Int(size.height)
let pixelRowAlignment = device.minimumTextureBufferAlignment(for: .rgba8Unorm)
let bytesPerRow = alignUp(size: width, align: pixelRowAlignment) * 4
let pagesize = Int(getpagesize())
let allocationSize = alignUp(size: bytesPerRow * height, align: pagesize)
var data: UnsafeMutableRawPointer? = nil
let result = posix_memalign(&data, pagesize, allocationSize)
if result != noErr {
fatalError("Error during memory allocation")
}
let context = CGContext(data: data,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: bytesPerRow,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!
context.scaleBy(x: 1.0, y: -1.0)
context.translateBy(x: 0, y: -CGFloat(context.height))
let buffer = device.makeBuffer(
bytesNoCopy: context.data!,
length: allocationSize,
options: .storageModeShared,
deallocator: { pointer, length in free(data) }
)!
let textureDescriptor = MTLTextureDescriptor()
textureDescriptor.pixelFormat = .rgba8Unorm
textureDescriptor.width = context.width
textureDescriptor.height = context.height
textureDescriptor.storageMode = buffer.storageMode
textureDescriptor.usage = .shaderRead
let texture = buffer.makeTexture(descriptor: textureDescriptor,
offset: 0,
bytesPerRow: context.bytesPerRow)
guard let requiredTexture = texture else {
return nil
}
let cgmtlContext = CGMTLContext(
cgContext: context,
buffer: buffer,
texture: requiredTexture
)
return cgmtlContext
}
Вот как смешивается металл настроено
1025 *