Как вы визуализируете OpenGL-ES на внешний экран с помощью адаптера VGA? - PullRequest
0 голосов
/ 21 января 2011

Я занимаюсь разработкой 3D-программы для iPad и iPhone и хотел бы иметь возможность отображать ее на внешнем экране.Насколько я понимаю, вы должны сделать что-то похожее на приведенный ниже код для его реализации (находится по адресу: Sunsetlakesoftware.com ):

if ([[UIScreen screens] count] > 1)
{
    // External screen attached
}
else
{
    // Only local screen present
}

CGRect externalBounds = [externalScreen bounds];
externalWindow = [[UIWindow alloc] initWithFrame:externalBounds];

UIView *backgroundView = [[UIView alloc]  initWithFrame:externalBounds];
backgroundView.backgroundColor = [UIColor whiteColor];

[externalWindow addSubview:backgroundView];

[backgroundView release];

externalWindow.screen = externalScreen;
[externalWindow makeKeyAndVisible];

Однако я не уверенчто изменить, чтобы сделать это для проекта OpenGL.Кто-нибудь знает, что вы сделаете, чтобы реализовать это в проекте по умолчанию openGL для iPad или iPhone в XCode?

Ответы [ 2 ]

2 голосов
/ 22 января 2011

Все, что вам нужно сделать, чтобы визуализировать содержимое OpenGL ES на внешнем дисплее, это либо создать UIView, поддерживаемый CAEAGLLayer, и добавить его в качестве подпредставления выше backgroundView, либо взять такой вид и переместить быть подпредставлением backgroundView.

На самом деле вы можете удалить backgroundView, если хотите, и просто разместить представление OpenGL-хостинга непосредственно в externalWindow экземпляре UIWindow. Это окно прикреплено к экземпляру UIScreen, который представляет внешний дисплей, поэтому все, что размещено на нем, будет отображаться на этом дисплее. Это включает в себя содержимое OpenGL ES.

По-видимому, существует проблема с определенными типами контента OpenGL ES, как вы можете видеть в экспериментальной поддержке, которую я пытался добавить в мое приложение Molecules . Если вы посмотрите исходный код там, я попытаюсь перенести мой вид рендеринга на внешний дисплей, но он никогда не появляется. Я проделал то же самое с другими приложениями OpenGL ES, и их содержимое хорошо отображалось, поэтому я считаю, что может быть проблема с буфером глубины на внешнем дисплее. Я все еще работаю, чтобы отследить это.

1 голос
/ 24 января 2011

Я выяснил, как получить ЛЮБОЙ контент OpenGL-ES для рендеринга на внешний дисплей.Это на самом деле очень просто.Вы просто копируете свой рендер-буфер в UIImage, а затем отображаете этот UIImage на внешнем экране.Ниже приведен код для создания снимка вашего буфера рендеринга:

- (UIImage*)snapshot:(UIView*)eaglview
{
// Get the size of the backing CAEAGLLayer
GLint backingWidth, backingHeight;
glBindRenderbufferOES(GL_RENDERBUFFER_OES, defaultFramebuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

NSInteger x = 0, y = 0, width = backingWidth, height = backingHeight;
NSInteger dataLength = width * height * 4;
GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte));

// Read pixel data from the framebuffer
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);

// Create a CGImage with the pixel data
// If your OpenGL ES content is opaque, use kCGImageAlphaNoneSkipLast to ignore the alpha channel
// otherwise, use kCGImageAlphaPremultipliedLast
CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast,
                                ref, NULL, true, kCGRenderingIntentDefault);

// OpenGL ES measures data in PIXELS
// Create a graphics context with the target size measured in POINTS
NSInteger widthInPoints, heightInPoints;
if (NULL != UIGraphicsBeginImageContextWithOptions) {
    // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
    // Set the scale parameter to your OpenGL ES view's contentScaleFactor
    // so that you get a high-resolution snapshot when its value is greater than 1.0
    CGFloat scale = eaglview.contentScaleFactor;
    widthInPoints = width / scale;
    heightInPoints = height / scale;
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthInPoints, heightInPoints), NO, scale);
}
else {
    // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
    widthInPoints = width;
    heightInPoints = height;
    UIGraphicsBeginImageContext(CGSizeMake(widthInPoints, heightInPoints));
}

CGContextRef cgcontext = UIGraphicsGetCurrentContext();

// UIKit coordinate system is upside down to GL/Quartz coordinate system
// Flip the CGImage by rendering it to the flipped bitmap context
// The size of the destination area is measured in POINTS
CGContextSetBlendMode(cgcontext, kCGBlendModeCopy);
CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, widthInPoints, heightInPoints), iref);

// Retrieve the UIImage from the current context
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

// Clean up
free(data);
CFRelease(ref);
CFRelease(colorspace);
CGImageRelease(iref);

return image;
}

Хотя по какой-то причине мне никогда не удавалось получить glGetRenderbufferParameterivOES, чтобы вернуть правильную полосу пропускания и высоту, поэтому мне пришлось использоватьмоя собственная функция для их вычисления.Просто вставьте это в вашу реализацию рендеринга и поместите результат на внешний экран, используя таймер.Если кто-нибудь может внести какие-либо улучшения в этот метод, пожалуйста, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...