Drawing and filling polygon

Forums Programming cocos2d support (graphics engine) Drawing and filling polygon

This topic contains 16 replies, has 9 voices, and was last updated by  Xtazyatu 2 years, 1 month ago.

Viewing 17 posts - 1 through 17 (of 17 total)
Author Posts
Author Posts
July 22, 2009 at 9:51 pm #216298

quano
@quano

What’s the best way to draw and fill a polygon using cocos2d/opengl/something else?

July 23, 2009 at 12:18 pm #253845

quano
@quano

I found this:

http://developer.apple.com/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html

It seems to be able to do what I want. However, not quite sure how to combine this with cocos2d. Does anyone have any idea?

July 25, 2009 at 3:48 pm #253846

quano
@quano

This is probably a crappy solution, but I think this would at least _work_.

Each CocosNode has a texture (Texture2D *). Texture2D class can be initialized from an UIImage. UIImage can be initialized from a CGImageRef. It is possible to create a CGImageRef context for the quartz lib.

So, what you would do is:

1. Create the CGImageRef context for quartz

2. Draw into this image with quartz

3. Initialize an UIImage with this CGImageRef

4. Make a Texture2D that is initialized with that image

5. Set the texture of a CocosNode to that Texture2D instance

Question is if this would be fast enough to do. I would prefer if you could sort of get a CGImageRef from the CocosNode directly and draw into it instead of going through all these steps, but I haven’t found a way to do that yet (and I’m kind of a noob at this so it’s hard to actually get somewhere at all).

You could of course use only opengl probably, but I really like the features that quartz has, and would prefer to use it. Especially the paths features is something I’d like to use (for drawing shapes and filling them, and moving the path nodes around in real time).

Unless anyone has got any advice, this is what I’m gonna try to do when I get some spare time.

July 26, 2009 at 12:47 am #253847

Codemattic
Moderator
@codemattic

What you need is an algorithm that converts a polygon into triangles. If its a convex poly then thats no problem, if it can be concave then its difficult.

July 26, 2009 at 12:53 am #253848

Codemattic
Moderator
@codemattic

http://en.wikipedia.org/wiki/Polygon_triangulation

http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml

http://www.cs.unc.edu/~dm/CODE/GEM/chapter.html

July 26, 2009 at 12:06 pm #253849

quano
@quano

@Codemattic:

Okay, so if I interpreted you correctly, you’re saying that you can only fill triangles, right? So if I want to fill a polygon, I first have to triangulate it.

I’ve implemented (or rather translated) the ear clipping algorithm for triangulation in actionscript once, so I guess I should be able to do it for objective-c. But, with this method that you’re suggesting, what’s the next step? When I’ve got the triangulated polygon, then what?

I still would very much like to use paths to draw shapes and fill them, as mentioned above. Implementing my own methods to do this sounds hard, and unnecessary considering that they’ve already been implemented in quartz. Is there really no better way than the one I suggested above to use quartz with cocos2d?

July 26, 2009 at 12:30 pm #253850

Codemattic
Moderator
@codemattic

Quartz will give you excellent looking polygons, with antialiasing, line widths, join types, etc. But it will be slow. If you need to draw some polygons that are generated at startup and dont change, then use quartz and save them to textures. But if you need polygons that are changing and animated in your game then probably go for opengles – which will be harder to code, but run faster.

July 26, 2009 at 5:13 pm #253851

quano
@quano

I’m having some trouble getting the polygon that I’m drawing to get alpha. I do glColor4f(1,0,0,.1), yet the background does not seem to affect the polygons color.

EDIT:

Nm, it did actually get transparent. Just hard to see because of how the background looked. Changed to another one and then it was easy to see that the polygon as a matter of fact did have alpha.

August 1, 2009 at 1:04 pm #253852

popgoblin
Participant
@popgoblin

Seems to be a bit bothersome,just to get a filled circle, for instance. I’ve been playing around with the drawPrimitimes sample, but need a way to fill a circle. Any hints (code?)

August 1, 2009 at 1:43 pm #253853

Steffen Altwiese
Moderator
@steve-oldmeadow

Look at DrawSolidCircle in GLES-Render.mm

August 1, 2009 at 11:27 pm #253854

quano
@quano

http://stackoverflow.com/questions/1081832/how-to-draw-a-solid-circle-with-cocos2d-for-iphone/1172971#1172971

March 6, 2010 at 7:12 pm #253855

wihu
Participant
@wihu

I was having same problem, trying to draw and fill polygon, but managed to find a quick solution from the link above,

I copied and modified a bit the ccDrawPoly function:

void ccFillPoly( CGPoint *poli, int points, BOOL closePolygon )

{

// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY

// Needed states: GL_VERTEX_ARRAY,

// Unneeded states: GL_TEXTURE_2D, GL_TEXTURE_COORD_ARRAY, GL_COLOR_ARRAY

glDisable(GL_TEXTURE_2D);

glDisableClientState(GL_TEXTURE_COORD_ARRAY);

glDisableClientState(GL_COLOR_ARRAY);

glVertexPointer(2, GL_FLOAT, 0, poli);

if( closePolygon )

// glDrawArrays(GL_LINE_LOOP, 0, points);

glDrawArrays(GL_TRIANGLE_FAN, 0, points);

else

glDrawArrays(GL_LINE_STRIP, 0, points);

// restore default state

glEnableClientState(GL_COLOR_ARRAY);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glEnable(GL_TEXTURE_2D);

}

example use below:

@implementation TestLayer

- (void)draw {

glColor4f(0.0f, 1.0f, 0.0f, 1.0f);

CGSize s = CGSizeMake(150, 200);

CGPoint vertices[4]={

ccp(50,50),ccp(s.width,0),

ccp(s.width,s.height),ccp(0,s.height),

};

ccFillPoly(vertices, 4, YES);

}

@end

March 11, 2011 at 3:47 pm #253856

horseshoe7
Participant
@horseshoe7

That’s great! I also just modified the ccDrawCircle method:

static void ccDrawFilledCircle( CGPoint center, float r, float a, NSUInteger segs)
{
int additionalSegment = 1;

const float coef = 2.0f * (float)M_PI/segs;

GLfloat *vertices = calloc( sizeof(GLfloat)*2*(segs+2), 1);
if( ! vertices )
return;

for(NSUInteger i=0;i<=segs;i++)
{
float rads = i*coef;
GLfloat j = r * cosf(rads + a) + center.x;
GLfloat k = r * sinf(rads + a) + center.y;

vertices = j * CC_CONTENT_SCALE_FACTOR();
vertices =k * CC_CONTENT_SCALE_FACTOR();
}
vertices[(segs+1)*2] = center.x * CC_CONTENT_SCALE_FACTOR();
vertices[(segs+1)*2+1] = center.y * CC_CONTENT_SCALE_FACTOR();

// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_TEXTURE_COORD_ARRAY, GL_COLOR_ARRAY
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, segs+additionalSegment); // this is what will fill it in.

// restore default state
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);

free( vertices );
}

April 13, 2011 at 4:24 pm #253857

badawe
Participant
@badawe

@wihu Thanks for sharing the code! But where you define what texture should use?

April 26, 2011 at 2:42 pm #253858

horseshoe7
Participant
@horseshoe7

this code isn’t for using a texture. If you want to draw a texture you use CCSprite.

September 23, 2011 at 2:19 pm #253859

Thnx4TheXP
Participant
@thnx4thexp

Retina Display Fill Poly:

void ccFillPoly(CGPoint*poli,int points,BOOL closePolygon) {
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

ccVertex2F newPoint[points];

if( sizeof(CGPoint) == sizeof(ccVertex2F) ) {
if(CC_CONTENT_SCALE_FACTOR() != 1 ) {
memcpy(newPoint, poli, points * sizeof(ccVertex2F) );
for(NSUInteger i=0; i<points;i++)
newPoint = (ccVertex2F) { poli.x * CC_CONTENT_SCALE_FACTOR(), poli.y * CC_CONTENT_SCALE_FACTOR() };
glVertexPointer(2, GL_FLOAT, 0, newPoint);
} else
glVertexPointer(2, GL_FLOAT, 0, poli);
}

if (closePolygon) glDrawArrays(GL_TRIANGLE_FAN, 0, points);
else glDrawArrays(GL_LINE_STRIP, 0, points);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
}

March 15, 2012 at 2:03 pm #253860

Xtazyatu
@xtazyatu

ok, but what if you what to draw an unlimited number on filled poly, how can i do that?

I have a screen I need to fill with the filled poly.

I get the poly’s coordinates based on a sprite’s movement ( my main character).

in big words i managed to get it to draw correctly but once i complete the drawing of this poly, when the sprite will move again i want to start to draw another poly.

any ideas?

Viewing 17 posts - 1 through 17 (of 17 total)

You must be logged in to reply to this topic.