tags:

views:

316

answers:

6

I want to open an OpenGL window ( to display and grab keystrokes / mouse events ) in MacOSX.

I don't want to use Glut (since it demandds it be the root thread).

I don't want to learn Objective C.

Is there anyway to access the OpenGL api in pure C?

Thanks!

+3  A: 

SDL? http://www.libsdl.org/
Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. It is used by MPEG playback software, emulators, and many popular games, including the award winning Linux port of "Civilization: Call To Power."

SDL supports Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX. The code contains support for AmigaOS, Dreamcast, Atari, AIX, OSF/Tru64, RISC OS, SymbianOS, and OS/2, but these are not officially supported.

Chris H
+3  A: 

If you want to grab events on OS X, there are a couple options:

  • SDL. Highly recommended, C, not very flexible. You will need to either install it on systems where you use it, or include the framework in your app bundle.
  • Cocoa. Use this if you need more flexibility.
  • Carbon. I don't recommend using this API, but it is pure C.

Objective C is a very small set of additions to pure C code. You don't have to learn much of it to get by using the Cocoa API. It's not at all the beast that is C++. If you know C, you can learn all you need in a couple hours. All of the best sample code and documentation on the web is for Cocoa, not Carbon. There's OpenGL sample code galore that uses Cocoa, all over the web and on Apple's dev website.

However, all the event handling has to go in the main thread regardless of the API you use. That's the purpose of the main thread, no? You can do OpenGL calls in any thread you like, of course.

Dietrich Epp
+2  A: 

The only pure C native API on Mac OS X is Carbon. The majority of it is however deprecated and you cannot write 64 bit apps using the Carbon API.

The other API is cocoa - which is objective-C based. The Cocoa framework itself restricts applications to having a single main thread with the message event dispatching on that thread.

glut is implemented on top of Cocoa, and so, on the Mac, inherits that restriction- and so does any other framework you might choose to wrap on top of that: Qt, SDL, glut, etc.

Even if the main thread restriction stands you still need to choose a framework that will save you the hassle of learning objective-c.

glut - if all you are doing is creating a window, and processing input, is a simple choice. SDL and Qt also provide c++ based message processing on MacOSX along with solid support direct access to OpenGL apis for rendering.

Chris Becke
A: 

I don't want to learn Objective C.

Then forget about writing code to run on OS X.

NSResponder
That's hardly true, as others have pointed out.
Shtééf
Interestingly enough, objective C is (or was) implemented as a C pre compiler, and a library of C functions.This means that it is entirely possible to create, call, and implement objective c objects in pure c++, or c, without writing a line of objective c.
Chris Becke
+2  A: 

Even though you dislike GLUT. How does this sound?

You could have a look at grabbing the GLUT sources from here and modify its main loop. You can find it in the GLUTApplication.m file. This is how it looks. Think you should easily extract the necessary GLUT calls to place them in your own main loop.

- (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];
}
epatel
+1  A: 

I ended up using GLFW.

At first, keyboard events do not work; but they have a sample script for building a bundle. After that, flawless.

anon