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
精彩评论