views:

408

answers:

1

Hi there,

I'm pretty new to Objective-C and even C in general here, so please bear with me. My main goal is to display my NSMutableArray of CGPoints (via NSValue) with glDrawArrays(GL_LINE_STRIP, 0, points);

I noticed that cocos2d requires an array(?) pointer *poli like so:


void ccDrawPoly( CGPoint *poli, int points, BOOL closePolygon ) { ... }

So I tried to convert my NSMutableArray to a C array and I can access/debug the CGPoints just fine:


NSUInteger count = [points count];
id *buffer = malloc(sizeof(NSValue) * count);
[points getObjects: buffer];
for(uint i = 0; i < count; i++) {
  NSValue *val = buffer[i];
  CGPoint p = [val CGPointValue];
  NSLog(@"points x %i: %f", i, p.x);
  /* shows up in the console as:
  -----------points at 0: 42.000000
  -----------points at 1: 44.000000
  ... etc
  */
}
free(buffer);

But I guess where I'm stuck is getting them into a data type that either ccDrawPoly or glDrawArrays(GL_LINE_STRIP, 0, points) will accept. Which is apparently a struct or something, but I'm not sure how to get them into a struct.

Any help would be greatly appreciated! Thanks!

A: 

Here's the new code I'm using in case it helps someone else:



@interface Blah : CCLayer
{
  CGPoint *parr;
  NSUInteger parr_count;
  NSUInteger parr_max;
}
@end

@implementation Blah

-(id) init
{
  if((self = [super init])) {
    parr_count = 0;
    parr_max = 64;
    parr = malloc(parr_max * 2 * sizeof(CGPoint));
  }
  return self;
}

...

-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
  CGPoint prev_loc = [touch previousLocationInView: [touch view]];
  CGPoint prev_glloc = [[CCDirector sharedDirector] convertToGL:prev_loc];

  CGPoint loc = [touch locationInView: [touch view]];
  CGPoint glloc = [[CCDirector sharedDirector] convertToGL:loc];

  if(parr_count >= 2048) { // hard limit of 2048
    return;
  } else if(parr_count == parr_max) {
    parr_max = 2 * parr_max;
    parr = realloc(parr, parr_max * 2 * sizeof(GLfloat));
  }

  parr[parr_count] = prev_glloc;
  parr_count += 1;
  parr[parr_count] = glloc;
  parr_count += 1;
}

...

-(void) draw
{
  if(parr_count < 2048)
    ccDrawPoly(parr, parr_count, NO);
}

- (void) dealloc
{
  free(parr);
  [super dealloc];
}

@end


It seems to work fine! If anyone has any optimizations or comments I'd be grateful, thanks.

taber
I'd be sure to include code to check and make sure you don't overflow your `points` array. As it stands, your code is vulnerable to buffer overflows.
Dave DeLong
Thanks Dave! I've updated the code, added parr_max, etc. - does that do the trick? Thanks again.
taber