What's the best way to draw and fill a polygon using cocos2d/opengl/something else?
Drawing and filling polygon
(17 posts) (9 voices)-
Posted 3 years ago #
-
I found this:
http://developer.apple.com/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.htmlIt seems to be able to do what I want. However, not quite sure how to combine this with cocos2d. Does anyone have any idea?
Posted 3 years ago # -
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 instanceQuestion 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.
Posted 3 years ago # -
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.
Posted 3 years ago # -
@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?
Posted 3 years ago # -
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.
Posted 3 years ago # -
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.Posted 3 years ago # -
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?)
Posted 3 years ago # -
Look at DrawSolidCircle in GLES-Render.mm
Posted 3 years ago # -
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
Posted 3 years ago # -
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[i*2] = j * CC_CONTENT_SCALE_FACTOR(); vertices[i*2+1] =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 ); }Posted 2 years ago # -
this code isn't for using a texture. If you want to draw a texture you use CCSprite.
Posted 2 years ago # -
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[i] = (ccVertex2F) { poli[i].x * CC_CONTENT_SCALE_FACTOR(), poli[i].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); }Posted 1 year ago # -
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?
Posted 1 year ago #
Reply
You must log in to post.