Browse Source

Move most of Text and Video love.graphics classes out of the opengl subfolder.

--HG--
branch : minor
Alex Szpakowski 8 years ago
parent
commit
13af754d3d

+ 44 - 22
platform/xcode/liblove.xcodeproj/project.pbxproj

@@ -471,9 +471,6 @@
 		FA0B7D701A95902C000E1D17 /* wrap_SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB61A95902C000E1D17 /* wrap_SpriteBatch.cpp */; };
 		FA0B7D711A95902C000E1D17 /* wrap_SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB61A95902C000E1D17 /* wrap_SpriteBatch.cpp */; };
 		FA0B7D721A95902C000E1D17 /* wrap_SpriteBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BB71A95902C000E1D17 /* wrap_SpriteBatch.h */; };
-		FA0B7D731A95902C000E1D17 /* wrap_Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB81A95902C000E1D17 /* wrap_Text.cpp */; };
-		FA0B7D741A95902C000E1D17 /* wrap_Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB81A95902C000E1D17 /* wrap_Text.cpp */; };
-		FA0B7D751A95902C000E1D17 /* wrap_Text.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BB91A95902C000E1D17 /* wrap_Text.h */; };
 		FA0B7D791A95902C000E1D17 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BBC1A95902C000E1D17 /* Quad.cpp */; };
 		FA0B7D7A1A95902C000E1D17 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BBC1A95902C000E1D17 /* Quad.cpp */; };
 		FA0B7D7B1A95902C000E1D17 /* Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BBD1A95902C000E1D17 /* Quad.h */; };
@@ -837,9 +834,6 @@
 		FA1557C41CE90BD200AFF582 /* EXRHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1557C21CE90BD200AFF582 /* EXRHandler.h */; };
 		FA1557C51CE90BD900AFF582 /* EXRHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1557C11CE90BD200AFF582 /* EXRHandler.cpp */; };
 		FA1583E21E196180005E603B /* wrap_Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA0B51E17043400AA2803 /* wrap_Shader.cpp */; };
-		FA19C4C51B4B0BD50059B0B3 /* wrap_Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA19C4C21B4B0BD50059B0B3 /* wrap_Video.cpp */; };
-		FA19C4C61B4B0BD50059B0B3 /* wrap_Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA19C4C21B4B0BD50059B0B3 /* wrap_Video.cpp */; };
-		FA19C4C71B4B0BD50059B0B3 /* wrap_Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FA19C4C31B4B0BD50059B0B3 /* wrap_Video.h */; };
 		FA1BA09D1E16CFCE00AA2803 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA09B1E16CFCE00AA2803 /* Font.cpp */; };
 		FA1BA09E1E16CFCE00AA2803 /* Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA1BA09B1E16CFCE00AA2803 /* Font.cpp */; };
 		FA1BA09F1E16CFCE00AA2803 /* Font.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1BA09C1E16CFCE00AA2803 /* Font.h */; };
@@ -1014,6 +1008,19 @@
 		FADF53F81E3C7ACD00012CC0 /* Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53F61E3C7ACD00012CC0 /* Buffer.cpp */; };
 		FADF53F91E3C7ACD00012CC0 /* Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53F61E3C7ACD00012CC0 /* Buffer.cpp */; };
 		FADF53FA1E3C7ACD00012CC0 /* Buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF53F71E3C7ACD00012CC0 /* Buffer.h */; };
+		FADF53FD1E3D74F200012CC0 /* Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53FB1E3D74F200012CC0 /* Text.cpp */; };
+		FADF53FE1E3D74F200012CC0 /* Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF53FB1E3D74F200012CC0 /* Text.cpp */; };
+		FADF53FF1E3D74F200012CC0 /* Text.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF53FC1E3D74F200012CC0 /* Text.h */; };
+		FADF54021E3D77B500012CC0 /* wrap_Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54001E3D77B500012CC0 /* wrap_Text.cpp */; };
+		FADF54031E3D77B500012CC0 /* wrap_Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54001E3D77B500012CC0 /* wrap_Text.cpp */; };
+		FADF54041E3D77B500012CC0 /* wrap_Text.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54011E3D77B500012CC0 /* wrap_Text.h */; };
+		FADF54071E3D78F700012CC0 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54051E3D78F700012CC0 /* Video.cpp */; };
+		FADF54081E3D78F700012CC0 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54051E3D78F700012CC0 /* Video.cpp */; };
+		FADF54091E3D78F700012CC0 /* Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54061E3D78F700012CC0 /* Video.h */; };
+		FADF540D1E3D7CDD00012CC0 /* wrap_Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF540A1E3D7CDD00012CC0 /* wrap_Video.cpp */; };
+		FADF540E1E3D7CDD00012CC0 /* wrap_Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF540A1E3D7CDD00012CC0 /* wrap_Video.cpp */; };
+		FADF540F1E3D7CDD00012CC0 /* wrap_Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF540B1E3D7CDD00012CC0 /* wrap_Video.h */; };
+		FADF54101E3D7CDD00012CC0 /* wrap_Video.lua in Resources */ = {isa = PBXBuildFile; fileRef = FADF540C1E3D7CDD00012CC0 /* wrap_Video.lua */; };
 		FAE272521C05A15B00A67640 /* ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE272501C05A15B00A67640 /* ParticleSystem.cpp */; };
 		FAE272531C05A15B00A67640 /* ParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE272511C05A15B00A67640 /* ParticleSystem.h */; };
 		FAF140531E20934C00F898D2 /* CodeGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FC21E20934C00F898D2 /* CodeGen.cpp */; };
@@ -1465,8 +1472,6 @@
 		FA0B7BB11A95902C000E1D17 /* wrap_ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_ParticleSystem.h; sourceTree = "<group>"; };
 		FA0B7BB61A95902C000E1D17 /* wrap_SpriteBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_SpriteBatch.cpp; sourceTree = "<group>"; };
 		FA0B7BB71A95902C000E1D17 /* wrap_SpriteBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_SpriteBatch.h; sourceTree = "<group>"; };
-		FA0B7BB81A95902C000E1D17 /* wrap_Text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Text.cpp; sourceTree = "<group>"; };
-		FA0B7BB91A95902C000E1D17 /* wrap_Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Text.h; sourceTree = "<group>"; };
 		FA0B7BBC1A95902C000E1D17 /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = "<group>"; };
 		FA0B7BBD1A95902C000E1D17 /* Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = "<group>"; };
 		FA0B7BBE1A95902C000E1D17 /* Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Texture.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
@@ -1713,9 +1718,6 @@
 		FA1557BF1CE90A2C00AFF582 /* tinyexr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyexr.h; sourceTree = "<group>"; };
 		FA1557C11CE90BD200AFF582 /* EXRHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EXRHandler.cpp; sourceTree = "<group>"; };
 		FA1557C21CE90BD200AFF582 /* EXRHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXRHandler.h; sourceTree = "<group>"; };
-		FA19C4C21B4B0BD50059B0B3 /* wrap_Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Video.cpp; sourceTree = "<group>"; };
-		FA19C4C31B4B0BD50059B0B3 /* wrap_Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Video.h; sourceTree = "<group>"; };
-		FA19C4C41B4B0BD50059B0B3 /* wrap_Video.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wrap_Video.lua; sourceTree = "<group>"; };
 		FA1BA09B1E16CFCE00AA2803 /* Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Font.cpp; sourceTree = "<group>"; };
 		FA1BA09C1E16CFCE00AA2803 /* Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Font.h; sourceTree = "<group>"; };
 		FA1BA0A01E16D97500AA2803 /* wrap_Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Font.cpp; sourceTree = "<group>"; };
@@ -1838,6 +1840,15 @@
 		FAC734C21B2E628700AB460A /* wrap_ImageData.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_ImageData.lua; sourceTree = "<group>"; };
 		FADF53F61E3C7ACD00012CC0 /* Buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Buffer.cpp; sourceTree = "<group>"; };
 		FADF53F71E3C7ACD00012CC0 /* Buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Buffer.h; sourceTree = "<group>"; };
+		FADF53FB1E3D74F200012CC0 /* Text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Text.cpp; sourceTree = "<group>"; };
+		FADF53FC1E3D74F200012CC0 /* Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Text.h; sourceTree = "<group>"; };
+		FADF54001E3D77B500012CC0 /* wrap_Text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Text.cpp; sourceTree = "<group>"; };
+		FADF54011E3D77B500012CC0 /* wrap_Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Text.h; sourceTree = "<group>"; };
+		FADF54051E3D78F700012CC0 /* Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Video.cpp; sourceTree = "<group>"; };
+		FADF54061E3D78F700012CC0 /* Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Video.h; sourceTree = "<group>"; };
+		FADF540A1E3D7CDD00012CC0 /* wrap_Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Video.cpp; sourceTree = "<group>"; };
+		FADF540B1E3D7CDD00012CC0 /* wrap_Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Video.h; sourceTree = "<group>"; };
+		FADF540C1E3D7CDD00012CC0 /* wrap_Video.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wrap_Video.lua; sourceTree = "<group>"; };
 		FAE272501C05A15B00A67640 /* ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cpp; sourceTree = "<group>"; };
 		FAE272511C05A15B00A67640 /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = "<group>"; };
 		FAF13FC21E20934C00F898D2 /* CodeGen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGen.cpp; sourceTree = "<group>"; };
@@ -2642,10 +2653,14 @@
 				FA1BA0B01E16FD0800AA2803 /* Shader.h */,
 				FA29C0041E12355B00268CD8 /* StreamBuffer.cpp */,
 				FA2AF6721DAD62710032B62C /* StreamBuffer.h */,
+				FADF53FB1E3D74F200012CC0 /* Text.cpp */,
+				FADF53FC1E3D74F200012CC0 /* Text.h */,
 				FA0B7BBE1A95902C000E1D17 /* Texture.cpp */,
 				FA0B7BBF1A95902C000E1D17 /* Texture.h */,
 				FA2AF6731DAD64970032B62C /* vertex.cpp */,
 				FA2AF6711DAC76FF0032B62C /* vertex.h */,
+				FADF54051E3D78F700012CC0 /* Video.cpp */,
+				FADF54061E3D78F700012CC0 /* Video.h */,
 				FA0B7BC01A95902C000E1D17 /* Volatile.cpp */,
 				FA0B7BC11A95902C000E1D17 /* Volatile.h */,
 				FA1BA0AA1E16F9EE00AA2803 /* wrap_Canvas.cpp */,
@@ -2656,8 +2671,13 @@
 				FA620A2F1AA2F8DB005DB4C2 /* wrap_Quad.h */,
 				FA1BA0B51E17043400AA2803 /* wrap_Shader.cpp */,
 				FA1BA0B61E17043400AA2803 /* wrap_Shader.h */,
+				FADF54001E3D77B500012CC0 /* wrap_Text.cpp */,
+				FADF54011E3D77B500012CC0 /* wrap_Text.h */,
 				FA620A301AA2F8DB005DB4C2 /* wrap_Texture.cpp */,
 				FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */,
+				FADF540A1E3D7CDD00012CC0 /* wrap_Video.cpp */,
+				FADF540B1E3D7CDD00012CC0 /* wrap_Video.h */,
+				FADF540C1E3D7CDD00012CC0 /* wrap_Video.lua */,
 			);
 			path = graphics;
 			sourceTree = "<group>";
@@ -2704,11 +2724,6 @@
 				FA0B7BB11A95902C000E1D17 /* wrap_ParticleSystem.h */,
 				FA0B7BB61A95902C000E1D17 /* wrap_SpriteBatch.cpp */,
 				FA0B7BB71A95902C000E1D17 /* wrap_SpriteBatch.h */,
-				FA0B7BB81A95902C000E1D17 /* wrap_Text.cpp */,
-				FA0B7BB91A95902C000E1D17 /* wrap_Text.h */,
-				FA19C4C21B4B0BD50059B0B3 /* wrap_Video.cpp */,
-				FA19C4C31B4B0BD50059B0B3 /* wrap_Video.h */,
-				FA19C4C41B4B0BD50059B0B3 /* wrap_Video.lua */,
 			);
 			path = opengl;
 			sourceTree = "<group>";
@@ -3512,7 +3527,6 @@
 				FA0B7E9F1A95902C000E1D17 /* WaveDecoder.h in Headers */,
 				FAF140871E20934C00F898D2 /* parseVersions.h in Headers */,
 				FA0B7AC61A958EA3000E1D17 /* types.h in Headers */,
-				FA0B7D751A95902C000E1D17 /* wrap_Text.h in Headers */,
 				FA0B7DBD1A95902C000E1D17 /* Joystick.h in Headers */,
 				FA0B7E901A95902C000E1D17 /* GmeDecoder.h in Headers */,
 				FA0B7D0E1A95902C000E1D17 /* wrap_Filesystem.h in Headers */,
@@ -3535,7 +3549,6 @@
 				FA0B7AA31A958EA3000E1D17 /* b2PulleyJoint.h in Headers */,
 				FAF140621E20934C00F898D2 /* ShHandle.h in Headers */,
 				FA0B7B2F1A958EA3000E1D17 /* utf8.h in Headers */,
-				FA19C4C71B4B0BD50059B0B3 /* wrap_Video.h in Headers */,
 				FA0B79231A958E3B000E1D17 /* EnumMap.h in Headers */,
 				FAF140571E20934C00F898D2 /* arrays.h in Headers */,
 				FA0B7A371A958EA3000E1D17 /* b2Distance.h in Headers */,
@@ -3561,6 +3574,7 @@
 				FA9159201CF1ED7500A7053F /* halffloat.h in Headers */,
 				FA0B7CE41A95902C000E1D17 /* wrap_Audio.h in Headers */,
 				FA0B7A7F1A958EA3000E1D17 /* b2ContactSolver.h in Headers */,
+				FADF540F1E3D7CDD00012CC0 /* wrap_Video.h in Headers */,
 				FA0B79491A958E3B000E1D17 /* version.h in Headers */,
 				FAF140581E20934C00F898D2 /* BaseTypes.h in Headers */,
 				FA0B7B2B1A958EA3000E1D17 /* stb_image.h in Headers */,
@@ -3644,6 +3658,7 @@
 				FA0B7E7D1A95902C000E1D17 /* wrap_World.h in Headers */,
 				FA0B7EBD1A95902C000E1D17 /* LuaThread.h in Headers */,
 				FA0B7D601A95902C000E1D17 /* wrap_Graphics.h in Headers */,
+				FADF53FF1E3D74F200012CC0 /* Text.h in Headers */,
 				FA0B7DC01A95902C000E1D17 /* JoystickModule.h in Headers */,
 				FA0B7E871A95902C000E1D17 /* CoreAudioDecoder.h in Headers */,
 				FA0B7CD51A95902C000E1D17 /* Source.h in Headers */,
@@ -3679,6 +3694,7 @@
 				FA0B7CD81A95902C000E1D17 /* Audio.h in Headers */,
 				FA0B7CF61A95902C000E1D17 /* File.h in Headers */,
 				FA0B7E961A95902C000E1D17 /* Mpg123Decoder.h in Headers */,
+				FADF54091E3D78F700012CC0 /* Video.h in Headers */,
 				FA0B7D501A95902C000E1D17 /* SpriteBatch.h in Headers */,
 				FA0B7DD51A95902C000E1D17 /* BezierCurve.h in Headers */,
 				FA0B79271A958E3B000E1D17 /* int.h in Headers */,
@@ -3844,6 +3860,7 @@
 				FA0B793F1A958E3B000E1D17 /* types.h in Headers */,
 				FA0B7AB31A958EA3000E1D17 /* b2Rope.h in Headers */,
 				FA41A3CA1C0A1F950084430C /* ASTCHandler.h in Headers */,
+				FADF54041E3D77B500012CC0 /* wrap_Text.h in Headers */,
 				FA0B7ED31A95902C000E1D17 /* wrap_ThreadModule.h in Headers */,
 				FA0B7A511A958EA3000E1D17 /* b2GrowableStack.h in Headers */,
 				FA0B7D921A95902C000E1D17 /* FormatHandler.h in Headers */,
@@ -3926,6 +3943,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				217DFC0F1D9F6D490055D849 /* url.lua in Resources */,
+				FADF54101E3D7CDD00012CC0 /* wrap_Video.lua in Resources */,
 				217DFBFC1D9F6D490055D849 /* smtp.lua in Resources */,
 				217DFBF01D9F6D490055D849 /* mbox.lua in Resources */,
 				217DFBE11D9F6D490055D849 /* ftp.lua in Resources */,
@@ -3945,11 +3963,11 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				FA0B7D741A95902C000E1D17 /* wrap_Text.cpp in Sources */,
 				FA0B7DE01A95902C000E1D17 /* wrap_Math.cpp in Sources */,
 				FA0B7DA91A95902C000E1D17 /* PVRHandler.cpp in Sources */,
 				FA0B7EC61A95902C000E1D17 /* ThreadModule.cpp in Sources */,
 				FA0B7D2C1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */,
+				FADF54081E3D78F700012CC0 /* Video.cpp in Sources */,
 				FA9D8DD81DEF8411002CD881 /* Data.cpp in Sources */,
 				FA0B7E8F1A95902C000E1D17 /* GmeDecoder.cpp in Sources */,
 				FA0B7CD71A95902C000E1D17 /* Audio.cpp in Sources */,
@@ -4010,6 +4028,7 @@
 				FAF1406A1E20934C00F898D2 /* glslang_tab.cpp in Sources */,
 				FA91591F1CF1ED7500A7053F /* halffloat.cpp in Sources */,
 				FA8951A31AA2EDF300EC385A /* wrap_Event.cpp in Sources */,
+				FADF540E1E3D7CDD00012CC0 /* wrap_Video.cpp in Sources */,
 				FA0B7A361A958EA3000E1D17 /* b2Distance.cpp in Sources */,
 				FA0B7D4C1A95902C000E1D17 /* Shader.cpp in Sources */,
 				FA0B792A1A958E3B000E1D17 /* Matrix.cpp in Sources */,
@@ -4035,6 +4054,7 @@
 				FA1BA0A31E16D97500AA2803 /* wrap_Font.cpp in Sources */,
 				FA0B7A931A958EA3000E1D17 /* b2GearJoint.cpp in Sources */,
 				FA0B7E0D1A95902C000E1D17 /* Fixture.cpp in Sources */,
+				FADF53FE1E3D74F200012CC0 /* Text.cpp in Sources */,
 				FA0B7D191A95902C000E1D17 /* TrueTypeRasterizer.cpp in Sources */,
 				FA0B7CFB1A95902C000E1D17 /* Filesystem.cpp in Sources */,
 				FA0B7D3D1A95902C000E1D17 /* Image.cpp in Sources */,
@@ -4045,6 +4065,7 @@
 				FA0B7AA21A958EA3000E1D17 /* b2PulleyJoint.cpp in Sources */,
 				FA9D8DDE1DEF842A002CD881 /* Drawable.cpp in Sources */,
 				FA0B7CCE1A95902C000E1D17 /* Audio.cpp in Sources */,
+				FADF54031E3D77B500012CC0 /* wrap_Text.cpp in Sources */,
 				FA0B7DCB1A95902C000E1D17 /* Keyboard.cpp in Sources */,
 				FA0B7A901A958EA3000E1D17 /* b2FrictionJoint.cpp in Sources */,
 				FA0B7DFB1A95902C000E1D17 /* Body.cpp in Sources */,
@@ -4279,7 +4300,6 @@
 				FA0B7E821A95902C000E1D17 /* Shape.cpp in Sources */,
 				FA0B7ACE1A958EA3000E1D17 /* packet.c in Sources */,
 				FAF140891E20934C00F898D2 /* PoolAlloc.cpp in Sources */,
-				FA19C4C61B4B0BD50059B0B3 /* wrap_Video.cpp in Sources */,
 				FA27B3B41B498151008A9DCE /* wrap_Video.cpp in Sources */,
 				FA1E88801DF363D400E808AA /* Filter.cpp in Sources */,
 				FA0B7AA81A958EA3000E1D17 /* b2RopeJoint.cpp in Sources */,
@@ -4299,11 +4319,11 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				FA0B7D731A95902C000E1D17 /* wrap_Text.cpp in Sources */,
 				217DFBDD1D9F6D490055D849 /* compat.c in Sources */,
 				FA0B7DDF1A95902C000E1D17 /* wrap_Math.cpp in Sources */,
 				FA0B7DA81A95902C000E1D17 /* PVRHandler.cpp in Sources */,
 				FA0B7EC51A95902C000E1D17 /* ThreadModule.cpp in Sources */,
+				FADF54071E3D78F700012CC0 /* Video.cpp in Sources */,
 				217DFC031D9F6D490055D849 /* timeout.c in Sources */,
 				FA9D8DD71DEF8411002CD881 /* Data.cpp in Sources */,
 				FA0B7D2B1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */,
@@ -4364,6 +4384,7 @@
 				FAF140691E20934C00F898D2 /* glslang_tab.cpp in Sources */,
 				FA0B7ABF1A958EA3000E1D17 /* host.c in Sources */,
 				FA0B7D4B1A95902C000E1D17 /* Shader.cpp in Sources */,
+				FADF540D1E3D7CDD00012CC0 /* wrap_Video.cpp in Sources */,
 				FA0B7A581A958EA3000E1D17 /* b2StackAllocator.cpp in Sources */,
 				FA0B7A301A958EA3000E1D17 /* b2CollidePolygon.cpp in Sources */,
 				FA0B7A641A958EA3000E1D17 /* b2Fixture.cpp in Sources */,
@@ -4389,6 +4410,7 @@
 				FA1BA0A21E16D97500AA2803 /* wrap_Font.cpp in Sources */,
 				FA0B7D3C1A95902C000E1D17 /* Image.cpp in Sources */,
 				FA0B7A8C1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */,
+				FADF53FD1E3D74F200012CC0 /* Text.cpp in Sources */,
 				217DFBE91D9F6D490055D849 /* io.c in Sources */,
 				FA0B7E421A95902C000E1D17 /* wrap_CircleShape.cpp in Sources */,
 				FA0B7CE51A95902C000E1D17 /* wrap_Source.cpp in Sources */,
@@ -4399,6 +4421,7 @@
 				FA0B7AA41A958EA3000E1D17 /* b2RevoluteJoint.cpp in Sources */,
 				FA9D8DDD1DEF842A002CD881 /* Drawable.cpp in Sources */,
 				FA0B7DFA1A95902C000E1D17 /* Body.cpp in Sources */,
+				FADF54021E3D77B500012CC0 /* wrap_Text.cpp in Sources */,
 				FA0B7ED11A95902C000E1D17 /* wrap_ThreadModule.cpp in Sources */,
 				FA0B7EDF1A95902D000E1D17 /* wrap_Touch.cpp in Sources */,
 				FA0B794A1A958E3B000E1D17 /* wrap_Data.cpp in Sources */,
@@ -4627,7 +4650,6 @@
 				FA0B7E811A95902C000E1D17 /* Shape.cpp in Sources */,
 				FA4F2BA81DE1E36400CA37D7 /* wrap_RecordingDevice.cpp in Sources */,
 				FA0B7B251A958EA3000E1D17 /* lutf8lib.c in Sources */,
-				FA19C4C51B4B0BD50059B0B3 /* wrap_Video.cpp in Sources */,
 				FAF140531E20934C00F898D2 /* CodeGen.cpp in Sources */,
 				FA27B3B31B498151008A9DCE /* wrap_Video.cpp in Sources */,
 				FA0B7A611A958EA3000E1D17 /* b2ContactManager.cpp in Sources */,

+ 7 - 0
src/modules/graphics/Graphics.h

@@ -36,6 +36,7 @@
 #include "Quad.h"
 #include "math/Transform.h"
 #include "font/Rasterizer.h"
+#include "video/VideoStream.h"
 
 // C++
 #include <string>
@@ -49,6 +50,8 @@ class Reference;
 namespace graphics
 {
 
+class Text;
+class Video;
 class Buffer;
 
 const int MAX_COLOR_RENDER_TARGETS = 8;
@@ -317,8 +320,12 @@ public:
 
 	virtual Shader *newShader(const Shader::ShaderSource &source) = 0;
 
+	virtual Video *newVideo(love::video::VideoStream *stream, float pixeldensity) = 0;
+
 	virtual Buffer *newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags) = 0;
 
+	virtual Text *newText(Font *font, const std::vector<Font::ColoredString> &text = {}) = 0;
+
 	bool validateShader(bool gles, const Shader::ShaderSource &source, std::string &err);
 
 	/**

+ 239 - 0
src/modules/graphics/Text.cpp

@@ -0,0 +1,239 @@
+/**
+ * Copyright (c) 2006-2017 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 "Text.h"
+#include "Graphics.h"
+
+#include <algorithm>
+
+namespace love
+{
+namespace graphics
+{
+
+love::Type Text::type("Text", &Drawable::type);
+
+Text::Text(Graphics *gfx, Font *font, const std::vector<Font::ColoredString> &text)
+	: font(font)
+	, vbo(nullptr)
+	, quadIndices(gfx, 20)
+	, vert_offset(0)
+	, texture_cache_id((uint32) -1)
+{
+	set(text);
+}
+
+Text::~Text()
+{
+	delete vbo;
+}
+
+void Text::uploadVertices(const std::vector<Font::GlyphVertex> &vertices, size_t vertoffset)
+{
+	size_t offset = vertoffset * sizeof(Font::GlyphVertex);
+	size_t datasize = vertices.size() * sizeof(Font::GlyphVertex);
+	uint8 *vbodata = nullptr;
+
+	// If we haven't created a VBO or the vertices are too big, make a new one.
+	if (datasize > 0 && (!vbo || (offset + datasize) > vbo->getSize()))
+	{
+		// Make it bigger than necessary to reduce potential future allocations.
+		size_t newsize = size_t((offset + datasize) * 1.5);
+
+		if (vbo != nullptr)
+			newsize = std::max(size_t(vbo->getSize() * 1.5), newsize);
+
+		auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
+		Buffer *new_vbo = gfx->newBuffer(newsize, nullptr, BUFFER_VERTEX, vertex::USAGE_DYNAMIC, 0);
+
+		if (vbo != nullptr)
+			vbo->copyTo(0, vbo->getSize(), new_vbo, 0);
+
+		delete vbo;
+		vbo = new_vbo;
+	}
+
+	if (vbo != nullptr && datasize > 0)
+	{
+		vbodata = (uint8 *) vbo->map();
+		memcpy(vbodata + offset, &vertices[0], datasize);
+		// We unmap when we draw, to avoid unnecessary full map()/unmap() calls.
+	}
+}
+
+void Text::regenerateVertices()
+{
+	// If the font's texture cache was invalidated then we need to recreate the
+	// text's vertices, since glyph texcoords might have changed.
+	if (font->getTextureCacheID() != texture_cache_id)
+	{
+		std::vector<TextData> textdata = text_data;
+
+		clear();
+
+		for (const TextData &t : textdata)
+			addTextData(t);
+
+		texture_cache_id = font->getTextureCacheID();
+	}
+}
+
+void Text::addTextData(const TextData &t)
+{
+	std::vector<Font::GlyphVertex> vertices;
+	std::vector<Font::DrawCommand> new_commands;
+
+	Font::TextInfo text_info;
+
+	Colorf constantcolor = Colorf(1.0f, 1.0f, 1.0f, 1.0f);
+
+	// We only have formatted text if the align mode is valid.
+	if (t.align == Font::ALIGN_MAX_ENUM)
+		new_commands = font->generateVertices(t.codepoints, constantcolor, vertices, 0.0f, Vector(0.0f, 0.0f), &text_info);
+	else
+		new_commands = font->generateVerticesFormatted(t.codepoints, constantcolor, t.wrap, t.align, vertices, &text_info);
+
+	if (t.use_matrix)
+		t.matrix.transform(&vertices[0], &vertices[0], (int) vertices.size());
+
+	size_t voffset = vert_offset;
+
+	if (!t.append_vertices)
+	{
+		voffset = 0;
+		draw_commands.clear();
+		text_data.clear();
+	}
+
+	uploadVertices(vertices, voffset);
+
+	if (!new_commands.empty())
+	{
+		// The start vertex should be adjusted to account for the vertex offset.
+		for (Font::DrawCommand &cmd : new_commands)
+			cmd.startvertex += (int) voffset;
+
+		auto firstcmd = new_commands.begin();
+
+		// If the first draw command in the new list has the same texture as the
+		// last one in the existing list we're building and its vertices are
+		// in-order, we can combine them (saving a draw call.)
+		if (!draw_commands.empty())
+		{
+			auto prevcmd = draw_commands.back();
+			if (prevcmd.texture == firstcmd->texture && (prevcmd.startvertex + prevcmd.vertexcount) == firstcmd->startvertex)
+			{
+				draw_commands.back().vertexcount += firstcmd->vertexcount;
+				++firstcmd;
+			}
+		}
+
+		// Append the new draw commands to the list we're building.
+		draw_commands.insert(draw_commands.end(), firstcmd, new_commands.end());
+	}
+
+	vert_offset = voffset + vertices.size();
+
+	text_data.push_back(t);
+	text_data.back().text_info = text_info;
+
+	// Font::generateVertices can invalidate the font's texture cache.
+	if (font->getTextureCacheID() != texture_cache_id)
+		regenerateVertices();
+}
+
+void Text::set(const std::vector<Font::ColoredString> &text)
+{
+	return set(text, -1.0f, Font::ALIGN_MAX_ENUM);
+}
+
+void Text::set(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align)
+{
+	if (text.empty() || (text.size() == 1 && text[0].str.empty()))
+		return clear();
+
+	Font::ColoredCodepoints codepoints;
+	Font::getCodepointsFromString(text, codepoints);
+
+	addTextData({codepoints, wrap, align, {}, false, false, Matrix4()});
+}
+
+int Text::add(const std::vector<Font::ColoredString> &text, const Matrix4 &m)
+{
+	return addf(text, -1.0f, Font::ALIGN_MAX_ENUM, m);
+}
+
+int Text::addf(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align, const Matrix4 &m)
+{
+	Font::ColoredCodepoints codepoints;
+	Font::getCodepointsFromString(text, codepoints);
+
+	addTextData({codepoints, wrap, align, {}, true, true, m});
+
+	return (int) text_data.size() - 1;
+}
+
+void Text::clear()
+{
+	text_data.clear();
+	draw_commands.clear();
+	texture_cache_id = font->getTextureCacheID();
+	vert_offset = 0;
+}
+
+void Text::setFont(Font *f)
+{
+	font.set(f);
+	
+	// Invalidate the texture cache ID since the font is different. We also have
+	// to re-upload all the vertices based on the new font's textures.
+	texture_cache_id = (uint32) -1;
+	regenerateVertices();
+}
+
+Font *Text::getFont() const
+{
+	return font.get();
+}
+
+int Text::getWidth(int index) const
+{
+	if (index < 0)
+		index = std::max((int) text_data.size() - 1, 0);
+	
+	if (index >= (int) text_data.size())
+		return 0;
+	
+	return text_data[index].text_info.width;
+}
+
+int Text::getHeight(int index) const
+{
+	if (index < 0)
+		index = std::max((int) text_data.size() - 1, 0);
+	
+	if (index >= (int) text_data.size())
+		return 0;
+	
+	return text_data[index].text_info.height;
+}
+
+} // graphics
+} // love

+ 99 - 0
src/modules/graphics/Text.h

@@ -0,0 +1,99 @@
+/**
+* Copyright (c) 2006-2017 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.
+**/
+
+#pragma once
+
+// LOVE
+#include "common/config.h"
+#include "Drawable.h"
+#include "Font.h"
+#include "Buffer.h"
+
+namespace love
+{
+namespace graphics
+{
+
+class Graphics;
+
+class Text : public Drawable
+{
+public:
+
+	static love::Type type;
+
+	Text(Graphics *gfx, Font *font, const std::vector<Font::ColoredString> &text = {});
+	virtual ~Text();
+
+	void set(const std::vector<Font::ColoredString> &text);
+	void set(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align);
+
+	int add(const std::vector<Font::ColoredString> &text, const Matrix4 &m);
+	int addf(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align, const Matrix4 &m);
+
+	void clear();
+
+	void setFont(Font *f);
+	Font *getFont() const;
+
+	/**
+	 * Gets the width of the currently set text.
+	 **/
+	int getWidth(int index = 0) const;
+
+	/**
+	 * Gets the height of the currently set text.
+	 **/
+	int getHeight(int index = 0) const;
+
+protected:
+
+	struct TextData
+	{
+		Font::ColoredCodepoints codepoints;
+		float wrap;
+		Font::AlignMode align;
+		Font::TextInfo text_info;
+		bool use_matrix;
+		bool append_vertices;
+		Matrix4 matrix;
+	};
+
+	void uploadVertices(const std::vector<Font::GlyphVertex> &vertices, size_t vertoffset);
+	void regenerateVertices();
+	void addTextData(const TextData &s);
+
+	StrongRef<Font> font;
+	Buffer *vbo;
+	QuadIndices quadIndices;
+
+	std::vector<Font::DrawCommand> draw_commands;
+
+	std::vector<TextData> text_data;
+
+	size_t vert_offset;
+	
+	// Used so we know when the font's texture cache is invalidated.
+	uint32 texture_cache_id;
+	
+}; // Text
+
+} // graphics
+} // love

+ 172 - 0
src/modules/graphics/Video.cpp

@@ -0,0 +1,172 @@
+/**
+ * Copyright (c) 2006-2017 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 "Video.h"
+
+// LOVE
+#include "Shader.h"
+#include "Graphics.h"
+
+namespace love
+{
+namespace graphics
+{
+
+love::Type Video::type("Video", &Drawable::type);
+
+Video::Video(love::video::VideoStream *stream, float pixeldensity)
+	: stream(stream)
+	, width(stream->getWidth() / pixeldensity)
+	, height(stream->getHeight() / pixeldensity)
+	, filter(Texture::defaultFilter)
+{
+	textureHandles[2] = textureHandles[1] = textureHandles[0] = 0;
+
+	filter.mipmap = Texture::FILTER_NONE;
+
+	stream->fillBackBuffer();
+
+	for (int i = 0; i < 4; i++)
+		vertices[i].color = Color(255, 255, 255, 255);
+
+	// Vertices are ordered for use with triangle strips:
+	// 0---2
+	// | / |
+	// 1---3
+	vertices[0].x = 0.0f;
+	vertices[0].y = 0.0f;
+	vertices[1].x = 0.0f;
+	vertices[1].y = (float) height;
+	vertices[2].x = (float) width;
+	vertices[2].y = 0.0f;
+	vertices[3].x = (float) width;
+	vertices[3].y = (float) height;
+
+	vertices[0].s = 0.0f;
+	vertices[0].t = 0.0f;
+	vertices[1].s = 0.0f;
+	vertices[1].t = 1.0f;
+	vertices[2].s = 1.0f;
+	vertices[2].t = 0.0f;
+	vertices[3].s = 1.0f;
+	vertices[3].t = 1.0f;
+}
+
+Video::~Video()
+{
+}
+
+love::video::VideoStream *Video::getStream()
+{
+	return stream;
+}
+
+void Video::draw(Graphics *gfx, const Matrix4 &m)
+{
+	update();
+
+	gfx->flushStreamDraws();
+
+	love::graphics::Shader *shader = Shader::current;
+	bool usingdefaultshader = (shader == Shader::defaultShader);
+	if (usingdefaultshader)
+	{
+		// If we're using the default shader, substitute the video version.
+		Shader::defaultVideoShader->attach();
+		shader = Shader::defaultVideoShader;
+	}
+
+	shader->setVideoTextures(textureHandles[0], textureHandles[1], textureHandles[2]);
+
+	Graphics::StreamDrawRequest req;
+	req.formats[0] = vertex::CommonFormat::XYf_STf_RGBAub;
+	req.indexMode = vertex::TriangleIndexMode::QUADS;
+	req.vertexCount = 4;
+
+	Graphics::StreamVertexData data = gfx->requestStreamDraw(req);
+	Vertex *verts = (Vertex *) data.stream[0];
+
+	Matrix4 t(gfx->getTransform(), m);
+	t.transform(verts, vertices, 4);
+
+	Color c = toColor(gfx->getColor());
+
+	for (int i = 0; i < 4; i++)
+	{
+		verts[i].s = vertices[i].s;
+		verts[i].t = vertices[i].t;
+		verts[i].color = c;
+	}
+
+	gfx->flushStreamDraws();
+
+	if (usingdefaultshader)
+		Shader::defaultShader->attach();
+}
+
+void Video::update()
+{
+	bool bufferschanged = stream->swapBuffers();
+	stream->fillBackBuffer();
+
+	if (bufferschanged)
+	{
+		auto frame = (const love::video::VideoStream::Frame*) stream->getFrontBuffer();
+		uploadFrame(frame);
+	}
+}
+
+love::audio::Source *Video::getSource()
+{
+	return source;
+}
+
+void Video::setSource(love::audio::Source *source)
+{
+	this->source = source;
+}
+
+int Video::getWidth() const
+{
+	return width;
+}
+
+int Video::getHeight() const
+{
+	return height;
+}
+
+int Video::getPixelWidth() const
+{
+	return stream->getWidth();
+}
+
+int Video::getPixelHeight() const
+{
+	return stream->getHeight();
+}
+
+const Texture::Filter &Video::getFilter() const
+{
+	return filter;
+}
+
+} // graphics
+} // love

+ 85 - 0
src/modules/graphics/Video.h

@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2006-2017 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.
+ **/
+
+#pragma once
+
+// LOVE
+#include "common/math.h"
+#include "Drawable.h"
+#include "Texture.h"
+#include "vertex.h"
+#include "video/VideoStream.h"
+#include "audio/Source.h"
+
+namespace love
+{
+namespace graphics
+{
+
+class Video : public Drawable
+{
+public:
+
+	static love::Type type;
+
+	Video(love::video::VideoStream *stream, float pixeldensity = 1.0f);
+	virtual ~Video();
+
+	// Drawable
+	void draw(Graphics *gfx, const Matrix4 &m) override;
+
+	love::video::VideoStream *getStream();
+
+	love::audio::Source *getSource();
+	void setSource(love::audio::Source *source);
+
+	int getWidth() const;
+	int getHeight() const;
+
+	int getPixelWidth() const;
+	int getPixelHeight() const;
+
+	virtual void setFilter(const Texture::Filter &f) = 0;
+	const Texture::Filter &getFilter() const;
+
+protected:
+
+	virtual void uploadFrame(const love::video::VideoStream::Frame *frame) = 0;
+
+	StrongRef<love::video::VideoStream> stream;
+
+	int width;
+	int height;
+
+	Texture::Filter filter;
+
+	Vertex vertices[4];
+
+	ptrdiff_t textureHandles[3];
+
+private:
+
+	void update();
+	StrongRef<love::audio::Source> source;
+	
+}; // Video
+
+} // graphics
+} // love

+ 4 - 2
src/modules/graphics/opengl/Graphics.cpp

@@ -30,6 +30,8 @@
 #include "math/MathModule.h"
 #include "window/Window.h"
 #include "Buffer.h"
+#include "Video.h"
+#include "Text.h"
 
 #include "libraries/xxHash/xxhash.h"
 
@@ -185,12 +187,12 @@ Mesh *Graphics::newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, con
 	return new Mesh(this, vertexformat, data, datasize, drawmode, usage);
 }
 
-Text *Graphics::newText(graphics::Font *font, const std::vector<Font::ColoredString> &text)
+love::graphics::Text *Graphics::newText(graphics::Font *font, const std::vector<Font::ColoredString> &text)
 {
 	return new Text(this, font, text);
 }
 
-Video *Graphics::newVideo(love::video::VideoStream *stream, float pixeldensity)
+love::graphics::Video *Graphics::newVideo(love::video::VideoStream *stream, float pixeldensity)
 {
 	return new Video(stream, pixeldensity);
 }

+ 2 - 6
src/modules/graphics/opengl/Graphics.h

@@ -36,16 +36,12 @@
 #include "image/Image.h"
 #include "image/ImageData.h"
 
-#include "video/VideoStream.h"
-
 #include "Image.h"
 #include "SpriteBatch.h"
 #include "ParticleSystem.h"
 #include "Canvas.h"
 #include "Shader.h"
 #include "Mesh.h"
-#include "Text.h"
-#include "Video.h"
 
 namespace love
 {
@@ -86,9 +82,9 @@ public:
 	Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage);
 	Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, const void *data, size_t datasize, Mesh::DrawMode drawmode, vertex::Usage usage);
 
-	Text *newText(love::graphics::Font *font, const std::vector<Font::ColoredString> &text = {});
+	love::graphics::Text *newText(love::graphics::Font *font, const std::vector<Font::ColoredString> &text = {}) override;
 
-	Video *newVideo(love::video::VideoStream *stream, float pixeldensity);
+	love::graphics::Video *newVideo(love::video::VideoStream *stream, float pixeldensity) override;
 
 	void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
 	bool setMode(int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil) override;

+ 3 - 3
src/modules/graphics/opengl/StreamBuffer.cpp

@@ -335,14 +335,14 @@ public:
 	}
 
 private:
-	
+
 	GLuint vbo;
 	size_t gpuReadOffset;
 	GLenum glMode;
 	uint8 *data;
-	
+
 	BufferSync sync;
-	
+
 }; // StreamBufferPersistentMapSync
 
 love::graphics::StreamBuffer *CreateStreamBuffer(BufferType mode, size_t size)

+ 1 - 202
src/modules/graphics/opengl/Text.cpp

@@ -19,12 +19,9 @@
  **/
 
 #include "Text.h"
-#include "common/Matrix.h"
 #include "graphics/Graphics.h"
 #include "OpenGL.h"
 
-#include <algorithm>
-
 namespace love
 {
 namespace graphics
@@ -32,174 +29,13 @@ namespace graphics
 namespace opengl
 {
 
-love::Type Text::type("Text", &Drawable::type);
-
 Text::Text(love::graphics::Graphics *gfx, love::graphics::Font *font, const std::vector<Font::ColoredString> &text)
-	: font(font)
-	, vbo(nullptr)
-	, quadIndices(gfx, 20)
-	, vert_offset(0)
-	, texture_cache_id((uint32) -1)
+	: love::graphics::Text(gfx, font, text)
 {
-	set(text);
 }
 
 Text::~Text()
 {
-	delete vbo;
-}
-
-void Text::uploadVertices(const std::vector<Font::GlyphVertex> &vertices, size_t vertoffset)
-{
-	size_t offset = vertoffset * sizeof(Font::GlyphVertex);
-	size_t datasize = vertices.size() * sizeof(Font::GlyphVertex);
-	uint8 *vbodata = nullptr;
-
-	// If we haven't created a VBO or the vertices are too big, make a new one.
-	if (datasize > 0 && (!vbo || (offset + datasize) > vbo->getSize()))
-	{
-		// Make it bigger than necessary to reduce potential future allocations.
-		size_t newsize = size_t((offset + datasize) * 1.5);
-
-		if (vbo != nullptr)
-			newsize = std::max(size_t(vbo->getSize() * 1.5), newsize);
-
-		auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
-		Buffer *new_vbo = gfx->newBuffer(newsize, nullptr, BUFFER_VERTEX, vertex::USAGE_DYNAMIC, 0);
-
-		if (vbo != nullptr)
-			vbo->copyTo(0, vbo->getSize(), new_vbo, 0);
-
-		delete vbo;
-		vbo = new_vbo;
-	}
-
-	if (vbo != nullptr && datasize > 0)
-	{
-		vbodata = (uint8 *) vbo->map();
-		memcpy(vbodata + offset, &vertices[0], datasize);
-		// We unmap when we draw, to avoid unnecessary full map()/unmap() calls.
-	}
-}
-
-void Text::regenerateVertices()
-{
-	// If the font's texture cache was invalidated then we need to recreate the
-	// text's vertices, since glyph texcoords might have changed.
-	if (font->getTextureCacheID() != texture_cache_id)
-	{
-		std::vector<TextData> textdata = text_data;
-
-		clear();
-
-		for (const TextData &t : textdata)
-			addTextData(t);
-
-		texture_cache_id = font->getTextureCacheID();
-	}
-}
-
-void Text::addTextData(const TextData &t)
-{
-	std::vector<Font::GlyphVertex> vertices;
-	std::vector<Font::DrawCommand> new_commands;
-
-	Font::TextInfo text_info;
-
-	Colorf constantcolor = Colorf(1.0f, 1.0f, 1.0f, 1.0f);
-
-	// We only have formatted text if the align mode is valid.
-	if (t.align == Font::ALIGN_MAX_ENUM)
-		new_commands = font->generateVertices(t.codepoints, constantcolor, vertices, 0.0f, Vector(0.0f, 0.0f), &text_info);
-	else
-		new_commands = font->generateVerticesFormatted(t.codepoints, constantcolor, t.wrap, t.align, vertices, &text_info);
-
-	if (t.use_matrix)
-		t.matrix.transform(&vertices[0], &vertices[0], (int) vertices.size());
-
-	size_t voffset = vert_offset;
-
-	if (!t.append_vertices)
-	{
-		voffset = 0;
-		draw_commands.clear();
-		text_data.clear();
-	}
-
-	uploadVertices(vertices, voffset);
-
-	if (!new_commands.empty())
-	{
-		// The start vertex should be adjusted to account for the vertex offset.
-		for (Font::DrawCommand &cmd : new_commands)
-			cmd.startvertex += (int) voffset;
-
-		auto firstcmd = new_commands.begin();
-
-		// If the first draw command in the new list has the same texture as the
-		// last one in the existing list we're building and its vertices are
-		// in-order, we can combine them (saving a draw call.)
-		if (!draw_commands.empty())
-		{
-			auto prevcmd = draw_commands.back();
-			if (prevcmd.texture == firstcmd->texture && (prevcmd.startvertex + prevcmd.vertexcount) == firstcmd->startvertex)
-			{
-				draw_commands.back().vertexcount += firstcmd->vertexcount;
-				++firstcmd;
-			}
-		}
-
-		// Append the new draw commands to the list we're building.
-		draw_commands.insert(draw_commands.end(), firstcmd, new_commands.end());
-	}
-
-	vert_offset = voffset + vertices.size();
-
-	text_data.push_back(t);
-	text_data.back().text_info = text_info;
-
-	// Font::generateVertices can invalidate the font's texture cache.
-	if (font->getTextureCacheID() != texture_cache_id)
-		regenerateVertices();
-}
-
-void Text::set(const std::vector<Font::ColoredString> &text)
-{
-	return set(text, -1.0f, Font::ALIGN_MAX_ENUM);
-}
-
-void Text::set(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align)
-{
-	if (text.empty() || (text.size() == 1 && text[0].str.empty()))
-		return clear();
-
-	Font::ColoredCodepoints codepoints;
-	Font::getCodepointsFromString(text, codepoints);
-
-	addTextData({codepoints, wrap, align, {}, false, false, Matrix4()});
-}
-
-int Text::add(const std::vector<Font::ColoredString> &text, const Matrix4 &m)
-{
-	return addf(text, -1.0f, Font::ALIGN_MAX_ENUM, m);
-}
-
-int Text::addf(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align, const Matrix4 &m)
-{
-	Font::ColoredCodepoints codepoints;
-	Font::getCodepointsFromString(text, codepoints);
-
-	addTextData({codepoints, wrap, align, {}, true, true, m});
-
-	return (int) text_data.size() - 1;
-}
-
-void Text::clear()
-{
-	text_data.clear();
-	draw_commands.clear();
-	texture_cache_id = font->getTextureCacheID();
-	vert_offset = 0;
 }
 
 void Text::draw(Graphics *gfx, const Matrix4 &m)
@@ -260,43 +96,6 @@ void Text::draw(Graphics *gfx, const Matrix4 &m)
 	}
 }
 
-void Text::setFont(love::graphics::Font *f)
-{
-	font.set(f);
-
-	// Invalidate the texture cache ID since the font is different. We also have
-	// to re-upload all the vertices based on the new font's textures.
-	texture_cache_id = (uint32) -1;
-	regenerateVertices();
-}
-
-love::graphics::Font *Text::getFont() const
-{
-	return font.get();
-}
-
-int Text::getWidth(int index) const
-{
-	if (index < 0)
-		index = std::max((int) text_data.size() - 1, 0);
-
-	if (index >= (int) text_data.size())
-		return 0;
-
-	return text_data[index].text_info.width;
-}
-
-int Text::getHeight(int index) const
-{
-	if (index < 0)
-		index = std::max((int) text_data.size() - 1, 0);
-
-	if (index >= (int) text_data.size())
-		return 0;
-
-	return text_data[index].text_info.height;
-}
-
 } // opengl
 } // graphics
 } // love

+ 4 - 66
src/modules/graphics/opengl/Text.h

@@ -18,92 +18,30 @@
  * 3. This notice may not be removed or altered from any source distribution.
  **/
 
-#ifndef LOVE_GRAPHICS_OPENGL_TEXT_H
-#define LOVE_GRAPHICS_OPENGL_TEXT_H
+#pragma once
 
 // LOVE
-#include "common/config.h"
-#include "graphics/Drawable.h"
-#include "graphics/Font.h"
-#include "graphics/Buffer.h"
+#include "graphics/Text.h"
 
 namespace love
 {
 namespace graphics
 {
-
-class Graphics;
-
 namespace opengl
 {
 
-class Text : public Drawable
+class Text final : public love::graphics::Text
 {
 public:
 
-	static love::Type type;
-
 	Text(love::graphics::Graphics *gfx, love::graphics::Font *font, const std::vector<Font::ColoredString> &text = {});
 	virtual ~Text();
 
-	void set(const std::vector<Font::ColoredString> &text);
-	void set(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align);
-
-	int add(const std::vector<Font::ColoredString> &text, const Matrix4 &m);
-	int addf(const std::vector<Font::ColoredString> &text, float wrap, Font::AlignMode align, const Matrix4 &m);
-
-	void clear();
-
 	// Implements Drawable.
-	void draw(Graphics *gfx, const Matrix4 &m) override;
-
-	void setFont(love::graphics::Font *f);
-	love::graphics::Font *getFont() const;
-
-	/**
-	 * Gets the width of the currently set text.
-	 **/
-	int getWidth(int index = 0) const;
-
-	/**
-	 * Gets the height of the currently set text.
-	 **/
-	int getHeight(int index = 0) const;
-
-private:
-
-	struct TextData
-	{
-		Font::ColoredCodepoints codepoints;
-		float wrap;
-		Font::AlignMode align;
-		Font::TextInfo text_info;
-		bool use_matrix;
-		bool append_vertices;
-		Matrix4 matrix;
-	};
-
-	void uploadVertices(const std::vector<Font::GlyphVertex> &vertices, size_t vertoffset);
-	void regenerateVertices();
-	void addTextData(const TextData &s);
-
-	StrongRef<love::graphics::Font> font;
-	Buffer *vbo;
-	QuadIndices quadIndices;
-
-	std::vector<Font::DrawCommand> draw_commands;
-
-	std::vector<TextData> text_data;
-
-	size_t vert_offset;
-
-	// Used so we know when the font's texture cache is invalidated.
-	uint32 texture_cache_id;
+	void draw(love::graphics::Graphics *gfx, const Matrix4 &m) override;
 
 }; // Text
 
 } // opengl
 } // graphics
 } // love
-
-#endif // LOVE_GRAPHICS_OPENGL_TEXT_H

+ 18 - 143
src/modules/graphics/opengl/Video.cpp

@@ -20,10 +20,6 @@
 
 #include "Video.h"
 
-// LOVE
-#include "Shader.h"
-#include "graphics/Graphics.h"
-
 namespace love
 {
 namespace graphics
@@ -31,43 +27,9 @@ namespace graphics
 namespace opengl
 {
 
-love::Type Video::type("Video", &Drawable::type);
-
 Video::Video(love::video::VideoStream *stream, float pixeldensity)
-	: stream(stream)
-	, width(stream->getWidth() / pixeldensity)
-	, height(stream->getHeight() / pixeldensity)
-	, filter(Texture::defaultFilter)
+	: love::graphics::Video(stream, pixeldensity)
 {
-	filter.mipmap = Texture::FILTER_NONE;
-
-	stream->fillBackBuffer();
-
-	for (int i = 0; i < 4; i++)
-		vertices[i].color = Color(255, 255, 255, 255);
-
-	// Vertices are ordered for use with triangle strips:
-	// 0---2
-	// | / |
-	// 1---3
-	vertices[0].x = 0.0f;
-	vertices[0].y = 0.0f;
-	vertices[1].x = 0.0f;
-	vertices[1].y = (float) height;
-	vertices[2].x = (float) width;
-	vertices[2].y = 0.0f;
-	vertices[3].x = (float) width;
-	vertices[3].y = (float) height;
-
-	vertices[0].s = 0.0f;
-	vertices[0].t = 0.0f;
-	vertices[1].s = 0.0f;
-	vertices[1].t = 1.0f;
-	vertices[2].s = 1.0f;
-	vertices[2].t = 0.0f;
-	vertices[3].s = 1.0f;
-	vertices[3].t = 1.0f;
-
 	loadVolatile();
 }
 
@@ -78,8 +40,12 @@ Video::~Video()
 
 bool Video::loadVolatile()
 {
+	GLuint textures[3];
 	glGenTextures(3, textures);
 
+	for (int i = 0; i < 3; i++)
+		textureHandles[i] = textures[i];
+
 	// Create the textures using the initial frame data.
 	auto frame = (const love::video::VideoStream::Frame*) stream->getFrontBuffer();
 
@@ -111,115 +77,29 @@ void Video::unloadVolatile()
 {
 	for (int i = 0; i < 3; i++)
 	{
-		gl.deleteTexture(textures[i]);
-		textures[i] = 0;
+		gl.deleteTexture((GLuint) textureHandles[i]);
+		textureHandles[i] = 0;
 	}
 }
 
-love::video::VideoStream *Video::getStream()
-{
-	return stream;
-}
-
-void Video::draw(Graphics *gfx, const Matrix4 &m)
+void Video::uploadFrame(const love::video::VideoStream::Frame *frame)
 {
-	update();
-
-	gfx->flushStreamDraws();
-
-	love::graphics::Shader *shader = Shader::current;
-	bool usingdefaultshader = (shader == Shader::defaultShader);
-	if (usingdefaultshader)
-	{
-		// If we're using the default shader, substitute the video version.
-		Shader::defaultVideoShader->attach();
-		shader = Shader::defaultVideoShader;
-	}
-
-	shader->setVideoTextures(textures[0], textures[1], textures[2]);
-
-	Graphics::StreamDrawRequest req;
-	req.formats[0] = vertex::CommonFormat::XYf_STf_RGBAub;
-	req.indexMode = vertex::TriangleIndexMode::QUADS;
-	req.vertexCount = 4;
-
-	Graphics::StreamVertexData data = gfx->requestStreamDraw(req);
-	Vertex *verts = (Vertex *) data.stream[0];
-
-	Matrix4 t(gfx->getTransform(), m);
-	t.transform(verts, vertices, 4);
-
-	Color c = toColor(gfx->getColor());
-
-	for (int i = 0; i < 4; i++)
-	{
-		verts[i].s = vertices[i].s;
-		verts[i].t = vertices[i].t;
-		verts[i].color = c;
-	}
-
-	gfx->flushStreamDraws();
+	int widths[3]  = {frame->yw, frame->cw, frame->cw};
+	int heights[3] = {frame->yh, frame->ch, frame->ch};
 
-	if (usingdefaultshader)
-		Shader::defaultShader->attach();
-}
+	const unsigned char *data[3] = {frame->yplane, frame->cbplane, frame->crplane};
 
-void Video::update()
-{
-	bool bufferschanged = stream->swapBuffers();
-	stream->fillBackBuffer();
+	bool srgb = false;
+	OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(PIXELFORMAT_R8, false, srgb);
 
-	if (bufferschanged)
+	for (int i = 0; i < 3; i++)
 	{
-		auto frame = (const love::video::VideoStream::Frame*) stream->getFrontBuffer();
-
-		int widths[3]  = {frame->yw, frame->cw, frame->cw};
-		int heights[3] = {frame->yh, frame->ch, frame->ch};
-
-		const unsigned char *data[3] = {frame->yplane, frame->cbplane, frame->crplane};
-
-		bool srgb = false;
-		OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(PIXELFORMAT_R8, false, srgb);
-
-		for (int i = 0; i < 3; i++)
-		{
-			gl.bindTextureToUnit(textures[i], 0, false);
-			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, widths[i], heights[i],
-			                fmt.externalformat, fmt.type, data[i]);
-		}
+		gl.bindTextureToUnit((GLuint) textureHandles[i], 0, false);
+		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, widths[i], heights[i],
+		                fmt.externalformat, fmt.type, data[i]);
 	}
 }
 
-love::audio::Source *Video::getSource()
-{
-	return source;
-}
-
-void Video::setSource(love::audio::Source *source)
-{
-	this->source = source;
-}
-
-int Video::getWidth() const
-{
-	return width;
-}
-
-int Video::getHeight() const
-{
-	return height;
-}
-
-int Video::getPixelWidth() const
-{
-	return stream->getWidth();
-}
-
-int Video::getPixelHeight() const
-{
-	return stream->getHeight();
-}
-
 void Video::setFilter(const Texture::Filter &f)
 {
 	if (!Texture::validateFilter(f, false))
@@ -229,16 +109,11 @@ void Video::setFilter(const Texture::Filter &f)
 
 	for (int i = 0; i < 3; i++)
 	{
-		gl.bindTextureToUnit(textures[i], 0, false);
+		gl.bindTextureToUnit((GLuint) textureHandles[i], 0, false);
 		gl.setTextureFilter(filter);
 	}
 }
 
-const Texture::Filter &Video::getFilter() const
-{
-	return filter;
-}
-
 } // opengl
 } // graphics
 } // love

+ 5 - 36
src/modules/graphics/opengl/Video.h

@@ -21,12 +21,8 @@
 #pragma once
 
 // LOVE
-#include "common/math.h"
-#include "graphics/Drawable.h"
+#include "graphics/Video.h"
 #include "graphics/Volatile.h"
-#include "video/VideoStream.h"
-#include "audio/Source.h"
-
 #include "OpenGL.h"
 
 namespace love
@@ -36,49 +32,22 @@ namespace graphics
 namespace opengl
 {
 
-class Video : public Drawable, public Volatile
+class Video : public love::graphics::Video, public Volatile
 {
 public:
 
-	static love::Type type;
-
 	Video(love::video::VideoStream *stream, float pixeldensity = 1.0f);
-	~Video();
+	virtual ~Video();
 
 	// Volatile
 	bool loadVolatile() override;
 	void unloadVolatile() override;
 
-	// Drawable
-	void draw(Graphics *gfx, const Matrix4 &m) override;
-
-	love::video::VideoStream *getStream();
-
-	love::audio::Source *getSource();
-	void setSource(love::audio::Source *source);
-
-	int getWidth() const;
-	int getHeight() const;
-
-	int getPixelWidth() const;
-	int getPixelHeight() const;
-
-	void setFilter(const Texture::Filter &f);
-	const Texture::Filter &getFilter() const;
+	void setFilter(const Texture::Filter &f) override;
 
 private:
 
-	void update();
-
-	StrongRef<love::video::VideoStream> stream;
-	StrongRef<love::audio::Source> source;
-
-	int width;
-	int height;
-
-	GLuint textures[3];
-
-	Vertex vertices[4];
+	void uploadFrame(const love::video::VideoStream::Frame *frame) override;
 
 	Texture::Filter filter;
 

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

@@ -31,8 +31,8 @@
 #include "graphics/wrap_Canvas.h"
 #include "graphics/wrap_Shader.h"
 #include "wrap_Mesh.h"
-#include "wrap_Text.h"
-#include "wrap_Video.h"
+#include "graphics/wrap_Text.h"
+#include "graphics/wrap_Video.h"
 #include "Graphics.h"
 
 namespace love

+ 1 - 4
src/modules/graphics/opengl/wrap_Text.cpp → src/modules/graphics/wrap_Text.cpp

@@ -19,15 +19,13 @@
  **/
 
 #include "wrap_Text.h"
-#include "graphics/wrap_Font.h"
+#include "wrap_Font.h"
 #include "math/wrap_Transform.h"
 
 namespace love
 {
 namespace graphics
 {
-namespace opengl
-{
 
 Text *luax_checktext(lua_State *L, int idx)
 {
@@ -227,6 +225,5 @@ extern "C" int luaopen_text(lua_State *L)
 	return luax_register_type(L, &Text::type, w_Text_functions, nullptr);
 }
 
-} // opengl
 } // graphics
 } // love

+ 1 - 8
src/modules/graphics/opengl/wrap_Text.h → src/modules/graphics/wrap_Text.h

@@ -18,8 +18,7 @@
  * 3. This notice may not be removed or altered from any source distribution.
  **/
 
-#ifndef LOVE_GRAPHICS_OPENGL_WRAP_TEXT_H
-#define LOVE_GRAPHICS_OPENGL_WRAP_TEXT_H
+#pragma once
 
 #include "Text.h"
 #include "common/runtime.h"
@@ -28,15 +27,9 @@ namespace love
 {
 namespace graphics
 {
-namespace opengl
-{
 
 Text *luax_checktext(lua_State *L, int idx);
 extern "C" int luaopen_text(lua_State *L);
 
-} // opengl
 } // graphics
 } // love
-
-#endif // LOVE_GRAPHICS_OPENGL_WRAP_TEXT_H
-

+ 0 - 3
src/modules/graphics/opengl/wrap_Video.cpp → src/modules/graphics/wrap_Video.cpp

@@ -29,8 +29,6 @@ namespace love
 {
 namespace graphics
 {
-namespace opengl
-{
 
 Video *luax_checkvideo(lua_State *L, int idx)
 {
@@ -177,6 +175,5 @@ int luaopen_video(lua_State *L)
 	return ret;
 }
 
-} // opengl
 } // graphics
 } // love

+ 0 - 3
src/modules/graphics/opengl/wrap_Video.h → src/modules/graphics/wrap_Video.h

@@ -28,11 +28,8 @@ namespace love
 {
 namespace graphics
 {
-namespace opengl
-{
 
 int luaopen_video(lua_State *L);
 
-} // opengl
 } // graphics
 } // love

+ 0 - 0
src/modules/graphics/opengl/wrap_Video.lua → src/modules/graphics/wrap_Video.lua