2012-03-29 6 views
2

Ich fange an, an einem 3D-Partikelsystem-Editor und -Entwickler zu arbeiten. Ich habe in der Vergangenheit etwas Ähnliches mit OpenGL gemacht, aber dieses Mal mache ich eine Mac OS X Kakaoverwendung. Ich habe nur ein paar Fragen zu Code, den ich bei der Einrichtung von OpenGL immer wieder aufrufe.Einrichten des kontinuierlichen Renderns in einer Mac OSX Cocoa-Anwendung mit OpenGL

1) Warum muss ich eine Menge Leute, die im Internet zu sehen mit ...

[self setNeedsDisplay:YES]; 

Ist dies der richtige Weg, OpenGL zu bekommen zu machen, jetzt verstehe ich es zu drawRect führt genannt zu werden, aber ist es der richtige Weg?

2) Ist drawRect die richtige Methode, die ich für meine Render-Frame-Methode überschreiben sollte?

Heres der Code, den ich weiterhin in auf dem Netz laufen:

-(void) prepareOpenGL { 
    [[self window] makeFirstResponder:self]; 
    glClearColor(1.0f, 1.0f, 0.0f, 10.f); 

    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0/60.0 target:self selector:@selector(idle:) userInfo:nil repeats:YES]; 
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; 
} 

-(void)idle:(NSTimer *)timer { 
    if(![[NSApplication sharedApplication] isHidden]) 
     [self setNeedsDisplay:YES]; 
} 
-(void) drawRect:(NSRect)dirtyRect { 
    glClear(GL_COLOR_BUFFER_BIT); 
} 

Antwort

4

Sie haben nicht angegeben, ob Sie Ihre OpenGL Inhalte innerhalb eines NSOpenGLView oder einer CAOpenGLLayer zeichnen wird. Diese beiden haben leicht unterschiedliche Möglichkeiten, ihren Inhalt für die Anzeige auf dem Bildschirm zu aktualisieren. Für eine NSOpenGLView müssen Sie die Ansicht nicht innerhalb der -drawRect:-Methode aktualisieren. In der Tat, ich denke, Sie wollen nicht -setNeedsDisplay: auslösen, um eine Aktualisierung des NSView wegen einiger Overhead, die auftreten könnten, zu tun. In einer meiner Anwendungen verwende ich einen CVDisplayLink, um Aktualisierungen mit 60 FPS innerhalb meiner eigenen benutzerdefinierten Rendermethoden in einer NSOpenGLView auszulösen. Keine davon berührt -drawRect:. Frames werden beim Aufruf von [[self openGLContext] flushBuffer] dem Bildschirm angezeigt, nicht durch Erzwingen eines Neuzeichnens des NSView.

CAOpenGLLayers sind etwas anders, indem Sie - drawInCGLContext:pixelFormat:forLayerTime:displayTime: mit Ihrem benutzerdefinierten Rendering-Code überschreiben. Diese Methode wird als Reaktion auf ein Manual -setNeedsDisplay oder durch den CAOpenGLLayer selbst ausgelöst, wenn die Eigenschaft asynchronous auf YES gesetzt ist. Es weiß, wann es bereit ist, neuen Inhalt mit dem booleschen Wert zu präsentieren, den Sie als Antwort auf -canDrawInCGLContext:pixelFormat:forLayerTime:displayTime: angegeben haben.

Ich habe beide verwendet, und jeder hat seine Vorteile. CAOpenGLLayers machen es viel einfacher, andere UI-Elemente in Ihrem OpenGL-Rendering zu überlagern, aber ihre Rendering-Methoden können möglicherweise nur schwer von einem Hintergrundthread funktionieren. NSOpenGLViews können leicht mit einem Hintergrund-Thread unter Verwendung eines CVDisplayLinks aktualisiert werden, sind aber ein Hilfsmittel, um Inhalte zu überlagern.

+0

Ich erweitere derzeit NSOpenGLView. Was würden Sie für die Verwendung der programmierbaren Pipelines von OpenGL für die Darstellung von Tausenden von Partikeln im 3D-Raum empfehlen? –

+0

@JimmyBouker - Beide werden Rendering-Aufgaben genauso gut behandeln. Wenn Sie planen, etwas über Ihre Ansicht zu legen, spart Ihnen CAOpenGLLayer Zeit. Wenn Sie Multithread-Rendering benötigen, macht NSOpenGLView das ein wenig einfacher. –

+0

Vielen Dank Zoo, ich werde auf jeden Fall Multi-Threading-Rendering haben und ich werde nicht etwas auf meiner Oberfläche legen. Danke Brad –