PDA

View Full Version : Problem with user interaction and OpenGL



bunny83
08-20-2008, 04:28 AM
Hey,

Iím teaching myself in Objective C in combination with OpenGL and have some displaying problems.
In my .xib file I defined a custom view, a button and a slider.
The user should be able to create an initial sphere (button) and change the radius (slider).
The action methods and the outlets are called and the values are correct, the sphere is also created, but it is not displayed.
When I initially draw a sphere it is displayed, but I canít change the radius, again.
Did I miss something?

Thanks




@interface SeedDefinition (privatestuff)

- (void)initGL;

@end


@implementation SeedDefinition

- (id)initWithFrame:(NSRect) frameRect
{

NSOpenGLPixelFormat *nsglFormat;
NSOpenGLPixelFormatAttribute attr[] =
{
NSOpenGLPFAAccelerated,
NSOpenGLPFANoRecovery,
NSOpenGLPFADoubleBuffer,
0
};

[self setPostsFrameChangedNotifications: YES];

nsglFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];

if(!nsglFormat) { NSLog(@"Invalid format... terminating."); return nil; }

self = [super initWithFrame:frameRect pixelFormat:nsglFormat];
[nsglFormat release];

if(!self) { NSLog(@"Self not created... terminating."); return nil; }

[[self openGLContext] makeCurrentContext];

[self initGL];
return self;
}

- (void)initGL
{

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

glClearDepth(1.0f);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);

}

- (void)awakeFromNib
{

NSTimer *time;

time = [ [NSTimer scheduledTimerWithTimeInterval: DEFAULT_TIME_INTERVAL
target:self
selector:@selector(drawFrame)
userInfo:nil
repeats:YES]
retain
];
[[NSRunLoop currentRunLoop] addTimer: time forMode: NSEventTrackingRunLoopMode];
[[NSRunLoop currentRunLoop] addTimer: time forMode: NSModalPanelRunLoopMode];

m_sphereHit = NO;
m_first = YES;
m_firstSphere = YES;

}

- (void) reshape
{

float aspect;
NSSize bound = [self frame].size;
aspect = bound.width / bound.height;
glViewport(0, 0, bound.width, bound.height);
glMatrixMode(GL_PROJECTION);

glLoadIdentity();
gluPerspective(45.0f, (GLfloat)aspect, 0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

}

- (void)drawFrame{

[[self openGLContext] makeCurrentContext];
[[self openGLContext] update];

glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


if([m_sphereList count] != 0){

[self drawSphereList];
}

[[self openGLContext] flushBuffer];

}

-(void)drawSphereList{

int xValue, yValue, zValue;
float sphereRadius;

int i;
for(i = 0; i < [m_sphereList count] ; i++){

xValue = [[m_sphereList objectAtIndex: i] getX ];
yValue = [[m_sphereList objectAtIndex: i] getY ];
zValue = [[m_sphereList objectAtIndex: i] getZ ];
sphereRadius = [[m_sphereList objectAtIndex: i] getRadius];

glLoadIdentity();
glTranslatef(0,0,-40);
glColor3f (1.0, 0.4, 0.8);

GLUquadricObj *glu_obj;
glu_obj = gluNewQuadric();
gluSphere (glu_obj, sphereRadius, 24, 24);
gluDeleteQuadric(glu_obj);

}
}

- (void)initSphereList{

m_sphereList= [[NSMutableArray alloc] init];

}

- (IBAction)drawSphere:(id)sender{

if(m_firstSphere){

[self initSphereList];
m_firstSphere = NO;
}

m_tempSphere = [Sphere new];
[m_tempSphere init];

[m_sphereList addObject: m_tempSphere ];
[self setActiveSphere:[m_sphereList count] - 1];

}

- (IBAction)proceed:(id)sender {

NSLog( @"TODO:proceed");
}

-(IBAction)setUserRadius:(id)sender{

float userRadius;
userRadius=[radius floatValue];

[[m_sphereList objectAtIndex: m_activeSphere] setRadius:userRadius];

}

- (unsigned int)getActiveSphere{

return m_activeSphere;
}

- (void)setActiveSphere:(unsigned int) sphereIndex{

m_activeSphere = sphereIndex;

int i;
for(i = 0; i < [m_sphereList count]; i++)
{
if( i != m_activeSphere){

[[m_sphereList objectAtIndex: i] setActivity:NO];
}
}

}

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


- (BOOL)acceptsFirstResponder{

return YES;
}
- (BOOL)becomeFirstResponder{

return YES;
}

- (void)keyDown:(NSEvent *)theEvent{

NSLog( @"key down" );
}

- (void)mouseUp:(NSEvent *)theEvent{

NSLog( @"Mouse L up");
}


- (void)rightMouseUp:(NSEvent *)theEvent
{
NSLog( @"Mouse R up");
}

- (void)otherMouseUp:(NSEvent *)theEvent
{
NSLog( @"Mouse O up");
}




@end

Duncan Champney
10-29-2008, 07:37 AM
Bunny,

What type of custom view are you creating? I use an NSOpenGLView for my appliation, but you don't have to do that.

In any case, if you change something that causes your view to need to be redrawn, you need to tell your view that it needs to redraw itself.

You would do a call like
[myView setNeedsDisplay: TRUE];


Or, if you only want to trigger drawing a portion of your view:

[myView setNeedsDisplayInRect: theRect];

That will cause Cocoa to invoke your view's -drawRect method. You view should then invoke the appropriate OpenGL code to draw your objects, and finish up with

glFlush ();

(assuming you are set up for double-buffered drawing, which you probably should be.)

I hope that helps.

OneSadCookie
10-29-2008, 02:44 PM
You should not call glFlush(). It's a performance penalty with no benefit.

If you're double-buffered, [openGLContext flushBuffer]; If not, you should be.