Browse Source

Add eclipse and roundedRectangle to love.graphics

muddmaker 10 years ago
parent
commit
fbc419fda6

+ 78 - 0
src/modules/graphics/opengl/Graphics.cpp

@@ -1134,6 +1134,28 @@ void Graphics::circle(DrawMode mode, float x, float y, float radius, int points)
 	delete[] coords;
 	delete[] coords;
 }
 }
 
 
+void Graphics::eclipse(DrawMode mode, float x, float y, float a, float b, int points)
+{
+	float two_pi = static_cast<float>(LOVE_M_PI * 2);
+	if (points <= 0) points = 1;
+	float angle_shift = (two_pi / points);
+	float phi = .0f;
+	
+	float *coords = new float[2 * (points + 1)];
+	for (int i = 0; i < points; ++i, phi += angle_shift)
+	{
+		coords[2*i]   = x + a * cosf(phi);
+		coords[2*i+1] = y + b * sinf(phi);
+	}
+	
+	coords[2*points]   = coords[0];
+	coords[2*points+1] = coords[1];
+	
+	polygon(mode, coords, (points + 1) * 2);
+	
+	delete[] coords;
+}
+	
 void Graphics::arc(DrawMode mode, float x, float y, float radius, float angle1, float angle2, int points)
 void Graphics::arc(DrawMode mode, float x, float y, float radius, float angle1, float angle2, int points)
 {
 {
 	// Nothing to display with no points or equal angles. (Or is there with line mode?)
 	// Nothing to display with no points or equal angles. (Or is there with line mode?)
@@ -1184,6 +1206,62 @@ void Graphics::arc(DrawMode mode, float x, float y, float radius, float angle1,
 	delete[] coords;
 	delete[] coords;
 }
 }
 
 
+void Graphics::roundedRectangle(DrawMode mode, float x, float y, float w, float h, float r, float points)
+{
+	if (points < 1)
+		points = 1;
+	
+	if (r == 0)
+	{
+		rectangle(mode, x, y, w, h);
+		return;
+	}
+	
+	const float half_pi = static_cast<float>(LOVE_M_PI / 2);
+	float angle_shift = half_pi / (points + 1);
+	
+	int num_coords = (points + 2) * 8;
+	float *coords = new float[num_coords + 2];
+	float phi = .0f;
+	
+	for (int i = 0; i <= points + 2; ++i, phi += angle_shift)
+	{
+		coords[2 * i] = x + r * (1 - cosf(phi));
+		coords[2 * i + 1] = y + r * (1 - sinf(phi));
+	}
+	
+	phi = half_pi;
+	
+	for (int i = points + 2; i <= 2 * (points + 2); ++i, phi += angle_shift)
+	{
+		coords[2 * i] = x + w - r * cosf(phi);
+		coords[2 * i + 1] = y + r * (1 - sinf(phi));
+	}
+	
+	phi = 2 * half_pi;
+	
+	for (int i = 2 * (points + 2); i <= 3 * (points + 2); ++i, phi += angle_shift)
+	{
+		coords[2 * i] = x + w - r * cosf(phi);
+		coords[2 * i + 1] = y + h - r * sinf(phi);
+	}
+	
+	phi =  3 * half_pi;
+	
+	for (int i = 3 * (points + 2); i <= 4 * (points + 2); ++i, phi += angle_shift)
+	{
+		coords[2 * i] = x + r * (1 - cosf(phi));
+		coords[2 * i + 1] = y + h - r * sinf(phi);
+	}
+	
+	coords[num_coords] = coords[0];
+	coords[num_coords + 1] = coords[1];
+	
+	polygon(mode, coords, num_coords + 2);
+	
+	delete[] coords;
+}
+	
 /// @param mode    the draw mode
 /// @param mode    the draw mode
 /// @param coords  the coordinate array
 /// @param coords  the coordinate array
 /// @param count   the number of coordinates/size of the array
 /// @param count   the number of coordinates/size of the array

+ 23 - 0
src/modules/graphics/opengl/Graphics.h

@@ -377,6 +377,17 @@ public:
 	 **/
 	 **/
 	void circle(DrawMode mode, float x, float y, float radius, int points = 10);
 	void circle(DrawMode mode, float x, float y, float radius, int points = 10);
 
 
+	/**
+	 * Draws an eclipse using the specified arguments.
+	 * @param mode The mode of drawing (line/filled).
+	 * @param x X-coordinate of center
+	 * @param y Y-coordinate of center
+	 * @param a Radius in x-direction
+	 * @param b Radius in y-direction
+	 * @param points Number of points to use to draw the circle.
+	 **/
+	void eclipse(DrawMode mode, float x, float y, float a, float b, int points = 10);
+	
 	/**
 	/**
 	 * Draws an arc using the specified arguments.
 	 * Draws an arc using the specified arguments.
 	 * @param mode The mode of drawing (line/filled).
 	 * @param mode The mode of drawing (line/filled).
@@ -389,6 +400,18 @@ public:
 	 **/
 	 **/
 	void arc(DrawMode mode, float x, float y, float radius, float angle1, float angle2, int points = 10);
 	void arc(DrawMode mode, float x, float y, float radius, float angle1, float angle2, int points = 10);
 
 
+	/**
+	 * Draws a rounded rectangle.
+	 * @param mode The mode of drawing (line/filled).
+	 * @param x X-coordinate of top-left corner
+	 * @param y Y-coordinate of top-left corner
+	 * @param w The width of the rectangle.
+	 * @param h The height of the rectangle.
+	 * @param r The radius of the corners.
+	 * @param points The number of points to use per corner
+	 **/
+	void roundedRectangle(DrawMode mode, float x, float y, float w, float h, float r, float points = 10);
+	
 	/**
 	/**
 	 * Draws a polygon with an arbitrary number of vertices.
 	 * Draws a polygon with an arbitrary number of vertices.
 	 * @param mode The type of drawing (line/filled).
 	 * @param mode The type of drawing (line/filled).

+ 45 - 0
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -1556,6 +1556,27 @@ int w_circle(lua_State *L)
 	return 0;
 	return 0;
 }
 }
 
 
+int w_eclipse(lua_State *L)
+{
+	Graphics::DrawMode mode;
+	const char *str = luaL_checkstring(L, 1);
+	if (!Graphics::getConstant(str, mode))
+		return luaL_error(L, "Incorrect draw mode %s", str);
+		
+	float x = (float)luaL_checknumber(L, 2);
+	float y = (float)luaL_checknumber(L, 3);
+	float a = (float)luaL_checknumber(L, 4);
+	float b = (float)luaL_checknumber(L, 5);
+	int points;
+	if (lua_isnoneornil(L, 6))
+		points = a > 10 || b > 10 ? (int)(a + b) : 10;
+	else
+		points = luaL_checkint(L, 6);
+
+	instance()->eclipse(mode, x, y, a, b, points);
+	return 0;
+}
+	
 int w_arc(lua_State *L)
 int w_arc(lua_State *L)
 {
 {
 	Graphics::DrawMode mode;
 	Graphics::DrawMode mode;
@@ -1578,6 +1599,28 @@ int w_arc(lua_State *L)
 	return 0;
 	return 0;
 }
 }
 
 
+int w_roundedRectangle(lua_State *L)
+{
+	Graphics::DrawMode mode;
+	const char *str = luaL_checkstring(L, 1);
+	if (!Graphics::getConstant(str, mode))
+		return luaL_error(L, "Incorrect draw mode %s", str);
+	
+	float x = (float)luaL_checknumber(L, 2);
+	float y = (float)luaL_checknumber(L, 3);
+	float w = (float)luaL_checknumber(L, 4);
+	float h = (float)luaL_checknumber(L, 5);
+	float r = (float)luaL_checknumber(L, 6);
+	int points;
+	if (lua_isnoneornil(L, 7))
+		points = r > 10 ? (int)(r) : 10;
+	else
+		points = luaL_checkint(L, 7);
+	
+	instance()->roundedRectangle(mode, x, y, w, h, r, points);
+	return 0;
+}
+	
 int w_polygon(lua_State *L)
 int w_polygon(lua_State *L)
 {
 {
 	int args = lua_gettop(L) - 1;
 	int args = lua_gettop(L) - 1;
@@ -1764,7 +1807,9 @@ static const luaL_Reg functions[] =
 	{ "line", w_line },
 	{ "line", w_line },
 	{ "rectangle", w_rectangle },
 	{ "rectangle", w_rectangle },
 	{ "circle", w_circle },
 	{ "circle", w_circle },
+	{ "eclipse", w_eclipse },
 	{ "arc", w_arc },
 	{ "arc", w_arc },
+	{ "roundedRectangle", w_roundedRectangle },
 
 
 	{ "polygon", w_polygon },
 	{ "polygon", w_polygon },
 
 

+ 2 - 0
src/modules/graphics/opengl/wrap_Graphics.h

@@ -109,7 +109,9 @@ int w_point(lua_State *L);
 int w_line(lua_State *L);
 int w_line(lua_State *L);
 int w_rectangle(lua_State *L);
 int w_rectangle(lua_State *L);
 int w_circle(lua_State *L);
 int w_circle(lua_State *L);
+int w_eclipse(lua_State *L);
 int w_arc(lua_State *L);
 int w_arc(lua_State *L);
+int w_roundedRectangle(lua_State *L);
 int w_polygon(lua_State *L);
 int w_polygon(lua_State *L);
 int w_push(lua_State *L);
 int w_push(lua_State *L);
 int w_pop(lua_State *L);
 int w_pop(lua_State *L);