Thursday, October 9, 2008

Circles, Ellipses, and Regular Polygons in OpenGL ES

The iPhone's use of OpenGL ES means that a lot of games and other programs can be ported relatively quickly. Unfortunately, the iPhone uses a relatively old version of OpenGL ES (1.1), and by the very nature of an embedded graphic engine, a lot of the niceties of the expansive OpenGL have been removed, including functions to draw a lot of standard primitive shapes.

Lines and squares are pretty easy, of course, but what about more complex shapes? Well, you're on your own for those, so unless you're comfortable with doing a little math, you're going to have problems with OpenGL ES. Here's one example - how do you draw an ellipse or circle in OpenGL? I'm not talking about a sphere (we'll look at that in a later post, maybe), but a two-dimensional circle? Or a triangle?

These two functions draw (respectively) an ellipse and a circle (which is just an ellipse with equal height and width) at a given location, either filled, or outlined. But, they actually do more then that. You can specify how precise you want the ellipse to be using the segments argument. If you specify, three, for example, it will draw a three-sided polygon (aka a triangle). If you specify 360, you'll get a 360-sided regular polygon, which is going to look like a circle on all but the biggest displays. For most purposes on the iPhone, a value above 12 will look like a circle. A value less than 3 won't work, but the error checking is your responsibility. :)


void GLDrawEllipse (int segments, CGFloat width, CGFloat height, CGPoint center, bool filled)
{
glTranslatef(center.x, center.y, 0.0);
GLfloat vertices[segments*2];
int count=0;
for (GLfloat i = 0; i < 360.0f; i+=(360.0f/segments))
{
vertices[count++] = (cos(degreesToRadian(i))*width);
vertices[count++] = (sin(degreesToRadian(i))*height);
}
glVertexPointer (2, GL_FLOAT , 0, vertices);
glDrawArrays ((filled) ? GL_TRIANGLE_FAN : GL_LINE_LOOP, 0, segments);
}
void GLDrawCircle (int circleSegments, CGFloat circleSize, CGPoint center, bool filled)
{
GLDrawEllipse(circleSegments, circleSize, circleSize, center, filled);
}

No comments:

Post a Comment