Commits

Alex Szpakowski committed 37e7d43

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)

Comments (0)

Files changed (31)

platform/macosx/love-framework.xcodeproj/project.pbxproj

 		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 */; };
 		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 */; };
 		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 */
 		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>"; };
 		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>"; };
 		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 */
 				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 */,
 			);
 				389E3CEC356050A27784290E /* Graphics.h */,
 				56D6030A0B8F7397715062B9 /* Image.cpp */,
 				3CFE5C4A12D5675E7C9C7BF9 /* Image.h */,
+				FAF4376D17F4AC530074F9E2 /* Mesh.cpp */,
+				FAF4376E17F4AC530074F9E2 /* Mesh.h */,
 				2E406F8328543EC63EB922C6 /* OpenGL.cpp */,
 				2C87695707B046B536F347D8 /* OpenGL.h */,
 				48A206C9004150640C432100 /* ParticleSystem.cpp */,
 				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 */,
 				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 */,
 				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 */,
 				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 */,
 				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 */,
 				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 */,

src/common/runtime.cpp

 
 	// 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},

src/common/types.h

 
 	// 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,
 
 // 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;

src/modules/graphics/DrawGable.cpp

-/**
- * 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 "DrawGable.h"
-
-namespace love
-{
-namespace graphics
-{
-
-DrawGable::~DrawGable()
-{
-}
-
-} // graphics
-} // love

src/modules/graphics/DrawGable.h

-/**
- * 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_DRAWGABLE_H
-#define LOVE_GRAPHICS_DRAWGABLE_H
-
-// LOVE
-#include "Drawable.h"
-#include "Geometry.h"
-
-namespace love
-{
-namespace graphics
-{
-
-/**
- * A DrawGable is anything that be drawn in part with a Geometry object.
- **/
-class DrawGable : public Drawable
-{
-public:
-
-	/**
-	 * Destructor.
-	 **/
-	virtual ~DrawGable();
-
-	/**
-	 * Draws the object with the specified transformation.
-	 *
-	 * @param geom The Geometry 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).
-	 * @param sx The scale factor along the x-axis.
-	 * @param sy The scale factor along the y-axis.
-	 * @param ox The origin offset along the x-axis.
-	 * @param oy The origin offset along the y-axis.
-	 * @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;
-};
-
-} // graphics
-} // love
-
-#endif // LOVE_GRAPHICS_DRAWGABLE_H

src/modules/graphics/DrawQable.h

+/**
+ * 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_DRAWQABLE_H
+#define LOVE_GRAPHICS_DRAWQABLE_H
+
+// LOVE
+#include "Drawable.h"
+#include "Quad.h"
+
+namespace love
+{
+namespace graphics
+{
+
+/**
+ * A DrawQable is anything that be drawn in part with a Quad object.
+ **/
+class DrawQable : public Drawable
+{
+public:
+
+	/**
+	 * Destructor.
+	 **/
+	virtual ~DrawQable() {}
+
+	/**
+	 * Draws the object with the specified transformation.
+	 *
+	 * @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).
+	 * @param sx The scale factor along the x-axis.
+	 * @param sy The scale factor along the y-axis.
+	 * @param ox The origin offset along the x-axis.
+	 * @param oy The origin offset along the y-axis.
+	 * @param kx Shear along the x-axis.
+	 * @param ky Shear along the y-axis.
+	 **/
+	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_DRAWQABLE_H

src/modules/graphics/Geometry.cpp

-/**
- * 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

src/modules/graphics/Geometry.h

-/**
- * 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

src/modules/graphics/Image.h

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

src/modules/graphics/Quad.cpp

+/**
+ * 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

src/modules/graphics/Quad.h

+/**
+ * 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

src/modules/graphics/opengl/Canvas.cpp

 	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;
-	}
+	const Vertex *v = quad->getVertices();
 
-	// 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);
-	}
+	// 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;
 
-	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());
-
-	if (geom->hasVertexColors())
-	{
-		glDisableClientState(GL_COLOR_ARRAY);
-		gl.setColor(gl.getColor());
-	}
-
-	delete[] v;
+	drawv(t, w);
 }
 
 bool Canvas::checkCreateStencil()
 	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();
 
 	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);

src/modules/graphics/opengl/Canvas.h

 #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"
 namespace opengl
 {
 
-class Canvas : public DrawGable, public Volatile
+class Canvas : public DrawQable, public Volatile
 {
 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.
 	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;

src/modules/graphics/opengl/Font.cpp

 #include "common/config.h"
 #include "Font.h"
 #include "font/GlyphData.h"
-#include "modules/graphics/Geometry.h"
 #include "Image.h"
 
 #include "libraries/utf8/utf8.h"

src/modules/graphics/opengl/Graphics.cpp

 	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)
 	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);

src/modules/graphics/opengl/Graphics.h

 
 #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;
 
 	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.
 
 	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.

src/modules/graphics/opengl/Image.cpp

 	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);
+	{
+		Vertex w[4];
+		love::Vector scale = getTexCoordScale();
 
-	// use colors stored in geometry (horrible, horrible hack)
-	if (geom->hasVertexColors())
+		for (int i = 0; i < 4; i++)
+		{
+			w[i] = v[i];
+			w[i].s *= scale.x;
+			w[i].t *= scale.y;
+		}
+
+		drawv(t, w);
+	}
+	else
 	{
-		glEnableClientState(GL_COLOR_ARRAY);
-		glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), (GLvoid *) &v[0].r);
+		drawv(t, v);
 	}
-
-	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, vertcount, glmode, geom->getElementArray(), geom->getElementCount());
-
-	if (geom->hasVertexColors())
-	{
-		glDisableClientState(GL_COLOR_ARRAY);
-		gl.setColor(gl.getColor());
-	}
-
-	// If we made new verts with scaled texcoords then we should clean them up.
-	if (!hasNpot())
-		delete[] v;
 }
 
 void Image::uploadCompressedMipmaps()
 	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();
 
 	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);

src/modules/graphics/opengl/Image.h

 	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.
 
 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

src/modules/graphics/opengl/Mesh.cpp

+/**
+ * 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

src/modules/graphics/opengl/Mesh.h

+/**
+ * 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

src/modules/graphics/opengl/SpriteBatch.cpp

 
 // LOVE
 #include "Image.h"
-#include "modules/graphics/Geometry.h"
 #include "VertexBuffer.h"
 
 // C++
 	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.
 
 	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++;

src/modules/graphics/opengl/SpriteBatch.h

 #include "graphics/Drawable.h"
 #include "graphics/Volatile.h"
 #include "graphics/Color.h"
-#include "graphics/Geometry.h"
+#include "graphics/Quad.h"
 
 namespace love
 {
 	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();
 	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();
 	Vertex sprite[4];
 
 	// Current color. This color, if present, will be applied to the next
-	// added geometry.
+	// added sprite.
 	Color *color;
 
 	VertexBuffer *array_buf;

src/modules/graphics/opengl/wrap_Geometry.cpp

-/**
- * 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

src/modules/graphics/opengl/wrap_Geometry.h

-/**
- * 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_WRAP_GEOMETRY_H