From c0e66eba83fc0511dbf27625f41815fe06a58434 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 29 Jan 2017 01:05:20 -0400 Subject: [PATCH] Move backend-agnostic Mesh and SpriteBatch code out of the opengl implementation folder. --HG-- branch : minor --- CMakeLists.txt | 22 +- .../xcode/liblove.xcodeproj/project.pbxproj | 80 ++- src/modules/graphics/Graphics.cpp | 5 + src/modules/graphics/Graphics.h | 14 + src/modules/graphics/Mesh.cpp | 642 ++++++++++++++++++ src/modules/graphics/Mesh.h | 270 ++++++++ src/modules/graphics/SpriteBatch.cpp | 258 +++++++ src/modules/graphics/SpriteBatch.h | 145 ++++ src/modules/graphics/opengl/Graphics.cpp | 17 +- src/modules/graphics/opengl/Graphics.h | 14 +- src/modules/graphics/opengl/Mesh.cpp | 596 +--------------- src/modules/graphics/opengl/Mesh.h | 233 +------ src/modules/graphics/opengl/SpriteBatch.cpp | 210 +----- src/modules/graphics/opengl/SpriteBatch.h | 115 +--- src/modules/graphics/opengl/wrap_Graphics.cpp | 16 +- src/modules/graphics/opengl/wrap_Graphics.h | 6 +- .../graphics/{opengl => }/wrap_Mesh.cpp | 6 +- src/modules/graphics/{opengl => }/wrap_Mesh.h | 8 +- .../{opengl => }/wrap_ParticleSystem.cpp | 5 +- .../{opengl => }/wrap_ParticleSystem.h | 8 +- .../{opengl => }/wrap_SpriteBatch.cpp | 8 +- .../graphics/{opengl => }/wrap_SpriteBatch.h | 8 +- 22 files changed, 1440 insertions(+), 1246 deletions(-) create mode 100644 src/modules/graphics/Mesh.cpp create mode 100644 src/modules/graphics/Mesh.h create mode 100644 src/modules/graphics/SpriteBatch.cpp create mode 100644 src/modules/graphics/SpriteBatch.h rename src/modules/graphics/{opengl => }/wrap_Mesh.cpp (99%) rename src/modules/graphics/{opengl => }/wrap_Mesh.h (89%) rename src/modules/graphics/{opengl => }/wrap_ParticleSystem.cpp (99%) rename src/modules/graphics/{opengl => }/wrap_ParticleSystem.h (86%) rename src/modules/graphics/{opengl => }/wrap_SpriteBatch.cpp (98%) rename src/modules/graphics/{opengl => }/wrap_SpriteBatch.h (86%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53f54a233..ed71c08e6 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -476,6 +476,10 @@ set(LOVE_SRC_MODULE_GRAPHICS_ROOT src/modules/graphics/Font.h src/modules/graphics/Graphics.cpp src/modules/graphics/Graphics.h + src/modules/graphics/Image.cpp + src/modules/graphics/Image.h + src/modules/graphics/Mesh.cpp + src/modules/graphics/Mesh.h src/modules/graphics/ParticleSystem.cpp src/modules/graphics/ParticleSystem.h src/modules/graphics/Polyline.cpp @@ -484,6 +488,8 @@ set(LOVE_SRC_MODULE_GRAPHICS_ROOT src/modules/graphics/Quad.h src/modules/graphics/Shader.cpp src/modules/graphics/Shader.h + src/modules/graphics/SpriteBatch.cpp + src/modules/graphics/SpriteBatch.h src/modules/graphics/StreamBuffer.cpp src/modules/graphics/StreamBuffer.h src/modules/graphics/Text.cpp @@ -500,10 +506,18 @@ set(LOVE_SRC_MODULE_GRAPHICS_ROOT src/modules/graphics/wrap_Canvas.h src/modules/graphics/wrap_Font.cpp src/modules/graphics/wrap_Font.h + src/modules/graphics/wrap_Image.cpp + src/modules/graphics/wrap_Image.h + src/modules/graphics/wrap_Mesh.cpp + src/modules/graphics/wrap_Mesh.h + src/modules/graphics/wrap_ParticleSystem.cpp + src/modules/graphics/wrap_ParticleSystem.h src/modules/graphics/wrap_Quad.cpp src/modules/graphics/wrap_Quad.h src/modules/graphics/wrap_Shader.cpp src/modules/graphics/wrap_Shader.h + src/modules/graphics/wrap_SpriteBatch.cpp + src/modules/graphics/wrap_SpriteBatch.h src/modules/graphics/wrap_Texture.cpp src/modules/graphics/wrap_Texture.h src/modules/graphics/wrap_Text.cpp @@ -543,14 +557,6 @@ set(LOVE_SRC_MODULE_GRAPHICS_OPENGL src/modules/graphics/opengl/Video.h src/modules/graphics/opengl/wrap_Graphics.cpp src/modules/graphics/opengl/wrap_Graphics.h - src/modules/graphics/opengl/wrap_Image.cpp - src/modules/graphics/opengl/wrap_Image.h - src/modules/graphics/opengl/wrap_Mesh.cpp - src/modules/graphics/opengl/wrap_Mesh.h - src/modules/graphics/opengl/wrap_ParticleSystem.cpp - src/modules/graphics/opengl/wrap_ParticleSystem.h - src/modules/graphics/opengl/wrap_SpriteBatch.cpp - src/modules/graphics/opengl/wrap_SpriteBatch.h ) set(LOVE_SRC_MODULE_GRAPHICS diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index 5e314bb37..a5b4924fc 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -459,15 +459,6 @@ FA0B7D5E1A95902C000E1D17 /* wrap_Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BAA1A95902C000E1D17 /* wrap_Graphics.cpp */; }; FA0B7D5F1A95902C000E1D17 /* wrap_Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BAA1A95902C000E1D17 /* wrap_Graphics.cpp */; }; FA0B7D601A95902C000E1D17 /* wrap_Graphics.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BAB1A95902C000E1D17 /* wrap_Graphics.h */; }; - FA0B7D641A95902C000E1D17 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BAE1A95902C000E1D17 /* wrap_Mesh.cpp */; }; - FA0B7D651A95902C000E1D17 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BAE1A95902C000E1D17 /* wrap_Mesh.cpp */; }; - FA0B7D661A95902C000E1D17 /* wrap_Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BAF1A95902C000E1D17 /* wrap_Mesh.h */; }; - FA0B7D671A95902C000E1D17 /* wrap_ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB01A95902C000E1D17 /* wrap_ParticleSystem.cpp */; }; - FA0B7D681A95902C000E1D17 /* wrap_ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BB01A95902C000E1D17 /* wrap_ParticleSystem.cpp */; }; - FA0B7D691A95902C000E1D17 /* wrap_ParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BB11A95902C000E1D17 /* wrap_ParticleSystem.h */; }; - 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 */; }; 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 */; }; @@ -1024,6 +1015,21 @@ FADF541B1E3DA46C00012CC0 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54191E3DA46C00012CC0 /* wrap_Image.cpp */; }; FADF541C1E3DA46C00012CC0 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54191E3DA46C00012CC0 /* wrap_Image.cpp */; }; FADF541D1E3DA46C00012CC0 /* wrap_Image.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF541A1E3DA46C00012CC0 /* wrap_Image.h */; }; + FADF54201E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF541E1E3DA52C00012CC0 /* wrap_ParticleSystem.cpp */; }; + FADF54211E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF541E1E3DA52C00012CC0 /* wrap_ParticleSystem.cpp */; }; + FADF54221E3DA52C00012CC0 /* wrap_ParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF541F1E3DA52C00012CC0 /* wrap_ParticleSystem.h */; }; + FADF54251E3DA5BA00012CC0 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54231E3DA5BA00012CC0 /* Mesh.cpp */; }; + FADF54261E3DA5BA00012CC0 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54231E3DA5BA00012CC0 /* Mesh.cpp */; }; + FADF54271E3DA5BA00012CC0 /* Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54241E3DA5BA00012CC0 /* Mesh.h */; }; + FADF542A1E3DAADA00012CC0 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54281E3DAADA00012CC0 /* wrap_Mesh.cpp */; }; + FADF542B1E3DAADA00012CC0 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54281E3DAADA00012CC0 /* wrap_Mesh.cpp */; }; + FADF542C1E3DAADA00012CC0 /* wrap_Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54291E3DAADA00012CC0 /* wrap_Mesh.h */; }; + FADF542F1E3DABF600012CC0 /* SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF542D1E3DABF600012CC0 /* SpriteBatch.cpp */; }; + FADF54301E3DABF600012CC0 /* SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF542D1E3DABF600012CC0 /* SpriteBatch.cpp */; }; + FADF54311E3DABF600012CC0 /* SpriteBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF542E1E3DABF600012CC0 /* SpriteBatch.h */; }; + FADF54341E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54321E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp */; }; + FADF54351E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FADF54321E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp */; }; + FADF54361E3DAE6E00012CC0 /* wrap_SpriteBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF54331E3DAE6E00012CC0 /* wrap_SpriteBatch.h */; }; 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 */; }; @@ -1467,12 +1473,6 @@ FA0B7BA51A95902C000E1D17 /* Buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Buffer.h; sourceTree = ""; }; FA0B7BAA1A95902C000E1D17 /* wrap_Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Graphics.cpp; sourceTree = ""; }; FA0B7BAB1A95902C000E1D17 /* wrap_Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Graphics.h; sourceTree = ""; }; - FA0B7BAE1A95902C000E1D17 /* wrap_Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Mesh.cpp; sourceTree = ""; }; - FA0B7BAF1A95902C000E1D17 /* wrap_Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Mesh.h; sourceTree = ""; }; - FA0B7BB01A95902C000E1D17 /* wrap_ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ParticleSystem.cpp; sourceTree = ""; }; - FA0B7BB11A95902C000E1D17 /* wrap_ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_ParticleSystem.h; sourceTree = ""; }; - FA0B7BB61A95902C000E1D17 /* wrap_SpriteBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_SpriteBatch.cpp; sourceTree = ""; }; - FA0B7BB71A95902C000E1D17 /* wrap_SpriteBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_SpriteBatch.h; sourceTree = ""; }; FA0B7BBC1A95902C000E1D17 /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = ""; }; FA0B7BBD1A95902C000E1D17 /* Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = ""; }; FA0B7BBE1A95902C000E1D17 /* Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Texture.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -1854,6 +1854,16 @@ FADF54151E3DA08E00012CC0 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; FADF54191E3DA46C00012CC0 /* wrap_Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Image.cpp; sourceTree = ""; }; FADF541A1E3DA46C00012CC0 /* wrap_Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Image.h; sourceTree = ""; }; + FADF541E1E3DA52C00012CC0 /* wrap_ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_ParticleSystem.cpp; sourceTree = ""; }; + FADF541F1E3DA52C00012CC0 /* wrap_ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_ParticleSystem.h; sourceTree = ""; }; + FADF54231E3DA5BA00012CC0 /* Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mesh.cpp; sourceTree = ""; }; + FADF54241E3DA5BA00012CC0 /* Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mesh.h; sourceTree = ""; }; + FADF54281E3DAADA00012CC0 /* wrap_Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Mesh.cpp; sourceTree = ""; }; + FADF54291E3DAADA00012CC0 /* wrap_Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Mesh.h; sourceTree = ""; }; + FADF542D1E3DABF600012CC0 /* SpriteBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpriteBatch.cpp; sourceTree = ""; }; + FADF542E1E3DABF600012CC0 /* SpriteBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpriteBatch.h; sourceTree = ""; }; + FADF54321E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_SpriteBatch.cpp; sourceTree = ""; }; + FADF54331E3DAE6E00012CC0 /* wrap_SpriteBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_SpriteBatch.h; sourceTree = ""; }; FAE272501C05A15B00A67640 /* ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cpp; sourceTree = ""; }; FAE272511C05A15B00A67640 /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = ""; }; FAF13FC21E20934C00F898D2 /* CodeGen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGen.cpp; sourceTree = ""; }; @@ -2649,6 +2659,8 @@ FA0B7B8B1A95902C000E1D17 /* Graphics.h */, FADF54141E3DA08E00012CC0 /* Image.cpp */, FADF54151E3DA08E00012CC0 /* Image.h */, + FADF54231E3DA5BA00012CC0 /* Mesh.cpp */, + FADF54241E3DA5BA00012CC0 /* Mesh.h */, FA0B7B8C1A95902C000E1D17 /* opengl */, FAE272501C05A15B00A67640 /* ParticleSystem.cpp */, FAE272511C05A15B00A67640 /* ParticleSystem.h */, @@ -2658,6 +2670,8 @@ FA0B7BBD1A95902C000E1D17 /* Quad.h */, FA1BA0AF1E16FD0800AA2803 /* Shader.cpp */, FA1BA0B01E16FD0800AA2803 /* Shader.h */, + FADF542D1E3DABF600012CC0 /* SpriteBatch.cpp */, + FADF542E1E3DABF600012CC0 /* SpriteBatch.h */, FA29C0041E12355B00268CD8 /* StreamBuffer.cpp */, FA2AF6721DAD62710032B62C /* StreamBuffer.h */, FADF53FB1E3D74F200012CC0 /* Text.cpp */, @@ -2676,10 +2690,16 @@ FA1BA0A11E16D97500AA2803 /* wrap_Font.h */, FADF54191E3DA46C00012CC0 /* wrap_Image.cpp */, FADF541A1E3DA46C00012CC0 /* wrap_Image.h */, + FADF54281E3DAADA00012CC0 /* wrap_Mesh.cpp */, + FADF54291E3DAADA00012CC0 /* wrap_Mesh.h */, + FADF541E1E3DA52C00012CC0 /* wrap_ParticleSystem.cpp */, + FADF541F1E3DA52C00012CC0 /* wrap_ParticleSystem.h */, FA620A2E1AA2F8DB005DB4C2 /* wrap_Quad.cpp */, FA620A2F1AA2F8DB005DB4C2 /* wrap_Quad.h */, FA1BA0B51E17043400AA2803 /* wrap_Shader.cpp */, FA1BA0B61E17043400AA2803 /* wrap_Shader.h */, + FADF54321E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp */, + FADF54331E3DAE6E00012CC0 /* wrap_SpriteBatch.h */, FADF54001E3D77B500012CC0 /* wrap_Text.cpp */, FADF54011E3D77B500012CC0 /* wrap_Text.h */, FA620A301AA2F8DB005DB4C2 /* wrap_Texture.cpp */, @@ -2725,12 +2745,6 @@ FA0B7BAA1A95902C000E1D17 /* wrap_Graphics.cpp */, FA0B7BAB1A95902C000E1D17 /* wrap_Graphics.h */, FA6AE6041B3335EC00583D5C /* wrap_Graphics.lua */, - FA0B7BAE1A95902C000E1D17 /* wrap_Mesh.cpp */, - FA0B7BAF1A95902C000E1D17 /* wrap_Mesh.h */, - FA0B7BB01A95902C000E1D17 /* wrap_ParticleSystem.cpp */, - FA0B7BB11A95902C000E1D17 /* wrap_ParticleSystem.h */, - FA0B7BB61A95902C000E1D17 /* wrap_SpriteBatch.cpp */, - FA0B7BB71A95902C000E1D17 /* wrap_SpriteBatch.h */, ); path = opengl; sourceTree = ""; @@ -3491,6 +3505,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + FADF54221E3DA52C00012CC0 /* wrap_ParticleSystem.h in Headers */, 217DFC0A1D9F6D490055D849 /* unix.h in Headers */, FA0B7D7E1A95902C000E1D17 /* Texture.h in Headers */, FA0B7E561A95902C000E1D17 /* wrap_GearJoint.h in Headers */, @@ -3520,6 +3535,7 @@ FA0B7DC61A95902C000E1D17 /* wrap_JoystickModule.h in Headers */, FA0B7D201A95902C000E1D17 /* ImageRasterizer.h in Headers */, FA0B7D241A95902C000E1D17 /* Vera.ttf.h in Headers */, + FADF54311E3DABF600012CC0 /* SpriteBatch.h in Headers */, FA0B7E5F1A95902C000E1D17 /* wrap_MouseJoint.h in Headers */, FAB17BED1ABFAF1800F9BA27 /* CompressedData.h in Headers */, 217DFC0C1D9F6D490055D849 /* unixtcp.h in Headers */, @@ -3538,7 +3554,6 @@ FA0B7E901A95902C000E1D17 /* GmeDecoder.h in Headers */, FA0B7D0E1A95902C000E1D17 /* wrap_Filesystem.h in Headers */, FA0B7EE41A95902D000E1D17 /* Window.h in Headers */, - FA0B7D721A95902C000E1D17 /* wrap_SpriteBatch.h in Headers */, FA0B7CFC1A95902C000E1D17 /* Filesystem.h in Headers */, FA0B7AD81A958EA3000E1D17 /* lua-enet.h in Headers */, FA0B7A3A1A958EA3000E1D17 /* b2DynamicTree.h in Headers */, @@ -3546,6 +3561,7 @@ FA0B7EBA1A95902C000E1D17 /* Channel.h in Headers */, FA0B7D3E1A95902C000E1D17 /* Image.h in Headers */, FA0B7ECA1A95902C000E1D17 /* threads.h in Headers */, + FADF54361E3DAE6E00012CC0 /* wrap_SpriteBatch.h in Headers */, FA0B7DB01A95902C000E1D17 /* wrap_CompressedImageData.h in Headers */, FA0B7AC11A958EA3000E1D17 /* callbacks.h in Headers */, FA0B7D8F1A95902C000E1D17 /* ddsHandler.h in Headers */, @@ -3629,6 +3645,7 @@ FA0B7DCC1A95902C000E1D17 /* Keyboard.h in Headers */, FA620A341AA2F8DB005DB4C2 /* wrap_Quad.h in Headers */, FA0B7EA51A95902C000E1D17 /* SoundData.h in Headers */, + FADF54271E3DA5BA00012CC0 /* Mesh.h in Headers */, FAF1405E1E20934C00F898D2 /* PoolAlloc.h in Headers */, FA0B7A821A958EA3000E1D17 /* b2EdgeAndCircleContact.h in Headers */, FA0B79341A958E3B000E1D17 /* Object.h in Headers */, @@ -3673,7 +3690,6 @@ FA0B7A2B1A958EA3000E1D17 /* b2BroadPhase.h in Headers */, 217DFBFD1D9F6D490055D849 /* smtp.lua.h in Headers */, FA27B39F1B498151008A9DCE /* Video.h in Headers */, - FA0B7D661A95902C000E1D17 /* wrap_Mesh.h in Headers */, FA0B7AAC1A958EA3000E1D17 /* b2WeldJoint.h in Headers */, 217DFC041D9F6D490055D849 /* timeout.h in Headers */, FA0B7E7A1A95902C000E1D17 /* wrap_WheelJoint.h in Headers */, @@ -3808,7 +3824,6 @@ FA0B7B2E1A958EA3000E1D17 /* unchecked.h in Headers */, FA0B7D081A95902C000E1D17 /* wrap_File.h in Headers */, FA0B79451A958E3B000E1D17 /* Variant.h in Headers */, - FA0B7D691A95902C000E1D17 /* wrap_ParticleSystem.h in Headers */, FA0B7E5C1A95902C000E1D17 /* wrap_MotorJoint.h in Headers */, FA4F2BA91DE1E36400CA37D7 /* wrap_RecordingDevice.h in Headers */, FA0B7A7C1A958EA3000E1D17 /* b2Contact.h in Headers */, @@ -3818,6 +3833,7 @@ FA0B7DED1A95902C000E1D17 /* Cursor.h in Headers */, FA0B7E501A95902C000E1D17 /* wrap_Fixture.h in Headers */, FA28EBD71E352DB5003446F4 /* BufferSync.h in Headers */, + FADF542C1E3DAADA00012CC0 /* wrap_Mesh.h in Headers */, FAA3A9B01B7D465A00CED060 /* android.h in Headers */, 217DFBDE1D9F6D490055D849 /* compat.h in Headers */, FA0B7A491A958EA3000E1D17 /* b2PolygonShape.h in Headers */, @@ -3978,6 +3994,7 @@ FADF54081E3D78F700012CC0 /* Video.cpp in Sources */, FA9D8DD81DEF8411002CD881 /* Data.cpp in Sources */, FA0B7E8F1A95902C000E1D17 /* GmeDecoder.cpp in Sources */, + FADF542B1E3DAADA00012CC0 /* wrap_Mesh.cpp in Sources */, FA0B7CD71A95902C000E1D17 /* Audio.cpp in Sources */, FA0B7AC01A958EA3000E1D17 /* host.c in Sources */, FA0B7EB01A95902C000E1D17 /* System.cpp in Sources */, @@ -4057,6 +4074,7 @@ FA0B7A3F1A958EA3000E1D17 /* b2ChainShape.cpp in Sources */, FA0B7E921A95902C000E1D17 /* ModPlugDecoder.cpp in Sources */, FA0B7E521A95902C000E1D17 /* wrap_FrictionJoint.cpp in Sources */, + FADF54351E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp in Sources */, FA4F2BB51DE1E4C300CA37D7 /* wrap_RecordingDevice.cpp in Sources */, FA0B7A311A958EA3000E1D17 /* b2CollidePolygon.cpp in Sources */, FA4F2C111DE936FE00CA37D7 /* unix.c in Sources */, @@ -4079,6 +4097,7 @@ FA0B7A901A958EA3000E1D17 /* b2FrictionJoint.cpp in Sources */, FA0B7DFB1A95902C000E1D17 /* Body.cpp in Sources */, FA0B7ED21A95902C000E1D17 /* wrap_ThreadModule.cpp in Sources */, + FADF54261E3DA5BA00012CC0 /* Mesh.cpp in Sources */, FA0B7EE01A95902D000E1D17 /* wrap_Touch.cpp in Sources */, FA0B7A3C1A958EA3000E1D17 /* b2TimeOfImpact.cpp in Sources */, FA4F2C081DE936DD00CA37D7 /* io.c in Sources */, @@ -4095,11 +4114,9 @@ FA0B7DAF1A95902C000E1D17 /* wrap_CompressedImageData.cpp in Sources */, FA0B7A481A958EA3000E1D17 /* b2PolygonShape.cpp in Sources */, FA0B7A991A958EA3000E1D17 /* b2MotorJoint.cpp in Sources */, - FA0B7D681A95902C000E1D17 /* wrap_ParticleSystem.cpp in Sources */, FA0B7AD51A958EA3000E1D17 /* unix.c in Sources */, FAB17BE71ABFAA9000F9BA27 /* lz4.c in Sources */, FA4F2BE71DE6650D00CA37D7 /* Transform.cpp in Sources */, - FA0B7D651A95902C000E1D17 /* wrap_Mesh.cpp in Sources */, FA0B7A531A958EA3000E1D17 /* b2Math.cpp in Sources */, FAF140A11E20934C00F898D2 /* RemoveTree.cpp in Sources */, FA0B7CDA1A95902C000E1D17 /* Pool.cpp in Sources */, @@ -4162,6 +4179,7 @@ FA0B7D071A95902C000E1D17 /* wrap_File.cpp in Sources */, FA0B7AD01A958EA3000E1D17 /* peer.c in Sources */, FA27B3C11B4985BF008A9DCE /* wrap_VideoStream.cpp in Sources */, + FADF54211E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */, FA0B791C1A958E3B000E1D17 /* b64.cpp in Sources */, FA1E88851DF363E100E808AA /* Filter.cpp in Sources */, FA0B7D941A95902C000E1D17 /* Image.cpp in Sources */, @@ -4187,6 +4205,7 @@ FA4F2C0B1DE936EA00CA37D7 /* options.c in Sources */, FA4F2C0D1DE936F100CA37D7 /* serial.c in Sources */, FA0B7E0A1A95902C000E1D17 /* EdgeShape.cpp in Sources */, + FADF54301E3DABF600012CC0 /* SpriteBatch.cpp in Sources */, FAB17BF11ABFB37500F9BA27 /* wrap_CompressedData.cpp in Sources */, FA0B7CF81A95902C000E1D17 /* FileData.cpp in Sources */, FA0B7DA61A95902C000E1D17 /* PNGHandler.cpp in Sources */, @@ -4211,7 +4230,6 @@ FA0B79411A958E3B000E1D17 /* utf8.cpp in Sources */, FAB17BE11ABFAA2000F9BA27 /* Compressor.cpp in Sources */, FA0B7ADF1A958EA3000E1D17 /* lodepng.cpp in Sources */, - FA0B7D711A95902C000E1D17 /* wrap_SpriteBatch.cpp in Sources */, FA0B7D341A95902C000E1D17 /* Canvas.cpp in Sources */, FAF140761E20934C00F898D2 /* IntermTraverse.cpp in Sources */, FA0B7E8C1A95902C000E1D17 /* FLACDecoder.cpp in Sources */, @@ -4335,6 +4353,7 @@ FADF54071E3D78F700012CC0 /* Video.cpp in Sources */, 217DFC031D9F6D490055D849 /* timeout.c in Sources */, FA9D8DD71DEF8411002CD881 /* Data.cpp in Sources */, + FADF542A1E3DAADA00012CC0 /* wrap_Mesh.cpp in Sources */, FA0B7D2B1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */, FA0B7E8E1A95902C000E1D17 /* GmeDecoder.cpp in Sources */, FA0B7CD61A95902C000E1D17 /* Audio.cpp in Sources */, @@ -4414,6 +4433,7 @@ FA0B7E911A95902C000E1D17 /* ModPlugDecoder.cpp in Sources */, FA0B7E511A95902C000E1D17 /* wrap_FrictionJoint.cpp in Sources */, FA0B7AD61A958EA3000E1D17 /* win32.c in Sources */, + FADF54341E3DAE6E00012CC0 /* wrap_SpriteBatch.cpp in Sources */, FA0B7E0C1A95902C000E1D17 /* Fixture.cpp in Sources */, FA0B7D181A95902C000E1D17 /* TrueTypeRasterizer.cpp in Sources */, FA0B7CFA1A95902C000E1D17 /* Filesystem.cpp in Sources */, @@ -4436,6 +4456,7 @@ FA0B7EDF1A95902D000E1D17 /* wrap_Touch.cpp in Sources */, FA0B794A1A958E3B000E1D17 /* wrap_Data.cpp in Sources */, 217DFBFB1D9F6D490055D849 /* serial.c in Sources */, + FADF54251E3DA5BA00012CC0 /* Mesh.cpp in Sources */, FA4F2BE51DE6650600CA37D7 /* wrap_Transform.cpp in Sources */, 217DFC0D1D9F6D490055D849 /* unixudp.c in Sources */, FA0B7CDC1A95902C000E1D17 /* Source.cpp in Sources */, @@ -4451,11 +4472,9 @@ FA0B7DAE1A95902C000E1D17 /* wrap_CompressedImageData.cpp in Sources */, FA0B7A6E1A958EA3000E1D17 /* b2WorldCallbacks.cpp in Sources */, FA0B7A831A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */, - FA0B7D671A95902C000E1D17 /* wrap_ParticleSystem.cpp in Sources */, FA0B7AA11A958EA3000E1D17 /* b2PulleyJoint.cpp in Sources */, FAB17BE61ABFAA9000F9BA27 /* lz4.c in Sources */, FA0B7B211A958EA3000E1D17 /* luasocket.cpp in Sources */, - FA0B7D641A95902C000E1D17 /* wrap_Mesh.cpp in Sources */, FA0B7A5B1A958EA3000E1D17 /* b2Timer.cpp in Sources */, FA0B7CD91A95902C000E1D17 /* Pool.cpp in Sources */, FAF140A01E20934C00F898D2 /* RemoveTree.cpp in Sources */, @@ -4519,6 +4538,7 @@ FA0B7A4E1A958EA3000E1D17 /* b2Draw.cpp in Sources */, FA27B3C01B4985BF008A9DCE /* wrap_VideoStream.cpp in Sources */, FA0B7D931A95902C000E1D17 /* Image.cpp in Sources */, + FADF54201E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */, FA0B7D9F1A95902C000E1D17 /* KTXHandler.cpp in Sources */, FA1E88831DF363DB00E808AA /* Filter.cpp in Sources */, FA0B7A2C1A958EA3000E1D17 /* b2CollideCircle.cpp in Sources */, @@ -4544,6 +4564,7 @@ FA4F2B791DE0125B00CA37D7 /* xxhash.c in Sources */, FA0B7E361A95902C000E1D17 /* WheelJoint.cpp in Sources */, FA0B7A471A958EA3000E1D17 /* b2PolygonShape.cpp in Sources */, + FADF542F1E3DABF600012CC0 /* SpriteBatch.cpp in Sources */, FA0B7D8D1A95902C000E1D17 /* ddsHandler.cpp in Sources */, FA0B7DFD1A95902C000E1D17 /* ChainShape.cpp in Sources */, FA0B79201A958E3B000E1D17 /* delay.cpp in Sources */, @@ -4562,7 +4583,6 @@ FA0B7AD41A958EA3000E1D17 /* unix.c in Sources */, FA0B7A771A958EA3000E1D17 /* b2CircleContact.cpp in Sources */, FAB17BE01ABFAA2000F9BA27 /* Compressor.cpp in Sources */, - FA0B7D701A95902C000E1D17 /* wrap_SpriteBatch.cpp in Sources */, FA0B7D331A95902C000E1D17 /* Canvas.cpp in Sources */, FA0B7E941A95902C000E1D17 /* Mpg123Decoder.cpp in Sources */, FA0B7E8B1A95902C000E1D17 /* FLACDecoder.cpp in Sources */, diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 89d94b075..4fff1405f 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -694,6 +694,11 @@ void Graphics::draw(Texture *texture, Quad *quad, const Matrix4 &m) texture->drawq(this, quad, m); } +void Graphics::drawInstanced(Mesh *mesh, const Matrix4 &m, int instancecount) +{ + mesh->drawInstanced(this, m, instancecount); +} + /** * Primitives (points, shapes, lines). **/ diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 0a4068455..51b6ee9d7 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -34,6 +34,7 @@ #include "Font.h" #include "Shader.h" #include "Quad.h" +#include "Mesh.h" #include "math/Transform.h" #include "font/Rasterizer.h" #include "video/VideoStream.h" @@ -50,6 +51,8 @@ class Reference; namespace graphics { +class SpriteBatch; +class ParticleSystem; class Text; class Video; class Buffer; @@ -314,6 +317,10 @@ public: Quad *newQuad(Quad::Viewport v, double sw, double sh); + virtual SpriteBatch *newSpriteBatch(Texture *texture, int size, vertex::Usage usage) = 0; + + virtual ParticleSystem *newParticleSystem(Texture *texture, int size) = 0; + virtual Font *newFont(love::font::Rasterizer *data, const Texture::Filter &filter = Texture::defaultFilter) = 0; virtual Canvas *newCanvas(int width, int height, const Canvas::Settings &settings) = 0; @@ -324,6 +331,12 @@ public: virtual Buffer *newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags) = 0; + virtual Mesh *newMesh(const std::vector &vertices, Mesh::DrawMode drawmode, vertex::Usage usage) = 0; + virtual Mesh *newMesh(int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) = 0; + + virtual Mesh *newMesh(const std::vector &vertexformat, int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) = 0; + virtual Mesh *newMesh(const std::vector &vertexformat, const void *data, size_t datasize, Mesh::DrawMode drawmode, vertex::Usage usage) = 0; + virtual Text *newText(Font *font, const std::vector &text = {}) = 0; bool validateShader(bool gles, const Shader::ShaderSource &source, std::string &err); @@ -546,6 +559,7 @@ public: void draw(Drawable *drawable, const Matrix4 &m); void draw(Texture *texture, Quad *quad, const Matrix4 &m); + void drawInstanced(Mesh *mesh, const Matrix4 &m, int instancecount); /** * Draws text at the specified coordinates diff --git a/src/modules/graphics/Mesh.cpp b/src/modules/graphics/Mesh.cpp new file mode 100644 index 000000000..f1a1a41a8 --- /dev/null +++ b/src/modules/graphics/Mesh.cpp @@ -0,0 +1,642 @@ +/** + * 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. + **/ + +// LOVE +#include "Mesh.h" +#include "common/Matrix.h" +#include "common/Exception.h" +#include "Shader.h" +#include "Graphics.h" + +// C++ +#include +#include + +namespace love +{ +namespace graphics +{ + +static const char *getBuiltinAttribName(VertexAttribID attribid) +{ + const char *name = ""; + vertex::getConstant(attribid, name); + return name; +} + +static_assert(offsetof(Vertex, x) == sizeof(float) * 0, "Incorrect position offset in Vertex struct"); +static_assert(offsetof(Vertex, s) == sizeof(float) * 2, "Incorrect texture coordinate offset in Vertex struct"); +static_assert(offsetof(Vertex, color.r) == sizeof(float) * 4, "Incorrect color offset in Vertex struct"); + +std::vector Mesh::getDefaultVertexFormat() +{ + // Corresponds to the love::Vertex struct. + std::vector vertexformat = { + {getBuiltinAttribName(ATTRIB_POS), Mesh::DATA_FLOAT, 2}, + {getBuiltinAttribName(ATTRIB_TEXCOORD), Mesh::DATA_FLOAT, 2}, + {getBuiltinAttribName(ATTRIB_COLOR), Mesh::DATA_BYTE, 4}, + }; + + return vertexformat; +} + +love::Type Mesh::type("Mesh", &Drawable::type); + +Mesh::Mesh(graphics::Graphics *gfx, const std::vector &vertexformat, const void *data, size_t datasize, DrawMode drawmode, vertex::Usage usage) + : vertexFormat(vertexformat) + , vbo(nullptr) + , vertexCount(0) + , vertexStride(0) + , ibo(nullptr) + , useIndexBuffer(false) + , elementCount(0) + , elementDataType(INDEX_UINT16) + , drawMode(drawmode) + , rangeStart(-1) + , rangeCount(-1) +{ + setupAttachedAttributes(); + calculateAttributeSizes(); + + vertexCount = datasize / vertexStride; + elementDataType = vertex::getIndexDataTypeFromMax(vertexCount); + + if (vertexCount == 0) + throw love::Exception("Data size is too small for specified vertex attribute formats."); + + vbo = gfx->newBuffer(datasize, data, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ); + + vertexScratchBuffer = new char[vertexStride]; +} + +Mesh::Mesh(graphics::Graphics *gfx, const std::vector &vertexformat, int vertexcount, DrawMode drawmode, vertex::Usage usage) + : vertexFormat(vertexformat) + , vbo(nullptr) + , vertexCount((size_t) vertexcount) + , vertexStride(0) + , ibo(nullptr) + , useIndexBuffer(false) + , elementCount(0) + , elementDataType(vertex::getIndexDataTypeFromMax(vertexcount)) + , drawMode(drawmode) + , rangeStart(-1) + , rangeCount(-1) +{ + if (vertexcount <= 0) + throw love::Exception("Invalid number of vertices (%d).", vertexcount); + + setupAttachedAttributes(); + calculateAttributeSizes(); + + size_t buffersize = vertexCount * vertexStride; + + vbo = gfx->newBuffer(buffersize, nullptr, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ); + + // Initialize the buffer's contents to 0. + memset(vbo->map(), 0, buffersize); + vbo->setMappedRangeModified(0, vbo->getSize()); + vbo->unmap(); + + vertexScratchBuffer = new char[vertexStride]; +} + +Mesh::~Mesh() +{ + delete vbo; + delete ibo; + delete vertexScratchBuffer; + + for (const auto &attrib : attachedAttributes) + { + if (attrib.second.mesh != this) + attrib.second.mesh->release(); + } +} + +void Mesh::setupAttachedAttributes() +{ + for (size_t i = 0; i < vertexFormat.size(); i++) + { + const std::string &name = vertexFormat[i].name; + + if (attachedAttributes.find(name) != attachedAttributes.end()) + throw love::Exception("Duplicate vertex attribute name: %s", name.c_str()); + + attachedAttributes[name] = {this, (int) i, STEP_PER_VERTEX, true}; + } +} + +void Mesh::calculateAttributeSizes() +{ + size_t stride = 0; + + for (const AttribFormat &format : vertexFormat) + { + // Hardware really doesn't like attributes that aren't 32 bit-aligned. + if (format.type == DATA_BYTE && format.components != 4) + throw love::Exception("byte vertex attributes must have 4 components."); + + if (format.components <= 0 || format.components > 4) + throw love::Exception("Vertex attributes must have between 1 and 4 components."); + + // Total size in bytes of each attribute in a single vertex. + attributeSizes.push_back(getAttribFormatSize(format)); + stride += attributeSizes.back(); + } + + vertexStride = stride; +} + +size_t Mesh::getAttributeOffset(size_t attribindex) const +{ + size_t offset = 0; + + for (size_t i = 0; i < attribindex; i++) + offset += attributeSizes[i]; + + return offset; +} + +void Mesh::setVertex(size_t vertindex, const void *data, size_t datasize) +{ + if (vertindex >= vertexCount) + throw love::Exception("Invalid vertex index: %ld", vertindex + 1); + + size_t offset = vertindex * vertexStride; + size_t size = std::min(datasize, vertexStride); + + uint8 *bufferdata = (uint8 *) vbo->map(); + memcpy(bufferdata + offset, data, size); + + vbo->setMappedRangeModified(offset, size); +} + +size_t Mesh::getVertex(size_t vertindex, void *data, size_t datasize) +{ + if (vertindex >= vertexCount) + throw love::Exception("Invalid vertex index: %ld", vertindex + 1); + + size_t offset = vertindex * vertexStride; + size_t size = std::min(datasize, vertexStride); + + // We're relying on vbo->map() returning read/write data... ew. + const uint8 *bufferdata = (const uint8 *) vbo->map(); + memcpy(data, bufferdata + offset, size); + + return size; +} + +void *Mesh::getVertexScratchBuffer() +{ + return vertexScratchBuffer; +} + +void Mesh::setVertexAttribute(size_t vertindex, int attribindex, const void *data, size_t datasize) +{ + if (vertindex >= vertexCount) + throw love::Exception("Invalid vertex index: %ld", vertindex + 1); + + if (attribindex >= (int) vertexFormat.size()) + throw love::Exception("Invalid vertex attribute index: %d", attribindex + 1); + + size_t offset = vertindex * vertexStride + getAttributeOffset(attribindex); + size_t size = std::min(datasize, attributeSizes[attribindex]); + + uint8 *bufferdata = (uint8 *) vbo->map(); + memcpy(bufferdata + offset, data, size); + + vbo->setMappedRangeModified(offset, size); +} + +size_t Mesh::getVertexAttribute(size_t vertindex, int attribindex, void *data, size_t datasize) +{ + if (vertindex >= vertexCount) + throw love::Exception("Invalid vertex index: %ld", vertindex + 1); + + if (attribindex >= (int) vertexFormat.size()) + throw love::Exception("Invalid vertex attribute index: %d", attribindex + 1); + + size_t offset = vertindex * vertexStride + getAttributeOffset(attribindex); + size_t size = std::min(datasize, attributeSizes[attribindex]); + + // We're relying on vbo->map() returning read/write data... ew. + const uint8 *bufferdata = (const uint8 *) vbo->map(); + memcpy(data, bufferdata + offset, size); + + return size; +} + +size_t Mesh::getVertexCount() const +{ + return vertexCount; +} + +size_t Mesh::getVertexStride() const +{ + return vertexStride; +} + +const std::vector &Mesh::getVertexFormat() const +{ + return vertexFormat; +} + +Mesh::DataType Mesh::getAttributeInfo(int attribindex, int &components) const +{ + if (attribindex < 0 || attribindex >= (int) vertexFormat.size()) + throw love::Exception("Invalid vertex attribute index: %d", attribindex + 1); + + DataType type = vertexFormat[attribindex].type; + components = vertexFormat[attribindex].components; + + return type; +} + +int Mesh::getAttributeIndex(const std::string &name) const +{ + for (int i = 0; i < (int) vertexFormat.size(); i++) + { + if (vertexFormat[i].name == name) + return i; + } + + return -1; +} + +void Mesh::setAttributeEnabled(const std::string &name, bool enable) +{ + auto it = attachedAttributes.find(name); + + if (it == attachedAttributes.end()) + throw love::Exception("Mesh does not have an attached vertex attribute named '%s'", name.c_str()); + + it->second.enabled = enable; +} + +bool Mesh::isAttributeEnabled(const std::string &name) const +{ + const auto it = attachedAttributes.find(name); + + if (it == attachedAttributes.end()) + throw love::Exception("Mesh does not have an attached vertex attribute named '%s'", name.c_str()); + + return it->second.enabled; +} + +void Mesh::attachAttribute(const std::string &name, Mesh *mesh, const std::string &attachname, AttributeStep step) +{ + auto gfx = Module::getInstance(Module::M_GRAPHICS); + if (step == STEP_PER_INSTANCE && !gfx->isSupported(Graphics::FEATURE_INSTANCING)) + throw love::Exception("Vertex attribute instancing is not supported on this system."); + + if (mesh != this) + { + for (const auto &it : mesh->attachedAttributes) + { + // If the supplied Mesh has attached attributes of its own, then we + // prevent it from being attached to avoid reference cycles. + if (it.second.mesh != mesh) + throw love::Exception("Cannot attach a Mesh which has attached Meshes of its own."); + } + } + + AttachedAttribute oldattrib = {}; + AttachedAttribute newattrib = {}; + + auto it = attachedAttributes.find(name); + if (it != attachedAttributes.end()) + oldattrib = it->second; + + newattrib.mesh = mesh; + newattrib.enabled = oldattrib.mesh ? oldattrib.enabled : true; + newattrib.index = mesh->getAttributeIndex(attachname); + newattrib.step = step; + + if (newattrib.index < 0) + throw love::Exception("The specified mesh does not have a vertex attribute named '%s'", attachname.c_str()); + + if (newattrib.mesh != this) + newattrib.mesh->retain(); + + attachedAttributes[name] = newattrib; + + if (oldattrib.mesh && oldattrib.mesh != this) + oldattrib.mesh->release(); +} + +bool Mesh::detachAttribute(const std::string &name) +{ + auto it = attachedAttributes.find(name); + + if (it != attachedAttributes.end() && it->second.mesh != this) + { + it->second.mesh->release(); + attachedAttributes.erase(it); + + if (getAttributeIndex(name) != -1) + attachAttribute(name, this, name); + + return true; + } + + return false; +} + +void *Mesh::mapVertexData() +{ + return vbo->map(); +} + +void Mesh::unmapVertexData(size_t modifiedoffset, size_t modifiedsize) +{ + vbo->setMappedRangeModified(modifiedoffset, modifiedsize); + vbo->unmap(); +} + +void Mesh::flush() +{ + vbo->unmap(); + + if (ibo != nullptr) + ibo->unmap(); +} + +/** + * Copies index data from a vector to a mapped index buffer. + **/ +template +static void copyToIndexBuffer(const std::vector &indices, Buffer::Mapper &buffermap, size_t maxval) +{ + T *elems = (T *) buffermap.get(); + + for (size_t i = 0; i < indices.size(); i++) + { + if (indices[i] >= maxval) + throw love::Exception("Invalid vertex map value: %d", indices[i] + 1); + + elems[i] = (T) indices[i]; + } +} + +void Mesh::setVertexMap(const std::vector &map) +{ + size_t maxval = getVertexCount(); + + IndexDataType datatype = vertex::getIndexDataTypeFromMax(maxval); + + // Calculate the size in bytes of the index buffer data. + size_t size = map.size() * vertex::getIndexDataSize(datatype); + + if (ibo && size > ibo->getSize()) + { + delete ibo; + ibo = nullptr; + } + + if (!ibo && size > 0) + { + auto gfx = Module::getInstance(Module::M_GRAPHICS); + ibo = gfx->newBuffer(size, nullptr, BUFFER_INDEX, vbo->getUsage(), Buffer::MAP_READ); + } + + useIndexBuffer = true; + elementCount = map.size(); + + if (!ibo || elementCount == 0) + return; + + Buffer::Mapper ibomap(*ibo); + + // Fill the buffer with the index values from the vector. + switch (datatype) + { + case INDEX_UINT16: + copyToIndexBuffer(map, ibomap, maxval); + break; + case INDEX_UINT32: + default: + copyToIndexBuffer(map, ibomap, maxval); + break; + } + + elementDataType = datatype; +} + +void Mesh::setVertexMap(IndexDataType datatype, const void *data, size_t datasize) +{ + if (ibo && datasize > ibo->getSize()) + { + delete ibo; + ibo = nullptr; + } + + if (!ibo && datasize > 0) + { + auto gfx = Module::getInstance(Module::M_GRAPHICS); + ibo = gfx->newBuffer(datasize, nullptr, BUFFER_INDEX, vbo->getUsage(), Buffer::MAP_READ); + } + + elementCount = datasize / vertex::getIndexDataSize(datatype); + + if (!ibo || elementCount == 0) + return; + + Buffer::Mapper ibomap(*ibo); + memcpy(ibomap.get(), data, datasize); + + useIndexBuffer = true; + elementDataType = datatype; +} + +void Mesh::setVertexMap() +{ + useIndexBuffer = false; +} + +/** + * Copies index data from a mapped buffer to a vector. + **/ +template +static void copyFromIndexBuffer(void *buffer, size_t count, std::vector &indices) +{ + T *elems = (T *) buffer; + for (size_t i = 0; i < count; i++) + indices.push_back((uint32) elems[i]); +} + +bool Mesh::getVertexMap(std::vector &map) const +{ + if (!useIndexBuffer) + return false; + + map.clear(); + map.reserve(elementCount); + + if (!ibo || elementCount == 0) + return true; + + // We unmap the buffer in Mesh::draw, Mesh::setVertexMap, and Mesh::flush. + void *buffer = ibo->map(); + + // Fill the vector from the buffer. + switch (elementDataType) + { + case INDEX_UINT16: + copyFromIndexBuffer(buffer, elementCount, map); + break; + case INDEX_UINT32: + default: + copyFromIndexBuffer(buffer, elementCount, map); + break; + } + + return true; +} + +size_t Mesh::getVertexMapCount() const +{ + return elementCount; +} + +void Mesh::setTexture(Texture *tex) +{ + texture.set(tex); +} + +void Mesh::setTexture() +{ + texture.set(nullptr); +} + +Texture *Mesh::getTexture() const +{ + return texture.get(); +} + +void Mesh::setDrawMode(DrawMode mode) +{ + drawMode = mode; +} + +Mesh::DrawMode Mesh::getDrawMode() const +{ + return drawMode; +} + +void Mesh::setDrawRange(int start, int count) +{ + if (start < 0 || count <= 0) + throw love::Exception("Invalid draw range."); + + rangeStart = start; + rangeCount = count; +} + +void Mesh::setDrawRange() +{ + rangeStart = rangeCount = -1; +} + +bool Mesh::getDrawRange(int &start, int &count) const +{ + if (rangeStart < 0 || rangeCount <= 0) + return false; + + start = rangeStart; + count = rangeCount; + return true; +} + +void Mesh::draw(love::graphics::Graphics *gfx, const love::Matrix4 &m) +{ + drawInstanced(gfx, m, 1); +} + +size_t Mesh::getAttribFormatSize(const AttribFormat &format) +{ + switch (format.type) + { + case DATA_BYTE: + return format.components * sizeof(uint8); + case DATA_FLOAT: + return format.components * sizeof(float); + default: + return 0; + } +} + +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); +} + +bool Mesh::getConstant(const char *in, DataType &out) +{ + return dataTypes.find(in, out); +} + +bool Mesh::getConstant(DataType in, const char *&out) +{ + return dataTypes.find(in, out); +} + +bool Mesh::getConstant(const char *in, AttributeStep &out) +{ + return attributeSteps.find(in, out); +} + +bool Mesh::getConstant(AttributeStep in, const char *&out) +{ + return attributeSteps.find(in, out); +} + +StringMap::Entry Mesh::drawModeEntries[] = +{ + { "fan", DRAWMODE_FAN }, + { "strip", DRAWMODE_STRIP }, + { "triangles", DRAWMODE_TRIANGLES }, + { "points", DRAWMODE_POINTS }, +}; + +StringMap Mesh::drawModes(Mesh::drawModeEntries, sizeof(Mesh::drawModeEntries)); + +StringMap::Entry Mesh::dataTypeEntries[] = +{ + { "byte", DATA_BYTE }, + { "float", DATA_FLOAT }, +}; + +StringMap Mesh::dataTypes(Mesh::dataTypeEntries, sizeof(Mesh::dataTypeEntries)); + +StringMap::Entry Mesh::attributeStepEntries[] = +{ + { "pervertex", STEP_PER_VERTEX }, + { "perinstance", STEP_PER_INSTANCE }, +}; + +StringMap Mesh::attributeSteps(Mesh::attributeStepEntries, sizeof(Mesh::attributeStepEntries)); + +} // graphics +} // love diff --git a/src/modules/graphics/Mesh.h b/src/modules/graphics/Mesh.h new file mode 100644 index 000000000..583e2d36f --- /dev/null +++ b/src/modules/graphics/Mesh.h @@ -0,0 +1,270 @@ +/** + * 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 "common/int.h" +#include "common/math.h" +#include "common/StringMap.h" +#include "Drawable.h" +#include "Texture.h" +#include "vertex.h" +#include "Buffer.h" + +// C++ +#include +#include + +namespace love +{ +namespace graphics +{ + +class Graphics; + +/** + * Holds and draws arbitrary vertex geometry. + * Each vertex in the Mesh has a collection of vertex attributes specified on + * creation. + **/ +class Mesh : public Drawable +{ +public: + + static love::Type type; + + // How the Mesh's vertices are used when drawing. + // http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png + enum DrawMode + { + DRAWMODE_FAN, + DRAWMODE_STRIP, + DRAWMODE_TRIANGLES, + DRAWMODE_POINTS, + DRAWMODE_MAX_ENUM + }; + + // The type of data a vertex attribute can store. + enum DataType + { + DATA_BYTE, + DATA_FLOAT, + DATA_MAX_ENUM + }; + + enum AttributeStep + { + STEP_PER_VERTEX, + STEP_PER_INSTANCE, + STEP_MAX_ENUM + }; + + struct AttribFormat + { + std::string name; + DataType type; + int components; // max 4 + }; + + Mesh(Graphics *gfx, const std::vector &vertexformat, const void *data, size_t datasize, DrawMode drawmode, vertex::Usage usage); + Mesh(Graphics *gfx, const std::vector &vertexformat, int vertexcount, DrawMode drawmode, vertex::Usage usage); + + virtual ~Mesh(); + + /** + * Sets the values of all attributes at a specific vertex index in the Mesh. + * The size of the data must be less than or equal to the total size of all + * vertex attributes. + **/ + void setVertex(size_t vertindex, const void *data, size_t datasize); + size_t getVertex(size_t vertindex, void *data, size_t datasize); + void *getVertexScratchBuffer(); + + /** + * Sets the values for a single attribute at a specific vertex index in the + * Mesh. The size of the data must be less than or equal to the size of the + * attribute. + **/ + void setVertexAttribute(size_t vertindex, int attribindex, const void *data, size_t datasize); + size_t getVertexAttribute(size_t vertindex, int attribindex, void *data, size_t datasize); + + /** + * Gets the total number of vertices that can be used when drawing the Mesh. + **/ + size_t getVertexCount() const; + + /** + * Gets the size in bytes of the start of one vertex to the start of the + * next, in the buffer. + **/ + size_t getVertexStride() const; + + /** + * Gets the format of each vertex attribute stored in the Mesh. + **/ + const std::vector &getVertexFormat() const; + DataType getAttributeInfo(int attribindex, int &components) const; + int getAttributeIndex(const std::string &name) const; + + /** + * Sets whether a specific vertex attribute is used when drawing the Mesh. + **/ + void setAttributeEnabled(const std::string &name, bool enable); + bool isAttributeEnabled(const std::string &name) const; + + /** + * Attaches a vertex attribute from another Mesh to this one. The attribute + * will be used when drawing this Mesh. + **/ + void attachAttribute(const std::string &name, Mesh *mesh, const std::string &attachname, AttributeStep step = STEP_PER_VERTEX); + bool detachAttribute(const std::string &name); + + void *mapVertexData(); + void unmapVertexData(size_t modifiedoffset = 0, size_t modifiedsize = -1); + + /** + * Flushes all modified data to the GPU. + **/ + void flush(); + + /** + * 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 &map); + void setVertexMap(IndexDataType datatype, const void *data, size_t datasize); + void setVertexMap(); + + /** + * Fills the uint32 vector passed into the method with the previously set + * vertex map (index buffer) values. + **/ + bool getVertexMap(std::vector &map) const; + + /** + * Gets the total number of elements in the vertex map array. + **/ + size_t getVertexMapCount() const; + + /** + * Sets the texture used when drawing the Mesh. + **/ + void setTexture(Texture *texture); + + /** + * Disables any texture from being used when drawing the Mesh. + **/ + void setTexture(); + + /** + * Gets the texture used when drawing the Mesh. May return null if no + * texture is set. + **/ + Texture *getTexture() const; + + /** + * Sets the draw mode used when drawing the Mesh. + **/ + void setDrawMode(DrawMode mode); + DrawMode getDrawMode() const; + + void setDrawRange(int start, int count); + void setDrawRange(); + bool getDrawRange(int &start, int &count) const; + + virtual int bindAttributeToShaderInput(int attributeindex, const std::string &inputname) = 0; + + virtual void drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount) = 0; + + // Implements Drawable. + void draw(Graphics *gfx, const Matrix4 &m) override; + + static bool getConstant(const char *in, DrawMode &out); + static bool getConstant(DrawMode in, const char *&out); + + static bool getConstant(const char *in, DataType &out); + static bool getConstant(DataType in, const char *&out); + + static bool getConstant(const char *in, AttributeStep &out); + static bool getConstant(AttributeStep in, const char *&out); + +protected: + + struct AttachedAttribute + { + Mesh *mesh; + int index; + AttributeStep step; + bool enabled; + }; + + void setupAttachedAttributes(); + void calculateAttributeSizes(); + size_t getAttributeOffset(size_t attribindex) const; + + static size_t getAttribFormatSize(const AttribFormat &format); + static std::vector getDefaultVertexFormat(); + + std::vector vertexFormat; + std::vector attributeSizes; + + std::unordered_map attachedAttributes; + + // Vertex buffer, for the vertex data. + Buffer *vbo; + size_t vertexCount; + size_t vertexStride; + + // Block of memory whose size is at least as large as a single vertex. Helps + // avoid memory allocations when using Mesh::setVertex etc. + char *vertexScratchBuffer; + + // Element (vertex index) buffer, for the vertex map. + Buffer *ibo; + bool useIndexBuffer; + size_t elementCount; + IndexDataType elementDataType; + + DrawMode drawMode; + + int rangeStart; + int rangeCount; + + StrongRef texture; + +private: + + static StringMap::Entry drawModeEntries[]; + static StringMap drawModes; + + static StringMap::Entry dataTypeEntries[]; + static StringMap dataTypes; + + static StringMap::Entry attributeStepEntries[]; + static StringMap attributeSteps; + +}; // Mesh + +} // graphics +} // love diff --git a/src/modules/graphics/SpriteBatch.cpp b/src/modules/graphics/SpriteBatch.cpp new file mode 100644 index 000000000..0b5cc3ce2 --- /dev/null +++ b/src/modules/graphics/SpriteBatch.cpp @@ -0,0 +1,258 @@ +/** + * 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 "common/config.h" +#include "SpriteBatch.h" + +// LOVE +#include "Texture.h" +#include "Quad.h" +#include "Graphics.h" +#include "Buffer.h" + +// C++ +#include + +// C +#include + +namespace love +{ +namespace graphics +{ + +love::Type SpriteBatch::type("SpriteBatch", &Drawable::type); + +SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, vertex::Usage usage) + : texture(texture) + , size(size) + , next(0) + , color(0) + , array_buf(nullptr) + , quad_indices(gfx, size) + , range_start(-1) + , range_count(-1) +{ + if (size <= 0) + throw love::Exception("Invalid SpriteBatch size."); + + size_t vertex_size = sizeof(Vertex) * 4 * size; + + array_buf = gfx->newBuffer(vertex_size, nullptr, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY); +} + +SpriteBatch::~SpriteBatch() +{ + delete color; + delete array_buf; +} + +int SpriteBatch::add(const Matrix4 &m, int index /*= -1*/) +{ + if (index < -1 || index >= size) + throw love::Exception("Invalid sprite index: %d", index + 1); + + if (index == -1 && next >= size) + setBufferSize(size * 2); + + addv(texture->getVertices(), m, (index == -1) ? next : index); + + // Increment counter. + if (index == -1) + return next++; + + return index; +} + +int SpriteBatch::addq(Quad *quad, const Matrix4 &m, int index /*= -1*/) +{ + if (index < -1 || index >= size) + throw love::Exception("Invalid sprite index: %d", index + 1); + + if (index == -1 && next >= size) + setBufferSize(size * 2); + + addv(quad->getVertices(), m, (index == -1) ? next : index); + + // Increment counter. + if (index == -1) + return next++; + + return index; +} + +void SpriteBatch::clear() +{ + // Reset the position of the next index. + next = 0; +} + +void SpriteBatch::flush() +{ + array_buf->unmap(); +} + +void SpriteBatch::setTexture(Texture *newtexture) +{ + texture.set(newtexture); +} + +Texture *SpriteBatch::getTexture() const +{ + return texture.get(); +} + +void SpriteBatch::setColor(const Color &color) +{ + if (!this->color) + this->color = new Color(color); + else + *(this->color) = color; +} + +void SpriteBatch::setColor() +{ + delete color; + color = nullptr; +} + +const Color *SpriteBatch::getColor() const +{ + return color; +} + +int SpriteBatch::getCount() const +{ + return next; +} + +void SpriteBatch::setBufferSize(int newsize) +{ + if (newsize <= 0) + throw love::Exception("Invalid SpriteBatch size."); + + if (newsize == size) + return; + + size_t vertex_size = sizeof(Vertex) * 4 * newsize; + love::graphics::Buffer *new_array_buf = nullptr; + + int new_next = std::min(next, newsize); + + try + { + auto gfx = Module::getInstance(Module::M_GRAPHICS); + new_array_buf = gfx->newBuffer(vertex_size, nullptr, array_buf->getType(), array_buf->getUsage(), array_buf->getMapFlags()); + + // Copy as much of the old data into the new GLBuffer as can fit. + size_t copy_size = sizeof(Vertex) * 4 * new_next; + array_buf->copyTo(0, copy_size, new_array_buf, 0); + + quad_indices = QuadIndices(gfx, newsize); + } + catch (love::Exception &) + { + delete new_array_buf; + throw; + } + + // We don't need to unmap the old GLBuffer since we're deleting it. + delete array_buf; + + array_buf = new_array_buf; + size = newsize; + + next = new_next; +} + +int SpriteBatch::getBufferSize() const +{ + return size; +} + +void SpriteBatch::attachAttribute(const std::string &name, Mesh *mesh) +{ + AttachedAttribute oldattrib = {}; + AttachedAttribute newattrib = {}; + + if (mesh->getVertexCount() < (size_t) next * 4) + throw love::Exception("Mesh has too few vertices to be attached to this SpriteBatch (at least %d vertices are required)", next*4); + + auto it = attached_attributes.find(name); + if (it != attached_attributes.end()) + oldattrib = it->second; + + newattrib.index = mesh->getAttributeIndex(name); + + if (newattrib.index < 0) + throw love::Exception("The specified mesh does not have a vertex attribute named '%s'", name.c_str()); + + newattrib.mesh = mesh; + + attached_attributes[name] = newattrib; +} + +void SpriteBatch::setDrawRange(int start, int count) +{ + if (start < 0 || count <= 0) + throw love::Exception("Invalid draw range."); + + range_start = start; + range_count = count; +} + +void SpriteBatch::setDrawRange() +{ + range_start = range_count = -1; +} + +bool SpriteBatch::getDrawRange(int &start, int &count) const +{ + if (range_start < 0 || range_count <= 0) + return false; + + start = range_start; + count = range_count; + return true; +} + +void SpriteBatch::addv(const Vertex *v, const Matrix4 &m, int index) +{ + // Needed for colors. + Vertex sprite[4] = {v[0], v[1], v[2], v[3]}; + const size_t sprite_size = 4 * sizeof(Vertex); // bytecount + + m.transform(sprite, sprite, 4); + + if (color != nullptr) + { + for (int i = 0; i < 4; i++) + sprite[i].color = *color; + } + + // Always keep the VBO mapped when adding data for now (it'll be unmapped + // on draw.) + array_buf->map(); + + array_buf->fill(index * sprite_size, sprite_size, sprite); +} + +} // graphics +} // love diff --git a/src/modules/graphics/SpriteBatch.h b/src/modules/graphics/SpriteBatch.h new file mode 100644 index 000000000..7590af7ae --- /dev/null +++ b/src/modules/graphics/SpriteBatch.h @@ -0,0 +1,145 @@ +/** + * 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 + +// C +#include + +// C++ +#include + +// LOVE +#include "common/math.h" +#include "common/Matrix.h" +#include "Drawable.h" +#include "Color.h" +#include "Mesh.h" + +namespace love +{ +namespace graphics +{ + +// Forward declarations. +class Graphics; +class Texture; +class Quad; +class Buffer; + +class SpriteBatch : public Drawable +{ +public: + + static love::Type type; + + SpriteBatch(Graphics *gfx, Texture *texture, int size, vertex::Usage usage); + virtual ~SpriteBatch(); + + int add(const Matrix4 &m, int index = -1); + int addq(Quad *quad, const Matrix4 &m, int index = -1); + void clear(); + + void flush(); + + void setTexture(Texture *newtexture); + Texture *getTexture() const; + + /** + * 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 sprites. + */ + void setColor(const Color &color); + + /** + * Disable per-sprite colors for this SpriteBatch. The next call to + * draw will use the global color for all sprites. + */ + void setColor(); + + /** + * Get the current color for this SpriteBatch. Returns NULL if no color is + * set. + **/ + const Color *getColor() const; + + /** + * Get the number of sprites currently in this SpriteBatch. + **/ + int getCount() const; + + /** + * Get the total number of sprites this SpriteBatch can currently hold. + **/ + int getBufferSize() const; + + /** + * Attaches a specific vertex attribute from a Mesh to this SpriteBatch. + * The vertex attribute will be used when drawing the SpriteBatch. + **/ + void attachAttribute(const std::string &name, Mesh *mesh); + + void setDrawRange(int start, int count); + void setDrawRange(); + bool getDrawRange(int &start, int &count) const; + +protected: + + struct AttachedAttribute + { + StrongRef mesh; + int index; + }; + + /** + * Sets the total number of sprites this SpriteBatch can hold. + * Leaves existing sprite data intact when possible. + **/ + void setBufferSize(int newsize); + + void addv(const Vertex *v, const Matrix4 &m, int index); + + StrongRef texture; + + // Max number of sprites in the batch. + int size; + + // The next free element. + int next; + + // Current color. This color, if present, will be applied to the next + // added sprite. + Color *color; + + love::graphics::Buffer *array_buf; + QuadIndices quad_indices; + + std::unordered_map attached_attributes; + + int range_start; + int range_count; + +}; // SpriteBatch + +} // graphics +} // love diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index fc982ce70..892e1d7e5 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -118,12 +118,12 @@ graphics::Font *Graphics::newFont(love::font::Rasterizer *r, const Texture::Filt return new Font(r, filter); } -SpriteBatch *Graphics::newSpriteBatch(Texture *texture, int size, vertex::Usage usage) +love::graphics::SpriteBatch *Graphics::newSpriteBatch(Texture *texture, int size, vertex::Usage usage) { return new SpriteBatch(this, texture, size, usage); } -ParticleSystem *Graphics::newParticleSystem(Texture *texture, int size) +love::graphics::ParticleSystem *Graphics::newParticleSystem(Texture *texture, int size) { return new ParticleSystem(this, texture, size); } @@ -167,22 +167,22 @@ love::graphics::Buffer *Graphics::newBuffer(size_t size, const void *data, Buffe return new Buffer(size, data, type, usage, mapflags); } -Mesh *Graphics::newMesh(const std::vector &vertices, Mesh::DrawMode drawmode, vertex::Usage usage) +love::graphics::Mesh *Graphics::newMesh(const std::vector &vertices, Mesh::DrawMode drawmode, vertex::Usage usage) { return new Mesh(this, vertices, drawmode, usage); } -Mesh *Graphics::newMesh(int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) +love::graphics::Mesh *Graphics::newMesh(int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) { return new Mesh(this, vertexcount, drawmode, usage); } -Mesh *Graphics::newMesh(const std::vector &vertexformat, int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) +love::graphics::Mesh *Graphics::newMesh(const std::vector &vertexformat, int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) { return new Mesh(this, vertexformat, vertexcount, drawmode, usage); } -Mesh *Graphics::newMesh(const std::vector &vertexformat, const void *data, size_t datasize, Mesh::DrawMode drawmode, vertex::Usage usage) +love::graphics::Mesh *Graphics::newMesh(const std::vector &vertexformat, const void *data, size_t datasize, Mesh::DrawMode drawmode, vertex::Usage usage) { return new Mesh(this, vertexformat, data, datasize, drawmode, usage); } @@ -498,11 +498,6 @@ void Graphics::flushStreamDraws() streamBufferState.indexCount = 0; } -void Graphics::drawInstanced(Mesh *mesh, const love::Matrix4 &m, int instancecount) -{ - mesh->drawInstanced(this, m, instancecount); -} - static void APIENTRY debugCB(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /*len*/, const GLchar *msg, const GLvoid* /*usr*/) { // Human-readable strings for the debug info. diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 53151bfe1..49c7d53dd 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -66,9 +66,9 @@ public: love::graphics::Font *newFont(love::font::Rasterizer *data, const Texture::Filter &filter = Texture::defaultFilter) override; - SpriteBatch *newSpriteBatch(Texture *texture, int size, vertex::Usage usage); + love::graphics::SpriteBatch *newSpriteBatch(Texture *texture, int size, vertex::Usage usage) override; - ParticleSystem *newParticleSystem(Texture *texture, int size); + love::graphics::ParticleSystem *newParticleSystem(Texture *texture, int size) override; love::graphics::Canvas *newCanvas(int width, int height, const Canvas::Settings &settings) override; @@ -76,11 +76,11 @@ public: love::graphics::Buffer *newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags) override; - Mesh *newMesh(const std::vector &vertices, Mesh::DrawMode drawmode, vertex::Usage usage); - Mesh *newMesh(int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage); + love::graphics::Mesh *newMesh(const std::vector &vertices, Mesh::DrawMode drawmode, vertex::Usage usage) override; + love::graphics::Mesh *newMesh(int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) override; - Mesh *newMesh(const std::vector &vertexformat, int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage); - Mesh *newMesh(const std::vector &vertexformat, const void *data, size_t datasize, Mesh::DrawMode drawmode, vertex::Usage usage); + love::graphics::Mesh *newMesh(const std::vector &vertexformat, int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) override; + love::graphics::Mesh *newMesh(const std::vector &vertexformat, const void *data, size_t datasize, Mesh::DrawMode drawmode, vertex::Usage usage) override; love::graphics::Text *newText(love::graphics::Font *font, const std::vector &text = {}) override; @@ -94,8 +94,6 @@ public: void flushStreamDraws() override; - void drawInstanced(Mesh *mesh, const Matrix4 &m, int instancecount); - void clear(Colorf color) override; void clear(const std::vector &colors) override; diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp index 800820a87..f91e20355 100644 --- a/src/modules/graphics/opengl/Mesh.cpp +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -20,7 +20,6 @@ // LOVE #include "Mesh.h" -#include "common/Matrix.h" #include "common/Exception.h" #include "Shader.h" #include "graphics/Graphics.h" @@ -36,87 +35,14 @@ namespace graphics namespace opengl { -static const char *getBuiltinAttribName(VertexAttribID attribid) -{ - const char *name = ""; - vertex::getConstant(attribid, name); - return name; -} - -static_assert(offsetof(Vertex, x) == sizeof(float) * 0, "Incorrect position offset in Vertex struct"); -static_assert(offsetof(Vertex, s) == sizeof(float) * 2, "Incorrect texture coordinate offset in Vertex struct"); -static_assert(offsetof(Vertex, color.r) == sizeof(float) * 4, "Incorrect color offset in Vertex struct"); - -static std::vector getDefaultVertexFormat() -{ - // Corresponds to the love::Vertex struct. - std::vector vertexformat = { - {getBuiltinAttribName(ATTRIB_POS), Mesh::DATA_FLOAT, 2}, - {getBuiltinAttribName(ATTRIB_TEXCOORD), Mesh::DATA_FLOAT, 2}, - {getBuiltinAttribName(ATTRIB_COLOR), Mesh::DATA_BYTE, 4}, - }; - - return vertexformat; -} - -love::Type Mesh::type("Mesh", &Drawable::type); - Mesh::Mesh(graphics::Graphics *gfx, const std::vector &vertexformat, const void *data, size_t datasize, DrawMode drawmode, vertex::Usage usage) - : vertexFormat(vertexformat) - , vbo(nullptr) - , vertexCount(0) - , vertexStride(0) - , ibo(nullptr) - , useIndexBuffer(false) - , elementCount(0) - , elementDataType(INDEX_UINT16) - , drawMode(drawmode) - , rangeStart(-1) - , rangeCount(-1) + : love::graphics::Mesh(gfx, vertexformat, data, datasize, drawmode, usage) { - setupAttachedAttributes(); - calculateAttributeSizes(); - - vertexCount = datasize / vertexStride; - elementDataType = vertex::getIndexDataTypeFromMax(vertexCount); - - if (vertexCount == 0) - throw love::Exception("Data size is too small for specified vertex attribute formats."); - - vbo = gfx->newBuffer(datasize, data, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ); - - vertexScratchBuffer = new char[vertexStride]; } Mesh::Mesh(graphics::Graphics *gfx, const std::vector &vertexformat, int vertexcount, DrawMode drawmode, vertex::Usage usage) - : vertexFormat(vertexformat) - , vbo(nullptr) - , vertexCount((size_t) vertexcount) - , vertexStride(0) - , ibo(nullptr) - , useIndexBuffer(false) - , elementCount(0) - , elementDataType(vertex::getIndexDataTypeFromMax(vertexcount)) - , drawMode(drawmode) - , rangeStart(-1) - , rangeCount(-1) + : love::graphics::Mesh(gfx, vertexformat, vertexcount, drawmode, usage) { - if (vertexcount <= 0) - throw love::Exception("Invalid number of vertices (%d).", vertexcount); - - setupAttachedAttributes(); - calculateAttributeSizes(); - - size_t buffersize = vertexCount * vertexStride; - - vbo = gfx->newBuffer(buffersize, nullptr, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ); - - // Initialize the buffer's contents to 0. - memset(vbo->map(), 0, buffersize); - vbo->setMappedRangeModified(0, vbo->getSize()); - vbo->unmap(); - - vertexScratchBuffer = new char[vertexStride]; } Mesh::Mesh(graphics::Graphics *gfx, const std::vector &vertices, DrawMode drawmode, vertex::Usage usage) @@ -131,448 +57,6 @@ Mesh::Mesh(graphics::Graphics *gfx, int vertexcount, DrawMode drawmode, vertex:: Mesh::~Mesh() { - delete vbo; - delete ibo; - delete vertexScratchBuffer; - - for (const auto &attrib : attachedAttributes) - { - if (attrib.second.mesh != this) - attrib.second.mesh->release(); - } -} - -void Mesh::setupAttachedAttributes() -{ - for (size_t i = 0; i < vertexFormat.size(); i++) - { - const std::string &name = vertexFormat[i].name; - - if (attachedAttributes.find(name) != attachedAttributes.end()) - throw love::Exception("Duplicate vertex attribute name: %s", name.c_str()); - - attachedAttributes[name] = {this, (int) i, STEP_PER_VERTEX, true}; - } -} - -void Mesh::calculateAttributeSizes() -{ - size_t stride = 0; - - for (const AttribFormat &format : vertexFormat) - { - // Hardware really doesn't like attributes that aren't 32 bit-aligned. - if (format.type == DATA_BYTE && format.components != 4) - throw love::Exception("byte vertex attributes must have 4 components."); - - if (format.components <= 0 || format.components > 4) - throw love::Exception("Vertex attributes must have between 1 and 4 components."); - - // Total size in bytes of each attribute in a single vertex. - attributeSizes.push_back(getAttribFormatSize(format)); - stride += attributeSizes.back(); - } - - vertexStride = stride; -} - -size_t Mesh::getAttributeOffset(size_t attribindex) const -{ - size_t offset = 0; - - for (size_t i = 0; i < attribindex; i++) - offset += attributeSizes[i]; - - return offset; -} - -void Mesh::setVertex(size_t vertindex, const void *data, size_t datasize) -{ - if (vertindex >= vertexCount) - throw love::Exception("Invalid vertex index: %ld", vertindex + 1); - - size_t offset = vertindex * vertexStride; - size_t size = std::min(datasize, vertexStride); - - uint8 *bufferdata = (uint8 *) vbo->map(); - memcpy(bufferdata + offset, data, size); - - vbo->setMappedRangeModified(offset, size); -} - -size_t Mesh::getVertex(size_t vertindex, void *data, size_t datasize) -{ - if (vertindex >= vertexCount) - throw love::Exception("Invalid vertex index: %ld", vertindex + 1); - - size_t offset = vertindex * vertexStride; - size_t size = std::min(datasize, vertexStride); - - // We're relying on vbo->map() returning read/write data... ew. - const uint8 *bufferdata = (const uint8 *) vbo->map(); - memcpy(data, bufferdata + offset, size); - - return size; -} - -void *Mesh::getVertexScratchBuffer() -{ - return vertexScratchBuffer; -} - -void Mesh::setVertexAttribute(size_t vertindex, int attribindex, const void *data, size_t datasize) -{ - if (vertindex >= vertexCount) - throw love::Exception("Invalid vertex index: %ld", vertindex + 1); - - if (attribindex >= (int) vertexFormat.size()) - throw love::Exception("Invalid vertex attribute index: %d", attribindex + 1); - - size_t offset = vertindex * vertexStride + getAttributeOffset(attribindex); - size_t size = std::min(datasize, attributeSizes[attribindex]); - - uint8 *bufferdata = (uint8 *) vbo->map(); - memcpy(bufferdata + offset, data, size); - - vbo->setMappedRangeModified(offset, size); -} - -size_t Mesh::getVertexAttribute(size_t vertindex, int attribindex, void *data, size_t datasize) -{ - if (vertindex >= vertexCount) - throw love::Exception("Invalid vertex index: %ld", vertindex + 1); - - if (attribindex >= (int) vertexFormat.size()) - throw love::Exception("Invalid vertex attribute index: %d", attribindex + 1); - - size_t offset = vertindex * vertexStride + getAttributeOffset(attribindex); - size_t size = std::min(datasize, attributeSizes[attribindex]); - - // We're relying on vbo->map() returning read/write data... ew. - const uint8 *bufferdata = (const uint8 *) vbo->map(); - memcpy(data, bufferdata + offset, size); - - return size; -} - -size_t Mesh::getVertexCount() const -{ - return vertexCount; -} - -size_t Mesh::getVertexStride() const -{ - return vertexStride; -} - -const std::vector &Mesh::getVertexFormat() const -{ - return vertexFormat; -} - -Mesh::DataType Mesh::getAttributeInfo(int attribindex, int &components) const -{ - if (attribindex < 0 || attribindex >= (int) vertexFormat.size()) - throw love::Exception("Invalid vertex attribute index: %d", attribindex + 1); - - DataType type = vertexFormat[attribindex].type; - components = vertexFormat[attribindex].components; - - return type; -} - -int Mesh::getAttributeIndex(const std::string &name) const -{ - for (int i = 0; i < (int) vertexFormat.size(); i++) - { - if (vertexFormat[i].name == name) - return i; - } - - return -1; -} - -void Mesh::setAttributeEnabled(const std::string &name, bool enable) -{ - auto it = attachedAttributes.find(name); - - if (it == attachedAttributes.end()) - throw love::Exception("Mesh does not have an attached vertex attribute named '%s'", name.c_str()); - - it->second.enabled = enable; -} - -bool Mesh::isAttributeEnabled(const std::string &name) const -{ - const auto it = attachedAttributes.find(name); - - if (it == attachedAttributes.end()) - throw love::Exception("Mesh does not have an attached vertex attribute named '%s'", name.c_str()); - - return it->second.enabled; -} - -void Mesh::attachAttribute(const std::string &name, Mesh *mesh, const std::string &attachname, AttributeStep step) -{ - if (step == STEP_PER_INSTANCE && !gl.isInstancingSupported()) - throw love::Exception("Vertex attribute instancing is not supported on this system."); - - if (mesh != this) - { - for (const auto &it : mesh->attachedAttributes) - { - // If the supplied Mesh has attached attributes of its own, then we - // prevent it from being attached to avoid reference cycles. - if (it.second.mesh != mesh) - throw love::Exception("Cannot attach a Mesh which has attached Meshes of its own."); - } - } - - AttachedAttribute oldattrib = {}; - AttachedAttribute newattrib = {}; - - auto it = attachedAttributes.find(name); - if (it != attachedAttributes.end()) - oldattrib = it->second; - - newattrib.mesh = mesh; - newattrib.enabled = oldattrib.mesh ? oldattrib.enabled : true; - newattrib.index = mesh->getAttributeIndex(attachname); - newattrib.step = step; - - if (newattrib.index < 0) - throw love::Exception("The specified mesh does not have a vertex attribute named '%s'", attachname.c_str()); - - if (newattrib.mesh != this) - newattrib.mesh->retain(); - - attachedAttributes[name] = newattrib; - - if (oldattrib.mesh && oldattrib.mesh != this) - oldattrib.mesh->release(); -} - -bool Mesh::detachAttribute(const std::string &name) -{ - auto it = attachedAttributes.find(name); - - if (it != attachedAttributes.end() && it->second.mesh != this) - { - it->second.mesh->release(); - attachedAttributes.erase(it); - - if (getAttributeIndex(name) != -1) - attachAttribute(name, this, name); - - return true; - } - - return false; -} - -void *Mesh::mapVertexData() -{ - return vbo->map(); -} - -void Mesh::unmapVertexData(size_t modifiedoffset, size_t modifiedsize) -{ - vbo->setMappedRangeModified(modifiedoffset, modifiedsize); - vbo->unmap(); -} - -void Mesh::flush() -{ - vbo->unmap(); - - if (ibo != nullptr) - ibo->unmap(); -} - -/** - * Copies index data from a vector to a mapped index buffer. - **/ -template -static void copyToIndexBuffer(const std::vector &indices, Buffer::Mapper &buffermap, size_t maxval) -{ - T *elems = (T *) buffermap.get(); - - for (size_t i = 0; i < indices.size(); i++) - { - if (indices[i] >= maxval) - throw love::Exception("Invalid vertex map value: %d", indices[i] + 1); - - elems[i] = (T) indices[i]; - } -} - -void Mesh::setVertexMap(const std::vector &map) -{ - size_t maxval = getVertexCount(); - - IndexDataType datatype = vertex::getIndexDataTypeFromMax(maxval); - - // Calculate the size in bytes of the index buffer data. - size_t size = map.size() * vertex::getIndexDataSize(datatype); - - if (ibo && size > ibo->getSize()) - { - delete ibo; - ibo = nullptr; - } - - if (!ibo && size > 0) - { - auto gfx = Module::getInstance(Module::M_GRAPHICS); - ibo = gfx->newBuffer(size, nullptr, BUFFER_INDEX, vbo->getUsage(), Buffer::MAP_READ); - } - - useIndexBuffer = true; - elementCount = map.size(); - - if (!ibo || elementCount == 0) - return; - - Buffer::Mapper ibomap(*ibo); - - // Fill the buffer with the index values from the vector. - switch (datatype) - { - case INDEX_UINT16: - copyToIndexBuffer(map, ibomap, maxval); - break; - case INDEX_UINT32: - default: - copyToIndexBuffer(map, ibomap, maxval); - break; - } - - elementDataType = datatype; -} - -void Mesh::setVertexMap(IndexDataType datatype, const void *data, size_t datasize) -{ - if (ibo && datasize > ibo->getSize()) - { - delete ibo; - ibo = nullptr; - } - - if (!ibo && datasize > 0) - { - auto gfx = Module::getInstance(Module::M_GRAPHICS); - ibo = gfx->newBuffer(datasize, nullptr, BUFFER_INDEX, vbo->getUsage(), Buffer::MAP_READ); - } - - elementCount = datasize / vertex::getIndexDataSize(datatype); - - if (!ibo || elementCount == 0) - return; - - Buffer::Mapper ibomap(*ibo); - memcpy(ibomap.get(), data, datasize); - - useIndexBuffer = true; - elementDataType = datatype; -} - -void Mesh::setVertexMap() -{ - useIndexBuffer = false; -} - -/** - * Copies index data from a mapped buffer to a vector. - **/ -template -static void copyFromIndexBuffer(void *buffer, size_t count, std::vector &indices) -{ - T *elems = (T *) buffer; - for (size_t i = 0; i < count; i++) - indices.push_back((uint32) elems[i]); -} - -bool Mesh::getVertexMap(std::vector &map) const -{ - if (!useIndexBuffer) - return false; - - map.clear(); - map.reserve(elementCount); - - if (!ibo || elementCount == 0) - return true; - - // We unmap the buffer in Mesh::draw, Mesh::setVertexMap, and Mesh::flush. - void *buffer = ibo->map(); - - // Fill the vector from the buffer. - switch (elementDataType) - { - case INDEX_UINT16: - copyFromIndexBuffer(buffer, elementCount, map); - break; - case INDEX_UINT32: - default: - copyFromIndexBuffer(buffer, elementCount, map); - break; - } - - return true; -} - -size_t Mesh::getVertexMapCount() const -{ - return elementCount; -} - -void Mesh::setTexture(Texture *tex) -{ - texture.set(tex); -} - -void Mesh::setTexture() -{ - texture.set(nullptr); -} - -Texture *Mesh::getTexture() const -{ - return texture.get(); -} - -void Mesh::setDrawMode(DrawMode mode) -{ - drawMode = mode; -} - -Mesh::DrawMode Mesh::getDrawMode() const -{ - return drawMode; -} - -void Mesh::setDrawRange(int start, int count) -{ - if (start < 0 || count <= 0) - throw love::Exception("Invalid draw range."); - - rangeStart = start; - rangeCount = count; -} - -void Mesh::setDrawRange() -{ - rangeStart = rangeCount = -1; -} - -bool Mesh::getDrawRange(int &start, int &count) const -{ - if (rangeStart < 0 || rangeCount <= 0) - return false; - - start = rangeStart; - count = rangeCount; - return true; } int Mesh::bindAttributeToShaderInput(int attributeindex, const std::string &inputname) @@ -627,7 +111,7 @@ void Mesh::drawInstanced(love::graphics::Graphics *gfx, const love::Matrix4 &m, if (!attrib.second.enabled) continue; - Mesh *mesh = attrib.second.mesh; + love::graphics::Mesh *mesh = attrib.second.mesh; int location = mesh->bindAttributeToShaderInput(attrib.second.index, attrib.first); if (location >= 0) @@ -692,24 +176,6 @@ void Mesh::drawInstanced(love::graphics::Graphics *gfx, const love::Matrix4 &m, } } -void Mesh::draw(love::graphics::Graphics *gfx, const love::Matrix4 &m) -{ - drawInstanced(gfx, m, 1); -} - -size_t Mesh::getAttribFormatSize(const AttribFormat &format) -{ - switch (format.type) - { - case DATA_BYTE: - return format.components * sizeof(uint8); - case DATA_FLOAT: - return format.components * sizeof(float); - default: - return 0; - } -} - GLenum Mesh::getGLDrawMode(DrawMode mode) { switch (mode) @@ -739,62 +205,6 @@ GLenum Mesh::getGLDataType(DataType type) } } -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); -} - -bool Mesh::getConstant(const char *in, DataType &out) -{ - return dataTypes.find(in, out); -} - -bool Mesh::getConstant(DataType in, const char *&out) -{ - return dataTypes.find(in, out); -} - -bool Mesh::getConstant(const char *in, AttributeStep &out) -{ - return attributeSteps.find(in, out); -} - -bool Mesh::getConstant(AttributeStep in, const char *&out) -{ - return attributeSteps.find(in, out); -} - -StringMap::Entry Mesh::drawModeEntries[] = -{ - { "fan", DRAWMODE_FAN }, - { "strip", DRAWMODE_STRIP }, - { "triangles", DRAWMODE_TRIANGLES }, - { "points", DRAWMODE_POINTS }, -}; - -StringMap Mesh::drawModes(Mesh::drawModeEntries, sizeof(Mesh::drawModeEntries)); - -StringMap::Entry Mesh::dataTypeEntries[] = -{ - { "byte", DATA_BYTE }, - { "float", DATA_FLOAT }, -}; - -StringMap Mesh::dataTypes(Mesh::dataTypeEntries, sizeof(Mesh::dataTypeEntries)); - -StringMap::Entry Mesh::attributeStepEntries[] = -{ - { "pervertex", STEP_PER_VERTEX }, - { "perinstance", STEP_PER_INSTANCE }, -}; - -StringMap Mesh::attributeSteps(Mesh::attributeStepEntries, sizeof(Mesh::attributeStepEntries)); - } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/Mesh.h b/src/modules/graphics/opengl/Mesh.h index 15e425105..89934d37f 100644 --- a/src/modules/graphics/opengl/Mesh.h +++ b/src/modules/graphics/opengl/Mesh.h @@ -18,78 +18,23 @@ * 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 +#pragma once // LOVE -#include "common/config.h" -#include "common/int.h" -#include "common/math.h" -#include "common/StringMap.h" -#include "graphics/Drawable.h" -#include "graphics/Texture.h" -#include "graphics/vertex.h" -#include "graphics/Buffer.h" +#include "graphics/Mesh.h" #include "OpenGL.h" -// C++ -#include -#include - namespace love { namespace graphics { - -class Graphics; - namespace opengl { -/** - * Holds and draws arbitrary vertex geometry. - * Each vertex in the Mesh has a collection of vertex attributes specified on - * creation. - **/ -class Mesh : public Drawable +class Mesh : public love::graphics::Mesh { public: - static love::Type type; - - // How the Mesh's vertices are used when drawing. - // http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png - enum DrawMode - { - DRAWMODE_FAN, - DRAWMODE_STRIP, - DRAWMODE_TRIANGLES, - DRAWMODE_POINTS, - DRAWMODE_MAX_ENUM - }; - - // The type of data a vertex attribute can store. - enum DataType - { - DATA_BYTE, - DATA_FLOAT, - DATA_MAX_ENUM - }; - - enum AttributeStep - { - STEP_PER_VERTEX, - STEP_PER_INSTANCE, - STEP_MAX_ENUM - }; - - struct AttribFormat - { - std::string name; - DataType type; - int components; // max 4 - }; - Mesh(graphics::Graphics *gfx, const std::vector &vertexformat, const void *data, size_t datasize, DrawMode drawmode, vertex::Usage usage); Mesh(graphics::Graphics *gfx, const std::vector &vertexformat, int vertexcount, DrawMode drawmode, vertex::Usage usage); @@ -98,184 +43,16 @@ public: virtual ~Mesh(); - /** - * Sets the values of all attributes at a specific vertex index in the Mesh. - * The size of the data must be less than or equal to the total size of all - * vertex attributes. - **/ - void setVertex(size_t vertindex, const void *data, size_t datasize); - size_t getVertex(size_t vertindex, void *data, size_t datasize); - void *getVertexScratchBuffer(); - - /** - * Sets the values for a single attribute at a specific vertex index in the - * Mesh. The size of the data must be less than or equal to the size of the - * attribute. - **/ - void setVertexAttribute(size_t vertindex, int attribindex, const void *data, size_t datasize); - size_t getVertexAttribute(size_t vertindex, int attribindex, void *data, size_t datasize); - - /** - * Gets the total number of vertices that can be used when drawing the Mesh. - **/ - size_t getVertexCount() const; - - /** - * Gets the size in bytes of the start of one vertex to the start of the - * next, in the buffer. - **/ - size_t getVertexStride() const; - - /** - * Gets the format of each vertex attribute stored in the Mesh. - **/ - const std::vector &getVertexFormat() const; - DataType getAttributeInfo(int attribindex, int &components) const; - int getAttributeIndex(const std::string &name) const; - - /** - * Sets whether a specific vertex attribute is used when drawing the Mesh. - **/ - void setAttributeEnabled(const std::string &name, bool enable); - bool isAttributeEnabled(const std::string &name) const; - - /** - * Attaches a vertex attribute from another Mesh to this one. The attribute - * will be used when drawing this Mesh. - **/ - void attachAttribute(const std::string &name, Mesh *mesh, const std::string &attachname, AttributeStep step = STEP_PER_VERTEX); - bool detachAttribute(const std::string &name); - - void *mapVertexData(); - void unmapVertexData(size_t modifiedoffset = 0, size_t modifiedsize = -1); - - /** - * Flushes all modified data to the GPU. - **/ - void flush(); - - /** - * 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 &map); - void setVertexMap(IndexDataType datatype, const void *data, size_t datasize); - void setVertexMap(); - - /** - * Fills the uint32 vector passed into the method with the previously set - * vertex map (index buffer) values. - **/ - bool getVertexMap(std::vector &map) const; - - /** - * Gets the total number of elements in the vertex map array. - **/ - size_t getVertexMapCount() const; - - /** - * Sets the texture used when drawing the Mesh. - **/ - void setTexture(Texture *texture); - - /** - * Disables any texture from being used when drawing the Mesh. - **/ - void setTexture(); - - /** - * Gets the texture used when drawing the Mesh. May return null if no - * texture is set. - **/ - Texture *getTexture() const; - - /** - * Sets the draw mode used when drawing the Mesh. - **/ - void setDrawMode(DrawMode mode); - DrawMode getDrawMode() const; - - void setDrawRange(int start, int count); - void setDrawRange(); - bool getDrawRange(int &start, int &count) const; - - int bindAttributeToShaderInput(int attributeindex, const std::string &inputname); - - void drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount); - - // Implements Drawable. - void draw(Graphics *gfx, const Matrix4 &m) override; - - static bool getConstant(const char *in, DrawMode &out); - static bool getConstant(DrawMode in, const char *&out); - - static bool getConstant(const char *in, DataType &out); - static bool getConstant(DataType in, const char *&out); - - static bool getConstant(const char *in, AttributeStep &out); - static bool getConstant(AttributeStep in, const char *&out); + int bindAttributeToShaderInput(int attributeindex, const std::string &inputname) override; + void drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount) override; private: - struct AttachedAttribute - { - Mesh *mesh; - int index; - AttributeStep step; - bool enabled; - }; - - void setupAttachedAttributes(); - void calculateAttributeSizes(); - size_t getAttributeOffset(size_t attribindex) const; - - static size_t getAttribFormatSize(const AttribFormat &format); - static GLenum getGLDrawMode(DrawMode mode); static GLenum getGLDataType(DataType type); - std::vector vertexFormat; - std::vector attributeSizes; - - std::unordered_map attachedAttributes; - - // Vertex buffer, for the vertex data. - Buffer *vbo; - size_t vertexCount; - size_t vertexStride; - - // Block of memory whose size is at least as large as a single vertex. Helps - // avoid memory allocations when using Mesh::setVertex etc. - char *vertexScratchBuffer; - - // Element (vertex index) buffer, for the vertex map. - Buffer *ibo; - bool useIndexBuffer; - size_t elementCount; - IndexDataType elementDataType; - - DrawMode drawMode; - - int rangeStart; - int rangeCount; - - StrongRef texture; - - static StringMap::Entry drawModeEntries[]; - static StringMap drawModes; - - static StringMap::Entry dataTypeEntries[]; - static StringMap dataTypes; - - static StringMap::Entry attributeStepEntries[]; - static StringMap attributeSteps; - }; // Mesh } // opengl } // graphics } // love - -#endif // LOVE_GRAPHICS_OPENGL_MESH_H diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp index 6dc503d6c..ef0cc203f 100644 --- a/src/modules/graphics/opengl/SpriteBatch.cpp +++ b/src/modules/graphics/opengl/SpriteBatch.cpp @@ -25,6 +25,7 @@ #include "OpenGL.h" // LOVE +#include "graphics/Buffer.h" #include "graphics/Texture.h" #include "graphics/Graphics.h" @@ -41,199 +42,13 @@ namespace graphics namespace opengl { -love::Type SpriteBatch::type("SpriteBatch", &Drawable::type); - SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, vertex::Usage usage) - : texture(texture) - , size(size) - , next(0) - , color(0) - , array_buf(nullptr) - , quad_indices(gfx, size) - , range_start(-1) - , range_count(-1) + : love::graphics::SpriteBatch(gfx, texture, size, usage) { - if (size <= 0) - throw love::Exception("Invalid SpriteBatch size."); - - size_t vertex_size = sizeof(Vertex) * 4 * size; - - array_buf = gfx->newBuffer(vertex_size, nullptr, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY); } SpriteBatch::~SpriteBatch() { - delete color; - delete array_buf; -} - -int SpriteBatch::add(const Matrix4 &m, int index /*= -1*/) -{ - if (index < -1 || index >= size) - throw love::Exception("Invalid sprite index: %d", index + 1); - - if (index == -1 && next >= size) - setBufferSize(size * 2); - - addv(texture->getVertices(), m, (index == -1) ? next : index); - - // Increment counter. - if (index == -1) - return next++; - - return index; -} - -int SpriteBatch::addq(Quad *quad, const Matrix4 &m, int index /*= -1*/) -{ - if (index < -1 || index >= size) - throw love::Exception("Invalid sprite index: %d", index + 1); - - if (index == -1 && next >= size) - setBufferSize(size * 2); - - addv(quad->getVertices(), m, (index == -1) ? next : index); - - // Increment counter. - if (index == -1) - return next++; - - return index; -} - -void SpriteBatch::clear() -{ - // Reset the position of the next index. - next = 0; -} - -void SpriteBatch::flush() -{ - array_buf->unmap(); -} - -void SpriteBatch::setTexture(Texture *newtexture) -{ - texture.set(newtexture); -} - -Texture *SpriteBatch::getTexture() const -{ - return texture.get(); -} - -void SpriteBatch::setColor(const Color &color) -{ - if (!this->color) - this->color = new Color(color); - else - *(this->color) = color; -} - -void SpriteBatch::setColor() -{ - delete color; - color = nullptr; -} - -const Color *SpriteBatch::getColor() const -{ - return color; -} - -int SpriteBatch::getCount() const -{ - return next; -} - -void SpriteBatch::setBufferSize(int newsize) -{ - if (newsize <= 0) - throw love::Exception("Invalid SpriteBatch size."); - - if (newsize == size) - return; - - size_t vertex_size = sizeof(Vertex) * 4 * newsize; - love::graphics::Buffer *new_array_buf = nullptr; - - int new_next = std::min(next, newsize); - - try - { - auto gfx = Module::getInstance(Module::M_GRAPHICS); - new_array_buf = gfx->newBuffer(vertex_size, nullptr, array_buf->getType(), array_buf->getUsage(), array_buf->getMapFlags()); - - // Copy as much of the old data into the new GLBuffer as can fit. - size_t copy_size = sizeof(Vertex) * 4 * new_next; - array_buf->copyTo(0, copy_size, new_array_buf, 0); - - quad_indices = QuadIndices(gfx, newsize); - } - catch (love::Exception &) - { - delete new_array_buf; - throw; - } - - // We don't need to unmap the old GLBuffer since we're deleting it. - delete array_buf; - - array_buf = new_array_buf; - size = newsize; - - next = new_next; -} - -int SpriteBatch::getBufferSize() const -{ - return size; -} - -void SpriteBatch::attachAttribute(const std::string &name, Mesh *mesh) -{ - AttachedAttribute oldattrib = {}; - AttachedAttribute newattrib = {}; - - if (mesh->getVertexCount() < (size_t) next * 4) - throw love::Exception("Mesh has too few vertices to be attached to this SpriteBatch (at least %d vertices are required)", next*4); - - auto it = attached_attributes.find(name); - if (it != attached_attributes.end()) - oldattrib = it->second; - - newattrib.index = mesh->getAttributeIndex(name); - - if (newattrib.index < 0) - throw love::Exception("The specified mesh does not have a vertex attribute named '%s'", name.c_str()); - - newattrib.mesh = mesh; - - attached_attributes[name] = newattrib; -} - -void SpriteBatch::setDrawRange(int start, int count) -{ - if (start < 0 || count <= 0) - throw love::Exception("Invalid draw range."); - - range_start = start; - range_count = count; -} - -void SpriteBatch::setDrawRange() -{ - range_start = range_count = -1; -} - -bool SpriteBatch::getDrawRange(int &start, int &count) const -{ - if (range_start < 0 || range_count <= 0) - return false; - - start = range_start; - count = range_count; - return true; } void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m) @@ -308,27 +123,6 @@ void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m) } } -void SpriteBatch::addv(const Vertex *v, const Matrix4 &m, int index) -{ - // Needed for colors. - Vertex sprite[4] = {v[0], v[1], v[2], v[3]}; - const size_t sprite_size = 4 * sizeof(Vertex); // bytecount - - m.transform(sprite, sprite, 4); - - if (color != nullptr) - { - for (int i = 0; i < 4; i++) - sprite[i].color = *color; - } - - // Always keep the VBO mapped when adding data for now (it'll be unmapped - // on draw.) - array_buf->map(); - - array_buf->fill(index * sprite_size, sprite_size, sprite); -} - } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/SpriteBatch.h b/src/modules/graphics/opengl/SpriteBatch.h index 81c0f640f..cab204a25 100644 --- a/src/modules/graphics/opengl/SpriteBatch.h +++ b/src/modules/graphics/opengl/SpriteBatch.h @@ -18,139 +18,30 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_GRAPHICS_OPENGL_SPRITE_BATCH_H -#define LOVE_GRAPHICS_OPENGL_SPRITE_BATCH_H - -// C -#include - -// C++ -#include +#pragma once // LOVE -#include "common/math.h" -#include "common/Matrix.h" -#include "graphics/Drawable.h" -#include "graphics/Volatile.h" -#include "graphics/Color.h" -#include "graphics/Quad.h" -#include "graphics/Buffer.h" -#include "Mesh.h" +#include "graphics/SpriteBatch.h" namespace love { namespace graphics { - -// Forward declarations. -class Texture; -class Graphics; - namespace opengl { -class SpriteBatch : public Drawable +class SpriteBatch : public love::graphics::SpriteBatch { public: - static love::Type type; - SpriteBatch(Graphics *gfx, Texture *texture, int size, vertex::Usage usage); virtual ~SpriteBatch(); - int add(const Matrix4 &m, int index = -1); - int addq(Quad *quad, const Matrix4 &m, int index = -1); - void clear(); - - void flush(); - - void setTexture(Texture *newtexture); - Texture *getTexture() const; - - /** - * 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 sprites. - */ - void setColor(const Color &color); - - /** - * Disable per-sprite colors for this SpriteBatch. The next call to - * draw will use the global color for all sprites. - */ - void setColor(); - - /** - * Get the current color for this SpriteBatch. Returns NULL if no color is - * set. - **/ - const Color *getColor() const; - - /** - * Get the number of sprites currently in this SpriteBatch. - **/ - int getCount() const; - - /** - * Get the total number of sprites this SpriteBatch can currently hold. - **/ - int getBufferSize() const; - - /** - * Attaches a specific vertex attribute from a Mesh to this SpriteBatch. - * The vertex attribute will be used when drawing the SpriteBatch. - **/ - void attachAttribute(const std::string &name, Mesh *mesh); - - void setDrawRange(int start, int count); - void setDrawRange(); - bool getDrawRange(int &start, int &count) const; - // Implements Drawable. void draw(Graphics *gfx, const Matrix4 &m) override; -private: - - struct AttachedAttribute - { - StrongRef mesh; - int index; - }; - - /** - * Sets the total number of sprites this SpriteBatch can hold. - * Leaves existing sprite data intact when possible. - **/ - void setBufferSize(int newsize); - - void addv(const Vertex *v, const Matrix4 &m, int index); - - StrongRef texture; - - // Max number of sprites in the batch. - int size; - - // The next free element. - int next; - - // Current color. This color, if present, will be applied to the next - // added sprite. - Color *color; - - love::graphics::Buffer *array_buf; - QuadIndices quad_indices; - - std::unordered_map attached_attributes; - - int range_start; - int range_count; - }; // SpriteBatch } // opengl } // graphics } // love - -#endif // LOVE_GRAPHICS_OPENGL_SPRITE_BATCH_H diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index fb93622ee..1ccc58f44 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -651,7 +651,7 @@ int w_newSpriteBatch(lua_State *L) return luaL_error(L, "Invalid usage hint: %s", usagestr); } - SpriteBatch *t = nullptr; + love::graphics::SpriteBatch *t = nullptr; luax_catchexcept(L, [&](){ t = instance()->newSpriteBatch(texture, size, usage); } ); @@ -667,7 +667,7 @@ int w_newParticleSystem(lua_State *L) Texture *texture = luax_checktexture(L, 1); lua_Number size = luaL_optnumber(L, 2, 1000); - ParticleSystem *t = 0; + love::graphics::ParticleSystem *t = nullptr; if (size < 1.0 || size > ParticleSystem::MAX_PARTICLES) return luaL_error(L, "Invalid ParticleSystem size"); @@ -882,9 +882,9 @@ static Mesh::DrawMode luax_optmeshdrawmode(lua_State *L, int idx, Mesh::DrawMode return def; } -static Mesh *newStandardMesh(lua_State *L) +static love::graphics::Mesh *newStandardMesh(lua_State *L) { - Mesh *t = nullptr; + love::graphics::Mesh *t = nullptr; Mesh::DrawMode drawmode = luax_optmeshdrawmode(L, 2, Mesh::DRAWMODE_FAN); vertex::Usage usage = luax_optmeshusage(L, 3, vertex::USAGE_DYNAMIC); @@ -938,9 +938,9 @@ static Mesh *newStandardMesh(lua_State *L) return t; } -static Mesh *newCustomMesh(lua_State *L) +static love::graphics::Mesh *newCustomMesh(lua_State *L) { - Mesh *t = nullptr; + love::graphics::Mesh *t = nullptr; // First argument is the vertex format, second is a table of vertices or // the number of vertices. @@ -1067,7 +1067,7 @@ int w_newMesh(lua_State *L) if (arg1type != LUA_TTABLE && arg1type != LUA_TNUMBER) luaL_argerror(L, 1, "table or number expected"); - Mesh *t = nullptr; + love::graphics::Mesh *t = nullptr; int arg2type = lua_type(L, 2); if (arg1type == LUA_TTABLE && (arg2type == LUA_TTABLE || arg2type == LUA_TNUMBER || arg2type == LUA_TUSERDATA)) @@ -1671,7 +1671,7 @@ int w_draw(lua_State *L) int w_drawInstanced(lua_State *L) { - Mesh *t = luax_checkmesh(L, 1); + love::graphics::Mesh *t = luax_checkmesh(L, 1); int instancecount = (int) luaL_checkinteger(L, 2); if (luax_istype(L, 3, math::Transform::type)) diff --git a/src/modules/graphics/opengl/wrap_Graphics.h b/src/modules/graphics/opengl/wrap_Graphics.h index 9cc8bfa90..6fa6ca2e5 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.h +++ b/src/modules/graphics/opengl/wrap_Graphics.h @@ -26,11 +26,11 @@ #include "graphics/wrap_Font.h" #include "graphics/wrap_Image.h" #include "graphics/wrap_Quad.h" -#include "wrap_SpriteBatch.h" -#include "wrap_ParticleSystem.h" +#include "graphics/wrap_SpriteBatch.h" +#include "graphics/wrap_ParticleSystem.h" #include "graphics/wrap_Canvas.h" #include "graphics/wrap_Shader.h" -#include "wrap_Mesh.h" +#include "graphics/wrap_Mesh.h" #include "graphics/wrap_Text.h" #include "graphics/wrap_Video.h" #include "Graphics.h" diff --git a/src/modules/graphics/opengl/wrap_Mesh.cpp b/src/modules/graphics/wrap_Mesh.cpp similarity index 99% rename from src/modules/graphics/opengl/wrap_Mesh.cpp rename to src/modules/graphics/wrap_Mesh.cpp index 2308341d5..f6122b394 100644 --- a/src/modules/graphics/opengl/wrap_Mesh.cpp +++ b/src/modules/graphics/wrap_Mesh.cpp @@ -22,18 +22,15 @@ #include "wrap_Mesh.h" #include "Image.h" #include "Canvas.h" -#include "graphics/wrap_Texture.h" +#include "wrap_Texture.h" // C++ -#include #include namespace love { namespace graphics { -namespace opengl -{ Mesh *luax_checkmesh(lua_State *L, int idx) { @@ -570,6 +567,5 @@ extern "C" int luaopen_mesh(lua_State *L) return luax_register_type(L, &Mesh::type, w_Mesh_functions, nullptr); } -} // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/wrap_Mesh.h b/src/modules/graphics/wrap_Mesh.h similarity index 89% rename from src/modules/graphics/opengl/wrap_Mesh.h rename to src/modules/graphics/wrap_Mesh.h index 64372b878..805defa3b 100644 --- a/src/modules/graphics/opengl/wrap_Mesh.h +++ b/src/modules/graphics/wrap_Mesh.h @@ -18,8 +18,7 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_GRAPHICS_OPENGL_WRAP_MESH_H -#define LOVE_GRAPHICS_OPENGL_WRAP_MESH_H +#pragma once // LOVE #include "common/config.h" @@ -30,8 +29,6 @@ namespace love { namespace graphics { -namespace opengl -{ char *luax_writeAttributeData(lua_State *L, int startidx, Mesh::DataType type, int components, char *data); const char *luax_readAttributeData(lua_State *L, Mesh::DataType type, int components, const char *data); @@ -39,8 +36,5 @@ const char *luax_readAttributeData(lua_State *L, Mesh::DataType type, int compon Mesh *luax_checkmesh(lua_State *L, int idx); extern "C" int luaopen_mesh(lua_State *L); -} // opengl } // graphics } // love - -#endif // LOVE_GRAPHICS_OPENGL_WRAP_MESH_H diff --git a/src/modules/graphics/opengl/wrap_ParticleSystem.cpp b/src/modules/graphics/wrap_ParticleSystem.cpp similarity index 99% rename from src/modules/graphics/opengl/wrap_ParticleSystem.cpp rename to src/modules/graphics/wrap_ParticleSystem.cpp index fcf5f0566..c2ec31839 100644 --- a/src/modules/graphics/opengl/wrap_ParticleSystem.cpp +++ b/src/modules/graphics/wrap_ParticleSystem.cpp @@ -24,7 +24,7 @@ #include "Image.h" #include "Canvas.h" -#include "graphics/wrap_Texture.h" +#include "wrap_Texture.h" // C #include @@ -33,8 +33,6 @@ namespace love { namespace graphics { -namespace opengl -{ ParticleSystem *luax_checkparticlesystem(lua_State *L, int idx) { @@ -772,6 +770,5 @@ extern "C" int luaopen_particlesystem(lua_State *L) return luax_register_type(L, &ParticleSystem::type, w_ParticleSystem_functions, nullptr); } -} // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/wrap_ParticleSystem.h b/src/modules/graphics/wrap_ParticleSystem.h similarity index 86% rename from src/modules/graphics/opengl/wrap_ParticleSystem.h rename to src/modules/graphics/wrap_ParticleSystem.h index 6a80d0187..dce04561e 100644 --- a/src/modules/graphics/opengl/wrap_ParticleSystem.h +++ b/src/modules/graphics/wrap_ParticleSystem.h @@ -18,8 +18,7 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_GRAPHICS_OPENGL_WRAP_PARTICLE_SYSTEM_H -#define LOVE_GRAPHICS_OPENGL_WRAP_PARTICLE_SYSTEM_H +#pragma once // LOVE #include "common/runtime.h" @@ -29,14 +28,9 @@ namespace love { namespace graphics { -namespace opengl -{ ParticleSystem *luax_checkparticlesystem(lua_State *L, int idx); extern "C" int luaopen_particlesystem(lua_State *L); -} // opengl } // graphics } // love - -#endif // LOVE_GRAPHICS_OPENGL_WRAP_PARTICLE_SYSTEM_H diff --git a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp b/src/modules/graphics/wrap_SpriteBatch.cpp similarity index 98% rename from src/modules/graphics/opengl/wrap_SpriteBatch.cpp rename to src/modules/graphics/wrap_SpriteBatch.cpp index 5d380ec3a..85c7bd0e7 100644 --- a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp +++ b/src/modules/graphics/wrap_SpriteBatch.cpp @@ -22,18 +22,13 @@ #include "wrap_SpriteBatch.h" #include "Image.h" #include "Canvas.h" -#include "graphics/wrap_Texture.h" +#include "wrap_Texture.h" #include "math/wrap_Transform.h" -// C++ -#include - namespace love { namespace graphics { -namespace opengl -{ SpriteBatch *luax_checkspritebatch(lua_State *L, int idx) { @@ -274,6 +269,5 @@ extern "C" int luaopen_spritebatch(lua_State *L) return luax_register_type(L, &SpriteBatch::type, w_SpriteBatch_functions, nullptr); } -} // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/wrap_SpriteBatch.h b/src/modules/graphics/wrap_SpriteBatch.h similarity index 86% rename from src/modules/graphics/opengl/wrap_SpriteBatch.h rename to src/modules/graphics/wrap_SpriteBatch.h index 7e292ca09..7e234104a 100644 --- a/src/modules/graphics/opengl/wrap_SpriteBatch.h +++ b/src/modules/graphics/wrap_SpriteBatch.h @@ -18,8 +18,7 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_GRAPHICS_OPENGL_WRAP_SPRITE_BATCH_H -#define LOVE_GRAPHICS_OPENGL_WRAP_SPRITE_BATCH_H +#pragma once #include "common/runtime.h" #include "SpriteBatch.h" @@ -28,14 +27,9 @@ namespace love { namespace graphics { -namespace opengl -{ SpriteBatch *luax_checkspritebatch(lua_State *L, int idx); extern "C" int luaopen_spritebatch(lua_State *L); -} // opengl } // graphics } // love - -#endif // LOVE_GRAPHICS_OPENGL_WRAP_SPRITE_BATCH_H