我有一个类似于GLPaint示例的应用程序(但在OpenGL ES 2.0上)。我希望在某些时刻获得绘图视图的屏幕截图。我已经阅读了这个topic
但我不明白我应该在什么时候调用CVOpenGLESTextureCacheCreate并做其他事情。谁可以帮助我?
答案 0 :(得分:2)
我在您链接的the answer中描述的代码描述了像素缓冲区的创建,其匹配纹理的提取以及该纹理作为帧缓冲区输出的绑定。您可以使用该代码一次来设置将渲染场景的帧缓冲区。
每当你想要从那个纹理中捕获时,你可能想要使用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。 / p>
答案 1 :(得分:0)
另一种选择是:
祝你好运!
修改强>
这可能不起作用:我现在正在测试它,并会尽快重新发布。
答案 2 :(得分:0)
试用with cte as (
select id, acronym, null as newid, id as baseid, 1 as lev,
cast(id as varchar(max)) as ids
from #GrwHist h
where newid is null
union all
select h.id, h.acronym, h.newid, cte.baseid, cte.lev + 1
cte.ids + ',' + cast(h.id as varchar(max)) as ids
from cte join
#GrwHist h
on h.new_id = cte.id
)
select baseid, ids
from (select cte.*, max(lev) over (partition by baseid) as maxlev
from cte
) cte
where maxlev = lev;
select baseid, id
from cte
order by baseid;
(适用于iOS 9.x +):
VTCreateCGImageFromCVPixelBuffer
指定将成为CGImage的图像数据源的像素缓冲区(将VideoToolbox
设置为NULL)。