views:

210

answers:

1

I've been banging my head against a wall for a few days with this. I've read every document I could find and more on the subject of OpenGL and Cocoa. I'm just not understanding where my attempts break and the other ones don't.

My code is listed below, it is fairly short as all I'm trying to do is render a rotating triangle. I am not new to OpenGL or programming, but I am a total newb with Cocoa and Objective-C.

MyOpenGL.h

#import <Cocoa/Cocoa.h>

@interface MyOpenGL : NSOpenGLView
{
 float rot;
 NSTimer *timer;
}

//+(NSOpenGLPixelFormat*) basicPixelFormat;

-(void) animTimer : (NSTimer *) timer;
-(void) drawRect : (NSRect) bounds;

@end

MyOpenGL.m

#include <OpenGL/gl.h>

#import <Cocoa/Cocoa.h>
#import "MyOpenGL.h"

@implementation MyOpenGL

/*
+ (NSOpenGLPixelFormat*) basicPixelFormat
{
    NSOpenGLPixelFormatAttribute attributes [] = {
        NSOpenGLPFAWindow,
        NSOpenGLPFADoubleBuffer,
        NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)16,
        (NSOpenGLPixelFormatAttribute)nil
    };
    return [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease];
}

-(id) initWithFrame : (NSRect) frameRect
{
 NSOpenGLPixelFormat * pf = [MyOpenGL basicPixelFormat];

 return self = [super initWithFrame: frameRect pixelFormat: pf];
}
*/

-(void) awakeFromNib
{
 rot = 0;
    timer = [NSTimer timerWithTimeInterval: (1.0f/60.0f)
         target:self
          selector:@selector(animTimer:)
          userInfo:nil
           repeats:YES];

 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode];
}

-(void) animTimer : (NSTimer *) atime
{
 [self setNeedsDisplay: YES];
 [self drawRect:[self bounds]];
}

-(void) drawRect: (NSRect) bounds
{
 glClearColor(0,0,0,0);
 glClear(GL_COLOR_BUFFER_BIT);
 glLoadIdentity();
 glRotatef(rot,1,0,0);

 glBegin(GL_TRIANGLES);
 {
  glColor3f(1,0,0); glVertex3f(0,0.6,0);
  glColor3f(0,1,0); glVertex3f(-0.2,-0.3,0);
  glColor3f(0,0,1); glVertex3f(0.2,0.3,0);
 }
 glEnd();

 glFlush();
 rot++;
}

@end

Uncommenting the +(NSOpenGLPixelFormat*) basicPixelFormat; line from the header and the associated function in the .m file and the -(id) initWithFrame : (NSRect) frameRect method in MyOpenGL.m file seem to make no difference.

The drawRect method seems to only be called once. I get the triangle in the initial position, but with no rotation. Any advice would be appreciated.

A: 

I just tried dropping your code above into a new project, and it's working for me. I see a triangle rotating around the X axis. Do you perhaps have a breakpoint set on your -drawRect: method?

BTW, sending -drawRect: yourself is redundant if you're sending a -setNeedsDisplay message.

NSResponder
No break-point. I'll pull out the extra -drawRect, and try a fresh project on another machine.
Oz
Not only is it redundant, but I'm pretty sure you'll get complaints in the Run Log, and it won't work, because there's no current context at the time. You would need to send `lockFocus` before `drawRect:` and `unlockFocus` after (if you weren't already sending `setNeedsDisplay:`, which is better, both generally and in this case).
Peter Hosey
Turns out my computer is too old to properly compile this :/ Time to upgrade!
Oz