ich möchte unter OSX OpenGL (kein GLUT) so initialisieren, dass ich folgende Struktur habe:
....
InitOpenGLWindow();
repeat
glDRAWStuff;
glFlashBuffers;
until event.keypressed;
außerdem brauche ich auch eine Eventbechandlung.
Ein Vorschlag war:
Code: Alles auswählen
program MinimalPlusMenuPlusGL;
{$mode objfpc}
{$modeswitch objectivec1}
uses
ctypes, MacOSAll, CocoaAll, GL, GLUT;
// -------------------- Window, view and OpenGL context
var
m_context: NSOpenGLContext;
a, b: Real;
type TestView = objcclass(NSView)
public
procedure drawRect (rect: NSRect); override;
procedure windowWillClose (note: NSNotification); message 'windowWillClose:';
end;
var
NSApp: NSApplication;
view: NSView;
procedure TestView.drawRect (rect: NSRect);
begin
m_context.clearDrawable;
glViewport(0, 0, Trunc(self.frame.size.width),
Trunc(self.frame.size.height));
m_context.setView(self);
m_context.makeCurrentContext;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glPushMatrix;
glTranslatef(0, 0, -2);
glRotatef(a, 0, 1, 0);
glRotatef(b, 1, 0, 0);
glScalef(-1, 1, 1);
glutSolidTeapot(0.75);
glPopMatrix;
m_context.flushBuffer;
end;
procedure TestView.windowWillClose (note: NSNotification);
begin
NSApp.terminate(NSApp);
end;
procedure MakeWindow;
var
window: NSWindow;
fmt: NSOpenGLPixelFormat;
attrs: array [0..3] of NSOpenGLPixelFormatAttribute =
(
NSOpenGLPFADoubleBuffer,
NSOpenGLPFADepthSize, 32,
0
);
frame: NSRect = (origin:(x: 10; y: 1200); size:(width: 400; height: 400));
begin
a := 0;
b := 0;
// Create the window and get its view.
window := NSWindow.alloc;
window.initWithContentRect_styleMask_backing_defer(frame,
NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask
or NSResizableWindowMask,
NSBackingStoreBuffered, LongBool(0));
window.setTitle(NSString(CFSTR('Minimal + MiniMenu + GLView')));
// Init GL context
fmt := NSOpenGLPixelFormat.alloc.initWithAttributes(@attrs);
m_context := NSOpenGLContext.alloc.initWithFormat_shareContext(fmt, nil);
fmt.release;
m_context.makeCurrentContext;
// GL inits
glClearColor(0.2,0.2,0.5,0);
glMatrixMode(GL_PROJECTION); glLoadIdentity();
glFrustum(-0.1, 0.1, -0.1, 0.1, 0.1, 100); // left, right, bottom, top, near, far
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
view := TestView.alloc;
view.initWithFrame(frame);
window.setContentView(view);
window.setDelegate(NSWindowDelegateProtocol(view));
window.makeKeyAndOrderFront(nil);
end;
// -------------------- Timer ------------------------
// Mini-mini class for the timer
type
TimerController = objcclass(NSObject)
public
procedure TimerAction(t: NSTimer); message 'timerFireMethod:';
end;
var
gTimer: NSTimer;
myTimerController: TimerController;
// Timer!
procedure TimerController.TimerAction(t: NSTimer);
var
theText: AnsiString;
CFText: CFStringRef;
begin
a += 1;
b += 1;
view.setNeedsDisplay_(true);
end;
// -------------------- Menu ------------------------
// Mini-mini class for collecting events
type
TMenuController = objcclass(NSObject)
public
procedure selectMenuItem (sender: id); message 'selectMenuItem:';
end;
procedure TMenuController.selectMenuItem (sender: id);
begin
WriteLn('Menu selection detected');
end;
var
myController: TMenuController;
procedure SetupMenu;
var
mainMenu, theMiniMenu: NSMenu;
menuItem1, menuItem2: NSMenuItem;
dummyItem: NSMenuItem;
begin
// Allocate controller
myController := TMenuController.alloc; // Create();
// Create main menu = menu bar
mainMenu := NSMenu.alloc;
mainMenu.initWithTitle(NSString(CFSTR('')));
NSApp.setMainMenu(mainMenu);
// Create the custom menu
theMiniMenu := NSMenu.alloc;
theMiniMenu.initWithTitle(NSString(CFSTR('The MiniMenu')));
// Create a menu item
menuItem1 := NSMenuItem.alloc;
menuItem1.initWithTitle_action_keyEquivalent(NSString(CFSTR('Item Text')), nil, NSString(CFSTR('')));
menuItem1.setTarget(myController); // Who will handle it?
menuItem1.setAction(sel_registerName(PChar('selectMenuItem:'))); // What method will handle it?
theMiniMenu.addItem(menuItem1);
// Create another menu item with standard message
menuItem2 := NSMenuItem.alloc;
menuItem2.initWithTitle_action_keyEquivalent(NSString(CFSTR('Quit')), nil, NSString(CFSTR('q')));
menuItem2.setKeyEquivalentModifierMask(NSCommandKeyMask);
menuItem2.setAction(sel_registerName(PChar('terminate:')));
theMiniMenu.addItem(menuItem2);
// Adding a menu is done with a dummy item to connect the menu to its parent
dummyItem := NSMenuItem.alloc;
dummyItem.initWithTitle_action_keyEquivalent(NSString(CFSTR('')), nil, NSString(CFSTR('')));
dummyItem.setSubmenu(theMiniMenu);
mainMenu.addItem(dummyItem);
end;
// ------------------ Main program ---------------------
var
pool: NSAutoreleasePool;
frame: NSRect = (origin:(x: 10; y: 1000); size:(width: 400; height: 400));
begin
pool := NSAutoreleasePool.new;
NSApp := NSApplication.sharedApplication;
// Timer
myTimerController := TimerController.alloc;
gTimer := NSTimer.alloc;
gTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats(0.02, myTimerController, sel_registerName(PChar('timerFireMethod:')), nil, true);
SetupMenu;
MakeWindow;
// Main loop
NSApp.run;
pool.dealloc; // Free;
end.
um zu Zeichnen wird hier ein Timer benutzt, dies kommt für mich nicht in Frage. Außerdem flackert das Bild

aber so ungefähr kommt es hin. Bin natürlich für alle Vorschläge offen

Danke,
Key-Real