2013-08-27 49 views
0

我正在使用OSX/Cocoa图形应用程序(出于性能原因),我想在用户选择“全屏”模式时以640x480进行渲染。对于它的价值,内容是使用openGL绘制的自定义NSView。如何以特定的分辨率以编程方式呈现全屏的OpenGL?

我明白,而不是实际上改变用户的决议,最好改变backbuffer(如在另一个SO问题在这里解释:Programmatically change resolution OS X)。

遵循这个建议,我最终得到以下两种方法(见下文)在全屏和窗口之间切换。麻烦的是,当我全屏显示时,内容确实呈现为640x480,但没有缩放(IE看起来好像我们停留在窗口的分辨率并“缩放”为渲染的640x480的角落)。

我很可能在这里丢失了一些明显的东西 - 我想我可以根据实际的屏幕分辨率将渲染翻译到“中心”,但这似乎过于复杂?

- (void)goFullscreen{ 

    // Bounce if we're already fullscreen 
    if(_isFullscreen){return;} 

    // Save original size and position 
    NSRect frame = [self.window.contentView frame]; 
    original_size = frame.size; 
    original_position = frame.origin; 

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
         [NSNumber numberWithBool:NO],NSFullScreenModeAllScreens, 
         nil]; 

    // In lieu of changing resolution, we set the backbuffer to 640x480 
    GLint dim[2] = {640, 480}; 
    CGLSetParameter([[self openGLContext] CGLContextObj], kCGLCPSurfaceBackingSize, dim); 
    CGLEnable ([[self openGLContext] CGLContextObj], kCGLCESurfaceBackingSize); 

    // Go fullscreen! 
    [self enterFullScreenMode:[NSScreen mainScreen] withOptions:options]; 
    _isFullscreen=true; 

} 


- (void)goWindowed{ 

    // Bounce if we're already windowed 
    if(!_isFullscreen){return;} 

    // Reset backbuffer 
    GLint dim[2] = {original_size.width, original_size.height}; 
    CGLSetParameter([[self openGLContext] CGLContextObj], kCGLCPSurfaceBackingSize, dim); 
    CGLEnable ([[self openGLContext] CGLContextObj], kCGLCESurfaceBackingSize); 

    // Go windowed! 
    [self exitFullScreenModeWithOptions:nil]; 
    [self.window makeFirstResponder:self]; 
    _isFullscreen=false; 

} 

更新

这里现在做类似下面datenwolf的建议的东西,但不是用openGL(非GL的内容很有用)。

// Render into a specific size 
renderDimensions = NSMakeSize(640, 480); 
NSImage *drawIntoImage = [[NSImage alloc] initWithSize:renderDimensions]; 
[drawIntoImage lockFocus]; 
[self drawViewOfSize:renderDimensions]; 
[drawIntoImage unlockFocus]; 
[self syphonSendImage:drawIntoImage]; 

// Resize to fit preview area and draw 
NSSize newSize = NSMakeSize(self.frame.size.width, self.frame.size.height); 
[drawIntoImage setSize: newSize]; 
[[NSColor blackColor] set]; 

[self lockFocus]; 
[NSBezierPath fillRect:self.frame]; 
[drawIntoImage drawAtPoint:NSZeroPoint fromRect:self.frame operation:NSCompositeCopy fraction:1]; 
[self unlockFocus]; 

回答

4

在所述分辨率中使用具有所需目标分辨率的纹理的FBO并将其呈现给该FBO /纹理。然后切换到主帧缓冲区,并使用之前渲染的纹理绘制全屏四边形。使用你最喜欢的任何放大滤镜。如果你想带出大枪,你可以在片段着色器中实现一个Lancosz/sinc插入器来提升中间纹理。

+0

这几乎肯定会起作用,它确实以书面形式回答了问题(谢谢)。我现在可能会以这种方式解决我的问题(并接受答案),但我希望将问题延长一段时间以防其他人想要权衡。我认为理想情况下我更愿意1.理解为什么backbuffer解决方案工作不正常,2.能够做到这一点“可可方式”,所以我可以在另一个使用CG而不是GL的相关项目上使用它。 – andrew

+0

我用一个例子说明了如何在可可中实现功能相当的事情(对非GL内容有用)。它工作得很好,但有点慢。 – andrew

相关问题