开发者

How do I make my own recordedPath in GLPaint Sample Code

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 = [NSMu开发者_StackOverflow中文版tableArray 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?


If you look at the Recording.data you will notice that each line is its own array. To capture the ink and play it back you need to have an array of arrays. For purposes of this demo - declare a mutable array - writRay

    @synthesize writRay;
//init in code
 writRay = [[NSMutableArray alloc]init];

Capture the ink

// Handles the continuation of a touch.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{  

 CGRect    bounds = [self bounds];
 UITouch*   touch = [[event touchesForView:self] anyObject];

 // Convert touch point from UIView referential to OpenGL one (upside-down flip)
 if (firstTouch) {
  firstTouch = NO;
  previousLocation = [touch previousLocationInView:self];
  previousLocation.y = bounds.size.height - previousLocation.y;
  /******************* create a new array for this stroke's points **************/
  [writRay addObject:[[NSMutableArray alloc]init]];
  /***** add 1st point *********/
  [[writRay objectAtIndex:[writRay count] -1]addObject:[NSValue valueWithCGPoint:previousLocation]];
 } else {
  location = [touch locationInView:self];
     location.y = bounds.size.height - location.y;
  previousLocation = [touch previousLocationInView:self];
  previousLocation.y = bounds.size.height - previousLocation.y;
  /********* add additional points *********/
  [[writRay objectAtIndex:[writRay count] -1]addObject:[NSValue valueWithCGPoint:previousLocation]];
 }

 // Render the stroke
 [self renderLineFromPoint:previousLocation toPoint:location];

}

Playback the ink.

- (void)playRay{

 if(writRay != NULL){

  for(int l = 0; l < [writRay count]; l++){
    //replays my writRay -1 because of location point
   for(int p = 0; p < [[writRay objectAtIndex:l]count] -1; p ++){
    [self renderLineFromPoint:[[[writRay objectAtIndex:l]objectAtIndex:p]CGPointValue] toPoint:[[[writRay objectAtIndex:l]objectAtIndex:p + 1]CGPointValue]];
   }
  }
 }
}

For best effect shake the screen to clear and call playRay from changeBrushColor in the AppController.


  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);


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜