首页 > 解决方案 > 如何使用指向 MTLBuffer Swift 适配的指针重新解释_cast

问题描述

我有一个 Objective-c 功能块,它使用(据我所知)一些额外的东西,我想在 Swift 中完全做到这一点。这是我开始的原始代码。(我试图使用 Swiftify 进行转换,但没有运气)不幸的是,这篇 SO 文章没有帮助:How to reinterpret_cast in Swift?

- (void)updateBuffers
{
    id<MTLBuffer> noiseBuffer = _noise[[self frameIndex]];
    RandomSample* ptr = reinterpret_cast<RandomSample*>([noiseBuffer contents]);
    for (NSUInteger i = 0; i < (NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE); ++i)
    {
        ptr->pixelSample.x = uniformFloatDistribution(randomGenerator);
        ptr->pixelSample.y = uniformFloatDistribution(randomGenerator);
        ptr->barycentricSample.x = uniformFloatDistribution(randomGenerator);
        ptr->barycentricSample.y = uniformFloatDistribution(randomGenerator);
        ptr->emitterBsdfSample.x = uniformFloatDistribution(randomGenerator);
        ptr->emitterBsdfSample.y = uniformFloatDistribution(randomGenerator);
        ptr->bsdfSample.x = uniformFloatDistribution(randomGenerator);
        ptr->bsdfSample.y = uniformFloatDistribution(randomGenerator);
        ptr->componentSample = uniformFloatDistribution(randomGenerator);
        ptr->emitterSample = uniformFloatDistribution(randomGenerator);
        ptr->rrSample = uniformFloatDistribution(randomGenerator);
        ++ptr;
    }
    [_noise[[self frameIndex]] didModifyRange:NSMakeRange(0, [noiseBuffer length])];


}

我假设,objective-c 代码用 Struct (RandomSample) 中的内容填充缓冲区的内容(使用 for 循环)。NOISE_BLOCK_SIZE 在这种情况下是 64

这就是我到目前为止所拥有的:

    func updateBuffers() {

        let noiseBuffer = noise[Int(frameIndex())] // MTLBuffer

        var randomStruct = RandomSample()
        // Here I should have this ptr (pointer) that like on objective-c

        for i in 0..<(NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE) {

            randomStruct.pixelSample.x          = Float.random(in: 0..<1)
            randomStruct.pixelSample.y          = Float.random(in: 0..<1)
            randomStruct.barycentricSample.x    = Float.random(in: 0..<1)
            randomStruct.barycentricSample.y    = Float.random(in: 0..<1)
            randomStruct.emitterBsdfSample.x    = Float.random(in: 0..<1)
            randomStruct.emitterBsdfSample.y    = Float.random(in: 0..<1)
            randomStruct.bsdfSample.x           = Float.random(in: 0..<1)
            randomStruct.bsdfSample.y           = Float.random(in: 0..<1)
            randomStruct.componentSample        = Float.random(in: 0..<1)
            randomStruct.emitterSample          = Float.random(in: 0..<1)
            randomStruct.rrSample               = Float.random(in: 0..<1)

        }

        // etc... etc...

    }

这是我要引用的 RandomSample 结构,在 .h 文件中定义(这是我的桥接头)

struct RandomSample
{
    simd_float2 pixelSample;
    simd_float2 barycentricSample;
    simd_float2 bsdfSample;
    simd_float2 emitterBsdfSample;
    float componentSample;
    float emitterSample;
    float rrSample;
};

而不是uniformFloatDistribution我使用的(在 Swift 代码 Float.random(in: 0..<1) 中)应该产生或多或少相同的结果。

标签: iosobjective-cswiftcastingmetal

解决方案


显然我无法在我的机器上验证这一点,但你应该能够做这样的事情。

var noiseRaw = noiseBuffer.contents()
let samples = noiseRaw.bindMemory(
    to: RandomSample.self,
    capacity: NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE
)

for i in 0..<NOISE_BLOCK_SIZE * NOISE_BLOCK_SIZE {
    let sample = samples + i
    sample.pointee.componentSample = Float.random(in: 0..<1)
    sample.pointee.emitterSample = Float.random(in: 0..<1)
    sample.pointee.rrSample = Float.random(in: 0..<1)
}

推荐阅读