Browse Source

Added Mesh objects and love.graphics.newMesh. Mesh objects are similar to Geometry but they're drawables (the relationship between meshes and images is the opposite of geometry and images.)
Removed Geometry objects and re-added Quads.

example:
local vertices = {{0, 0, 0, 0}, {100, 0, 1, 0}, {100, 100, 1, 1}, {0, 100, 0, 1}}
mesh = love.graphics.newMesh(vertices, image, "fan")
..
love.graphics.draw(mesh, 0, 0)

--HG--
branch : Mesh

Alex Szpakowski 12 years ago
parent
commit
1e696c4505

+ 36 - 24
platform/macosx/love-framework.xcodeproj/project.pbxproj

@@ -259,6 +259,8 @@
 		FA636D8E171B72A70065623F /* wrap_RandomGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */; };
 		FA636D8F171B72A70065623F /* wrap_RandomGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FA636D8D171B72A70065623F /* wrap_RandomGenerator.h */; };
 		FA7175AA178E8418001FE7FE /* lua.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7175A9178E8418001FE7FE /* lua.h */; };
+		FA7AA59217F6AC1F00704BE2 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */; };
+		FA7AA59317F6AC1F00704BE2 /* wrap_Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */; };
 		FA7C937A16DCC6C2006F2BEE /* wrap_Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */; };
 		FA7C937B16DCC6C2006F2BEE /* wrap_Math.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7C937616DCC6C2006F2BEE /* wrap_Math.h */; };
 		FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; };
@@ -277,12 +279,11 @@
 		FAC5710117402D1100D147E4 /* BezierCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC570FD17402D1100D147E4 /* BezierCurve.h */; };
 		FAC5710217402D1100D147E4 /* wrap_BezierCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */; };
 		FAC5710317402D1100D147E4 /* wrap_BezierCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC570FF17402D1100D147E4 /* wrap_BezierCurve.h */; };
-		FAC86E631724552C00EED715 /* wrap_Geometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E611724552C00EED715 /* wrap_Geometry.cpp */; };
-		FAC86E641724552C00EED715 /* wrap_Geometry.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E621724552C00EED715 /* wrap_Geometry.h */; };
-		FAC86E691724555D00EED715 /* DrawGable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E651724555D00EED715 /* DrawGable.cpp */; };
-		FAC86E6A1724555D00EED715 /* DrawGable.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E661724555D00EED715 /* DrawGable.h */; };
-		FAC86E6B1724555D00EED715 /* Geometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E671724555D00EED715 /* Geometry.cpp */; };
-		FAC86E6C1724555D00EED715 /* Geometry.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E681724555D00EED715 /* Geometry.h */; };
+		FAC86E631724552C00EED715 /* wrap_Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E611724552C00EED715 /* wrap_Quad.cpp */; };
+		FAC86E641724552C00EED715 /* wrap_Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E621724552C00EED715 /* wrap_Quad.h */; };
+		FAC86E6A1724555D00EED715 /* DrawQable.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E661724555D00EED715 /* DrawQable.h */; };
+		FAC86E6B1724555D00EED715 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E671724555D00EED715 /* Quad.cpp */; };
+		FAC86E6C1724555D00EED715 /* Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E681724555D00EED715 /* Quad.h */; };
 		FAE010DB170DDE99006F29D0 /* ddsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010D8170DDE99006F29D0 /* ddsinfo.h */; };
 		FAE010DC170DDE99006F29D0 /* ddsparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010D9170DDE99006F29D0 /* ddsparse.cpp */; };
 		FAE010DD170DDE99006F29D0 /* ddsparse.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010DA170DDE99006F29D0 /* ddsparse.h */; };
@@ -310,6 +311,8 @@
 		FAF272B616E3D46400CC193A /* Thread.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272B216E3D46400CC193A /* Thread.h */; };
 		FAF272B716E3D46400CC193A /* threads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF272B316E3D46400CC193A /* threads.cpp */; };
 		FAF272B816E3D46400CC193A /* threads.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272B416E3D46400CC193A /* threads.h */; };
+		FAF4376F17F4AC530074F9E2 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF4376D17F4AC530074F9E2 /* Mesh.cpp */; };
+		FAF4377017F4AC530074F9E2 /* Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF4376E17F4AC530074F9E2 /* Mesh.h */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -798,6 +801,8 @@
 		FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_RandomGenerator.cpp; sourceTree = "<group>"; };
 		FA636D8D171B72A70065623F /* wrap_RandomGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_RandomGenerator.h; sourceTree = "<group>"; };
 		FA7175A9178E8418001FE7FE /* lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua.h; sourceTree = "<group>"; };
+		FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Mesh.cpp; sourceTree = "<group>"; };
+		FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Mesh.h; sourceTree = "<group>"; };
 		FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Math.cpp; sourceTree = "<group>"; };
 		FA7C937616DCC6C2006F2BEE /* wrap_Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Math.h; sourceTree = "<group>"; };
 		FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = "<absolute>"; };
@@ -816,12 +821,11 @@
 		FAC570FD17402D1100D147E4 /* BezierCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BezierCurve.h; sourceTree = "<group>"; };
 		FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_BezierCurve.cpp; sourceTree = "<group>"; };
 		FAC570FF17402D1100D147E4 /* wrap_BezierCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_BezierCurve.h; sourceTree = "<group>"; };
-		FAC86E611724552C00EED715 /* wrap_Geometry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Geometry.cpp; sourceTree = "<group>"; };
-		FAC86E621724552C00EED715 /* wrap_Geometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Geometry.h; sourceTree = "<group>"; };
-		FAC86E651724555D00EED715 /* DrawGable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DrawGable.cpp; sourceTree = "<group>"; };
-		FAC86E661724555D00EED715 /* DrawGable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawGable.h; sourceTree = "<group>"; };
-		FAC86E671724555D00EED715 /* Geometry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Geometry.cpp; sourceTree = "<group>"; };
-		FAC86E681724555D00EED715 /* Geometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Geometry.h; sourceTree = "<group>"; };
+		FAC86E611724552C00EED715 /* wrap_Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Quad.cpp; sourceTree = "<group>"; };
+		FAC86E621724552C00EED715 /* wrap_Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Quad.h; sourceTree = "<group>"; };
+		FAC86E661724555D00EED715 /* DrawQable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawQable.h; sourceTree = "<group>"; };
+		FAC86E671724555D00EED715 /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = "<group>"; };
+		FAC86E681724555D00EED715 /* Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = "<group>"; };
 		FAE010D8170DDE99006F29D0 /* ddsinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsinfo.h; sourceTree = "<group>"; };
 		FAE010D9170DDE99006F29D0 /* ddsparse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsparse.cpp; sourceTree = "<group>"; };
 		FAE010DA170DDE99006F29D0 /* ddsparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsparse.h; sourceTree = "<group>"; };
@@ -849,6 +853,8 @@
 		FAF272B216E3D46400CC193A /* Thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Thread.h; sourceTree = "<group>"; };
 		FAF272B316E3D46400CC193A /* threads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = threads.cpp; sourceTree = "<group>"; };
 		FAF272B416E3D46400CC193A /* threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = threads.h; sourceTree = "<group>"; };
+		FAF4376D17F4AC530074F9E2 /* Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mesh.cpp; sourceTree = "<group>"; };
+		FAF4376E17F4AC530074F9E2 /* Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mesh.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -1437,15 +1443,14 @@
 				4941079838020ECA049B5C21 /* Color.h */,
 				58BA2BB460AF3C591B22690E /* Drawable.cpp */,
 				5D93601669875EE06721689E /* Drawable.h */,
-				FAC86E651724555D00EED715 /* DrawGable.cpp */,
-				FAC86E661724555D00EED715 /* DrawGable.h */,
-				FAC86E671724555D00EED715 /* Geometry.cpp */,
-				FAC86E681724555D00EED715 /* Geometry.h */,
+				FAC86E661724555D00EED715 /* DrawQable.h */,
 				03F17FF546D637744E263961 /* Graphics.cpp */,
 				777352284E262F48543E6E7F /* Graphics.h */,
 				58CC50E70A375FDF53EF01B6 /* Image.cpp */,
 				1DA41DFF0869489411A71AFC /* Image.h */,
 				75093EE94918576801F50993 /* opengl */,
+				FAC86E671724555D00EED715 /* Quad.cpp */,
+				FAC86E681724555D00EED715 /* Quad.h */,
 				4B731754147B27AF73AC5358 /* Volatile.cpp */,
 				0CFF64090F0F4F481BB80CF0 /* Volatile.h */,
 			);
@@ -1629,6 +1634,8 @@
 				389E3CEC356050A27784290E /* Graphics.h */,
 				56D6030A0B8F7397715062B9 /* Image.cpp */,
 				3CFE5C4A12D5675E7C9C7BF9 /* Image.h */,
+				FAF4376D17F4AC530074F9E2 /* Mesh.cpp */,
+				FAF4376E17F4AC530074F9E2 /* Mesh.h */,
 				2E406F8328543EC63EB922C6 /* OpenGL.cpp */,
 				2C87695707B046B536F347D8 /* OpenGL.h */,
 				48A206C9004150640C432100 /* ParticleSystem.cpp */,
@@ -1645,12 +1652,14 @@
 				3AFB3A18384A2D22352262B1 /* wrap_Canvas.h */,
 				7A3B52AF1FBE73FC36AD50C8 /* wrap_Font.cpp */,
 				3CDA3E9B364F17A902384AAC /* wrap_Font.h */,
-				FAC86E611724552C00EED715 /* wrap_Geometry.cpp */,
-				FAC86E621724552C00EED715 /* wrap_Geometry.h */,
+				FAC86E611724552C00EED715 /* wrap_Quad.cpp */,
+				FAC86E621724552C00EED715 /* wrap_Quad.h */,
 				1A9810F758AC1D1E4B6431FD /* wrap_Graphics.cpp */,
 				05DF237B657042515F3B4E52 /* wrap_Graphics.h */,
 				14AE68E14C2C74526A612FA0 /* wrap_Image.cpp */,
 				78A2127828793F7A778D7932 /* wrap_Image.h */,
+				FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */,
+				FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */,
 				5F42052D7C8271A1105541DE /* wrap_ParticleSystem.cpp */,
 				678E42771C9B415628A3234D /* wrap_ParticleSystem.h */,
 				FA577A8716C71CF000860150 /* wrap_Shader.cpp */,
@@ -1896,6 +1905,7 @@
 				FA7C937B16DCC6C2006F2BEE /* wrap_Math.h in Headers */,
 				FAF272A516E3D44400CC193A /* Channel.h in Headers */,
 				FAF272A716E3D44400CC193A /* LuaThread.h in Headers */,
+				FAF4377017F4AC530074F9E2 /* Mesh.h in Headers */,
 				FAF272A916E3D44400CC193A /* ThreadModule.h in Headers */,
 				FAF272AB16E3D44400CC193A /* wrap_Channel.h in Headers */,
 				FAF272AD16E3D44400CC193A /* wrap_LuaThread.h in Headers */,
@@ -1909,13 +1919,14 @@
 				FAE010E1170DE25E006F29D0 /* ddsHandler.h in Headers */,
 				FAE010E5170DF75C006F29D0 /* wrap_CompressedData.h in Headers */,
 				FA0CDE3D1710F9A50056E8D7 /* FormatHandler.h in Headers */,
+				FA7AA59317F6AC1F00704BE2 /* wrap_Mesh.h in Headers */,
 				FAEC808B1710FEA60057279A /* ImageData.h in Headers */,
 				FAEC808F1711E76C0057279A /* CompressedData.h in Headers */,
 				FA636D8B171B70920065623F /* RandomGenerator.h in Headers */,
 				FA636D8F171B72A70065623F /* wrap_RandomGenerator.h in Headers */,
-				FAC86E641724552C00EED715 /* wrap_Geometry.h in Headers */,
-				FAC86E6A1724555D00EED715 /* DrawGable.h in Headers */,
-				FAC86E6C1724555D00EED715 /* Geometry.h in Headers */,
+				FAC86E641724552C00EED715 /* wrap_Quad.h in Headers */,
+				FAC86E6A1724555D00EED715 /* DrawQable.h in Headers */,
+				FAC86E6C1724555D00EED715 /* Quad.h in Headers */,
 				FA03546D1731F3A700284828 /* simplexnoise1234.h in Headers */,
 				FA3D9E0E16E68DE600CA6630 /* Cursor.h in Headers */,
 				FA3D9E1216E68EAE00CA6630 /* Cursor.h in Headers */,
@@ -2112,6 +2123,7 @@
 				FA08F61C16C7541400F007B5 /* Font.cpp in Sources */,
 				FA08F61D16C7541400F007B5 /* GLee.c in Sources */,
 				FA08F61E16C7541400F007B5 /* Graphics.cpp in Sources */,
+				FAF4376F17F4AC530074F9E2 /* Mesh.cpp in Sources */,
 				FA08F61F16C7541400F007B5 /* Image.cpp in Sources */,
 				FA08F62016C7541400F007B5 /* OpenGL.cpp in Sources */,
 				FA08F62116C7541400F007B5 /* ParticleSystem.cpp in Sources */,
@@ -2131,6 +2143,7 @@
 				FA08F63116C7542600F007B5 /* wrap_Image.cpp in Sources */,
 				FA08F63216C7542600F007B5 /* wrap_ImageData.cpp in Sources */,
 				FA08F63416C7542D00F007B5 /* JoystickModule.cpp in Sources */,
+				FA7AA59217F6AC1F00704BE2 /* wrap_Mesh.cpp in Sources */,
 				FA08F63516C7542D00F007B5 /* wrap_JoystickModule.cpp in Sources */,
 				FA08F63616C7543400F007B5 /* Keyboard.cpp in Sources */,
 				FA08F63716C7543400F007B5 /* Keyboard.cpp in Sources */,
@@ -2219,9 +2232,8 @@
 				FAEC808E1711E76C0057279A /* CompressedData.cpp in Sources */,
 				FA636D8A171B70920065623F /* RandomGenerator.cpp in Sources */,
 				FA636D8E171B72A70065623F /* wrap_RandomGenerator.cpp in Sources */,
-				FAC86E631724552C00EED715 /* wrap_Geometry.cpp in Sources */,
-				FAC86E691724555D00EED715 /* DrawGable.cpp in Sources */,
-				FAC86E6B1724555D00EED715 /* Geometry.cpp in Sources */,
+				FAC86E631724552C00EED715 /* wrap_Quad.cpp in Sources */,
+				FAC86E6B1724555D00EED715 /* Quad.cpp in Sources */,
 				FA03546C1731F3A700284828 /* simplexnoise1234.cpp in Sources */,
 				FA3D9E0D16E68DE600CA6630 /* Cursor.cpp in Sources */,
 				FA3D9E1116E68EAE00CA6630 /* Cursor.cpp in Sources */,

+ 2 - 2
src/common/runtime.cpp

@@ -680,14 +680,14 @@ StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[] =
 
 	// Graphics
 	{"Drawable", GRAPHICS_DRAWABLE_ID},
-	{"DrawGable", GRAPHICS_DRAWGABLE_ID},
 	{"Image", GRAPHICS_IMAGE_ID},
-	{"Geometry", GRAPHICS_GEOMETRY_ID},
+	{"Quad", GRAPHICS_QUAD_ID},
 	{"Font", GRAPHICS_FONT_ID},
 	{"ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_ID},
 	{"SpriteBatch", GRAPHICS_SPRITE_BATCH_ID},
 	{"Canvas", GRAPHICS_CANVAS_ID},
 	{"Shader", GRAPHICS_SHADER_ID},
+	{"Mesh", GRAPHICS_MESH_ID},
 
 	// Image
 	{"ImageData", IMAGE_IMAGE_DATA_ID},

+ 8 - 6
src/common/types.h

@@ -45,14 +45,15 @@ enum Type
 
 	// Graphics
 	GRAPHICS_DRAWABLE_ID,
-	GRAPHICS_DRAWGABLE_ID,
+	GRAPHICS_DRAWQABLE_ID,
 	GRAPHICS_IMAGE_ID,
-	GRAPHICS_GEOMETRY_ID,
+	GRAPHICS_QUAD_ID,
 	GRAPHICS_FONT_ID,
 	GRAPHICS_PARTICLE_SYSTEM_ID,
 	GRAPHICS_SPRITE_BATCH_ID,
 	GRAPHICS_CANVAS_ID,
 	GRAPHICS_SHADER_ID,
+	GRAPHICS_MESH_ID,
 
 	// Image
 	IMAGE_IMAGE_DATA_ID,
@@ -128,14 +129,15 @@ const bits FONT_RASTERIZER_T = (bits(1) << FONT_RASTERIZER_ID) | OBJECT_T;
 
 // Graphics.
 const bits GRAPHICS_DRAWABLE_T = (bits(1) << GRAPHICS_DRAWABLE_ID) | OBJECT_T;
-const bits GRAPHICS_DRAWGABLE_T = (bits(1) << GRAPHICS_DRAWGABLE_ID) | GRAPHICS_DRAWABLE_T;
-const bits GRAPHICS_IMAGE_T = (bits(1) << GRAPHICS_IMAGE_ID) | GRAPHICS_DRAWGABLE_T;
-const bits GRAPHICS_GEOMETRY_T = (bits(1) << GRAPHICS_GEOMETRY_ID) | OBJECT_T;
+const bits GRAPHICS_DRAWQABLE_T = (bits(1) << GRAPHICS_DRAWQABLE_ID) | GRAPHICS_DRAWABLE_T;
+const bits GRAPHICS_IMAGE_T = (bits(1) << GRAPHICS_IMAGE_ID) | GRAPHICS_DRAWQABLE_T;
+const bits GRAPHICS_QUAD_T = (bits(1) << GRAPHICS_QUAD_ID) | OBJECT_T;
 const bits GRAPHICS_FONT_T = (bits(1) << GRAPHICS_FONT_ID) | OBJECT_T;
 const bits GRAPHICS_PARTICLE_SYSTEM_T = (bits(1) << GRAPHICS_PARTICLE_SYSTEM_ID) | GRAPHICS_DRAWABLE_T;
 const bits GRAPHICS_SPRITE_BATCH_T = (bits(1) << GRAPHICS_SPRITE_BATCH_ID) | GRAPHICS_DRAWABLE_T;
-const bits GRAPHICS_CANVAS_T = (bits(1) << GRAPHICS_CANVAS_ID) | GRAPHICS_DRAWGABLE_T;
+const bits GRAPHICS_CANVAS_T = (bits(1) << GRAPHICS_CANVAS_ID) | GRAPHICS_DRAWQABLE_T;
 const bits GRAPHICS_SHADER_T = (bits(1) << GRAPHICS_SHADER_ID) | OBJECT_T;
+const bits GRAPHICS_MESH_T = (bits(1) << GRAPHICS_MESH_ID) | GRAPHICS_DRAWABLE_T;
 
 // Image.
 const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T;

+ 9 - 9
src/modules/graphics/DrawGable.h → src/modules/graphics/DrawQable.h

@@ -18,12 +18,12 @@
  * 3. This notice may not be removed or altered from any source distribution.
  **/
 
-#ifndef LOVE_GRAPHICS_DRAWGABLE_H
-#define LOVE_GRAPHICS_DRAWGABLE_H
+#ifndef LOVE_GRAPHICS_DRAWQABLE_H
+#define LOVE_GRAPHICS_DRAWQABLE_H
 
 // LOVE
 #include "Drawable.h"
-#include "Geometry.h"
+#include "Quad.h"
 
 namespace love
 {
@@ -31,21 +31,21 @@ namespace graphics
 {
 
 /**
- * A DrawGable is anything that be drawn in part with a Geometry object.
+ * A DrawQable is anything that be drawn in part with a Quad object.
  **/
-class DrawGable : public Drawable
+class DrawQable : public Drawable
 {
 public:
 
 	/**
 	 * Destructor.
 	 **/
-	virtual ~DrawGable();
+	virtual ~DrawQable() {}
 
 	/**
 	 * Draws the object with the specified transformation.
 	 *
-	 * @param geom The Geometry object to use to draw the object.
+	 * @param quad The Quad object to use to draw the object.
 	 * @param x The position of the object along the x-axis.
 	 * @param y The position of the object along the y-axis.
 	 * @param angle The angle of the object (in radians).
@@ -56,10 +56,10 @@ public:
 	 * @param kx Shear along the x-axis.
 	 * @param ky Shear along the y-axis.
 	 **/
-	virtual void drawg(Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0;
+	virtual void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0;
 };
 
 } // graphics
 } // love
 
-#endif // LOVE_GRAPHICS_DRAWGABLE_H
+#endif // LOVE_GRAPHICS_DRAWQABLE_H

+ 0 - 197
src/modules/graphics/Geometry.cpp

@@ -1,197 +0,0 @@
-/**
- * Copyright (c) 2006-2013 LOVE Development Team
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- **/
-
-#include "Geometry.h"
-#include "common/Exception.h"
-#include "common/Vector.h"
-#include "modules/math/MathModule.h"
-
-using love::math::Math;
-
-// STD
-#include <limits>
-#include <algorithm> // for std::swap()
-#include <cstring> // For memcpy
-
-namespace love
-{
-namespace graphics
-{
-
-Geometry::Geometry(const std::vector<Vertex> &polygon, const std::vector<uint16> &elements, Geometry::DrawMode mode)
-	: vertexArray(NULL)
-	, vertexCount(polygon.size())
-	, elementArray(NULL)
-	, elementCount(elements.size())
-	, vertexColors(false)
-	, drawMode(mode)
-{
-	if (polygon.size() < 3)
-		throw love::Exception("At least 3 vertices are needed to create a Geometry.");
-
-	for (size_t i = 0; i < elementCount; i++)
-	{
-		// All values in the element array need to be a valid vertex index.
-		if (elements[i] >= vertexCount)
-			throw love::Exception("Invalid vertex map value");
-	}
-
-	vertexArray = new Vertex[vertexCount];
-	memcpy(vertexArray, &polygon[0], vertexCount * sizeof(Vertex));
-
-	if (elementCount > 0)
-	{
-		elementArray = new uint16[elementCount];
-		memcpy(elementArray, &elements[0], elementCount * sizeof(uint16));
-	}
-}
-
-Geometry::Geometry(float x, float y, float w, float h, float sw, float sh)
-	: vertexArray(NULL)
-	, vertexCount(4)
-	, elementArray(NULL)
-	, elementCount(0)
-	, vertexColors(false)
-	, drawMode(DRAW_MODE_FAN)
-{
-	float s0 = x/sw, s1 = (x+w)/sw, t0 = y/sh, t1 = (y+h)/sh;
-
-	Vertex verts[4] = {
-		{0,0, s0,t0, 255, 255, 255, 255},
-		{w,0, s1,t0, 255, 255, 255, 255},
-		{w,h, s1,t1, 255, 255, 255, 255},
-		{0,h, s0,t1, 255, 255, 255, 255}
-	};
-
-	vertexArray = new Vertex[4];
-
-	for (int i = 0; i < 4; i++)
-		vertexArray[i] = verts[i];
-}
-
-Geometry::Geometry(const Geometry &other)
-	: vertexCount(other.vertexCount)
-	, elementCount(other.elementCount)
-	, vertexColors(other.vertexColors)
-	, drawMode(other.drawMode)
-{
-	vertexArray = new Vertex[vertexCount];
-	memcpy(vertexArray, other.vertexArray, vertexCount * sizeof(Vertex));
-
-	if (elementCount > 0)
-	{
-		elementArray = new uint16[elementCount];
-		memcpy(elementArray, other.elementArray, elementCount * sizeof(uint16));
-	}
-}
-
-Geometry &Geometry::operator=(const Geometry &other)
-{
-	if (this != &other)
-	{
-		Geometry temp(other);
-		std::swap(vertexArray, temp.vertexArray);
-		std::swap(elementArray, temp.elementArray);
-
-		vertexCount  = temp.vertexCount;
-		elementCount = temp.elementCount;
-
-		vertexColors = other.vertexColors;
-		drawMode     = other.drawMode;
-	}
-
-	return *this;
-}
-
-Geometry::~Geometry()
-{
-	delete[] vertexArray;
-	delete[] elementArray;
-}
-
-const Vertex &Geometry::getVertex(size_t i) const
-{
-	if (i >= vertexCount)
-		throw Exception("Invalid vertex index");
-
-	return vertexArray[i];
-}
-
-void Geometry::setVertex(size_t i, const Vertex &v)
-{
-	if (i >= vertexCount)
-		throw Exception("Invalid vertex index");
-
-	vertexArray[i] = v;
-}
-
-
-void Geometry::setElementArray(const uint16 *elements, size_t count)
-{
-	if (count == 0 || elements == NULL)
-	{
-		delete[] elementArray;
-		elementArray = NULL;
-		elementCount = 0;
-		return;
-	}
-
-	for (size_t i = 0; i < count; i++)
-	{
-		if (elements[i] >= vertexCount)
-			throw love::Exception("Invalid vertex map value");
-	}
-
-	if (count > elementCount)
-	{
-		delete[] elementArray;
-		elementArray = new uint16[count];
-	}
-
-	elementCount = count;
-	memcpy(elementArray, elements, elementCount * sizeof(uint16));
-}
-
-void Geometry::setVertexColors(bool on)
-{
-	vertexColors = on;
-}
-
-bool Geometry::getConstant(const char *in, Geometry::DrawMode &out)
-{
-	return drawModes.find(in, out);
-}
-
-bool Geometry::getConstant(Geometry::DrawMode in, const char *&out)
-{
-	return drawModes.find(in, out);
-}
-
-StringMap<Geometry::DrawMode, Geometry::DRAW_MODE_MAX_ENUM>::Entry Geometry::drawModeEntries[] =
-{
-	{"fan", Geometry::DRAW_MODE_FAN},
-	{"strip", Geometry::DRAW_MODE_STRIP},
-	{"triangles", Geometry::DRAW_MODE_TRIANGLES}
-};
-
-StringMap<Geometry::DrawMode, Geometry::DRAW_MODE_MAX_ENUM> Geometry::drawModes(Geometry::drawModeEntries, sizeof(Geometry::drawModeEntries));
-
-} // graphics
-} // love

+ 0 - 146
src/modules/graphics/Geometry.h

@@ -1,146 +0,0 @@
-/**
- * Copyright (c) 2006-2013 LOVE Development Team
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- **/
-
-#ifndef LOVE_GRAPHICS_GEOMETRY_H
-#define LOVE_GRAPHICS_GEOMETRY_H
-
-// LOVE
-#include "common/Object.h"
-#include "common/math.h"
-#include "common/StringMap.h"
-#include "common/int.h"
-
-// stdlib
-#include <vector>
-
-namespace love
-{
-namespace graphics
-{
-
-class Geometry : public Object
-{
-public:
-
-	// How the Geometry's vertices are used when drawing.
-	// http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png
-	enum DrawMode
-	{
-		DRAW_MODE_FAN,
-		DRAW_MODE_STRIP,
-		DRAW_MODE_TRIANGLES,
-		DRAW_MODE_MAX_ENUM
-	};
-
-	/**
-	 * Creates a new geometry object from a std::vector<vertex>.
-	 **/
-	Geometry(const std::vector<Vertex> &polygon, const std::vector<uint16> &elements, DrawMode mode = DRAW_MODE_FAN);
-
-	/**
-	 * Creates a new geometry from (texture) quad information.
-	 * @param x Top left position in the image.
-	 * @param y Top left position in the image.
-	 * @param w Width of the quad.
-	 * @param h Height of the quad.
-	 * @param sw The reference width, the width of the Image.
-	 * @param sh The reference height, the height of the Image.
-	 */
-	Geometry(float x, float y, float w, float h, float sw, float sh);
-
-	Geometry(const Geometry &other);
-	Geometry &operator=(const Geometry &other);
-	virtual ~Geometry();
-
-	const Vertex &getVertex(size_t i) const;
-	void setVertex(size_t i, const Vertex &v);
-
-	/**
-	 * Returns a pointer to the vertex array.
-	 **/
-	inline const Vertex *getVertexArray() const
-	{
-		return vertexArray;
-	}
-
-	/**
-	 * Returns the size of the vertex array.
-	 **/
-	inline size_t getVertexCount() const
-	{
-		return vertexCount;
-	}
-
-	inline const uint16 *getElementArray() const
-	{
-		return elementArray;
-	}
-
-	inline size_t getElementCount() const
-	{
-		return elementCount;
-	}
-
-	void setElementArray(const uint16 *elements, size_t count);
-
-	/**
-	 * Sets whether this Geometry will use custom per-vertex colors.
-	 **/
-	void setVertexColors(bool on);
-
-	/**
-	 * Returns whether this Geometry is using custom per-vertex colors.
-	 **/
-	inline bool hasVertexColors() const
-	{
-		return vertexColors;
-	};
-
-	/**
-	 * Returns the mode used when drawing this Geometry.
-	 **/
-	inline DrawMode getDrawMode() const
-	{
-		return drawMode;
-	}
-
-	static bool getConstant(const char *in, DrawMode &out);
-	static bool getConstant(DrawMode in, const char *&out);
-
-private:
-
-	Vertex *vertexArray;
-	size_t vertexCount;
-
-	uint16 *elementArray;
-	size_t elementCount;
-
-	bool vertexColors;
-
-	DrawMode drawMode;
-
-	static StringMap<DrawMode, DRAW_MODE_MAX_ENUM>::Entry drawModeEntries[];
-	static StringMap<DrawMode, DRAW_MODE_MAX_ENUM> drawModes;
-};
-
-} // graphics
-} // love
-
-#endif // LOVE_GRAPHICS_GEOMETRY_H

+ 2 - 2
src/modules/graphics/Image.h

@@ -23,7 +23,7 @@
 
 // LOVE
 #include "graphics/Volatile.h"
-#include "graphics/DrawGable.h"
+#include "graphics/DrawQable.h"
 #include "common/StringMap.h"
 
 namespace love
@@ -31,7 +31,7 @@ namespace love
 namespace graphics
 {
 
-class Image : public DrawGable, public Volatile
+class Image : public DrawQable, public Volatile
 {
 public:
 

+ 114 - 0
src/modules/graphics/Quad.cpp

@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2006-2013 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "Quad.h"
+
+// C
+#include <cstring> // For memcpy
+
+namespace love
+{
+namespace graphics
+{
+
+Quad::Quad(const Quad::Viewport &v, float sw, float sh)
+	: sw(sw)
+	, sh(sh)
+{
+	memset(vertices, 255, sizeof(Vertex) * NUM_VERTICES);
+	refresh(v, sw, sh);
+}
+
+Quad::~Quad()
+{
+}
+
+void Quad::refresh(const Quad::Viewport &v, float sw, float sh)
+{
+	viewport = v;
+
+	vertices[0].x = 0;
+	vertices[0].y = 0;
+	vertices[1].x = 0;
+	vertices[1].y = v.h;
+	vertices[2].x = v.w;
+	vertices[2].y = v.h;
+	vertices[3].x = v.w;
+	vertices[3].y = 0;
+
+	vertices[0].s = v.x/sw;
+	vertices[0].t = v.y/sh;
+	vertices[1].s = v.x/sw;
+	vertices[1].t = (v.y+v.h)/sh;
+	vertices[2].s = (v.x+v.w)/sw;
+	vertices[2].t = (v.y+v.h)/sh;
+	vertices[3].s = (v.x+v.w)/sw;
+	vertices[3].t = v.y/sh;
+}
+
+void Quad::setViewport(const Quad::Viewport &v)
+{
+	refresh(v, sw, sh);
+}
+
+Quad::Viewport Quad::getViewport() const
+{
+	return viewport;
+}
+
+void Quad::flip(bool x, bool y)
+{
+	Vertex temp[NUM_VERTICES];
+
+	if (x)
+	{
+		memcpy(temp, vertices, sizeof(Vertex) * NUM_VERTICES);
+		vertices[0].s = temp[3].s;
+		vertices[0].t = temp[3].t;
+		vertices[1].s = temp[2].s;
+		vertices[1].t = temp[2].t;
+		vertices[2].s = temp[1].s;
+		vertices[2].t = temp[1].t;
+		vertices[3].s = temp[0].s;
+		vertices[3].t = temp[0].t;
+	}
+
+	if (y)
+	{
+		memcpy(temp, vertices, sizeof(Vertex) * NUM_VERTICES);
+		vertices[0].s = temp[1].s;
+		vertices[0].t = temp[1].t;
+		vertices[1].s = temp[0].s;
+		vertices[1].t = temp[0].t;
+		vertices[2].s = temp[3].s;
+		vertices[2].t = temp[3].t;
+		vertices[3].s = temp[2].s;
+		vertices[3].t = temp[2].t;
+	}
+}
+
+const Vertex *Quad::getVertices() const
+{
+	return vertices;
+}
+
+} // graphics
+} // love

+ 69 - 0
src/modules/graphics/Quad.h

@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2006-2013 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_GRAPHICS_QUAD_H
+#define LOVE_GRAPHICS_QUAD_H
+
+// LOVE
+#include "common/Object.h"
+#include "common/math.h"
+
+namespace love
+{
+namespace graphics
+{
+
+class Quad : public Object
+{
+public:
+
+	struct Viewport
+	{
+		float x, y;
+		float w, h;
+	};
+
+	static const size_t NUM_VERTICES = 4;
+
+	Quad(const Viewport &v, float sw, float sh);
+	virtual ~Quad();
+
+	void refresh(const Viewport &v, float sw, float sh);
+	void setViewport(const Viewport &v);
+	Viewport getViewport() const;
+
+	void flip(bool x, bool y);
+
+	const Vertex *getVertices() const;
+
+private:
+
+	Vertex vertices[NUM_VERTICES];
+
+	Viewport viewport;
+	float sw;
+	float sh;
+
+}; // Quad
+
+} // graphics
+} // love
+
+#endif // LOVE_GRAPHICS_QUAD_H

+ 10 - 49
src/modules/graphics/opengl/Canvas.cpp

@@ -607,52 +607,20 @@ void Canvas::draw(float x, float y, float angle, float sx, float sy, float ox, f
 	drawv(t, vertices);
 }
 
-void Canvas::drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
+void Canvas::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
 {
 	static Matrix t;
 	t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
 
-	// flip texture coordinates vertically
-	size_t vcount = geom->getVertexCount();
-	const Vertex *w = geom->getVertexArray();
-	Vertex *v = new Vertex[vcount];
-	for (size_t i = 0; i < vcount; ++i)
-	{
-		v[i] = w[i];
-		v[i].t = 1. - v[i].t;
-	}
-
-	// use colors stored in geometry (horrible, horrible hack)
-	if (geom->hasVertexColors())
-	{
-		glEnableClientState(GL_COLOR_ARRAY);
-		glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), (GLvoid *)&v->r);
-	}
-
-	GLenum glmode;
-	switch (geom->getDrawMode())
-	{
-	case Geometry::DRAW_MODE_FAN:
-	default:
-		glmode = GL_TRIANGLE_FAN;
-		break;
-	case Geometry::DRAW_MODE_STRIP:
-		glmode = GL_TRIANGLE_STRIP;
-		break;
-	case Geometry::DRAW_MODE_TRIANGLES:
-		glmode = GL_TRIANGLES;
-		break;
-	}
-
-	drawv(t, v, vcount, glmode, geom->getElementArray(), geom->getElementCount());
+	const Vertex *v = quad->getVertices();
 
-	if (geom->hasVertexColors())
-	{
-		glDisableClientState(GL_COLOR_ARRAY);
-		gl.setColor(gl.getColor());
-	}
+	// flip texture coordinates vertically.
+	Vertex w[4];
+	memcpy(w, v, sizeof(Vertex) * 4);
+	for (size_t i = 0; i < 4; i++)
+		w[i].t = 1.0f - w[i].t;
 
-	delete[] v;
+	drawv(t, w);
 }
 
 bool Canvas::checkCreateStencil()
@@ -785,7 +753,7 @@ int Canvas::getHeight()
 	return height;
 }
 
-void Canvas::drawv(const Matrix &t, const Vertex *v, GLsizei count, GLenum mode, const uint16 *e, GLsizei ecount) const
+void Canvas::drawv(const Matrix &t, const Vertex *v) const
 {
 	glPushMatrix();
 
@@ -796,17 +764,10 @@ void Canvas::drawv(const Matrix &t, const Vertex *v, GLsizei count, GLenum mode,
 	glEnableClientState(GL_VERTEX_ARRAY);
 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
-	// XXX: drawg() enables/disables GL_COLOR_ARRAY in order to use the color
-	//      defined in the geometry to draw itself.
-	//      if the drawing method below is changed to use something other than
-	//      glDrawArrays(), drawg() needs to be updated accordingly!
 	glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].x);
 	glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].s);
 
-	if (e != 0 && ecount > 0)
-		glDrawElements(mode, ecount, GL_UNSIGNED_SHORT, (GLvoid *) e);
-	else
-		glDrawArrays(mode, 0, count);
+	glDrawArrays(GL_QUADS, 0, 4);
 
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 	glDisableClientState(GL_VERTEX_ARRAY);

+ 5 - 5
src/modules/graphics/opengl/Canvas.h

@@ -21,7 +21,7 @@
 #ifndef LOVE_GRAPHICS_OPENGL_CANVAS_H
 #define LOVE_GRAPHICS_OPENGL_CANVAS_H
 
-#include "graphics/DrawGable.h"
+#include "graphics/DrawQable.h"
 #include "graphics/Volatile.h"
 #include "graphics/Image.h"
 #include "graphics/Color.h"
@@ -38,7 +38,7 @@ namespace graphics
 namespace opengl
 {
 
-class Canvas : public DrawGable, public Volatile
+class Canvas : public DrawQable, public Volatile
 {
 public:
 
@@ -65,9 +65,9 @@ public:
 	virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
 
 	/**
-	 * @copydoc DrawGable::drawg()
+	 * @copydoc DrawQable::drawq()
 	 **/
-	void drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
+	void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
 
 	/**
 	 * Create and attach a stencil buffer to this Canvas' framebuffer, if necessary.
@@ -142,7 +142,7 @@ private:
 	std::vector<Canvas *> attachedCanvases;
 
 	void setupGrab();
-	void drawv(const Matrix &t, const Vertex *v, GLsizei count = 4, GLenum mode = GL_QUADS, const uint16 *e = 0, GLsizei ecount = 0) const;
+	void drawv(const Matrix &t, const Vertex *v) const;
 
 	static StringMap<TextureType, TYPE_MAX_ENUM>::Entry textureTypeEntries[];
 	static StringMap<TextureType, TYPE_MAX_ENUM> textureTypes;

+ 0 - 1
src/modules/graphics/opengl/Font.cpp

@@ -20,7 +20,6 @@
 #include "common/config.h"
 #include "Font.h"
 #include "font/GlyphData.h"
-#include "modules/graphics/Geometry.h"
 #include "Image.h"
 
 #include "libraries/utf8/utf8.h"

+ 7 - 7
src/modules/graphics/opengl/Graphics.cpp

@@ -369,14 +369,9 @@ Image *Graphics::newImage(love::image::CompressedData *cdata)
 	return image;
 }
 
-Geometry *Graphics::newGeometry(const std::vector<Vertex> &vertices, const std::vector<uint16> &vertexmap, Geometry::DrawMode mode)
+Quad *Graphics::newQuad(Quad::Viewport v, float sw, float sh)
 {
-	return new Geometry(vertices, vertexmap, mode);
-}
-
-Geometry *Graphics::newQuad(float x, float y, float w, float h, float sw, float sh)
-{
-	return new Geometry(x, y, w, h, sw, sh);
+	return new Quad(v, sw, sh);
 }
 
 Font *Graphics::newFont(love::font::Rasterizer *r, const Image::Filter &filter)
@@ -457,6 +452,11 @@ Shader *Graphics::newShader(const Shader::ShaderSources &sources)
 	return new Shader(sources);
 }
 
+Mesh *Graphics::newMesh(const std::vector<Vertex> &vertices, Mesh::DrawMode mode)
+{
+	return new Mesh(vertices, mode);
+}
+
 void Graphics::setColor(const Color &c)
 {
 	gl.setColor(c);

+ 5 - 10
src/modules/graphics/opengl/Graphics.h

@@ -40,11 +40,12 @@
 
 #include "Font.h"
 #include "Image.h"
-#include "graphics/Geometry.h"
+#include "graphics/Quad.h"
 #include "SpriteBatch.h"
 #include "ParticleSystem.h"
 #include "Canvas.h"
 #include "Shader.h"
+#include "Mesh.h"
 
 using love::window::WindowFlags;
 
@@ -199,15 +200,7 @@ public:
 	Image *newImage(love::image::ImageData *data);
 	Image *newImage(love::image::CompressedData *cdata);
 
-	/**
-	 * Creates a Geometry object.
-	 **/
-	Geometry *newGeometry(const std::vector<Vertex> &vertices, const std::vector<uint16> &vertexmap, Geometry::DrawMode mode);
-
-	/**
-	 * Creates a quadliteral Geometry object.
-	 **/
-	Geometry *newQuad(float x, float y, float w, float h, float sw, float sh);
+	Quad *newQuad(Quad::Viewport v, float sw, float sh);
 
 	/**
 	 * Creates a Font object.
@@ -222,6 +215,8 @@ public:
 
 	Shader *newShader(const Shader::ShaderSources &sources);
 
+	Mesh *newMesh(const std::vector<Vertex> &vertices, Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN);
+
 	/**
 	 * Sets the foreground color.
 	 * @param c The new foreground color.

+ 17 - 58
src/modules/graphics/opengl/Image.cpp

@@ -108,51 +108,32 @@ void Image::draw(float x, float y, float angle, float sx, float sy, float ox, fl
 	drawv(t, vertices);
 }
 
-void Image::drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
+void Image::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
 {
 	static Matrix t;
 	t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
 
-	const Vertex *v = geom->getVertexArray();
-	size_t vertcount = geom->getVertexCount();
+	const Vertex *v = quad->getVertices();
 
-	// Padded NPOT images require texture coordinate scaling with Geometry.
+	// Padded NPOT images require texture coordinate scaling with Quads.
 	if (!hasNpot())
-		v = scaleNPOT(v, vertcount);
-
-	// use colors stored in geometry (horrible, horrible hack)
-	if (geom->hasVertexColors())
-	{
-		glEnableClientState(GL_COLOR_ARRAY);
-		glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), (GLvoid *) &v[0].r);
-	}
-
-	GLenum glmode;
-	switch (geom->getDrawMode())
 	{
-	case Geometry::DRAW_MODE_FAN:
-	default:
-		glmode = GL_TRIANGLE_FAN;
-		break;
-	case Geometry::DRAW_MODE_STRIP:
-		glmode = GL_TRIANGLE_STRIP;
-		break;
-	case Geometry::DRAW_MODE_TRIANGLES:
-		glmode = GL_TRIANGLES;
-		break;
-	}
+		Vertex w[4];
+		love::Vector scale = getTexCoordScale();
 
-	drawv(t, v, vertcount, glmode, geom->getElementArray(), geom->getElementCount());
+		for (int i = 0; i < 4; i++)
+		{
+			w[i] = v[i];
+			w[i].s *= scale.x;
+			w[i].t *= scale.y;
+		}
 
-	if (geom->hasVertexColors())
+		drawv(t, w);
+	}
+	else
 	{
-		glDisableClientState(GL_COLOR_ARRAY);
-		gl.setColor(gl.getColor());
+		drawv(t, v);
 	}
-
-	// If we made new verts with scaled texcoords then we should clean them up.
-	if (!hasNpot())
-		delete[] v;
 }
 
 void Image::uploadCompressedMipmaps()
@@ -602,22 +583,7 @@ love::Vector Image::getTexCoordScale() const
 	return love::Vector(vertices[2].s, vertices[2].t);
 }
 
-Vertex *Image::scaleNPOT(const love::Vertex *v, size_t count) const
-{
-	Vertex *newverts = new Vertex[count];
-	love::Vector scale = getTexCoordScale();
-
-	for (size_t i = 0; i < count; i++)
-	{
-		newverts[i] = v[i];
-		newverts[i].s *= scale.x;
-		newverts[i].t *= scale.y;
-	}
-
-	return newverts;
-}
-
-void Image::drawv(const Matrix &t, const Vertex *v, GLsizei count, GLenum mode, const uint16 *e, GLsizei ecount) const
+void Image::drawv(const Matrix &t, const Vertex *v) const
 {
 	bind();
 
@@ -628,17 +594,10 @@ void Image::drawv(const Matrix &t, const Vertex *v, GLsizei count, GLenum mode,
 	glEnableClientState(GL_VERTEX_ARRAY);
 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
-	// XXX: drawg() enables/disables GL_COLOR_ARRAY in order to use the color
-	//      defined in the geometry to draw itself.
-	//      if the drawing method below is changed to use something other than
-	//      glDrawArrays(), drawg() needs to be updated accordingly!
 	glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].x);
 	glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].s);
 
-	if (e != 0 && ecount > 0)
-		glDrawElements(mode, ecount, GL_UNSIGNED_SHORT, (GLvoid *) e);
-	else
-		glDrawArrays(mode, 0, count);
+	glDrawArrays(GL_QUADS, 0, 4);
 
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 	glDisableClientState(GL_VERTEX_ARRAY);

+ 3 - 4
src/modules/graphics/opengl/Image.h

@@ -84,9 +84,9 @@ public:
 	void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
 
 	/**
-	 * @copydoc DrawGable::drawg()
+	 * @copydoc DrawQable::drawq()
 	 **/
-	void drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
+	void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
 
 	/**
 	 * Sets the filter mode.
@@ -145,10 +145,9 @@ public:
 
 private:
 
-	Vertex *scaleNPOT(const Vertex *v, size_t count) const;
 	void uploadDefaultTexture();
 
-	void drawv(const Matrix &t, const Vertex *v, GLsizei count = 4, GLenum mode = GL_QUADS, const uint16 *e = 0, GLsizei ecount = 0) const;
+	void drawv(const Matrix &t, const Vertex *v) const;
 
 	friend class Shader;
 	GLuint getTextureName() const

+ 213 - 0
src/modules/graphics/opengl/Mesh.cpp

@@ -0,0 +1,213 @@
+/**
+ * Copyright (c) 2006-2013 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "Mesh.h"
+#include "common/Matrix.h"
+#include "common/Exception.h"
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+
+Mesh::Mesh(const std::vector<Vertex> &verts, Mesh::DrawMode mode)
+	: draw_mode(mode)
+	, image(0)
+{
+	setVertices(verts);
+}
+
+void Mesh::setVertices(const std::vector<Vertex> &verts)
+{
+	if (verts.size() < 3)
+		throw love::Exception("At least 3 vertices are required.");
+
+	vertices = verts;
+}
+
+const std::vector<Vertex> &Mesh::getVertices() const
+{
+	return vertices;
+}
+
+void Mesh::setVertex(size_t i, Vertex v)
+{
+	if (i >= vertices.size())
+		throw love::Exception("Invalid index.");
+
+	vertices[i] = v;
+}
+
+Vertex Mesh::getVertex(size_t i) const
+{
+	if (i >= vertices.size())
+		throw love::Exception("Invalid index.");
+
+	return vertices[i];
+}
+
+size_t Mesh::getVertexCount() const
+{
+	return vertices.size();
+}
+
+void Mesh::setVertexMap(const std::vector<uint16> &map)
+{
+	for (size_t i = 0; i < map.size(); i++)
+	{
+		if (map[i] >= vertices.size())
+			throw love::Exception("Invalid vertex map value: %d", map[i]);
+	}
+
+	vertex_map = map;
+}
+
+const std::vector<uint16> &Mesh::getVertexMap() const
+{
+	return vertex_map;
+}
+
+Mesh::~Mesh()
+{
+}
+
+void Mesh::setImage(Image *img)
+{
+	img->retain();
+
+	if (image)
+		image->release();
+
+	image = img;
+}
+
+void Mesh::setImage()
+{
+	if (image)
+		image->release();
+
+	image = 0;
+}
+
+Image *Mesh::getImage() const
+{
+	return image;
+}
+
+void Mesh::setDrawMode(Mesh::DrawMode mode)
+{
+	draw_mode = mode;
+}
+
+Mesh::DrawMode Mesh::getDrawMode() const
+{
+	return draw_mode;
+}
+
+void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
+{
+	if (vertices.size() == 0)
+		return;
+
+	if (image)
+		image->bind();
+	else
+		gl.bindTexture(0);
+
+	Matrix m;
+	m.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
+
+	glPushMatrix();
+	glMultMatrixf(m.getElements());
+
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+	glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &(vertices[0].x));
+	glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &(vertices[0].s));
+
+	{
+		glEnableClientState(GL_COLOR_ARRAY);
+		glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &(vertices[0].r));
+	}
+
+	GLenum gl_draw_mode = getGLDrawMode(draw_mode);
+
+	if (vertex_map.size() > 0)
+		glDrawElements(gl_draw_mode, vertex_map.size(), GL_UNSIGNED_SHORT, &vertex_map[0]);
+	else
+		glDrawArrays(gl_draw_mode, 0, vertices.size());
+
+	glDisableClientState(GL_VERTEX_ARRAY);
+	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+	{
+		glDisableClientState(GL_COLOR_ARRAY);
+		gl.setColor(gl.getColor());
+	}
+
+	glPopMatrix();
+}
+
+GLenum Mesh::getGLDrawMode(Mesh::DrawMode mode) const
+{
+	switch (mode)
+	{
+	case DRAW_MODE_FAN:
+		return GL_TRIANGLE_FAN;
+	case DRAW_MODE_STRIP:
+		return GL_TRIANGLE_STRIP;
+	case DRAW_MODE_TRIANGLES:
+		return GL_TRIANGLES;
+	case DRAW_MODE_POINTS:
+		return GL_POINTS;
+	default:
+		break;
+	}
+
+	return GL_TRIANGLES;
+}
+
+bool Mesh::getConstant(const char *in, Mesh::DrawMode &out)
+{
+	return drawModes.find(in, out);
+}
+
+bool Mesh::getConstant(Mesh::DrawMode in, const char *&out)
+{
+	return drawModes.find(in, out);
+}
+
+StringMap<Mesh::DrawMode, Mesh::DRAW_MODE_MAX_ENUM>::Entry Mesh::drawModeEntries[] =
+{
+	{"fan", Mesh::DRAW_MODE_FAN},
+	{"strip", Mesh::DRAW_MODE_STRIP},
+	{"triangles", Mesh::DRAW_MODE_TRIANGLES},
+	{"points", Mesh::DRAW_MODE_POINTS},
+};
+
+StringMap<Mesh::DrawMode, Mesh::DRAW_MODE_MAX_ENUM> Mesh::drawModes(Mesh::drawModeEntries, sizeof(Mesh::drawModeEntries));
+
+} // opengl
+} // graphics
+} // love

+ 149 - 0
src/modules/graphics/opengl/Mesh.h

@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2006-2013 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+#ifndef LOVE_GRAPHICS_OPENGL_MESH_H
+#define LOVE_GRAPHICS_OPENGL_MESH_H
+
+// LOVE
+#include "common/int.h"
+#include "common/math.h"
+#include "common/StringMap.h"
+#include "graphics/Volatile.h"
+#include "graphics/Drawable.h"
+#include "graphics/opengl/Image.h"
+
+// C++
+#include <vector>
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+
+/**
+ * Holds and draws arbitrary vertex geometry.
+ * Each vertex in a Mesh has a position, texture coordinate, and color.
+ **/
+class Mesh : public Drawable
+{
+public:
+
+	// How the Mesh's vertices are used when drawing.
+	// http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png
+	enum DrawMode
+	{
+		DRAW_MODE_FAN,
+		DRAW_MODE_STRIP,
+		DRAW_MODE_TRIANGLES,
+		DRAW_MODE_POINTS,
+		DRAW_MODE_MAX_ENUM
+	};
+
+	/**
+	 * Constructor.
+	 * @param verts The vertices to use in the Mesh.
+	 * @param mode The draw mode to use when drawing the Mesh.
+	 **/
+	Mesh(const std::vector<Vertex> &verts, DrawMode mode = DRAW_MODE_FAN);
+	virtual ~Mesh();
+
+	/**
+	 * Replaces all the vertices in the Mesh with a new set of vertices.
+	 **/
+	void setVertices(const std::vector<Vertex> &verts);
+
+	/**
+	 * Gets a reference to the vertices used in the Mesh.
+	 **/
+	const std::vector<Vertex> &getVertices() const;
+
+	/**
+	 * Sets an individual vertex in the Mesh.
+	 * @param i The index into the list of vertices to use.
+	 * @param v The new vertex.
+	 **/
+	void setVertex(size_t i, Vertex v);
+	Vertex getVertex(size_t i) const;
+
+	/**
+	 * Gets the total number of vertices in the Mesh.
+	 **/
+	size_t getVertexCount() const;
+
+	/**
+	 * Sets the vertex map to use when drawing the Mesh. The vertex map
+	 * determines the order in which vertices are used by the draw mode.
+	 * A 0-element vector is equivalent to the default vertex map:
+	 * {0, 1, 2, 3, 4, ...}
+	 **/
+	void setVertexMap(const std::vector<uint16> &map);
+	const std::vector<uint16> &getVertexMap() const;
+
+	/**
+	 * Sets the Image used when drawing the Mesh.
+	 **/
+	void setImage(Image *img);
+
+	/**
+	 * Disables any Image from being used when drawing the Mesh.
+	 **/
+	void setImage();
+
+	/**
+	 * Gets the Image used when drawing the Mesh. May return null if no Image is
+	 * set.
+	 **/
+	Image *getImage() const;
+
+	/**
+	 * Sets the draw mode used when drawing the Mesh.
+	 **/
+	void setDrawMode(DrawMode mode);
+	DrawMode getDrawMode() const;
+
+	// Implements Drawable.
+	void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
+
+	static bool getConstant(const char *in, DrawMode &out);
+	static bool getConstant(DrawMode in, const char *&out);
+
+private:
+
+	GLenum getGLDrawMode(DrawMode mode) const;
+
+	std::vector<Vertex> vertices;
+	std::vector<uint16> vertex_map;
+
+	DrawMode draw_mode;
+
+	Image *image;
+
+	static StringMap<DrawMode, DRAW_MODE_MAX_ENUM>::Entry drawModeEntries[];
+	static StringMap<DrawMode, DRAW_MODE_MAX_ENUM> drawModes;
+
+}; // Mesh
+
+} // opengl
+} // graphics
+} // love
+
+#endif // LOVE_GRAPHICS_OPENGL_MESH_H

+ 4 - 28
src/modules/graphics/opengl/SpriteBatch.cpp

@@ -26,7 +26,6 @@
 
 // LOVE
 #include "Image.h"
-#include "modules/graphics/Geometry.h"
 #include "VertexBuffer.h"
 
 // C++
@@ -129,39 +128,20 @@ int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, fl
 	return index;
 }
 
-int SpriteBatch::addg(Geometry *geom, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/)
+int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/)
 {
 	// Only do this if there's a free slot.
 	if ((index == -1 && next >= size) || index < -1 || index >= next)
 		return -1;
 
-	size_t vertexcount = geom->getVertexCount();
-	if (vertexcount > 4)
-		throw love::Exception("Cannot add Geometries with more than 4 vertices to SpriteBatch");
-
-	// Which vertices to add to the SpriteBatch.
-	size_t vertex_indices[4] = {0, 1, 2, 3};
-
-	if (geom->getDrawMode() == Geometry::DRAW_MODE_STRIP)
-	{
-		// We have to do some vertex reordering shenanigans to get 4-vertex
-		// triangle strip Geometries to render properly.
-		std::swap(vertex_indices[0], vertex_indices[1]);
-	}
-
-	// If the Geometry has 3 vertices, then 2 triangles will be added to the
-	// SpriteBatch: 0-1-2 and 0-2-0. 0-2-0 will get ignored during rasterization.
-	for (size_t i = geom->getVertexCount(); i < 4; i++)
-		vertex_indices[i] = vertex_indices[0];
-
-	for (size_t i = 0; i < 4; i++)
-		sprite[i] = geom->getVertex(vertex_indices[i]);
+	// Needed for colors.
+	memcpy(sprite, quad->getVertices(), sizeof(Vertex) * 4);
 
 	static Matrix t;
 	t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
 	t.transform(sprite, sprite, 4);
 
-	if (color && !geom->hasVertexColors())
+	if (color)
 		setColorv(sprite, *color);
 
 	// Auto-padded NPOT images require texcoord scaling for their vertices.
@@ -169,10 +149,6 @@ int SpriteBatch::addg(Geometry *geom, float x, float y, float a, float sx, float
 
 	addv(sprite, (index == -1) ? next : index);
 
-	// Make sure SpriteBatch colors are enabled if the Geometry has custom colors.
-	if (!color && geom->hasVertexColors())
-		setColor(Color(255, 255, 255, 255));
-
 	// Increment counter.
 	if (index == -1)
 		return next++;

+ 6 - 6
src/modules/graphics/opengl/SpriteBatch.h

@@ -32,7 +32,7 @@
 #include "graphics/Drawable.h"
 #include "graphics/Volatile.h"
 #include "graphics/Color.h"
-#include "graphics/Geometry.h"
+#include "graphics/Quad.h"
 
 namespace love
 {
@@ -62,7 +62,7 @@ public:
 	virtual ~SpriteBatch();
 
 	int add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
-	int addg(Geometry *geom, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
+	int addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
 	void clear();
 
 	void *lock();
@@ -72,16 +72,16 @@ public:
 	Image *getImage();
 
 	/**
-	 * Set the current color for this SpriteBatch. The geometry added
+	 * Set the current color for this SpriteBatch. The sprites added
 	 * after this call will use this color. Note that global color
 	 * will not longer apply to the SpriteBatch if this is used.
 	 *
-	 * @param color The color to use for the following geometry.
+	 * @param color The color to use for the following sprites.
 	 */
 	void setColor(const Color &color);
 
 	/**
-	 * Disable per-geometry colors for this SpriteBatch. The next call to
+	 * Disable per-sprite colors for this SpriteBatch. The next call to
 	 * draw will use the global color for all sprites.
 	 */
 	void setColor();
@@ -140,7 +140,7 @@ private:
 	Vertex sprite[4];
 
 	// Current color. This color, if present, will be applied to the next
-	// added geometry.
+	// added sprite.
 	Color *color;
 
 	VertexBuffer *array_buf;

+ 0 - 214
src/modules/graphics/opengl/wrap_Geometry.cpp

@@ -1,214 +0,0 @@
-/**
- * Copyright (c) 2006-2013 LOVE Development Team
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- **/
-
-// LOVE
-#include "wrap_Geometry.h"
-#include "common/Exception.h"
-
-namespace love
-{
-namespace graphics
-{
-namespace opengl
-{
-
-Geometry *luax_checkgeometry(lua_State *L, int idx)
-{
-	return luax_checktype<Geometry>(L, idx, "Geometry", GRAPHICS_GEOMETRY_T);
-}
-
-int w_Geometry_getVertexCount(lua_State *L)
-{
-	Geometry *geom = luax_checkgeometry(L, 1);
-	lua_pushinteger(L, geom->getVertexCount());
-	return 1;
-}
-
-int w_Geometry_getVertex(lua_State *L)
-{
-	Geometry *geom = luax_checkgeometry(L, 1);
-	size_t i = size_t(luaL_checkinteger(L, 2));
-
-	EXCEPT_GUARD(
-		const Vertex &v = geom->getVertex(i-1);
-		lua_pushnumber(L, v.x);
-		lua_pushnumber(L, v.y);
-		lua_pushnumber(L, v.s);
-		lua_pushnumber(L, v.t);
-		lua_pushnumber(L, v.r);
-		lua_pushnumber(L, v.g);
-		lua_pushnumber(L, v.b);
-		lua_pushnumber(L, v.a);
-	)
-
-	return 8;
-}
-
-int w_Geometry_setVertex(lua_State *L)
-{
-	Geometry *geom = luax_checkgeometry(L, 1);
-	size_t i = size_t(luaL_checkinteger(L, 2));
-
-	Vertex v;
-
-	if (lua_istable(L, 3))
-	{
-		for (int i = 1; i <= 8; i++)
-			lua_rawgeti(L, 3, i);
-
-		v.x = luaL_checknumber(L, -8);
-		v.y = luaL_checknumber(L, -7);
-		v.s = luaL_checknumber(L, -6);
-		v.t = luaL_checknumber(L, -5);
-		v.r = luaL_optinteger(L, -4, 255);
-		v.g = luaL_optinteger(L, -3, 255);
-		v.b = luaL_optinteger(L, -2, 255);
-		v.a = luaL_optinteger(L, -1, 255);
-
-		lua_pop(L, 8);
-	}
-	else
-	{
-		v.x = luaL_checknumber(L, 3);
-		v.y = luaL_checknumber(L, 4);
-		v.s = luaL_checknumber(L, 5);
-		v.t = luaL_checknumber(L, 6);
-		v.r = luaL_optinteger(L,  7, 255);
-		v.g = luaL_optinteger(L,  8, 255);
-		v.b = luaL_optinteger(L,  9, 255);
-		v.a = luaL_optinteger(L, 10, 255);
-	}
-
-	EXCEPT_GUARD(geom->setVertex(i-1, v);)
-
-	if (v.r != 255 || v.g != 255 || v.b != 255 || v.a != 255)
-		geom->setVertexColors(true);
-
-	return 0;
-}
-
-int w_Geometry_setVertexColors(lua_State *L)
-{
-	Geometry *geom = luax_checkgeometry(L, 1);
-	geom->setVertexColors(luax_toboolean(L, 2));
-	return 0;
-}
-
-int w_Geometry_hasVertexColors(lua_State *L)
-{
-	Geometry *geom = luax_checkgeometry(L, 1);
-	luax_pushboolean(L, geom->hasVertexColors());
-	return 1;
-}
-
-int w_Geometry_getDrawMode(lua_State *L)
-{
-	Geometry *geom = luax_checkgeometry(L, 1);
-
-	Geometry::DrawMode mode = geom->getDrawMode();
-	const char *str;
-
-	if (!Geometry::getConstant(mode, str))
-		return luaL_error(L, "Unknown Geometry draw mode");
-
-	lua_pushstring(L, str);
-
-	return 1;
-}
-
-int w_Geometry_getVertexMap(lua_State *L)
-{
-	Geometry *g = luax_checkgeometry(L, 1);
-
-	size_t elemcount = g->getElementCount();
-	const uint16 *elements = g->getElementArray();
-
-	if (elemcount == 0)
-		elemcount = g->getVertexCount();
-
-	lua_createtable(L, elemcount, 0);
-	for (size_t i = 0; i < elemcount; i++)
-	{
-		if (elements)
-			lua_pushinteger(L, elements[i] + 1);
-		else
-			lua_pushinteger(L, i + 1);
-
-		lua_rawseti(L, -2, i + 1);
-	}
-
-	return 1;
-}
-
-int w_Geometry_setVertexMap(lua_State *L)
-{
-	Geometry *g = luax_checkgeometry(L, 1);
-
-	for (int i = lua_gettop(L); i >= 2; i--)
-	{
-		if (lua_isnil(L, i))
-			lua_pop(L, 1);
-		else
-			break;
-	}
-
-	bool is_table = lua_istable(L, 2);
-	int nargs = is_table ? lua_objlen(L, 2) : lua_gettop(L) - 1;
-
-	std::vector<uint16> vertexmap;
-	vertexmap.reserve(nargs);
-
-	for (int i = 0; i < nargs; i++)
-	{
-		if (is_table)
-		{
-			lua_rawgeti(L, 2, i + 1);
-			vertexmap.push_back(luaL_checkinteger(L, -1) - 1);
-			lua_pop(L, 1);
-		}
-		else
-			vertexmap.push_back(luaL_checkinteger(L, i + 2) - 1);
-	}
-
-	EXCEPT_GUARD(g->setElementArray(&vertexmap[0], vertexmap.size());)
-	return 0;
-}
-
-static const luaL_Reg w_Geometry_functions[] =
-{
-	{ "getVertexCount", w_Geometry_getVertexCount },
-	{ "getVertex", w_Geometry_getVertex },
-	{ "setVertex", w_Geometry_setVertex },
-	{ "setVertexColors", w_Geometry_setVertexColors },
-	{ "hasVertexColors", w_Geometry_hasVertexColors },
-	{ "getDrawMode", w_Geometry_getDrawMode },
-	{ "getVertexMap", w_Geometry_getVertexMap },
-	{ "setVertexMap", w_Geometry_setVertexMap },
-	{ 0, 0 }
-};
-
-extern "C" int luaopen_geometry(lua_State *L)
-{
-	return luax_register_type(L, "Geometry", w_Geometry_functions);
-}
-
-} // opengl
-} // graphics
-} // love

+ 80 - 156
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -20,7 +20,7 @@
 
 #include "wrap_Graphics.h"
 #include "OpenGL.h"
-#include "graphics/DrawGable.h"
+#include "graphics/DrawQable.h"
 #include "image/ImageData.h"
 #include "font/Rasterizer.h"
 
@@ -194,156 +194,19 @@ int w_newImage(lua_State *L)
 	return 1;
 }
 
-int w_newGeometry(lua_State *L)
-{
-	luaL_checktype(L, 1, LUA_TTABLE);
-
-	// Determine whether a table of vertices is being given. We assume it is if
-	// type(args[1][1]) == "table", otherwise assume the args are the verts.
-	lua_rawgeti(L, 1, 1);
-	bool is_table = lua_istable(L, -1);
-	lua_pop(L, 1);
-
-	// Get rid of any trailing nils in the arg list (it messes with our style.)
-	for (int i = lua_gettop(L); i >= 2; i--)
-	{
-		if (lua_isnil(L, i))
-			lua_pop(L, 1);
-		else
-			break;
-	}
-
-	Geometry::DrawMode mode = Geometry::DRAW_MODE_FAN;
-	std::string txt;
-	bool has_vertexmap = false;
-
-	// The last argument (or second-last) may be an optional draw mode.
-	if (lua_type(L, -1) == LUA_TSTRING)
-	{
-		txt = luaL_checkstring(L, -1);
-		lua_remove(L, -1);
-	}
-	else if (lua_type(L, -2) == LUA_TSTRING && lua_istable(L, -1))
-	{
-		txt = luaL_checkstring(L, -2);
-		lua_remove(L, -2);
-
-		// If the draw mode is the second-last argument, the last argument will
-		// be the vertex map.
-		has_vertexmap = true;
-	}
-
-	if (txt.length() > 0 && !Geometry::getConstant(txt.c_str(), mode))
-		return luaL_error(L, "Invalid Geometry draw mode: %s", txt.c_str());
-
-	std::vector<uint16> vertexmap;
-
-	// Get the vertex map table, if it exists.
-	if (has_vertexmap)
-	{
-		// It will always be the last argument.
-		int tableidx = lua_gettop(L);
-
-		size_t elementcount = lua_objlen(L, -1);
-		vertexmap.reserve(elementcount);
-
-		for (size_t i = 0; i < elementcount; i++)
-		{
-			lua_rawgeti(L, tableidx, i + 1);
-			if (!lua_isnumber(L, -1))
-				return luaL_argerror(L, tableidx + 1, "vertex index expected");
-
-			vertexmap.push_back(lua_tointeger(L, -1) - 1);
-			lua_pop(L, 1);
-		}
-
-		// We don't want to read the vertex map as a vertex table later.
-		lua_remove(L, -1);
-	}
-
-	size_t vertexcount = is_table ? lua_objlen(L, 1) : lua_gettop(L);
-	if (vertexcount < 3)
-		return luaL_error(L, "At least three points are needed to construct a Geometry.");
-
-	if (!lua_checkstack(L, 9))
-		return luaL_error(L, "Too many arguments!");
-
-	bool hasvertexcolors = false;
-
-	std::vector<Vertex> vertices;
-	vertices.reserve(vertexcount);
-
-	for (size_t i = 0; i < vertexcount; ++i)
-	{
-		Vertex v;
-
-		if (is_table)
-		{
-			lua_rawgeti(L, 1, i+1);
-			if (!lua_istable(L, -1))
-				return luax_typerror(L, 1, "table of tables");
-		}
-		else
-		{
-			// Push the vertex table at this arg index to the top of the stack.
-			luaL_checktype(L, i + 1, LUA_TTABLE);
-			lua_pushvalue(L, i + 1);
-		}
-
-		for (int j = 1; j <= 8; j++)
-			lua_rawgeti(L, -j, j);
-
-		v.x = luaL_checknumber(L, -8);
-		v.y = luaL_checknumber(L, -7);
-
-		v.s = luaL_checknumber(L, -6);
-		v.t = luaL_checknumber(L, -5);
-
-		v.r = luaL_optinteger(L, -4, 255);
-		v.g = luaL_optinteger(L, -3, 255);
-		v.b = luaL_optinteger(L, -2, 255);
-		v.a = luaL_optinteger(L, -1, 255);
-
-		lua_pop(L, 9);
-
-		// Custom vertex colors are disabled by default unless a unique color
-		// is used for at least one vertex.
-		if (v.r != 255 || v.g != 255 || v.b != 255 || v.a != 255)
-			hasvertexcolors = true;
-
-		vertices.push_back(v);
-	}
-
-	Geometry *geom = 0;
-	EXCEPT_GUARD(geom = instance->newGeometry(vertices, vertexmap, mode);)
-
-	if (geom == 0)
-		return luaL_error(L, "Could not create geometry.");
-
-	geom->setVertexColors(hasvertexcolors);
-
-	// Note: This should be changed to luax_pushtype if the new Geometry is ever
-	// expected to be pushed to Lua from another C++ function!
-	// We're only using rawnewtype instead of pushtype for performance.
-	luax_rawnewtype(L, "Geometry", GRAPHICS_GEOMETRY_T, geom);
-	return 1;
-}
-
 int w_newQuad(lua_State *L)
 {
-	float x = (float) luaL_checknumber(L, 1);
-	float y = (float) luaL_checknumber(L, 2);
-	float w = (float) luaL_checknumber(L, 3);
-	float h = (float) luaL_checknumber(L, 4);
-	float sw = (float) luaL_checknumber(L, 5);
-	float sh = (float) luaL_checknumber(L, 6);
+	Quad::Viewport v;
+	v.x = (float) luaL_checknumber(L, 1);
+	v.y = (float) luaL_checknumber(L, 1);
+	v.w = (float) luaL_checknumber(L, 1);
+	v.h = (float) luaL_checknumber(L, 1);
 
-	Geometry *quad = instance->newQuad(x, y, w, h, sw, sh);
+	float sw = (float) luaL_checknumber(L, 1);
+	float sh = (float) luaL_checknumber(L, 1);
 
-	// Note: This should be changed to luax_pushtype if the new Geometry is ever
-	// expected to be pushed to Lua from another C++ function!
-	// We're only using rawnewtype instead of pushtype for performance.
-	luax_rawnewtype(L, "Geometry", GRAPHICS_GEOMETRY_T, quad);
+	Quad *quad = instance->newQuad(v, sw, sh);
+	luax_pushtype(L, "Quad", GRAPHICS_QUAD_T, quad);
 	return 1;
 }
 
@@ -568,6 +431,66 @@ int w_newShader(lua_State *L)
 	return 1;
 }
 
+int w_newMesh(lua_State *L)
+{
+	// Check first argument: mandatory table of vertices.
+	luaL_checktype(L, 1, LUA_TTABLE);
+
+	// Second argument: optional image.
+	Image *img = 0;
+	if (!lua_isnoneornil(L, 2))
+		img = luax_checkimage(L, 2);
+
+	// Third argument: optional draw mode.
+	const char *str = 0;
+	Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN;
+	str = lua_isnoneornil(L, 3) ? 0 : luaL_checkstring(L, 3);
+
+	if (str && !Mesh::getConstant(str, mode))
+		return luaL_error(L, "Invalid mesh draw mode: %s", str);
+
+	size_t vertex_count = lua_objlen(L, 1);
+	std::vector<Vertex> vertices;
+	vertices.reserve(vertex_count);
+
+	// Get the vertices from the table.
+	for (size_t i = 1; i <= vertex_count; i++)
+	{
+		lua_rawgeti(L, 1, i);
+
+		if (lua_type(L, -1) != LUA_TTABLE)
+			return luax_typerror(L, 2, "table of tables");
+
+		for (int j = 1; j <= 8; j++)
+			lua_rawgeti(L, -j, j);
+
+		Vertex v;
+
+		v.x = (float) luaL_checknumber(L, -8);
+		v.y = (float) luaL_checknumber(L, -7);
+
+		v.s = (float) luaL_checknumber(L, -6);
+		v.t = (float) luaL_checknumber(L, -5);
+
+		v.r = (unsigned char) luaL_optinteger(L, -4, 255);
+		v.g = (unsigned char) luaL_optinteger(L, -3, 255);
+		v.b = (unsigned char) luaL_optinteger(L, -2, 255);
+		v.a = (unsigned char) luaL_optinteger(L, -1, 255);
+
+		lua_pop(L, 9);
+		vertices.push_back(v);
+	}
+
+	Mesh *t = 0;
+	EXCEPT_GUARD(t = instance->newMesh(vertices, mode);)
+
+	if (img)
+		t->setImage(img);
+
+	luax_pushtype(L, "Mesh", GRAPHICS_MESH_T, t);
+	return 1;
+}
+
 int w_setColor(lua_State *L)
 {
 	Color c;
@@ -1076,14 +999,14 @@ int w_getRendererInfo(lua_State *L)
 int w_draw(lua_State *L)
 {
 	Drawable *drawable = 0;
-	DrawGable *drawgable = 0;
-	Geometry *geom = 0;
+	DrawQable *drawqable = 0;
+	Quad *quad = 0;
 	int startidx = 2;
 
-	if (luax_istype(L, 2, GRAPHICS_GEOMETRY_T))
+	if (luax_istype(L, 2, GRAPHICS_QUAD_T))
 	{
-		drawgable = luax_checktype<DrawGable>(L, 1, "DrawGable", GRAPHICS_DRAWGABLE_T);
-		geom = luax_totype<Geometry>(L, 2, "Geometry", GRAPHICS_GEOMETRY_T);
+		drawqable = luax_checktype<DrawQable>(L, 1, "DrawQable", GRAPHICS_DRAWQABLE_T);
+		quad = luax_totype<Quad>(L, 2, "Quad", GRAPHICS_QUAD_T);
 		startidx = 3;
 	}
 	else
@@ -1102,8 +1025,8 @@ int w_draw(lua_State *L)
 	float kx = (float) luaL_optnumber(L, startidx + 7, 0.0);
 	float ky = (float) luaL_optnumber(L, startidx + 8, 0.0);
 
-	if (drawgable && geom)
-		drawgable->drawg(geom, x, y, a, sx, sy, ox, oy, kx, ky);
+	if (drawqable && quad)
+		drawqable->drawq(quad, x, y, a, sx, sy, ox, oy, kx, ky);
 	else if (drawable)
 		drawable->draw(x, y, a, sx, sy, ox, oy, kx, ky);
 
@@ -1371,13 +1294,13 @@ static const luaL_Reg functions[] =
 
 	{ "newImage", w_newImage },
 	{ "newQuad", w_newQuad },
-	{ "newGeometry", w_newGeometry },
 	{ "newFont", w_newFont },
 	{ "newImageFont", w_newImageFont },
 	{ "newSpriteBatch", w_newSpriteBatch },
 	{ "newParticleSystem", w_newParticleSystem },
 	{ "newCanvas", w_newCanvas },
 	{ "newShader", w_newShader },
+	{ "newMesh", w_newMesh },
 
 	{ "setColor", w_setColor },
 	{ "getColor", w_getColor },
@@ -1457,11 +1380,12 @@ static const lua_CFunction types[] =
 {
 	luaopen_font,
 	luaopen_image,
-	luaopen_geometry,
+	luaopen_quad,
 	luaopen_spritebatch,
 	luaopen_particlesystem,
 	luaopen_canvas,
 	luaopen_shader,
+	luaopen_mesh,
 	0
 };
 

+ 3 - 3
src/modules/graphics/opengl/wrap_Graphics.h

@@ -24,11 +24,12 @@
 // LOVE
 #include "wrap_Font.h"
 #include "wrap_Image.h"
-#include "wrap_Geometry.h"
+#include "wrap_Quad.h"
 #include "wrap_SpriteBatch.h"
 #include "wrap_ParticleSystem.h"
 #include "wrap_Canvas.h"
 #include "wrap_Shader.h"
+#include "wrap_Mesh.h"
 #include "Graphics.h"
 
 namespace love
@@ -50,7 +51,6 @@ int w_getScissor(lua_State *L);
 int w_setStencil(lua_State *L);
 int w_getMaxImageSize(lua_State *L);
 int w_newImage(lua_State *L);
-int w_newGeometry(lua_State *L);
 int w_newQuad(lua_State *L);
 int w_newFont(lua_State *L);
 int w_newImageFont(lua_State *L);
@@ -58,6 +58,7 @@ int w_newSpriteBatch(lua_State *L);
 int w_newParticleSystem(lua_State *L);
 int w_newCanvas(lua_State *L);  // comments in function
 int w_newShader(lua_State *L);
+int w_newMesh(lua_State *L);
 int w_setColor(lua_State *L);
 int w_getColor(lua_State *L);
 int w_setBackgroundColor(lua_State *L);
@@ -91,7 +92,6 @@ int w_getShader(lua_State *L);
 int w_isSupported(lua_State *L);
 int w_getRendererInfo(lua_State *L);
 int w_draw(lua_State *L);
-int w_drawg(lua_State *L);
 int w_print(lua_State *L);
 int w_printf(lua_State *L);
 int w_point(lua_State *L);

+ 263 - 0
src/modules/graphics/opengl/wrap_Mesh.cpp

@@ -0,0 +1,263 @@
+/**
+ * Copyright (c) 2006-2013 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "wrap_Mesh.h"
+#include "wrap_Image.h"
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+
+Mesh *luax_checkmesh(lua_State *L, int idx)
+{
+	return luax_checktype<Mesh>(L, idx, "Mesh", GRAPHICS_MESH_T);
+}
+
+int w_Mesh_setVertex(lua_State *L)
+{
+	Mesh *t = luax_checkmesh(L, 1);
+	size_t i = size_t(luaL_checkinteger(L, 2) - 1);
+
+	Vertex v;
+
+	if (lua_istable(L, 3))
+	{
+		for (int i = 1; i <= 8; i++)
+			lua_rawgeti(L, 3, i);
+
+		v.x = luaL_checknumber(L, -8);
+		v.y = luaL_checknumber(L, -7);
+		v.s = luaL_checknumber(L, -6);
+		v.t = luaL_checknumber(L, -5);
+		v.r = luaL_optinteger(L, -4, 255);
+		v.g = luaL_optinteger(L, -3, 255);
+		v.b = luaL_optinteger(L, -2, 255);
+		v.a = luaL_optinteger(L, -1, 255);
+
+		lua_pop(L, 8);
+	}
+	else
+	{
+		v.x = luaL_checknumber(L, 3);
+		v.y = luaL_checknumber(L, 4);
+		v.s = luaL_checknumber(L, 5);
+		v.t = luaL_checknumber(L, 6);
+		v.r = luaL_optinteger(L,  7, 255);
+		v.g = luaL_optinteger(L,  8, 255);
+		v.b = luaL_optinteger(L,  9, 255);
+		v.a = luaL_optinteger(L, 10, 255);
+	}
+
+	EXCEPT_GUARD(t->setVertex(i, v);)
+	return 0;
+}
+
+int w_Mesh_getVertex(lua_State *L)
+{
+	Mesh *t = luax_checkmesh(L, 1);
+	size_t i = (size_t) (luaL_checkinteger(L, 2) - 1);
+
+	Vertex v;
+	EXCEPT_GUARD(v = t->getVertex(i);)
+
+	lua_pushnumber(L, v.x);
+	lua_pushnumber(L, v.y);
+	lua_pushnumber(L, v.s);
+	lua_pushnumber(L, v.t);
+	lua_pushnumber(L, v.r);
+	lua_pushnumber(L, v.g);
+	lua_pushnumber(L, v.b);
+	lua_pushnumber(L, v.a);
+
+	return 8;
+}
+
+int w_Mesh_getVertices(lua_State *L)
+{
+	Mesh *t = luax_checkmesh(L, 1);
+	const std::vector<Vertex> &vertices = t->getVertices();
+
+	lua_createtable(L, vertices.size(), 0);
+
+	for (size_t i = 0; i < vertices.size(); i++)
+	{
+		lua_createtable(L, 8, 0);
+		const Vertex &v = vertices[i];
+
+		lua_pushnumber(L, v.x);
+		lua_rawseti(L, -2, 1);
+
+		lua_pushnumber(L, v.y);
+		lua_rawseti(L, -2, 2);
+
+		lua_pushnumber(L, v.s);
+		lua_rawseti(L, -2, 3);
+
+		lua_pushnumber(L, v.t);
+		lua_rawseti(L, -2, 4);
+
+		lua_pushnumber(L, v.r);
+		lua_rawseti(L, -2, 5);
+
+		lua_pushnumber(L, v.g);
+		lua_rawseti(L, -2, 6);
+
+		lua_pushnumber(L, v.b);
+		lua_rawseti(L, -2, 7);
+
+		lua_pushnumber(L, v.a);
+		lua_rawseti(L, -2, 8);
+
+		lua_rawseti(L, -2, i + 1);
+	}
+
+	return 1;
+}
+
+int w_Mesh_getVertexCount(lua_State *L)
+{
+	Mesh *t = luax_checkmesh(L, 1);
+	lua_pushinteger(L, t->getVertexCount());
+	return 1;
+}
+
+int w_Mesh_setVertexMap(lua_State *L)
+{
+	Mesh *t = luax_checkmesh(L, 1);
+
+	bool is_table = lua_istable(L, 2);
+	int nargs = is_table ? lua_objlen(L, 2) : lua_gettop(L) - 1;
+
+	std::vector<uint16> vertexmap;
+	vertexmap.reserve(nargs);
+
+	for (int i = 0; i < nargs; i++)
+	{
+		if (is_table)
+		{
+			lua_rawgeti(L, 2, i + 1);
+			vertexmap.push_back(uint16(luaL_checkinteger(L, -1) - 1));
+			lua_pop(L, 1);
+		}
+		else
+			vertexmap.push_back(uint16(luaL_checkinteger(L, i + 2) - 1));
+	}
+
+	EXCEPT_GUARD(t->setVertexMap(vertexmap);)
+	return 0;
+}
+
+int w_Mesh_getVertexMap(lua_State *L)
+{
+	Mesh *t = luax_checkmesh(L, 1);
+
+	const std::vector<uint16> &map = t->getVertexMap();
+	lua_createtable(L, map.size(), 0);
+
+	for (size_t i = 0; i < map.size(); i++)
+	{
+		lua_pushinteger(L, map[i] + 1);
+		lua_rawseti(L, -2, i + 1);
+	}
+
+	return 1;
+}
+
+int w_Mesh_setImage(lua_State *L)
+{
+	Mesh *t = luax_checkmesh(L, 1);
+
+	if (lua_isnoneornil(L, 2))
+		t->setImage();
+	else
+	{
+		Image *img = luax_checkimage(L, 2);
+		t->setImage(img);
+	}
+
+	return 0;
+}
+
+int w_Mesh_getImage(lua_State *L)
+{
+	Mesh *t = luax_checkmesh(L, 1);
+	Image *img = t->getImage();
+
+	if (img == NULL)
+		return 0;
+
+	img->retain();
+	luax_pushtype(L, "Image", GRAPHICS_IMAGE_T, img);
+	return 1;
+}
+
+int w_Mesh_setDrawMode(lua_State *L)
+{
+	Mesh *t = luax_checkmesh(L, 1);
+	const char *str = luaL_checkstring(L, 2);
+	Mesh::DrawMode mode;
+
+	if (!Mesh::getConstant(str, mode))
+		return luaL_error(L, "Invalid mesh draw mode: %s", str);
+
+	t->setDrawMode(mode);
+	return 0;
+}
+
+int w_Mesh_getDrawMode(lua_State *L)
+{
+	Mesh *t = luax_checkmesh(L, 1);
+	Mesh::DrawMode mode = t->getDrawMode();
+	const char *str;
+
+	if (!Mesh::getConstant(mode, str))
+		return luaL_error(L, "Unknown mesh draw mode.");
+
+	lua_pushstring(L, str);
+	return 1;
+}
+
+static const luaL_Reg functions[] =
+{
+	{ "setVertex", w_Mesh_setVertex },
+	{ "getVertex", w_Mesh_getVertex },
+	{ "getVertices", w_Mesh_getVertices },
+	{ "getVertexCount", w_Mesh_getVertexCount },
+	{ "setVertexMap", w_Mesh_setVertexMap },
+	{ "getVertexMap", w_Mesh_getVertexMap },
+	{ "setImage", w_Mesh_setImage },
+	{ "getImage", w_Mesh_getImage },
+	{ "setDrawMode", w_Mesh_setDrawMode },
+	{ "getDrawMode", w_Mesh_getDrawMode },
+	{ 0, 0 }
+};
+
+extern "C" int luaopen_mesh(lua_State *L)
+{
+	return luax_register_type(L, "Mesh", functions);
+}
+
+} // opengl
+} // graphics
+} // love

+ 18 - 14
src/modules/graphics/opengl/wrap_Geometry.h → src/modules/graphics/opengl/wrap_Mesh.h

@@ -18,12 +18,12 @@
  * 3. This notice may not be removed or altered from any source distribution.
  **/
 
-#ifndef LOVE_GRAPHICS_OPENGL_WRAP_GEOMETRY_H
-#define LOVE_GRAPHICS_OPENGL_WRAP_GEOMETRY_H
+#ifndef LOVE_GRAPHICS_OPENGL_WRAP_MESH_H
+#define LOVE_GRAPHICS_OPENGL_WRAP_MESH_H
 
 // LOVE
 #include "common/runtime.h"
-#include "graphics/Geometry.h"
+#include "Mesh.h"
 
 namespace love
 {
@@ -32,19 +32,23 @@ namespace graphics
 namespace opengl
 {
 
-Geometry *luax_checkgeometry(lua_State *L, int idx);
-int w_Geometry_getVertexCount(lua_State *L);
-int w_Geometry_getVertex(lua_State *L);
-int w_Geometry_setVertex(lua_State *L);
-int w_Geometry_setVertexColors(lua_State *L);
-int w_Geometry_hasVertexColors(lua_State *L);
-int w_Geometry_getDrawMode(lua_State *L);
-int w_Geometry_getVertexMap(lua_State *L);
-int w_Geometry_setVertexMap(lua_State *L);
-extern "C" int luaopen_geometry(lua_State *L);
+Mesh *luax_checkmesh(lua_State *L, int idx);
+
+int w_Mesh_setVertex(lua_State *L);
+int w_Mesh_getVertex(lua_State *L);
+int w_Mesh_getVertices(lua_State *L);
+int w_Mesh_getVertexCount(lua_State *L);
+int w_Mesh_setVertexMap(lua_State *L);
+int w_Mesh_getVertexMap(lua_State *L);
+int w_Mesh_setImage(lua_State *L);
+int w_Mesh_getImage(lua_State *L);
+int w_Mesh_setDrawMode(lua_State *L);
+int w_Mesh_getDrawMode(lua_State *L);
+
+extern "C" int luaopen_mesh(lua_State *L);
 
 } // opengl
 } // graphics
 } // love
 
-#endif // LOVE_GRAPHICS_OPENGL_WRAP_GEOMETRY_H
+#endif // LOVE_GRAPHICS_OPENGL_WRAP_MESH_H

+ 91 - 0
src/modules/graphics/opengl/wrap_Quad.cpp

@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2006-2013 LOVE Development Team
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ **/
+
+// LOVE
+#include "wrap_Quad.h"
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+
+Quad *luax_checkquad(lua_State *L, int idx)
+{
+	return luax_checktype<Quad>(L, idx, "Quad", GRAPHICS_QUAD_T);
+}
+
+int w_Quad_flip(lua_State *L)
+{
+	Quad *quad = luax_checkquad(L, 1);
+	quad->flip(luax_toboolean(L, 2), luax_toboolean(L, 3));
+	return 0;
+}
+
+int w_Quad_setViewport(lua_State *L)
+{
+	Quad *quad = luax_checkquad(L, 1);
+
+	Quad::Viewport v;
+	v.x = (float) luaL_checknumber(L, 2);
+	v.y = (float) luaL_checknumber(L, 3);
+	v.w = (float) luaL_checknumber(L, 4);
+	v.h = (float) luaL_checknumber(L, 5);
+
+	if (lua_isnoneornil(L, 6))
+		quad->setViewport(v);
+	else
+	{
+		float sw = (float) luaL_checknumber(L, 6);
+		float sh = (float) luaL_checknumber(L, 7);
+		quad->refresh(v, sw, sh);
+	}
+
+	return 0;
+}
+
+int w_Quad_getViewport(lua_State *L)
+{
+	Quad *quad = luax_checkquad(L, 1);
+	Quad::Viewport v = quad->getViewport();
+	lua_pushnumber(L, v.x);
+	lua_pushnumber(L, v.y);
+	lua_pushnumber(L, v.w);
+	lua_pushnumber(L, v.h);
+	return 4;
+}
+
+static const luaL_Reg functions[] =
+{
+	{ "flip", w_Quad_flip },
+	{ "setViewport", w_Quad_setViewport },
+	{ "getViewport", w_Quad_getViewport },
+	{ 0, 0 }
+};
+
+extern "C" int luaopen_quad(lua_State *L)
+{
+	return luax_register_type(L, "Quad", functions);
+}
+
+} // opengl
+} // graphics
+} // love

+ 16 - 4
src/modules/graphics/DrawGable.cpp → src/modules/graphics/opengl/wrap_Quad.h

@@ -18,16 +18,28 @@
  * 3. This notice may not be removed or altered from any source distribution.
  **/
 
-#include "DrawGable.h"
+#ifndef LOVE_GRAPHICS_OPENGL_WRAP_QUAD_H
+#define LOVE_GRAPHICS_OPENGL_WRAP_QUAD_H
+
+// LOVE
+#include "common/runtime.h"
+#include "graphics/Quad.h"
 
 namespace love
 {
 namespace graphics
 {
-
-DrawGable::~DrawGable()
+namespace opengl
 {
-}
 
+Quad *luax_checkquad(lua_State *L, int idx);
+int w_Quad_flip(lua_State *L);
+int w_Quad_setViewport(lua_State *L);
+int w_Quad_getViewport(lua_State *L);
+extern "C" int luaopen_quad(lua_State *L);
+
+} // opengl
 } // graphics
 } // love
+
+#endif // LOVE_GRAPHICS_OPENGL_WRAP_QUAD_H

+ 10 - 10
src/modules/graphics/opengl/wrap_SpriteBatch.cpp

@@ -36,12 +36,12 @@ SpriteBatch *luax_checkspritebatch(lua_State *L, int idx)
 int w_SpriteBatch_add(lua_State *L)
 {
 	SpriteBatch *t = luax_checkspritebatch(L, 1);
-	Geometry *geom = 0;
+	Quad *quad = 0;
 	int startidx = 2;
 
-	if (luax_istype(L, 2, GRAPHICS_GEOMETRY_T))
+	if (luax_istype(L, 2, GRAPHICS_QUAD_T))
 	{
-		geom = luax_totype<Geometry>(L, 2, "Geometry", GRAPHICS_GEOMETRY_T);
+		quad = luax_totype<Quad>(L, 2, "Quad", GRAPHICS_QUAD_T);
 		startidx = 3;
 	}
 
@@ -57,8 +57,8 @@ int w_SpriteBatch_add(lua_State *L)
 
 	int id = 0;
 	EXCEPT_GUARD(
-		if (geom)
-			id = t->addg(geom, x, y, a, sx, sy, ox, oy, kx, ky);
+		if (quad)
+			id = t->addq(quad, x, y, a, sx, sy, ox, oy, kx, ky);
 		else
 			id = t->add(x, y, a, sx, sy, ox, oy, kx, ky);
 	)
@@ -72,12 +72,12 @@ int w_SpriteBatch_set(lua_State *L)
 	SpriteBatch *t = luax_checkspritebatch(L, 1);
 	int id = luaL_checkinteger(L, 2);
 
-	Geometry *geom = 0;
+	Quad *quad = 0;
 	int startidx = 3;
 
-	if (luax_istype(L, 3, GRAPHICS_GEOMETRY_T))
+	if (luax_istype(L, 3, GRAPHICS_QUAD_T))
 	{
-		geom = luax_totype<Geometry>(L, 3, "Geometry", GRAPHICS_GEOMETRY_T);
+		quad = luax_totype<Quad>(L, 3, "Quad", GRAPHICS_QUAD_T);
 		startidx = 4;
 	}
 
@@ -92,8 +92,8 @@ int w_SpriteBatch_set(lua_State *L)
 	float ky = (float) luaL_optnumber(L, startidx + 8, 0.0);
 
 	EXCEPT_GUARD(
-		if (geom)
-			t->addg(geom, x, y, a, sx, sy, ox, oy, kx, ky, id);
+		if (quad)
+			t->addq(quad, x, y, a, sx, sy, ox, oy, kx, ky, id);
 		else
 			t->add(x, y, a, sx, sy, ox, oy, kx, ky, id);
 	)