PDA

View Full Version : NSOpenGLView isn't redrawing...




Stachelsk
Dec 18, 2009, 08:50 PM
I'm stumped. I'm by no means familiar with objective-c++ or Apple's libraries, so please bear with me. My renderer code is only getting called once (when the application starts). It only gets called again if I minimize and restore the window. No idea how to make it refresh.

Code in question:
#import "GLView.h"

@implementation GLView

- (id)initWithFrame:(NSRect)frameRect
{
NSOpenGLPixelFormatAttribute attr[] =
{
NSOpenGLPFAAccelerated,
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute) 32,
(NSOpenGLPixelFormatAttribute) 0
};
NSOpenGLPixelFormat *nsglFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attr] autorelease];

if (self = [super initWithFrame:frameRect pixelFormat:nsglFormat])
renderer = new Renderer();
return self;
}

- (void)dealloc
{
delete renderer;
[super dealloc];
}

- (void)prepareOpenGL
{
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 400, 300, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
}

- (void)drawRect:(NSRect)rect
{
renderer->DrawGL();
// DOESN'T WORK --- [super setNeedsDisplay:YES];
// DOESN'T WORK --- [self setNeedsDisplay:YES];
}

@end



kainjow
Dec 18, 2009, 11:26 PM
[self setNeedsDisplay:YES];
is the way to do it. But don't call that inside your drawRect: method. When/where are you actually wanting to redraw?

Edit: you need this at the end of your drawRect:
[[self openGLContext] flushBuffer];

Stachelsk
Dec 19, 2009, 12:17 AM
Thanks for the help, kainjow. Unfortunately, it did not work. :(

It's still only calling DrawGL() once.

kainjow
Dec 19, 2009, 12:35 AM
Well what does your code look like now?

Stachelsk
Dec 19, 2009, 10:30 AM
#import "GLView.h"

@implementation GLView

- (id)initWithFrame:(NSRect)frameRect {
NSOpenGLPixelFormatAttribute attr[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute) 32,
(NSOpenGLPixelFormatAttribute) 0
};
NSOpenGLPixelFormat *nsglFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attr] autorelease];

if ((self = [super initWithFrame:frameRect pixelFormat:nsglFormat]))
; //...
return self;
}

- (void)dealloc {
[super dealloc];
}

- (void)prepareOpenGL {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 400, 300, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
}

- (void)drawRect:(NSRect)rect {
render();
[[self openGLContext] flushBuffer];
[self setNeedsDisplay:YES];
}

@end


I want the code to redraw as soon as its done rendering a frame... so I put the [self setNeedsDisplay:YES]; after flushing the buffer. Can it just absolutely not be there? Where can I put it so that the screen is constantly redrawing as soon as the render method is done?

lloyddean
Dec 19, 2009, 11:27 AM
'setNeedsDisplay' does nothing when placed within your draw loop. Instead you'll need to drive your rendering loop from an NSTimer or DisplayLink callback handler.

Check out this (http://developer.apple.com/mac/library/qa/qa2004/qa1385.html) document.

Stachelsk
Dec 19, 2009, 01:01 PM
'setNeedsDisplay' does nothing when placed within your draw loop. Instead you'll need to drive your rendering loop from an NSTimer or DisplayLink callback handler.

Check out this (http://developer.apple.com/mac/library/qa/qa2004/qa1385.html) document.

Works perfectly, thanks.
Happy holidays!