#iphone #opengl-es
#iPhone #opengl-es
Вопрос:
у меня есть glview в моем uiview, теперь я должен сделать предварительный снимок комбинированного просмотра uiview и glview. я много гуглил, но не нашел ничего полезного, я знаю, как сделать снимок экрана glview
nt width = glView.frame.size.width; int height = glView.frame.size.height;
NSInteger myDataLength = width * height * 4;
// allocate array and read pixels into it.
GLubyte *buffer = (GLubyte *) malloc(myDataLength);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// gl renders "upside down" so swap top to bottom into new array.
// there's gotta be a better way, but this works.
GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
for(int y = 0; y < height; y )
{
for(int x = 0; x < width * 4; x )
{
buffer2[((height - 1) - y) * width * 4 x] = buffer[y * 4 * width x];
}
}
// make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL);
// prep the ingredients
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefau<
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefau<
// make the cgimage
CGImageRef imageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
// then make the uiimage from that
UIImage *myImage = [UIImage imageWithCGImage:imageRef];
return myImage;
Ответ №1:
Кажется, что в наши дни довольно сложно получить скриншот, особенно когда вы смешиваете UIKit и OpenGL ES: раньше было, UIGetScreenImage()
но Apple снова сделала его приватным и отклоняет приложения, которые его используют.
Вместо этого есть два «решения» для его замены: захват экрана в приложениях UIKit и моментальный снимок OpenGL ES View. Первый не захватывает OpenGL ES или видеоконтент, в то время как более поздний — только для OpenGL ES.
Есть еще одно техническое примечание, как мне сделать снимок экрана моего приложения, которое содержит как элементы UIKit, так и камеры?, и здесь они по сути говорят: вам нужно сначала сделать снимок с камеры, а затем при рендеринге иерархии представлений нарисовать это изображение в контексте.
То же самое применимо и к OpenGL ES: сначала вам нужно будет сделать снимок для вашего представления OpenGL ES, затем отобразить иерархию представлений UIKit в контексте изображения и нарисовать поверх нее изображение вашего представления OpenGL ES. Очень некрасиво, и в зависимости от вашей иерархии представлений на самом деле это может быть не то, что вы видите на экране (например, если перед вашим представлением OpenGL есть представления).
Комментарии:
1. @ DarkDust: — очень полезный ответ ….. привет, у меня проблема с захватом OpenGL es с использованием glReadPixels ….вызов glReadPixels () снижает частоту кадров в секунду примерно с 30 до 2-3 …. почему?
2. @Tornado: Понятия не имею, но в целом Apple заявляет, что ее реализация OpenGL ES настроена на операции записи, а чтение любого состояния происходит медленно, и этого следует избегать. Лучше запоминать состояния, о которых вы заботитесь сами, а не запрашивать их. Конечно, это невозможно сделать для
glReadPixels
, но я думаю, вам следует попытаться уменьшить количество обращений к нему, если это возможно.3. @ DarkDust k привет, я пытаюсь записать игровой процесс моей игры, чтобы я мог загружать видео на YouTube с самого устройства … пытаюсь сделать то же самое, что приложение Talking tomcat для iphone .. записывать видео, затем воспроизводить его и т.д. … я думаю, что это приложение также создано с помощью Opengl ES, В нем также есть функция записи видео, но оно не замедляется при чтении каждого кадра есть идеи?
4. @Tornado: Нет, пожалуйста, задайте новый вопрос по этому поводу.
Ответ №2:
Вдохновленный DarkDust, я успешно реализовал захват экрана в сочетании uiview и openglview (просмотр cocos2d 2.0). Я немного переработал код и вставил ниже, надеюсь, это полезно для других.
Чтобы помочь объяснить настройку, экран моего приложения имеет 4 слоя просмотра: задняя часть — фоновый UIView с фоновыми изображениями «backgroundLayer», средняя — 2 слоя Cocos2d glview «glLayer1 и glLayer2»; и передняя часть — еще один слой UIView с несколькими элементами управления пользовательского интерфейса (например, UIButtons) «frontView».
Вот код:
(UIImage *) grabScreenshot
{
// Get the 2 layers in the middle of cocos2d glview and store it as UIImage
[CCDirector sharedDirector].nextDeltaTimeZero = YES;
CGSize winSize = [CCDirector sharedDirector].winSize;
CCRenderTexture* rtx =
[CCRenderTexture renderTextureWithWidth:winSize.width
height:winSize.height];
[rtx begin];
[glLayer1 visit];
[glLayer2 visit];
[rtx end];
UIImage *openglImage = [rtx getUIImage];
UIGraphicsBeginImageContext(winSize);
// Capture the bottom layer
[backgroundView.layer renderInContext:UIGraphicsGetCurrentContext()];
// Save the captured glLayers image to the image context
[openglImage drawInRect:CGRectMake(0, 0, openglImage.size.width, openglImage.size.height)];
[frontView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}