What is UnsafeMutablePointer? How to modify the underlying memory?

后端 未结 2 1519
梦如初夏
梦如初夏 2020-12-28 22:33

I am trying to work with SpriteKit\'s SKMutableTexture class but I don\'t know how to work with UnsafeMutablePointer< Void >. I have a vague idea that it

相关标签:
2条回答
  • 2020-12-28 22:55

    UnsafeMutablePointer<Void> is the Swift equivalent of void* - a pointer to anything at all. You can access the underlying memory as its memory property. Typically, if you know what the underlying type is, you'll coerce to a pointer to that type first. You can then use subscripting to reach a particular "slot" in memory.

    For example, if the data is really a sequence of UInt8 values, you could say:

    let buffer = UnsafeMutablePointer<UInt8>(ptr)
    

    You can now access the individual UIInt8 values as buffer[0], buffer[1], and so forth.

    0 讨论(0)
  • 2020-12-28 23:08

    From the docs for SKMutableTexture.modifyPixelDataWithBlock:

    The texture bytes are assumed to be stored as tightly packed 32 bpp, 8bpc (unsigned integer) RGBA pixel data. The color components you provide should have already been multiplied by the alpha value.

    So, while you’re given a void*, the underlying data is in the form of a stream of 4x8 bits.

    You could manipulate such a structure like so:

    // struct of 4 bytes
    struct RGBA {
        var r: UInt8
        var g: UInt8
        var b: UInt8
        var a: UInt8
    }
    
    let tex = SKMutableTexture(size: CGSize(width: 10, height: 10))
    tex.modifyPixelDataWithBlock { voidptr, len in
        // convert the void pointer into a pointer to your struct
        let rgbaptr = UnsafeMutablePointer<RGBA>(voidptr)
    
        // next, create a collection-like structure from that pointer
        // (this second part isn’t necessary but can be nicer to work with)
        // note the length you supply to create the buffer is the number of 
        // RGBA structs, so you need to convert the supplied length accordingly...
        let pixels = UnsafeMutableBufferPointer(start: rgbaptr, count: Int(len / sizeof(RGBA))
    
        // now, you can manipulate the pixels buffer like any other mutable collection type
        for i in indices(pixels) {
            pixels[i].r = 0x00
            pixels[i].g = 0xff
            pixels[i].b = 0x00
            pixels[i].a = 0x20
        }
    }
    
    0 讨论(0)
提交回复
热议问题