Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS OpenGL layer and UIScrollView

I'm creating a drawing app on the iPad where the user can draw and scroll through the drawing. (Think of a canvas 4000 pixels wide with a view port width of 1024) At the moment, I'm using OpenGL for the drawing, and with a width of 1024, it works great. When I change the frame size of the UIView to 4000, I get "failed to make complete framebuffer object 8cd6". When I reduced it to a width of 2000, I ended up getting "wacky" results. I know I can manipulate the frame correctly, as having a frame width of 500 creates the correct result.

I was also thinking of leaving the width 1024 and moving the camera of the OpenGL layer, but how would that work with the UIScrollView that I setup? So I'm unsure on what to do at the moment. Any advice?

Thanks in advance

P.S. The code is largely based of GLPaint sample Apple provides here

like image 275
Basil Al-Dajane Avatar asked Feb 20 '12 01:02

Basil Al-Dajane


2 Answers

I think you'd be best off with the scheme you suggest towards the end — keeping the OpenGL view static and outside of the scroll view, and moving its contents so as to match the movement of the scroll view.

Assuming you're using a GLKView, implement your glkView:drawInRect: so that it gets the contentOffset (and, probably, the bounds) properties from your scroll view and draws appropriately. E.g. (pretending you're using GLES 1.0 just because the matrix manipulation methods are so well known):

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // displayArea will be the area the scroll view is
    // currently displaying; taking just the bounds would
    // likely be fine too
    CGRect displayArea;
    displayArea.origin = scrollView.contentOffset;
    displayArea.size = scrollView.bounds.size;

    // assuming (0, 0) in the GL view is in the centre,
    // we'll adjust things so that it's in the corner ala
    // UIKit
    CGPoint centre = CGPointMake(
           displayArea.origin.x + displayArea.size.width*0.5f,
           displayArea.origin.y + displayArea.size.height*0.5f);

    glPushMatrix();

        // apply the scroll as per the scroll view
        // so that its centre is aligned with our centre
        glTranslatef(-centre.x, -centre.y, -1);

                /* rest of drawing here */

    glPopMatrix();
}

Then connect yourself as a delegate to the scrollview and just perform:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [glView setNeedsDisplay];
}

To ensure the GL redraws whenever the scroll view is scrolled.

like image 64
Tommy Avatar answered Nov 16 '22 21:11

Tommy


I would strongly recommend to do your zooming in panning with your OpenGL camera instead of trying to use it in a UIScrollView. It will be a little more work to set up, but ultimately the way to go IMHO.

like image 32
Jeshua Lacock Avatar answered Nov 16 '22 23:11

Jeshua Lacock