4

In my iOS application I have a texture applied to a sphere rendered in OpenGLES1. The sphere can be rotated by the user. How can I track where a given point on the texture is in 2D space at any given time?

For example, given point (200, 200) on a texture that's 1000px x 1000px, I'd like to place a UIButton on top of my OpenGL view that tracks the point as the sphere is manipulated.

What's the best way to do this?

On my first attempt, I tried to use a color-picking technique where I have a separate sphere in an off-screen framebuffer that uses a black texture with a red square at point (200, 200). Then, I used glReadPixels() to track the position of the red square and I moved my button accordingly. Unfortunately, grabbing all the pixel data and iterating it 60 times a second just isn't possible for obvious performance reasons. I tried a number of ways to optimize this hack (eg: iterating only the red pixels, iterating every 4th red pixel, etc), but it just didn't prove to be reliable.

I'm an OpenGL noob, so I'd appreciate any guidance. Is there a better solution? Thanks!

user2393462435
  • 2,652
  • 5
  • 37
  • 45
  • What coordinate information do you have. Do you have the sphere center coordinates? Rotation angle? Radius? Give me something to work with. – dave234 Jun 13 '15 at 04:45

1 Answers1

0

I think it's easier to keep track of where your ball is instead of searching for it with pixels. Then just have a couple of functions to translate your ball's coordinates to your view's coordinates (and back), then set your subview's center to the translated coordinates.

CGPoint translatePointFromGLCoordinatesToUIView(CGPoint coordinates, UIView *myGLView){

    //if your drawing coordinates were between (horizontal {-1.0 -> 1.0} vertical {-1 -> 1})
    CGFloat leftMostGLCoord       = -1;
    CGFloat rightMostGLCoord      = 1;
    CGFloat bottomMostGLCoord     = -1;
    CGFloat topMostGLCoord        = 1;

    CGPoint scale;
    scale.x = (rightMostGLCoord - leftMostGLCoord) / myGLView.bounds.size.width;
    scale.y = (topMostGLCoord - bottomMostGLCoord) / myGLView.bounds.size.height;


    coordinates.x -= leftMostGLCoord;
    coordinates.y -= bottomMostGLCoord;


    CGPoint translatedPoint;
    translatedPoint.x = coordinates.x / scale.x;
    translatedPoint.y =coordinates.y / scale.y;

    //flip y for iOS coordinates
    translatedPoint.y = myGLView.bounds.size.height - translatedPoint.y;

    return translatedPoint;
}

CGPoint translatePointFromUIViewToGLCoordinates(CGPoint pointInView, UIView *myGLView){

    //if your drawing coordinates were between (horizontal {-1.0 -> 1.0} vertical {-1 -> 1})
    CGFloat leftMostGLCoord       = -1;
    CGFloat rightMostGLCoord      = 1;
    CGFloat bottomMostGLCoord     = -1;
    CGFloat topMostGLCoord        = 1;

    CGPoint scale;
    scale.x = (rightMostGLCoord - leftMostGLCoord) / myGLView.bounds.size.width;
    scale.y = (topMostGLCoord - bottomMostGLCoord) / myGLView.bounds.size.height;

    //flip y for iOS coordinates
    pointInView.y = myGLView.bounds.size.height - pointInView.y;

    CGPoint translatedPoint;
    translatedPoint.x = leftMostGLCoord + (pointInView.x * scale.x);
    translatedPoint.y = bottomMostGLCoord + (pointInView.y * scale.y);

    return translatedPoint;
}

In my app I choose to use the iOS coordinate system for my drawing too. I just apply a projection matrix to my whole glkView the reconciles the coordinate system.

static GLKMatrix4 GLKMatrix4MakeIOSCoordsWithSize(CGSize screenSize){
    GLKMatrix4 matrix4 = GLKMatrix4MakeScale(
                                             2.0 / screenSize.width,
                                             -2.0 / screenSize.height,
                                             1.0);
    matrix4 = GLKMatrix4Translate(matrix4,-screenSize.width / 2.0, -screenSize.height / 2.0, 0);

    return matrix4;
}

This way you don't have to translate anything.

dave234
  • 4,793
  • 1
  • 14
  • 29
  • This is helpful, except that I'm not tracking the position of the sphere, I'm tracking a point on the sphere as the sphere rotates. I guess I could do something similar though, but I may need some help with the math... – user2393462435 Jun 05 '15 at 20:13