Cocoa / Objective-C / OpenGL Template

mdavis1982
Unregistered
 
Post: #1
Hi everyone...

Following in the footsteps of ss2_cire, here is an OpenGL template that you can use as a basis for all your OpenGL projects.

It is implemented using MVC, and is pretty easy to use. I haven't included a readme or anything, but the code is fully commented! The features are:
  • Switches from windowed to full screen easily (one method call!)
  • Doesn't have the annoying minimize bug
  • Will respond correctly when the user drags the window's resize handle
  • Pauses when the window is not the active one
  • Is OOP!

Many thanks go to ss2_cire for his original template, and NCarter and CarbonX for their help tracking down the bugs!

Hope everyone enjoys it and will help me to make it better,

Many thanks,

Matt
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #2
I took a brief look, there are a few problems here:

* the pixel format assumes hardware acceleration. What if I have a 233 MHz iMac?
* the pixel format uses weird values (RGB16, A8) and FSAA, but multisampling isn't enabled.
* the pixel format only works with the main display. You should be able to drag the window to any attached display and go fullscreen there (this means handling Macs with more than one video card.)
* the minimization readback isn't as optimal as it could be (ARGB->RGBA->ARGB.)
* window resizing isn't as optimal as it could be (double swap.)
* the controller's timer is only in the default mode, so the animation stops while clicking on a menu or resizing the window.
* not VBL synched, so there is horrible nasty tearing.
Quote this message in a reply
mdavis1982
Unregistered
 
Post: #3
arekkusu Wrote:I took a brief look, there are a few problems here:

* the pixel format assumes hardware acceleration. What if I have a 233 MHz iMac
* the pixel format uses weird values (RGB16, A8) and FSAA, but multisampling isn't enabled.
* the pixel format only works with the main display. You should be able to drag the window to any attached display and go fullscreen there (this means handling Macs with more than one video card.)
* the minimization readback isn't as optimal as it could be (ARGB->RGBA->ARGB.)
* window resizing isn't as optimal as it could be (double swap.)
* the controller's timer is only in the default mode, so the animation stops while clicking on a menu or resizing the window.
* not VBL synched, so there is horrible nasty tearing.

Hi Arrekusu...

I agree with your problems, however this is only a 1.0 release, and I'm still developing it. The VBL syncing issue is as it is at the moment because it is frame based. By syncing to the VBL, it slows down dramatically. The next release is going to be time-based to avoid that. The animation stopping isn't because of the timer; it's because the animation is set to only happen when the window is the key window.

Look for the next release... There will be some updates!

Thanks,

mdavis1982
Quote this message in a reply
Hog
Member
Posts: 151
Joined: 2002.09
Post: #4
some issues:
1. "// Handle all updating of objects and call the view's drawFrame method only if the window is the key window"
you might want to put the drawing in - (void)drawRect: (NSRect) r, and drawFrame should call [self setNeedsDisplay: YES]; instead

2. the objects don't rotate while resizing, i'm pretty new to cocoa so i don't know how to fix this
Quote this message in a reply
MarkJ
Unregistered
 
Post: #5
Quote:The VBL syncing issue is as it is at the moment because it is frame based.
I think this is a cool project, but this is bad. Your animation example should definitely be time based. Themsalltook has a pretty good tutorial on time-based animation here. Definitely check it out, and good luck with the template Grin.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #6
I saw that you are only updating if the window is key, but your timer is also only in the default mode. Click on the resize corner or in the close button and hold the mouse down-- the window is still key, but stops animating. Add your timer to NSEventTrackingRunLoopMode to fix this.

Frame-based vs time-based is an important issue, but it is separate from VBL. There is a simple rule for this: if your rendering is going to be visible to human eyes, it should be VBL synched.
Check Apple's VBL sample for time-based animation with and without VBL.
Quote this message in a reply
mdavis1982
Unregistered
 
Post: #7
Hi everyone...

Thanks for all your feedback! I'm just about to start some work on the improvements everyone has suggested! Cool

I'm going to check out Apple's VBL example, and also add the timer to the various run modes that I should do.

I haven't implemented the drawing in - (void)drawRect:(NSRect)aRect; and used setNeedsDisplay because that depends on the event system to eventually tell the view to draw, which isn't really what I want to do! I think it's faster to just call a method to draw the stuff and then flush the buffer. Can anyone clarify this?

Again, thanks for all the comments and stuff, and I hope to have a new release ready really soon! Smile

Matt
Quote this message in a reply
mdavis1982
Unregistered
 
Post: #8
Hi Everyone,

Thanks for the feedback on my template. I've implemented the features and improvements, and fixed the bugs that you all suggested!

The new version is 1.1, and is available at my website.

Hope this new one improves on the old one! Any feedback would be greatly appreciated!

Thanks again,

Matt
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #9
Better, but now it flickers while resizing. You don't subclass -drawRect, so system-requested redraws do nothing!

Of course, no template will ever be able to cover everybody's needs, but...

* prepareOpenGL only works on 10.3. Have you tried this on 10.2?
* pixel format assumes hardware acceleration and only goes fullscreen on the main display.
* minimize and redraw not optimal.
Quote this message in a reply
mdavis1982
Unregistered
 
Post: #10
Quote:Better, but now it flickers while resizing. You don't subclass -drawRect, so system-requested redraws do nothing!
True. I'll try to add it, although it will make the template confusing.

Quote:* prepareOpenGL only works on 10.3. Have you tried this on 10.2?
I am aware that it only works on 10.3+. However, for my own needs, I don't see the point of developing for anything earlier than that. If someone wants to support earlier versions of the OS, then they can dig around and do it. But, I'm going by the official Apple docs. If they've added functionality, then I'm going to use it.

Quote:* pixel format assumes hardware acceleration and only goes fullscreen on the main display.
Even though it assumes hardware acceleration, it will still fall back to a software renderer if it needs to. How many Macs are in use without a hardware accelerator? Not that many, so why develop for the minority?

Yes, it does only go full screen on the main display, but again, for my needs, and for most other people's needs, this is perfectly acceptable. Again, this is a template. If people want to support multiple monitors, they can do so. But why make the template confusing for people?

Quote:* minimize and redraw not optimal.
Miniaturisation should now be optimal with the change to the color size in the pixel format. Not sure what you mean by the redraw not being optimal. Maybe you could elaborate?

Also, instead of posting the same criticisms over and over again, why not suggest ways to fix them?

Matt
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #11
mdavis1982 Wrote:Even though it assumes hardware acceleration, it will still fall back to a software renderer if it needs to.
Not with NSOpenGLPFANoRecovery in the pixel format, it won't. But you're right, every mac sold in the last three years will have HW acceleration, so this is probably not an issue for most people developing new products.

Quote:Miniaturisation should now be optimal with the change to the color size in the pixel format.
See thread.

Quote:Not sure what you mean by the redraw not being optimal. Maybe you could elaborate?
The window server swaps your context during live resize. So you're flushing twice.
Try code like this:
Code:
    if ([self inLiveResize] && ((oldsize.width != size.width) || (oldsize.height != size.height))) {
        glFlush();
        oldsize.width = size.width; oldsize.height = size.height;
    }
    else [ctx flushBuffer];
Quote this message in a reply
Hog
Member
Posts: 151
Joined: 2002.09
Post: #12
you need to call makeCurrentContext in reshape and drawFrame, otherwise the wrong context will be affected.
Quote this message in a reply
mdavis1982
Unregistered
 
Post: #13
Okay...

Noted! I will update the template just as soon as I have a bit of time!

Thanks,

Matt
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #14
The context is current per thread-- so if your app only uses one context, you only need to make it active once. Not once per draw.

If you use more than one context, you should make it current per draw to make sure you're drawing where you expect.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Opengl/Cocoa text rendering tesil 15 17,458 Mar 20, 2012 11:16 AM
Last Post: OneSadCookie
  OpenGL Text Rendering (in Cocoa) daveh84 5 7,904 Feb 19, 2009 12:44 PM
Last Post: TomorrowPlusX
  OpenGL & Cocoa - Improving frame rate daveh84 4 5,562 Feb 2, 2009 06:53 AM
Last Post: backslash
  bad depth sorting in Cocoa OpenGL aldermoore 2 4,650 Dec 30, 2008 03:07 PM
Last Post: ThemsAllTook
  Loading and using textures with alpha in OpenGL with Cocoa corporatenewt 4 6,417 Dec 8, 2007 02:06 PM
Last Post: Malarkey