私はGLPaintの例に似たアプリを持っています(ただしOpenGL ES 2.0上)。しばらくして、図面ビューのスクリーンショットを取得したいと考えています。私はすでにこのトピックを読みました
しかし、どの時点で CVOpenGLESTextureCacheCreate を呼び出して他のことを行うべきかわかりません。誰が私を助けてくれますか?
私はGLPaintの例に似たアプリを持っています(ただしOpenGL ES 2.0上)。しばらくして、図面ビューのスクリーンショットを取得したいと考えています。私はすでにこのトピックを読みました
しかし、どの時点で CVOpenGLESTextureCacheCreate を呼び出して他のことを行うべきかわかりません。誰が私を助けてくれますか?
リンク先の回答で説明しているコードは、ピクセルバッファーの作成、それに一致するテクスチャの抽出、およびフレームバッファーの出力としてのそのテクスチャのバインドについて説明しています。そのコードを1回使用して、シーンをレンダリングするフレームバッファを設定します。
そのテクスチャからキャプチャする場合は常に、glFinish()
すべてのOpenGL ESレンダリングが完了するまでブロックしてから、そこで説明するコードを使用することをお勧めします。
CVPixelBufferLockBaseAddress(renderTarget, 0);
_rawBytesForImage = (GLubyte *)CVPixelBufferGetBaseAddress(renderTarget);
// Do something with the bytes
CVPixelBufferUnlockBaseAddress(renderTarget, 0);
シーンの画像を含むテクスチャの生のバイトを抽出します。
iOSテクスチャの内部バイト順序はBGRAであるため、次のようなものを使用して、これらのバイトからCGImageRefを作成する必要があります。
// It appears that the width of a texture must be padded out to be a multiple of 8 (32 bytes) if reading from it using a texture cache
NSUInteger paddedWidthOfImage = CVPixelBufferGetBytesPerRow(renderTarget) / 4.0;
NSUInteger paddedBytesForImage = paddedWidthOfImage * (int)currentFBOSize.height * 4;
dataProvider = CGDataProviderCreateWithData((__bridge_retained void*)self, _rawBytesForImage, paddedBytesForImage, dataProviderUnlockCallback);
cgImageFromBytes = CGImageCreate((int)currentFBOSize.width, (int)currentFBOSize.height, 8, 32, CVPixelBufferGetBytesPerRow(renderTarget), defaultRGBColorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst, dataProvider, NULL, NO, kCGRenderingIntentDefault);
上記でdataProviderUnlockCallback()
は、ピクセルバッファのロック解除とレンダリングの安全な再開を処理する関数を使用していますが、おそらくそれを無視して、パラメータにNULLを渡すだけです。