SOLVED! thanks to Jonathan in the comments below, and Andy Zupko moments before on IM. 🙂 You guys rock.
I usually try to share solutions on this blog, but sometimes I just feel dumb and need some help. I’ve searched all over for this one, but I know some wicked smart people read this blog, so maybe they can help me.
So I am rendering some points in OpenGL ES on the iPhone and want to rotate them with touches. Swipe left/right to rotate on y axis, up/down on x axis. Simple. If you open up XCode and build a project from the OpenGL ES Application template, and then make the following changes, you’ll have what I have…
[c] CGFloat dx, dy;
CGPoint startPoint;
[/c]
[c]- (void)drawView {
// Replace the implementation of this method to do your own custom drawing
const GLfloat squareVertices[] = {
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f
};
const GLubyte squareColors[] = {
0, 0, 0, 255,
0, 0, 0, 255,
0, 0, 0, 255,
0, 0, 0, 255,
0, 0, 0, 255,
0, 0, 0, 255,
0, 0, 0, 255,
0, 0, 0, 255,
};
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glRotatef(dx, 1.0f, 0.0f, 0.0f);
glRotatef(dy, 0.0f, 1.0f, 0.0f);
dx = dy = 0.0;
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glVertexPointer(3, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
glEnableClientState(GL_COLOR_ARRAY);
glPointSize(4.0f);
glDrawArrays(GL_POINTS, 0, 8);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}[/c]
This adds a few points to make a cube, colors all the points black, and renders them as points. And rotates them around based on the dx, dy values.
[c]- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
startPoint = [touch locationInView:self];
}
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
dx = point.y – startPoint.y;
dy = point.x – startPoint.x;
startPoint = point;
}[/c]
This just calculates dx, dy as the distance the touch moved.
Now this all works fine for starters. Swipe left/right or up/down and the cube moves correctly. But rotate it down 90 degrees and then swipe horizontally and the thing rotates in the z axis. I know, I know, it’s still rotating on the local y axis, but that’s not what I want. I just want it so that no matter what the orientation, when I drag up and down, it looks like I’m dragging it that way, and same for left/right. I’ve hit a brick wall with this one. Some combination of push/pop matrix? mult matrix? Do I need to use quaternions? Am I just screwed? My brain is locked up.
Oh, and yes, I know how glRotatef works – rotate n degrees around a vector defined by the last three params. I’ve tackled it that way too, to no avail. I think I’ve exhausted every bright idea I’ve had on this one.