纯C中的Cocoa OpenGL窗口?

我想在MacOSX中打开一个OpenGL窗口(以显示和抓取击键/鼠标事件)。

我不想使用Glut(因为它要求它是根线程)。

我不想学习目标C.

反正有无法在纯C中访问OpenGL API吗?

谢谢!

如果你想在OS X上获取事件,有几个选项:

  • SDL。 强烈推荐,C,不是很灵活。 您需要将其安装在您使用它的系统上,或者在您的应用程序包中包含该框架。
  • cocoa。 如果您需要更多灵活性,请使用它。
  • 碳。 我不建议使用这个API,但它是纯粹的C.

Objective C是纯C代码的一小部分补充。 您不必通过使用Cocoa API来学习它。 它根本不是C ++的野兽。 如果您了解C,您可以在几个小时内了解所需的一切。 网上所有最好的示例代码和文档都是针对Cocoa而不是Carbon。 OpenGL示例代码丰富,使用Cocoa,遍布整个网络和Apple的开发网站。

但是,无论您使用哪种API,所有事件处理都必须进入主线程。 这是主线程的目的,不是吗? 当然,您可以在任何您喜欢的线程中进行OpenGL调用。

我最终使用了GLFW。

起初,键盘事件不起作用; 但他们有一个用于构建捆绑的示例脚本。 在那之后,完美无瑕。

SDL? http://www.libsdl.org/
简单的DirectMedia Layer是一个跨平台的多媒体库,旨在通过OpenGL和2Dvideo帧缓冲提供对音频,键盘,鼠标,操纵杆,3D硬件的低级访问。 它被MPEG播放软件,模拟器和许多流行的游戏使用,包括获奖的Linux端口“文明:呼唤权力”。

SDL支持Linux,Windows,Windows CE,BeOS,MacOS,Mac OS X,FreeBSD,NetBSD,OpenBSD,BSD / OS,Solaris,IRIX和QNX。 该代码包含对AmigaOS,Dreamcast,Atari,AIX,OSF / Tru64,RISC OS,SymbianOS和OS / 2的支持,但这些都不受官方支持。

即使你不喜欢GLUT。 这听起来怎么样?

你可以看一下从这里抓取GLUT源并修改它的主循环。 您可以在GLUTApplication.m文件中找到它。 这是它的外观。 认为你应该轻松​​提取必要的GLUT调用,将它们放在你自己的主循环中。

 - (void)run { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSRunLoop *runLoop = [[NSRunLoop currentRunLoop] retain]; [self finishLaunching]; __glutEnableVisibilityUpdates(); _running = 1; while([self isRunning]) { __glutProcessWorkEvents(); /* Process all pending user events and fire all timers which have a fire date before or equal to the current system time. */ if(__glutIdleFunc || __glutHasWorkEvents()) { /* IMPORTANT: This case may _never_ block. */ [self _runMainLoopUntilDate: _distantPast autoreleasePool: &pool]; if(__glutIdleFunc) { __glutIdleFuncCalled = YES; __glutIdleFunc(); } } else { /* IMPORTANT: We may either block until the next timer in line is due, or until a new user event arives from the WindowServer. */ NSDate *limitDate = [runLoop limitDateForMode: NSDefaultRunLoopMode]; [self _runMainLoopUntilDate: limitDate autoreleasePool: &pool]; } [pool drain]; pool = [[NSAutoreleasePool alloc] init]; } [runLoop release]; [pool drain]; } 

Mac OS X上唯一的纯C本机API是Carbon。 但是大部分内容都已弃用,您无法使用Carbon API编写64位应​​用程序。

另一个API是cocoa – 这是基于目标C的。 Cocoa框架本身将应用程序限制为具有单个主线程,并在该线程上调度消息事件。

过剩是在Cocoa之上实现的,因此,在Mac上,inheritance了这种限制 – 你可能选择在其上包含的任何其他框架也是如此:Qt,SDL,过剩等等。

即使主线程限制仍然存在,您仍然需要选择一个框架,以节省学习objective-c的麻烦。

过剩 – 如果你所做的只是创建一个窗口,并处理输入,这是一个简单的选择。 SDL和Qt还在MacOSX上提供基于c ++的消息处理,以及可靠的支持直接访问OpenGL apis进行渲染。

这是一个回购,正是你所要求的。

https://github.com/jimon/osx_app_in_plain_c

要严格过分简化这里发生的事情,您可以将Objective-C视为一系列转换为纯C的预处理器宏。请参阅此处的答案。

查找简单Objective-C语法的基本C版本是正在使用的方法。 哪里…

 [NSApplication sharedApplication]; 

成为…

 id nsapp = objc_getClass("NSApplication"); id sel_sharedApp = sel_registerName("sharedApplication"); id ret = objc_msgSend(nsapp, sel_sharedApp); 

在Google文档中搜索objc_msgSend()等函数是了解更多信息的途径。 这是一个非常深的兔子洞。

我不想学习目标C.

然后忘记编写代码以在OS X上运行。