我正在使用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];
这几乎肯定会起作用,它确实以书面形式回答了问题(谢谢)。我现在可能会以这种方式解决我的问题(并接受答案),但我希望将问题延长一段时间以防其他人想要权衡。我认为理想情况下我更愿意1.理解为什么backbuffer解决方案工作不正常,2.能够做到这一点“可可方式”,所以我可以在另一个使用CG而不是GL的相关项目上使用它。 – andrew
我用一个例子说明了如何在可可中实现功能相当的事情(对非GL内容有用)。它工作得很好,但有点慢。 – andrew