2015-02-08 3 views
8

Я стараюсь работать с классом SKMutableTexture от SpriteKit, но я не знаю, как работать с UnsafeMutablePointer<Void>. У меня есть неопределенная идея, что это указатель на последовательность байтовых данных в памяти. Но как я могу его обновить? Что бы это на самом деле выглядело в коде?Что такое UnsafeMutablePointer <Void>? Как изменить базовую память?

Редактировать

Вот основной пример кода для работы с. Как мне заставить это сделать что-то так же просто, как создать красный квадрат на экране?

let tex = SKMutableTexture(size: CGSize(width: 10, height: 10)) 
    tex.modifyPixelDataWithBlock { (ptr:UnsafeMutablePointer<Void>, n:UInt) -> Void in 

     /* ??? */ 

    } 

ответ

12

Из документов для SKMutableTexture.modifyPixelDataWithBlock:

Текстура байтов предполагаются быть сохранены в виде плотно набитый 32 бит на пиксел, 8bpc (целое без знака) данных RGBA пикселов. Компоненты цвета, которые вы предоставляете, должны быть уже умножены на альфа-значение.

Итак, если вам даны void*, базовые данные представлены в виде потока 4x8 бит.

Вы могли бы управлять такой структурой, как так:

// 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

Просто попробовал это с примером проекта SpriteKit в Xcode и, похоже, поступил правильно, но я ничего не знаю о SpriteKit, поэтому не могу гарантировать, что это «способ» сделать это. –

+0

Спасибо, что это работает. Однако теперь я вижу квадрат на экране, но ожидал, что метод modifyPixelDataWithBlock будет вызываться один раз для каждого кадра - как альтернатива фрагментатору, но блок вызывается только один раз. Больше копания ... – Bret

+0

Обратите внимание, что вам нужно передать предварительно умноженные значения альфа для части RGB. Из документа [docs] (https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKMutableTexture_Ref/# // apple_ref/occ/instm/SKMutableTexture/modifyPixelDataWithBlock :) 'Предполагается, что байты текстуры хранятся как плотно упакованные 32 bpp, 8bpc (unsigned integer) RGBA-пиксель данные. Компоненты цвета, которые вы предоставляете, должны быть уже умножены на альфа-значение. ' – Benzi

7

UnsafeMutablePointer<Void> является Swift эквивалент void* - указатель на что-либо вообще. Вы можете получить доступ к основной памяти как к свойству memory. Как правило, если вы знаете, что такое базовый тип, вы сначала будете принуждать к указателю на этот тип. Затем вы можете использовать subscriptip для достижения определенного «слота» в памяти.

Например, если данные действительно последовательность значений Uint8, можно сказать:

let buffer = UnsafeMutablePointer<UInt8>(ptr) 

Теперь Вы можете получить доступ к отдельным значения UIInt8 в buffer[0], buffer[1], и так далее.

+0

И увидеть мой Swift учебник для получения дополнительной информации: http://www.apeth.com/swiftBook/apa.html#_c_pointers – matt

+0

Судя по методу подпись [modifyPixelDataWithBlock] (https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKMutableTexture_Ref/index.html#//apple_ref/occ/instm/SKMutableTexture/modifyPixelDataWithBlock :), я думаю, что базовая type - 8-битное целое число. Что бы на самом деле было похоже на код? Я действительно надеюсь на некоторые примеры кода, как это сделать. – Bret

+0

Если это 8-битное целое число, это будет Int8 или UInt8. Поэтому, если вы примените к UnsafeMutablePointer или UnsafeMutablePointer , в зависимости от того, что это такое, вы можете использовать подписку, чтобы получить индивидуальный байт по номеру. – matt