Hi,
I have a curious problem about an App which MainView is inherited from NSOpenGlView. I am able to draw many things in it, like a basic OpenGL tutorial.... but when I try to implement a basic trackball, it looks like the app waits until I release the mouse button before it refreshes my view... even if I call directly the "DrawRect" callback from the "MouseDragged" callback, it acts the same. Then, I really can't find out how to do such a basic thing and what is the problem about my solution..
Any idea?
My NSOpenGLVIew has double buffer, and and additional depth buffer. Here are the main messages.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)mouseDragged:(NSEvent *)theEvent {
//[[self openGLContext] makeCurrentContext];
float curPos[3], dx, dy, dz;
dx = curPos[0] - lastPos[0];
dy = curPos[1] - lastPos[1];
dz = curPos[2] - lastPos[2];
angle = 90.0 * sqrt(dx*dx + dy*dy + dz*dz);
axis[0] = lastPos[1]*curPos[2] - lastPos[2]*curPos[1];
axis[1] = lastPos[2]*curPos[0] - lastPos[0]*curPos[2];
axis[2] = lastPos[0]*curPos[1] - lastPos[1]*curPos[0];
//glutPostRedisplay();
//[self drawRect:self.bounds]; // different attempts
[self setNeedsDisplay:YES]; //
//[self display];
}
#pragma mark Mouse Handling
- (void)mouseDown:(NSEvent *)theEvent {
m_PreviousMouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
ptov(m_PreviousMouseLoc.x,m_PreviousMouseLoc.y,m_width,m_height,lastPos);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)mouseUp:(NSEvent *)theEvent {
[self setNeedsDisplay:YES];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ptov(int x, int y, int width, int height, float v[3]){
float a,d;
// project x,y onto 1/2 sphere centered within width and height
v[0] = (2.0*x - width)/ width;
v[1] = (height - 2.0*y)/ height;
d = sqrt(v[0]*v[0] + v[1]*v[1]);
v[2] = cos((PI/2)*((d < 1.0) ? d : 1.0));
a = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
v[0] *=a;
v[1] *=a;
v[2] *=a;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-(void)prepareOpenGL{
if( ![ self loadGLTextures ] ){
NSLog(@"Failed to load GL Textures");
}
GLint swapInt = 1;
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; // set to vbl sync
//glEnable( GL_TEXTURE_2D ); // Enable texture mapping
glShadeModel( GL_SMOOTH ); // Enable smooth shading
glClearColor( 0.0f, 0.0f, 0.0f, 0.5f ); // Black background
glClearDepth( 1.0f ); // Depth buffer setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glEnable (GL_BLEND);
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPolygonOffset (1.0f, 1.0f);
firstOccurenceOfDrawRect = NO;
/* // set start values...
rVel[0] = 0.3; rVel[1] = 0.1; rVel[2] = 0.2;
rAccel[0] = 0.003; rAccel[1] = -0.005; rAccel[2] = 0.004;*/
[[self window] setAcceptsMouseMovedEvents: YES];
glViewport(0, 0, (GLsizei) self.bounds.size.width, (GLsizei) self.bounds.size.height);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void) drawRect: (NSRect) rect
{
/// if (firstOccurenceOfDrawRect)
// [self initGL];
// On charge la matrice de projection pour définir ce que l'on va voir et comment
glMatrixMode(GL_PROJECTION);
// On centre
glLoadIdentity();
// On prend du recul
glOrtho(-1.0f, 1.0f, -1.5f, 1.5f, -10.0f, 10.0f);
// On efface ce qui a été dessiné auparavant
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// On va maintenant définir ce que l'on veut dessiner
glMatrixMode(GL_MODELVIEW);
// Avant de commencer à dessiner, on va affecter de deux rotations le repère des coordonnées du cube pour le faire "bouger"
glLoadIdentity();
glRotatef(angle, axis[0], axis[1], axis[2]);
// [self resizeGL]; // forces projection matrix update (does test for size changes)
// [self updateModelView];
glColor3f (1.0, 1.0, 1.0);
glDisable(GL_CULL_FACE);
glFrontFace(GL_CW);
glutSolidTeapot(200.0);
glFrontFace(GL_CCW);
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, texture[ 0 ] ); // Select our texture
glBegin( GL_QUADS );
// Front
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( -1.0f, -1.0f, 0.0f ); // Bottom left
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 1.0f, -1.0f, 0.0f ); // Bottom right
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 1.0f, 1.0f, 0.0f ); // Top right
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -1.0f, 1.0f, 0.0f ); // Top left
glEnd();
glBindTexture( GL_TEXTURE_2D, texture[ 1 ] ); // Select our texture
glBegin( GL_QUADS );
// side
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 0.0f, -1.0f, -1.0f ); // Bottom right
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 0.0f, 1.0f, -1.0f ); // Top right
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( 0.0f, 1.0f, 1.0f ); // Top left
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( 0.0f, -1.0f, 1.0f ); // Bottom left
glEnd();
glBindTexture( GL_TEXTURE_2D, texture[ 2 ] ); // Select our texture
glBegin( GL_QUADS );
// Top
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -1.0f, 0.0f, -1.0f ); // Top left
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( -1.0f, 0.0f, 1.0f ); // Bottom left
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 1.0f, 0.0f, 1.0f ); // Bottom right
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 1.0f, 0.0f, -1.0f ); // Top right
glEnd();
glDisable(GL_TEXTURE_2D);
glColor3f (1.0, 1.0, 1.0);
glDisable(GL_CULL_FACE);
glFrontFace(GL_CW);
glutSolidTeapot(200.0);
[self postRemoteImage];
[[self openGLContext] flushBuffer];
}