diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index dcce08386..f2aea4504 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -834,44 +834,48 @@ namespace opengl void Graphics::arc(DrawMode mode, float x, float y, float radius, float angle1, float angle2, int points) { - angle1 = fmod(angle1, 2.0f * (float)LOVE_M_PI); - angle2 = fmod(angle2, 2.0f * (float)LOVE_M_PI); - if (angle1 == angle2) + // Nothing to display with no points or equal angles. (Or is there with line mode?) + if (points <= 0 || angle1 == angle2) return; - else if (angle1 > angle2) - angle2 += (float)LOVE_M_PI * 2.0f; + // Oh, you want to draw a circle? + if (fabs(angle1 - angle2) >= 2.0f * (float) LOVE_M_PI) + { + circle(mode, x, y, radius, points); + return; + } + + float angle_shift = (angle2 - angle1) / points; + // Bail on precision issues. + if (angle_shift == 0.0) + return; - if (points <= 0) points = 1; - float angle_shift = ((angle2 - angle1) / points); float phi = angle1; + int num_coords = (points + 3) * 2; + float * coords = new float[num_coords]; + coords[0] = coords[num_coords - 2] = x; + coords[1] = coords[num_coords - 1] = y; + + for (int i = 0; i <= points; ++i, phi += angle_shift) + { + coords[2 * (i+1)] = x + radius * cos(phi); + coords[2 * (i+1) + 1] = y + radius * sin(phi); + } // GL_POLYGON can only fill-draw convex polygons, so we need to do stuff manually here if (mode == DRAW_LINE) - { - float *coords = new float[(points + 3) * 2]; - coords[0] = coords[2 * points + 4] = x; - coords[1] = coords[2 * points + 5] = y; - for (int i = 0; i <= points; ++i, phi += angle_shift) - { - coords[2 * (i+1)] = x + radius * cos(phi); - coords[2 * (i+1) + 1] = y - radius * sin(phi); - } - polyline(coords, (points + 3) * 2); // artifacts at sharp angles if set to looping - - delete[] coords; - } + polyline(coords, num_coords); // Artifacts at sharp angles if set to looping. else { glDisable(GL_TEXTURE_2D); - glBegin(GL_TRIANGLE_FAN); - glVertex2f(x, y); - for (int i = 0; i <= points; ++i, phi += angle_shift) - glVertex2f(x + radius * cos(phi), y - radius * sin(phi)); - glEnd(); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, (const GLvoid *) coords); + glDrawArrays(GL_TRIANGLE_FAN, 0, points + 2); + glDisableClientState(GL_VERTEX_ARRAY); glEnable(GL_TEXTURE_2D); } + delete[] coords; } /// @param mode the draw mode diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index a9691471e..a73ee6022 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -1018,10 +1018,11 @@ namespace opengl float y = (float)luaL_checknumber(L, 3); float radius = (float)luaL_checknumber(L, 4); int points; - if (lua_gettop(L) > 4) - points = lua_tointeger(L, 5); - else + if (lua_isnoneornil(L, 5)) points = radius > 10 ? radius : 10; + else + points = luaL_checkint(L, 5); + instance->circle(mode, x, y, radius, points); return 0; } @@ -1038,7 +1039,12 @@ namespace opengl float radius = (float)luaL_checknumber(L, 4); float angle1 = (float)luaL_checknumber(L, 5); float angle2 = (float)luaL_checknumber(L, 6); - int points = luaL_optint(L, 7, 10); + int points; + if (lua_isnoneornil(L, 7)) + points = radius > 10 ? radius : 10; + else + points = luaL_checkint(L, 7); + instance->arc(mode, x, y, radius, angle1, angle2, points); return 0; }