当我将 MTKView 的内容捕获到 UIImage 中时,生成的图像看起来有质的不同,如下所示:
我用来生成 UIImage 的代码如下:
let kciOptions = [kCIContextWorkingColorSpace: CGColorSpace(name: CGColorSpace.sRGB)!,
kCIContextOutputPremultiplied: true,
kCIContextUseSoftwareRenderer: false] as [String : Any]
let lastDrawableDisplayed = self.currentDrawable! // needed to hold the last drawable presented to screen
drawingUIView.image = UIImage(ciImage: CIImage(mtlTexture: lastDrawableDisplayed.texture, options: kciOptions)!)
Run Code Online (Sandbox Code Playgroud)
由于我没有修改 ciImage 方向 (.orientation(CGImagePropertyOrientation.downMirrored)),因此生成的图像是颠倒的,如上图所示。我保持镜像方向不变,以便我可以指出两个图像捕获之间的颜色差异。
无论我如何更改 kciOptions 参数(例如,甚至将色彩空间更改为灰度),我都没有看到生成的 UIImage 有任何变化,它看起来比原始图像更暗/不饱和。有人对我如何准确地将我在 MTKView 上绘制的内容捕获到 UIImage 有任何建议吗?任何建议将不胜感激。
以下是我可能证明相关的 MTKView 设置:
let renderPipelineDescriptor = MTLRenderPipelineDescriptor()
renderPipelineDescriptor.vertexFunction = vertexProgram
renderPipelineDescriptor.sampleCount = self.sampleCount
renderPipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormat.bgra8Unorm
renderPipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
renderPipelineDescriptor.colorAttachments[0].rgbBlendOperation = .add
renderPipelineDescriptor.colorAttachments[0].alphaBlendOperation = …Run Code Online (Sandbox Code Playgroud) 我正在开发一个绘画程序,通过 MTKView 绘制交互式笔画。如果我将 renderPassDescriptor loadAction 设置为“clear”:
renderPassDescriptor?.colorAttachments[0].loadAction = .clear
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,帧缓冲区显示 的最新内容renderCommandEncoder?.drawPrimitives,在本例中是笔触的前缘。
如果我将 loadAction 设置为“加载”:
renderPassDescriptor?.colorAttachments[0].loadAction = .load
Run Code Online (Sandbox Code Playgroud)
帧缓冲区疯狂地闪烁,并显示出我刚刚绘制的斑驳痕迹。我现在明白闪烁可能是由 MTKView 的默认三重缓冲造成的。因此,每次写入 currentDrawable 时,我可能会写入 3 个循环缓冲区之一。如果我错了,请纠正我。
我的问题是,我需要做什么才能绘制干净的笔触而不像现在那样帧缓冲区闪烁?换句话说,有没有办法让主缓冲区使用 commandEncoder 的最新内容进行更新?
我有兴趣将视频上传到youtube以及标题,说明和关键字.下面的代码将视频上传到youtube而没有任何属性:
func postVideoToYouTube(token: String, callback: Bool -> Void){
let headers = ["Authorization": "Bearer \(token)"]
let urlYoutube = "https://www.googleapis.com/upload/youtube/v3/videos?part=id"
let path = NSBundle.mainBundle().pathForResource("video", ofType: "mp4")
let videodata: NSData = NSData.dataWithContentsOfMappedFile(path!)! as! NSData
upload(
.POST,
urlYoutube,
headers: headers,
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(data: videodata, name: "video", fileName: "video.mp4", mimeType: "application/octet-stream")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { request, response, error in
print(response)
callback(true)
}
case .Failure(_):
callback(false)
}
})
Run Code Online (Sandbox Code Playgroud)
}
我一直在尝试修改urlYoutube以包含必要的代码段信息无效:
let snippetTitle = …Run Code Online (Sandbox Code Playgroud) 我正在通过 MTKView 合成 UIImage 数组,并且我看到刷新问题仅在合成阶段显现出来,但一旦我与应用程序交互,这些问题就会消失。换句话说,复合材料按预期工作,但它们在屏幕上的外观看起来有点问题,直到我通过放大/平移等强制刷新。
我发布了两个视频来展示实际问题:Glitch1、Glitch2
我选择的复合方法是将每个 UIImage 转换为 MTLTexture,并将其提交到设置为“.load”的渲染缓冲区,该缓冲区会渲染带有此纹理的多边形,然后对 UIImage 中的每个图像重复该过程大批。
复合材料可以工作,但是屏幕反馈(正如您从视频中看到的那样)非常不稳定。
关于可能发生的事情有什么想法吗?任何建议,将不胜感激
一些相关代码:
for strokeDataCurrent in strokeDataArray {
let strokeImage = UIImage(data: strokeDataCurrent.image)
let strokeBbox = strokeDataCurrent.bbox
let strokeType = strokeDataCurrent.strokeType
self.brushStrokeMetal.drawStrokeImage(paintingViewMetal: self.canvasMetalViewPainting, strokeImage: strokeImage!, strokeBbox: strokeBbox, strokeType: strokeType)
} // end of for strokeDataCurrent in strokeDataArray
...
func drawStrokeUIImage (strokeUIImage: UIImage, strokeBbox: CGRect, strokeType: brushTypeMode) {
// set up proper compositing mode fragmentFunction
self.updateRenderPipeline(stampCompStyle: drawStampCompMode)
let stampTexture = UIImageToMTLTexture(strokeUIImage: strokeUIImage)
let stampColor = UIColor.white …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个金属支持的绘图应用程序,通过沿着路径重复标记一个带纹理的正方形,在 MTKView 上绘制笔触。我遇到的问题是,虽然每个画笔图章都正确显示了纹理的不透明度,但重叠的方块不会建立价值,而是相互覆盖。在下面的标题中,每个图章都是一个带有 alpha 分量的带纹理的圆圈
我有一种感觉,因为所有的图章都被一次渲染,渲染器无法“建立”价值。然而,我对我的金属专业知识有点不了解,所以我希望有人能指出我正确的方向。
以下是更多相关信息:
对于单个画笔笔划,所有几何图形都存储在包含所有正方形图章(每个正方形由 2 个三角形组成)的数组 vertexArrayBrush3DMesh 中。每个顶点的坐标的 z 值为 0.0,这意味着它们都占据相同的 3d“平面”。这可能是一个问题吗?(我测试了放置随机 z 值,但我没有看到行为的视觉差异)
下面是我的 renderPipeline 设置。请注意,“.isBlendingEnabled = true”和“.alphaBlendingOperation = .add”都被注释掉了,因为它们对解决我的问题没有影响
// 5a. Define render pipeline settings
let renderPipelineDescriptor = MTLRenderPipelineDescriptor()
renderPipelineDescriptor.vertexFunction = vertexProgram
renderPipelineDescriptor.sampleCount = self.sampleCount
renderPipelineDescriptor.colorAttachments[0].pixelFormat = self.colorPixelFormat
//renderPipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
//renderPipelineDescriptor.colorAttachments[0].alphaBlendOperation = .add
renderPipelineDescriptor.fragmentFunction = fragmentProgram
Run Code Online (Sandbox Code Playgroud)
请注意,将以下属性添加到 renderPassDescriptor 确实对设置整个画布的透明度有影响
// ensure canvas is transparent
renderPassDescriptor?.colorAttachments[0].loadAction = .clear
renderPassDescriptor?.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0)
Run Code Online (Sandbox Code Playgroud)
下面是我进行渲染的代码部分。
func metalRenderColoredMesh(){
// the key to this routine is …Run Code Online (Sandbox Code Playgroud) 我正在尝试以设备允许的速度将随机网格渲染到 MTKView .. 我发现的几乎所有金属示例都展示了如何绘制仅定义一次缓冲区大小(即固定)的几何图形:
let dataSize = vertexCount * MemoryLayout<VertexWithColor>.size // size of the vertex data in bytes
let vertexBuffer: MTLBuffer = device!.makeBuffer(bytes: verticesWithColorArray, length: dataSize, options: []) // create a new buffer on the GPU
Run Code Online (Sandbox Code Playgroud)
目标是最终在给定一些点云输入的情况下动态生成网格。我已将绘图设置为通过点击触发,如下所示:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let touchPoint = touch.location(in: view)
print ("...touch \(touchPoint)")
autoreleasepool {
delaunayView.setupTriangles()
delaunayView.renderTriangles()
}
}
}
Run Code Online (Sandbox Code Playgroud)
我可以用新的三角形刷新屏幕,只要我不要太频繁地点击。但是,如果我点击太快(比如双击),应用程序会崩溃并显示以下错误:
[CAMetalLayerDrawable texture] should not be called after presenting the drawable.
Run Code Online (Sandbox Code Playgroud)
性能显然与绘制的三角形数量有关。除了让应用程序稳定运行之外,同样重要的问题是,我怎样才能最好地利用 GPU …
metal ×5
swift ×5
metalkit ×2
swift3 ×2
alamofire ×1
buffer ×1
frame-rate ×1
gpu ×1
mtkview ×1
uiimageview ×1
youtube ×1
youtube-api ×1