views:

470

answers:

2

Hi, I've recently downloaded the GLPaint sample code and looked at a very interesting part in it. There is a recordedPaths NSMutableArray that has points in it that are then read and drawn by GLPaint.

It's declared here:

NSMutableArray *recordedPaths;
recordedPaths = [NSMutableArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Recording" ofType:@"data"]];
if([recordedPaths count])
     [self performSelector:@selector(playback:) withObject:recordedPaths afterDelay:0.2];

This is the code for playback:

 - (void) playback:(NSMutableArray*)recordedPaths {

     NSData*                    data = [recordedPaths objectAtIndex:0];

     CGPoint*               point = (CGPoint*)[data bytes];

     NSUInteger               count = [data length] / sizeof(CGPoint),

                              i;



     //Render the current path

     for(i = 0; i < count - 1; ++i, ++point)

          [self renderLineFromPoint:*point toPoint:*(point + 1)];



     //Render the next path after a short delay 

     [recordedPaths removeObjectAtIndex:0];

     if([recordedPaths count])

          [self performSelector:@selector(playback:) withObject:recordedPaths afterDelay:0.01];

}

From this I understand that recordedPaths is a mutable array that his in it struct c arrays of CGPoint that are then read and rendered. I'd like to put in my own array and i've been having trouble with that.

I tried changing the recordedPaths declaration to this:

      NSMutableArray *myArray = [[NSMutableArray alloc] init];

      CGPoint* points;

      CGPoint a = CGPointMake(50,50);

      int i;

      for (i=0; i<100; i++,points++) {

           a = CGPointMake(i,i);

           points = &a;

      }

      NSData *data = [NSData dataWithBytes:&points length:sizeof(*points)];

      [myArray addObject:data];

This didn't work though... Any advice?

A: 
  CGPoint* points;
  CGPoint a = CGPointMake(50,50);
  int i;
  for (i=0; i<100; i++,points++) {
       a = CGPointMake(i,i);
       points = &a;
  }
  NSData *data = [NSData dataWithBytes:&points length:sizeof(*points)];

Wrong code.

(1) You need an array of points. Simply declaring CGPoint* points; won't create an array of points, just an uninitialized pointer of CGPoint. You need to allocate space for the array either with

CGPoint points[100];

or

CGPoint* points = malloc(sizeof(CGPoint)*100);

Remember to free the points if you choose the malloc way.

(2) To copy value to the content of the pointer you need to use

*points = a;

But I suggest you keep the pointer points invariant in the loop, since you're going to reuse it later. Use the array syntax points[i].

(3)

sizeof(*points)

Since *points is just one CGPoint, so the sizeof is always 8 bytes. You need to multiply the result by 100 to get the correct length.

(4)

 [NSData dataWithBytes:&points ...

points already is a pointer to the actual data. You don't need to take the address of it again. Just pass points directly.


So the final code should look like

  CGPoint* points = malloc(sizeof(CGPoint)*100); // make a cast if the compiler warns.
  CGPoint a;
  int i;
  for (i=0; i<100; i++) {
       a = CGPointMake(i,i);
       points[i] = a;
  }
  NSData *data = [NSData dataWithBytes:points length:sizeof(*points)*100];
  free(points);
KennyTM
I tried the code,with this added lines in the end: NSMutableArray *myArray = [[NSMutableArray alloc] init]; [myArray addObject:data]; [self performSelector:@selector(playback:) withObject:recordedPaths afterDelay:0.2];but it didn't show up anything when I launched the app in the simulator
gizmoitai
@giz how to do you implement `-renderLineFromPoint:toPoint:`?
KennyTM
Well, the playback function implements it... (See the original question for the code)
gizmoitai
@giz: Ah right, sorry.
KennyTM
So how do I fix this?
gizmoitai
@giz: Does anything show up without the delay?
KennyTM
nothing shows up.. the screen is blackHere is the source code of GLPaint: (It's an apple sample code)http://developer.apple.com/iphone/library/samplecode/GLPaint/GLPaint.zip
gizmoitai
A: 

Hi there,

I was just reading over this post as I am trying to achive a similar thing. With modifications to the original project by Apple, I was able to create a new 'shape' by modifying the code accordingly.

Note that it only draws a diagonal line... several times. But the theory is there to create your own drawing.

I've taken the code from KennyTM's post and incorporated it into the 'payback' function, this could be adapted to create the array in the initWithCoder function and then send it through like the original code but for now - this will get you a result.

    CGPoint* points = malloc(sizeof(CGPoint)*100);
CGPoint a;
int iter;
for (iter=0; iter<200; iter++) {
    a = CGPointMake(iter,iter);
    points[iter] = a;
}
NSData *data = [NSData dataWithBytes:points length:sizeof(*points)*100];
free(points);

CGPoint*            point = (CGPoint*)[data bytes];
NSUInteger      count = [data length] / sizeof(CGPoint),
                    i;

for(i = 0; i < count - 1; ++i, ++point)
    [self renderLineFromPoint:*point toPoint:*(point + 1)];

[recordedPaths removeObjectAtIndex:0];
if([recordedPaths count])
    [self performSelector:@selector(playback:) withObject:recordedPaths afterDelay:0.01];

I am still in my first weeks on openGL coding, so forgive any glaring mistakes / bad methods and thanks for the help!

Hope this helps

dpmguise