Cocoa OpenGL

Sage
Posts: 1,066
Joined: 2004.07
Post: #1
Before anybody even thinks it: I searched the forums with multiple phrases and could not find this answer. I also searched google and came up with nothing of use.

I'm trying to learn how to use Cocoa with OpenGL. I can already use OpenGL with SDL and C++ but I want to learn and expand my knowledge. I know a decent amount of Objective-C (after quite a bit of reading and testing) and figured I'd give this a shot. I looked at a site called Deep Cocoa but found the tutorials rather worthless in explaining what was going on. I also downloaded NeHe's base code but I can't figure it out without explanation (unless it's hiding somewhere I can't find).

I don't expect anybody to provide me with a lecture on the subject (as I figure that would take a while), I'm simply wondering if there are any websites better than Deep Cocoa and NeHe's base code for learning OpenGL in Cocoa? Or do I just have to tough it out and do it myself? Shock
Quote this message in a reply
Moderator
Posts: 608
Joined: 2002.04
Post: #2
Quote:I'm simply wondering if there are any websites better than Deep Cocoa and NeHe's base code for learning OpenGL in Cocoa?
In a word: no. Try to figure out the flow of the programs, and then ask any specific questions here. Smile
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #3
Start with Apple's sample code.
Quote this message in a reply
Vertizor
Unregistered
 
Post: #4
If you understand how to use Interface Builder and make a subclass of widgets you drag n drop, then that's half the battle.

There are methods of NSOpenGLView for you to overload to make things work.

- (void) reshape:
This is where you put your code that handles resizing the viewport, and resetting the projection.

- (void) drawRect:
This is where you put your OpenGL rendering code. The framework will call it for you whenever it's needed. If you need to manually redraw the scene (like based on a timer or mouse/keyboard input) some sample code tells us to call NSView's setNeedsDisplay: YES

- (void) prepareOpenGL:
This was added in OSX 10.3, it's called by the framework after the opengl context is created and attached to the view widget. This is where you do all your setup, like your glEnable() calls.

Hope this is enough to get your started. Like arekkusu said, just look at Apple's sample projects.
Quote this message in a reply
Moderator
Posts: 508
Joined: 2002.09
Post: #5
Try this little tutorial: OpenGL in Cocoa

"When you dream, there are no rules..."
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #6
Cool. That OpenGL in Cocoa link looks useful. I'll take a look at it later when I get home and see if that helps.
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #7
Vertizor Wrote:- (void) prepareOpenGL:
This was added in OSX 10.3, it's called by the framework after the opengl context is created and attached to the view widget. This is where you do all your setup, like your glEnable() calls.
any advantage to this over awakeFromNib?
Quote this message in a reply
Moderator
Posts: 508
Joined: 2002.09
Post: #8
skyhawk Wrote:any advantage to this over awakeFromNib?

not really, but if you wanna keep compatibility with non Mac OS X 10.3 users, I recommend doing your OpenGL initialization in:

Code:
- (id)initWithCoder:(NSCoder*)coder {
//setup NSOpenGLView with a pixelFormat
//init OpenGL
//init everything else you need
}

That's how do it Smile

edit: smileys and code don't work well together

"When you dream, there are no rules..."
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #9
That tutorial helped a lot. Got that all set up. Played around with it a bit. Made a rectangle move instead of one point of a triangle.

One thing I'd like to know is setting up the resolution of the view. If I use (0,0) I'm in one corner and (1,0) is the other corner. How can I change this so that it's like (0,0) is the top left and (800,0) is the top right? I can do this in SDL but my code (from the tutorial) doesn't have any of the projection matrix setting or the glViewport code so I'm at a loss for how to do this.

Would this fit into the prepareOpenGL function (or similarly named) from one of the above posts? If I override that function what else am I going to have to put in it to have it still work (seeing as none of the code from the original function will get called)?
Quote this message in a reply
Moderator
Posts: 508
Joined: 2002.09
Post: #10
You can set the resolution using the glViewPort function. Do this in the reshape method of the NSOpenGLView. Like this:

Code:
- (void)reshape {
    float ratio;
    NSSize bounds = [self bounds].size;
    ratio = bounds.width / bounds.height;
    
    glViewport(0, 0, [self frame].size.width, [self frame].size.height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

//set your other stuff here (glPerspective of glOrtho)
}

Now if you want get the mouse position in that view you'll need convert the point into OpenGL units.

I've found that temporarily switching to orthographic mode is the best way to get the mouse coordinates, since glPerspective will give you some odd values.

"When you dream, there are no rules..."
Quote this message in a reply
Vertizor
Unregistered
 
Post: #11
Taxxodium Wrote:Now if you want get the mouse position in that view you'll need convert the point into OpenGL units.

I've found that temporarily switching to orthographic mode is the best way to get the mouse coordinates, since glPerspective will give you some odd values.
Do a search (either in this forum or Google) for gluUnproject.

If you're using glOrtho, here's a code snippet to reorient the coordinate system so that the top/left corner is (0,0) this would go in your -reshape: method.

Code:
    glViewport(0, 0, w, h);       // Establish viewing area to cover entire window.
    glMatrixMode(GL_PROJECTION);  // Start modifying the projection matrix.
    glLoadIdentity();             // Reset project matrix.
    glOrtho(0, w, 0, h, -1, 1);   // Map abstract coords directly to window coords.
    glScalef(1, -1, 1);           // Invert Y axis so increasing Y goes down.
    glTranslatef(0.0f, (float)-h, 0.0f);

I haven't tried this but I think if you omit the last 2 lines of code (glScalef() and glTranslatef()) then (0,0) will be in the lower right corner of the viewport, which is more OSX centric.
Quote this message in a reply
Moderator
Posts: 508
Joined: 2002.09
Post: #12
Vertizor Wrote:Do a search (either in this forum or Google) for gluUnproject.

I do use gluUnProject, mainly to convert local mouse coordinates to OpenGL coordinates.

Perhaps some code might be useful on how to use this:

Code:
- (TWVector)convertFromWindowCoords:(NSPoint)localPoint {
    GLint viewport[4];
    GLdouble mvmatrix[16], projmatrix[16];
    GLdouble wx, wy, wz;
    
    glGetIntegerv(GL_VIEWPORT, viewport);
    glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
    glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
    
    gluUnProject((GLdouble)localPoint.x, (GLdouble)localPoint.y, 0.0, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);
    
    return TWVectorMake(wx, wy, 0.0);
}

TWVector is a simple 3D vector, so what this does is convert a point from your window to a vector in OpenGL, keeping the z-axis as zero.

I use this method in my method to get the OpenGL mouse coordinates:

Code:
- (NSPoint)mouseLocationInUnits {
    NSPoint localPoint = [[self window] convertScreenToBase:[NSEvent mouseLocation]];
    NSPoint unitPoint;
    
    unitPoint = NSMakePoint([self convertFromWindowCoords:localPoint].x, [self convertFromWindowCoords:localPoint].y);

    return unitPoint;
}

Perhaps there is a better method to do this, but this works for me.

"When you dream, there are no rules..."
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #13
I'm getting a couple errors building this right now (line 1 is just the #import "MyOpenGLView.h" line):
Code:
MyOpenGLView.m:1: fatal error: method definition not in class context
MyOpenGLView.m:1: error: parse error before "TWVector"


I've tried a few things but I haven't gotten it yet. Any advice?
Quote this message in a reply
Moderator
Posts: 508
Joined: 2002.09
Post: #14
SimReality/Nick Wrote:Any advice?

Yes, don't copy/paste the code above. You need create a vector structure and replace that with TWVector, same for the function TWVectorMake, those are things from me, not from Cocoa.

"When you dream, there are no rules..."
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #15
I see. I'll get right on that. Smile
Quote this message in a reply
Post Reply 

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