From 1e696c4505df36d68825d5a01624f5587d1becfe Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sat, 28 Sep 2013 18:26:47 -0300 Subject: [PATCH 1/5] Added Mesh objects and love.graphics.newMesh. Mesh objects are similar to Geometry but they're drawables (the relationship between meshes and images is the opposite of geometry and images.) Removed Geometry objects and re-added Quads. example: local vertices = {{0, 0, 0, 0}, {100, 0, 1, 0}, {100, 100, 1, 1}, {0, 100, 0, 1}} mesh = love.graphics.newMesh(vertices, image, "fan") .. love.graphics.draw(mesh, 0, 0) --HG-- branch : Mesh --- .../love-framework.xcodeproj/project.pbxproj | 60 ++-- src/common/runtime.cpp | 4 +- src/common/types.h | 14 +- .../graphics/{DrawGable.h => DrawQable.h} | 18 +- src/modules/graphics/Geometry.cpp | 197 ------------- src/modules/graphics/Geometry.h | 146 ---------- src/modules/graphics/Image.h | 4 +- src/modules/graphics/Quad.cpp | 114 ++++++++ src/modules/graphics/Quad.h | 69 +++++ src/modules/graphics/opengl/Canvas.cpp | 59 +--- src/modules/graphics/opengl/Canvas.h | 10 +- src/modules/graphics/opengl/Font.cpp | 1 - src/modules/graphics/opengl/Graphics.cpp | 14 +- src/modules/graphics/opengl/Graphics.h | 15 +- src/modules/graphics/opengl/Image.cpp | 77 ++--- src/modules/graphics/opengl/Image.h | 7 +- src/modules/graphics/opengl/Mesh.cpp | 213 ++++++++++++++ src/modules/graphics/opengl/Mesh.h | 149 ++++++++++ src/modules/graphics/opengl/SpriteBatch.cpp | 32 +-- src/modules/graphics/opengl/SpriteBatch.h | 12 +- src/modules/graphics/opengl/wrap_Geometry.cpp | 214 -------------- src/modules/graphics/opengl/wrap_Graphics.cpp | 236 ++++++---------- src/modules/graphics/opengl/wrap_Graphics.h | 6 +- src/modules/graphics/opengl/wrap_Mesh.cpp | 263 ++++++++++++++++++ .../opengl/{wrap_Geometry.h => wrap_Mesh.h} | 32 ++- src/modules/graphics/opengl/wrap_Quad.cpp | 91 ++++++ .../{DrawGable.cpp => opengl/wrap_Quad.h} | 20 +- .../graphics/opengl/wrap_SpriteBatch.cpp | 20 +- 28 files changed, 1141 insertions(+), 956 deletions(-) rename src/modules/graphics/{DrawGable.h => DrawQable.h} (77%) delete mode 100644 src/modules/graphics/Geometry.cpp delete mode 100644 src/modules/graphics/Geometry.h create mode 100644 src/modules/graphics/Quad.cpp create mode 100644 src/modules/graphics/Quad.h create mode 100644 src/modules/graphics/opengl/Mesh.cpp create mode 100644 src/modules/graphics/opengl/Mesh.h delete mode 100644 src/modules/graphics/opengl/wrap_Geometry.cpp create mode 100644 src/modules/graphics/opengl/wrap_Mesh.cpp rename src/modules/graphics/opengl/{wrap_Geometry.h => wrap_Mesh.h} (63%) create mode 100644 src/modules/graphics/opengl/wrap_Quad.cpp rename src/modules/graphics/{DrawGable.cpp => opengl/wrap_Quad.h} (70%) diff --git a/platform/macosx/love-framework.xcodeproj/project.pbxproj b/platform/macosx/love-framework.xcodeproj/project.pbxproj index 5f71882ed..d41f933b1 100644 --- a/platform/macosx/love-framework.xcodeproj/project.pbxproj +++ b/platform/macosx/love-framework.xcodeproj/project.pbxproj @@ -259,6 +259,8 @@ FA636D8E171B72A70065623F /* wrap_RandomGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */; }; FA636D8F171B72A70065623F /* wrap_RandomGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FA636D8D171B72A70065623F /* wrap_RandomGenerator.h */; }; FA7175AA178E8418001FE7FE /* lua.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7175A9178E8418001FE7FE /* lua.h */; }; + FA7AA59217F6AC1F00704BE2 /* wrap_Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */; }; + FA7AA59317F6AC1F00704BE2 /* wrap_Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */; }; FA7C937A16DCC6C2006F2BEE /* wrap_Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */; }; FA7C937B16DCC6C2006F2BEE /* wrap_Math.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7C937616DCC6C2006F2BEE /* wrap_Math.h */; }; FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; }; @@ -277,12 +279,11 @@ FAC5710117402D1100D147E4 /* BezierCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC570FD17402D1100D147E4 /* BezierCurve.h */; }; FAC5710217402D1100D147E4 /* wrap_BezierCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */; }; FAC5710317402D1100D147E4 /* wrap_BezierCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC570FF17402D1100D147E4 /* wrap_BezierCurve.h */; }; - FAC86E631724552C00EED715 /* wrap_Geometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E611724552C00EED715 /* wrap_Geometry.cpp */; }; - FAC86E641724552C00EED715 /* wrap_Geometry.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E621724552C00EED715 /* wrap_Geometry.h */; }; - FAC86E691724555D00EED715 /* DrawGable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E651724555D00EED715 /* DrawGable.cpp */; }; - FAC86E6A1724555D00EED715 /* DrawGable.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E661724555D00EED715 /* DrawGable.h */; }; - FAC86E6B1724555D00EED715 /* Geometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E671724555D00EED715 /* Geometry.cpp */; }; - FAC86E6C1724555D00EED715 /* Geometry.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E681724555D00EED715 /* Geometry.h */; }; + FAC86E631724552C00EED715 /* wrap_Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E611724552C00EED715 /* wrap_Quad.cpp */; }; + FAC86E641724552C00EED715 /* wrap_Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E621724552C00EED715 /* wrap_Quad.h */; }; + FAC86E6A1724555D00EED715 /* DrawQable.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E661724555D00EED715 /* DrawQable.h */; }; + FAC86E6B1724555D00EED715 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC86E671724555D00EED715 /* Quad.cpp */; }; + FAC86E6C1724555D00EED715 /* Quad.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC86E681724555D00EED715 /* Quad.h */; }; FAE010DB170DDE99006F29D0 /* ddsinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010D8170DDE99006F29D0 /* ddsinfo.h */; }; FAE010DC170DDE99006F29D0 /* ddsparse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE010D9170DDE99006F29D0 /* ddsparse.cpp */; }; FAE010DD170DDE99006F29D0 /* ddsparse.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE010DA170DDE99006F29D0 /* ddsparse.h */; }; @@ -310,6 +311,8 @@ FAF272B616E3D46400CC193A /* Thread.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272B216E3D46400CC193A /* Thread.h */; }; FAF272B716E3D46400CC193A /* threads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF272B316E3D46400CC193A /* threads.cpp */; }; FAF272B816E3D46400CC193A /* threads.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF272B416E3D46400CC193A /* threads.h */; }; + FAF4376F17F4AC530074F9E2 /* Mesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF4376D17F4AC530074F9E2 /* Mesh.cpp */; }; + FAF4377017F4AC530074F9E2 /* Mesh.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF4376E17F4AC530074F9E2 /* Mesh.h */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -798,6 +801,8 @@ FA636D8C171B72A70065623F /* wrap_RandomGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_RandomGenerator.cpp; sourceTree = ""; }; FA636D8D171B72A70065623F /* wrap_RandomGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_RandomGenerator.h; sourceTree = ""; }; FA7175A9178E8418001FE7FE /* lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua.h; sourceTree = ""; }; + FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Mesh.cpp; sourceTree = ""; }; + FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Mesh.h; sourceTree = ""; }; FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Math.cpp; sourceTree = ""; }; FA7C937616DCC6C2006F2BEE /* wrap_Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Math.h; sourceTree = ""; }; FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; @@ -816,12 +821,11 @@ FAC570FD17402D1100D147E4 /* BezierCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BezierCurve.h; sourceTree = ""; }; FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_BezierCurve.cpp; sourceTree = ""; }; FAC570FF17402D1100D147E4 /* wrap_BezierCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_BezierCurve.h; sourceTree = ""; }; - FAC86E611724552C00EED715 /* wrap_Geometry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Geometry.cpp; sourceTree = ""; }; - FAC86E621724552C00EED715 /* wrap_Geometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Geometry.h; sourceTree = ""; }; - FAC86E651724555D00EED715 /* DrawGable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DrawGable.cpp; sourceTree = ""; }; - FAC86E661724555D00EED715 /* DrawGable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawGable.h; sourceTree = ""; }; - FAC86E671724555D00EED715 /* Geometry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Geometry.cpp; sourceTree = ""; }; - FAC86E681724555D00EED715 /* Geometry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Geometry.h; sourceTree = ""; }; + FAC86E611724552C00EED715 /* wrap_Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Quad.cpp; sourceTree = ""; }; + FAC86E621724552C00EED715 /* wrap_Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Quad.h; sourceTree = ""; }; + FAC86E661724555D00EED715 /* DrawQable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawQable.h; sourceTree = ""; }; + FAC86E671724555D00EED715 /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = ""; }; + FAC86E681724555D00EED715 /* Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = ""; }; FAE010D8170DDE99006F29D0 /* ddsinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsinfo.h; sourceTree = ""; }; FAE010D9170DDE99006F29D0 /* ddsparse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsparse.cpp; sourceTree = ""; }; FAE010DA170DDE99006F29D0 /* ddsparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsparse.h; sourceTree = ""; }; @@ -849,6 +853,8 @@ FAF272B216E3D46400CC193A /* Thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Thread.h; sourceTree = ""; }; FAF272B316E3D46400CC193A /* threads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = threads.cpp; sourceTree = ""; }; FAF272B416E3D46400CC193A /* threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = threads.h; sourceTree = ""; }; + FAF4376D17F4AC530074F9E2 /* Mesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mesh.cpp; sourceTree = ""; }; + FAF4376E17F4AC530074F9E2 /* Mesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mesh.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1437,15 +1443,14 @@ 4941079838020ECA049B5C21 /* Color.h */, 58BA2BB460AF3C591B22690E /* Drawable.cpp */, 5D93601669875EE06721689E /* Drawable.h */, - FAC86E651724555D00EED715 /* DrawGable.cpp */, - FAC86E661724555D00EED715 /* DrawGable.h */, - FAC86E671724555D00EED715 /* Geometry.cpp */, - FAC86E681724555D00EED715 /* Geometry.h */, + FAC86E661724555D00EED715 /* DrawQable.h */, 03F17FF546D637744E263961 /* Graphics.cpp */, 777352284E262F48543E6E7F /* Graphics.h */, 58CC50E70A375FDF53EF01B6 /* Image.cpp */, 1DA41DFF0869489411A71AFC /* Image.h */, 75093EE94918576801F50993 /* opengl */, + FAC86E671724555D00EED715 /* Quad.cpp */, + FAC86E681724555D00EED715 /* Quad.h */, 4B731754147B27AF73AC5358 /* Volatile.cpp */, 0CFF64090F0F4F481BB80CF0 /* Volatile.h */, ); @@ -1629,6 +1634,8 @@ 389E3CEC356050A27784290E /* Graphics.h */, 56D6030A0B8F7397715062B9 /* Image.cpp */, 3CFE5C4A12D5675E7C9C7BF9 /* Image.h */, + FAF4376D17F4AC530074F9E2 /* Mesh.cpp */, + FAF4376E17F4AC530074F9E2 /* Mesh.h */, 2E406F8328543EC63EB922C6 /* OpenGL.cpp */, 2C87695707B046B536F347D8 /* OpenGL.h */, 48A206C9004150640C432100 /* ParticleSystem.cpp */, @@ -1645,12 +1652,14 @@ 3AFB3A18384A2D22352262B1 /* wrap_Canvas.h */, 7A3B52AF1FBE73FC36AD50C8 /* wrap_Font.cpp */, 3CDA3E9B364F17A902384AAC /* wrap_Font.h */, - FAC86E611724552C00EED715 /* wrap_Geometry.cpp */, - FAC86E621724552C00EED715 /* wrap_Geometry.h */, + FAC86E611724552C00EED715 /* wrap_Quad.cpp */, + FAC86E621724552C00EED715 /* wrap_Quad.h */, 1A9810F758AC1D1E4B6431FD /* wrap_Graphics.cpp */, 05DF237B657042515F3B4E52 /* wrap_Graphics.h */, 14AE68E14C2C74526A612FA0 /* wrap_Image.cpp */, 78A2127828793F7A778D7932 /* wrap_Image.h */, + FA7AA59017F6AC1F00704BE2 /* wrap_Mesh.cpp */, + FA7AA59117F6AC1F00704BE2 /* wrap_Mesh.h */, 5F42052D7C8271A1105541DE /* wrap_ParticleSystem.cpp */, 678E42771C9B415628A3234D /* wrap_ParticleSystem.h */, FA577A8716C71CF000860150 /* wrap_Shader.cpp */, @@ -1896,6 +1905,7 @@ FA7C937B16DCC6C2006F2BEE /* wrap_Math.h in Headers */, FAF272A516E3D44400CC193A /* Channel.h in Headers */, FAF272A716E3D44400CC193A /* LuaThread.h in Headers */, + FAF4377017F4AC530074F9E2 /* Mesh.h in Headers */, FAF272A916E3D44400CC193A /* ThreadModule.h in Headers */, FAF272AB16E3D44400CC193A /* wrap_Channel.h in Headers */, FAF272AD16E3D44400CC193A /* wrap_LuaThread.h in Headers */, @@ -1909,13 +1919,14 @@ FAE010E1170DE25E006F29D0 /* ddsHandler.h in Headers */, FAE010E5170DF75C006F29D0 /* wrap_CompressedData.h in Headers */, FA0CDE3D1710F9A50056E8D7 /* FormatHandler.h in Headers */, + FA7AA59317F6AC1F00704BE2 /* wrap_Mesh.h in Headers */, FAEC808B1710FEA60057279A /* ImageData.h in Headers */, FAEC808F1711E76C0057279A /* CompressedData.h in Headers */, FA636D8B171B70920065623F /* RandomGenerator.h in Headers */, FA636D8F171B72A70065623F /* wrap_RandomGenerator.h in Headers */, - FAC86E641724552C00EED715 /* wrap_Geometry.h in Headers */, - FAC86E6A1724555D00EED715 /* DrawGable.h in Headers */, - FAC86E6C1724555D00EED715 /* Geometry.h in Headers */, + FAC86E641724552C00EED715 /* wrap_Quad.h in Headers */, + FAC86E6A1724555D00EED715 /* DrawQable.h in Headers */, + FAC86E6C1724555D00EED715 /* Quad.h in Headers */, FA03546D1731F3A700284828 /* simplexnoise1234.h in Headers */, FA3D9E0E16E68DE600CA6630 /* Cursor.h in Headers */, FA3D9E1216E68EAE00CA6630 /* Cursor.h in Headers */, @@ -2112,6 +2123,7 @@ FA08F61C16C7541400F007B5 /* Font.cpp in Sources */, FA08F61D16C7541400F007B5 /* GLee.c in Sources */, FA08F61E16C7541400F007B5 /* Graphics.cpp in Sources */, + FAF4376F17F4AC530074F9E2 /* Mesh.cpp in Sources */, FA08F61F16C7541400F007B5 /* Image.cpp in Sources */, FA08F62016C7541400F007B5 /* OpenGL.cpp in Sources */, FA08F62116C7541400F007B5 /* ParticleSystem.cpp in Sources */, @@ -2131,6 +2143,7 @@ FA08F63116C7542600F007B5 /* wrap_Image.cpp in Sources */, FA08F63216C7542600F007B5 /* wrap_ImageData.cpp in Sources */, FA08F63416C7542D00F007B5 /* JoystickModule.cpp in Sources */, + FA7AA59217F6AC1F00704BE2 /* wrap_Mesh.cpp in Sources */, FA08F63516C7542D00F007B5 /* wrap_JoystickModule.cpp in Sources */, FA08F63616C7543400F007B5 /* Keyboard.cpp in Sources */, FA08F63716C7543400F007B5 /* Keyboard.cpp in Sources */, @@ -2219,9 +2232,8 @@ FAEC808E1711E76C0057279A /* CompressedData.cpp in Sources */, FA636D8A171B70920065623F /* RandomGenerator.cpp in Sources */, FA636D8E171B72A70065623F /* wrap_RandomGenerator.cpp in Sources */, - FAC86E631724552C00EED715 /* wrap_Geometry.cpp in Sources */, - FAC86E691724555D00EED715 /* DrawGable.cpp in Sources */, - FAC86E6B1724555D00EED715 /* Geometry.cpp in Sources */, + FAC86E631724552C00EED715 /* wrap_Quad.cpp in Sources */, + FAC86E6B1724555D00EED715 /* Quad.cpp in Sources */, FA03546C1731F3A700284828 /* simplexnoise1234.cpp in Sources */, FA3D9E0D16E68DE600CA6630 /* Cursor.cpp in Sources */, FA3D9E1116E68EAE00CA6630 /* Cursor.cpp in Sources */, diff --git a/src/common/runtime.cpp b/src/common/runtime.cpp index 00ea9f687..bcb2e89f5 100644 --- a/src/common/runtime.cpp +++ b/src/common/runtime.cpp @@ -680,14 +680,14 @@ StringMap::Entry typeEntries[] = // Graphics {"Drawable", GRAPHICS_DRAWABLE_ID}, - {"DrawGable", GRAPHICS_DRAWGABLE_ID}, {"Image", GRAPHICS_IMAGE_ID}, - {"Geometry", GRAPHICS_GEOMETRY_ID}, + {"Quad", GRAPHICS_QUAD_ID}, {"Font", GRAPHICS_FONT_ID}, {"ParticleSystem", GRAPHICS_PARTICLE_SYSTEM_ID}, {"SpriteBatch", GRAPHICS_SPRITE_BATCH_ID}, {"Canvas", GRAPHICS_CANVAS_ID}, {"Shader", GRAPHICS_SHADER_ID}, + {"Mesh", GRAPHICS_MESH_ID}, // Image {"ImageData", IMAGE_IMAGE_DATA_ID}, diff --git a/src/common/types.h b/src/common/types.h index 3e4804c22..c6f56f6e4 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -45,14 +45,15 @@ enum Type // Graphics GRAPHICS_DRAWABLE_ID, - GRAPHICS_DRAWGABLE_ID, + GRAPHICS_DRAWQABLE_ID, GRAPHICS_IMAGE_ID, - GRAPHICS_GEOMETRY_ID, + GRAPHICS_QUAD_ID, GRAPHICS_FONT_ID, GRAPHICS_PARTICLE_SYSTEM_ID, GRAPHICS_SPRITE_BATCH_ID, GRAPHICS_CANVAS_ID, GRAPHICS_SHADER_ID, + GRAPHICS_MESH_ID, // Image IMAGE_IMAGE_DATA_ID, @@ -128,14 +129,15 @@ const bits FONT_RASTERIZER_T = (bits(1) << FONT_RASTERIZER_ID) | OBJECT_T; // Graphics. const bits GRAPHICS_DRAWABLE_T = (bits(1) << GRAPHICS_DRAWABLE_ID) | OBJECT_T; -const bits GRAPHICS_DRAWGABLE_T = (bits(1) << GRAPHICS_DRAWGABLE_ID) | GRAPHICS_DRAWABLE_T; -const bits GRAPHICS_IMAGE_T = (bits(1) << GRAPHICS_IMAGE_ID) | GRAPHICS_DRAWGABLE_T; -const bits GRAPHICS_GEOMETRY_T = (bits(1) << GRAPHICS_GEOMETRY_ID) | OBJECT_T; +const bits GRAPHICS_DRAWQABLE_T = (bits(1) << GRAPHICS_DRAWQABLE_ID) | GRAPHICS_DRAWABLE_T; +const bits GRAPHICS_IMAGE_T = (bits(1) << GRAPHICS_IMAGE_ID) | GRAPHICS_DRAWQABLE_T; +const bits GRAPHICS_QUAD_T = (bits(1) << GRAPHICS_QUAD_ID) | OBJECT_T; const bits GRAPHICS_FONT_T = (bits(1) << GRAPHICS_FONT_ID) | OBJECT_T; const bits GRAPHICS_PARTICLE_SYSTEM_T = (bits(1) << GRAPHICS_PARTICLE_SYSTEM_ID) | GRAPHICS_DRAWABLE_T; const bits GRAPHICS_SPRITE_BATCH_T = (bits(1) << GRAPHICS_SPRITE_BATCH_ID) | GRAPHICS_DRAWABLE_T; -const bits GRAPHICS_CANVAS_T = (bits(1) << GRAPHICS_CANVAS_ID) | GRAPHICS_DRAWGABLE_T; +const bits GRAPHICS_CANVAS_T = (bits(1) << GRAPHICS_CANVAS_ID) | GRAPHICS_DRAWQABLE_T; const bits GRAPHICS_SHADER_T = (bits(1) << GRAPHICS_SHADER_ID) | OBJECT_T; +const bits GRAPHICS_MESH_T = (bits(1) << GRAPHICS_MESH_ID) | GRAPHICS_DRAWABLE_T; // Image. const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T; diff --git a/src/modules/graphics/DrawGable.h b/src/modules/graphics/DrawQable.h similarity index 77% rename from src/modules/graphics/DrawGable.h rename to src/modules/graphics/DrawQable.h index 160af1e19..1c0d5230e 100644 --- a/src/modules/graphics/DrawGable.h +++ b/src/modules/graphics/DrawQable.h @@ -18,12 +18,12 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_GRAPHICS_DRAWGABLE_H -#define LOVE_GRAPHICS_DRAWGABLE_H +#ifndef LOVE_GRAPHICS_DRAWQABLE_H +#define LOVE_GRAPHICS_DRAWQABLE_H // LOVE #include "Drawable.h" -#include "Geometry.h" +#include "Quad.h" namespace love { @@ -31,21 +31,21 @@ namespace graphics { /** - * A DrawGable is anything that be drawn in part with a Geometry object. + * A DrawQable is anything that be drawn in part with a Quad object. **/ -class DrawGable : public Drawable +class DrawQable : public Drawable { public: /** * Destructor. **/ - virtual ~DrawGable(); + virtual ~DrawQable() {} /** * Draws the object with the specified transformation. * - * @param geom The Geometry object to use to draw the object. + * @param quad The Quad object to use to draw the object. * @param x The position of the object along the x-axis. * @param y The position of the object along the y-axis. * @param angle The angle of the object (in radians). @@ -56,10 +56,10 @@ public: * @param kx Shear along the x-axis. * @param ky Shear along the y-axis. **/ - virtual void drawg(Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0; + virtual void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0; }; } // graphics } // love -#endif // LOVE_GRAPHICS_DRAWGABLE_H +#endif // LOVE_GRAPHICS_DRAWQABLE_H diff --git a/src/modules/graphics/Geometry.cpp b/src/modules/graphics/Geometry.cpp deleted file mode 100644 index 79196f3a2..000000000 --- a/src/modules/graphics/Geometry.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/** - * Copyright (c) 2006-2013 LOVE Development Team - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - **/ - -#include "Geometry.h" -#include "common/Exception.h" -#include "common/Vector.h" -#include "modules/math/MathModule.h" - -using love::math::Math; - -// STD -#include -#include // for std::swap() -#include // For memcpy - -namespace love -{ -namespace graphics -{ - -Geometry::Geometry(const std::vector &polygon, const std::vector &elements, Geometry::DrawMode mode) - : vertexArray(NULL) - , vertexCount(polygon.size()) - , elementArray(NULL) - , elementCount(elements.size()) - , vertexColors(false) - , drawMode(mode) -{ - if (polygon.size() < 3) - throw love::Exception("At least 3 vertices are needed to create a Geometry."); - - for (size_t i = 0; i < elementCount; i++) - { - // All values in the element array need to be a valid vertex index. - if (elements[i] >= vertexCount) - throw love::Exception("Invalid vertex map value"); - } - - vertexArray = new Vertex[vertexCount]; - memcpy(vertexArray, &polygon[0], vertexCount * sizeof(Vertex)); - - if (elementCount > 0) - { - elementArray = new uint16[elementCount]; - memcpy(elementArray, &elements[0], elementCount * sizeof(uint16)); - } -} - -Geometry::Geometry(float x, float y, float w, float h, float sw, float sh) - : vertexArray(NULL) - , vertexCount(4) - , elementArray(NULL) - , elementCount(0) - , vertexColors(false) - , drawMode(DRAW_MODE_FAN) -{ - float s0 = x/sw, s1 = (x+w)/sw, t0 = y/sh, t1 = (y+h)/sh; - - Vertex verts[4] = { - {0,0, s0,t0, 255, 255, 255, 255}, - {w,0, s1,t0, 255, 255, 255, 255}, - {w,h, s1,t1, 255, 255, 255, 255}, - {0,h, s0,t1, 255, 255, 255, 255} - }; - - vertexArray = new Vertex[4]; - - for (int i = 0; i < 4; i++) - vertexArray[i] = verts[i]; -} - -Geometry::Geometry(const Geometry &other) - : vertexCount(other.vertexCount) - , elementCount(other.elementCount) - , vertexColors(other.vertexColors) - , drawMode(other.drawMode) -{ - vertexArray = new Vertex[vertexCount]; - memcpy(vertexArray, other.vertexArray, vertexCount * sizeof(Vertex)); - - if (elementCount > 0) - { - elementArray = new uint16[elementCount]; - memcpy(elementArray, other.elementArray, elementCount * sizeof(uint16)); - } -} - -Geometry &Geometry::operator=(const Geometry &other) -{ - if (this != &other) - { - Geometry temp(other); - std::swap(vertexArray, temp.vertexArray); - std::swap(elementArray, temp.elementArray); - - vertexCount = temp.vertexCount; - elementCount = temp.elementCount; - - vertexColors = other.vertexColors; - drawMode = other.drawMode; - } - - return *this; -} - -Geometry::~Geometry() -{ - delete[] vertexArray; - delete[] elementArray; -} - -const Vertex &Geometry::getVertex(size_t i) const -{ - if (i >= vertexCount) - throw Exception("Invalid vertex index"); - - return vertexArray[i]; -} - -void Geometry::setVertex(size_t i, const Vertex &v) -{ - if (i >= vertexCount) - throw Exception("Invalid vertex index"); - - vertexArray[i] = v; -} - - -void Geometry::setElementArray(const uint16 *elements, size_t count) -{ - if (count == 0 || elements == NULL) - { - delete[] elementArray; - elementArray = NULL; - elementCount = 0; - return; - } - - for (size_t i = 0; i < count; i++) - { - if (elements[i] >= vertexCount) - throw love::Exception("Invalid vertex map value"); - } - - if (count > elementCount) - { - delete[] elementArray; - elementArray = new uint16[count]; - } - - elementCount = count; - memcpy(elementArray, elements, elementCount * sizeof(uint16)); -} - -void Geometry::setVertexColors(bool on) -{ - vertexColors = on; -} - -bool Geometry::getConstant(const char *in, Geometry::DrawMode &out) -{ - return drawModes.find(in, out); -} - -bool Geometry::getConstant(Geometry::DrawMode in, const char *&out) -{ - return drawModes.find(in, out); -} - -StringMap::Entry Geometry::drawModeEntries[] = -{ - {"fan", Geometry::DRAW_MODE_FAN}, - {"strip", Geometry::DRAW_MODE_STRIP}, - {"triangles", Geometry::DRAW_MODE_TRIANGLES} -}; - -StringMap Geometry::drawModes(Geometry::drawModeEntries, sizeof(Geometry::drawModeEntries)); - -} // graphics -} // love diff --git a/src/modules/graphics/Geometry.h b/src/modules/graphics/Geometry.h deleted file mode 100644 index 5b7c8abae..000000000 --- a/src/modules/graphics/Geometry.h +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Copyright (c) 2006-2013 LOVE Development Team - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - **/ - -#ifndef LOVE_GRAPHICS_GEOMETRY_H -#define LOVE_GRAPHICS_GEOMETRY_H - -// LOVE -#include "common/Object.h" -#include "common/math.h" -#include "common/StringMap.h" -#include "common/int.h" - -// stdlib -#include - -namespace love -{ -namespace graphics -{ - -class Geometry : public Object -{ -public: - - // How the Geometry's vertices are used when drawing. - // http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png - enum DrawMode - { - DRAW_MODE_FAN, - DRAW_MODE_STRIP, - DRAW_MODE_TRIANGLES, - DRAW_MODE_MAX_ENUM - }; - - /** - * Creates a new geometry object from a std::vector. - **/ - Geometry(const std::vector &polygon, const std::vector &elements, DrawMode mode = DRAW_MODE_FAN); - - /** - * Creates a new geometry from (texture) quad information. - * @param x Top left position in the image. - * @param y Top left position in the image. - * @param w Width of the quad. - * @param h Height of the quad. - * @param sw The reference width, the width of the Image. - * @param sh The reference height, the height of the Image. - */ - Geometry(float x, float y, float w, float h, float sw, float sh); - - Geometry(const Geometry &other); - Geometry &operator=(const Geometry &other); - virtual ~Geometry(); - - const Vertex &getVertex(size_t i) const; - void setVertex(size_t i, const Vertex &v); - - /** - * Returns a pointer to the vertex array. - **/ - inline const Vertex *getVertexArray() const - { - return vertexArray; - } - - /** - * Returns the size of the vertex array. - **/ - inline size_t getVertexCount() const - { - return vertexCount; - } - - inline const uint16 *getElementArray() const - { - return elementArray; - } - - inline size_t getElementCount() const - { - return elementCount; - } - - void setElementArray(const uint16 *elements, size_t count); - - /** - * Sets whether this Geometry will use custom per-vertex colors. - **/ - void setVertexColors(bool on); - - /** - * Returns whether this Geometry is using custom per-vertex colors. - **/ - inline bool hasVertexColors() const - { - return vertexColors; - }; - - /** - * Returns the mode used when drawing this Geometry. - **/ - inline DrawMode getDrawMode() const - { - return drawMode; - } - - static bool getConstant(const char *in, DrawMode &out); - static bool getConstant(DrawMode in, const char *&out); - -private: - - Vertex *vertexArray; - size_t vertexCount; - - uint16 *elementArray; - size_t elementCount; - - bool vertexColors; - - DrawMode drawMode; - - static StringMap::Entry drawModeEntries[]; - static StringMap drawModes; -}; - -} // graphics -} // love - -#endif // LOVE_GRAPHICS_GEOMETRY_H diff --git a/src/modules/graphics/Image.h b/src/modules/graphics/Image.h index a6ca06795..e2c49116d 100644 --- a/src/modules/graphics/Image.h +++ b/src/modules/graphics/Image.h @@ -23,7 +23,7 @@ // LOVE #include "graphics/Volatile.h" -#include "graphics/DrawGable.h" +#include "graphics/DrawQable.h" #include "common/StringMap.h" namespace love @@ -31,7 +31,7 @@ namespace love namespace graphics { -class Image : public DrawGable, public Volatile +class Image : public DrawQable, public Volatile { public: diff --git a/src/modules/graphics/Quad.cpp b/src/modules/graphics/Quad.cpp new file mode 100644 index 000000000..cdfe55df5 --- /dev/null +++ b/src/modules/graphics/Quad.cpp @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2006-2013 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +// LOVE +#include "Quad.h" + +// C +#include // For memcpy + +namespace love +{ +namespace graphics +{ + +Quad::Quad(const Quad::Viewport &v, float sw, float sh) + : sw(sw) + , sh(sh) +{ + memset(vertices, 255, sizeof(Vertex) * NUM_VERTICES); + refresh(v, sw, sh); +} + +Quad::~Quad() +{ +} + +void Quad::refresh(const Quad::Viewport &v, float sw, float sh) +{ + viewport = v; + + vertices[0].x = 0; + vertices[0].y = 0; + vertices[1].x = 0; + vertices[1].y = v.h; + vertices[2].x = v.w; + vertices[2].y = v.h; + vertices[3].x = v.w; + vertices[3].y = 0; + + vertices[0].s = v.x/sw; + vertices[0].t = v.y/sh; + vertices[1].s = v.x/sw; + vertices[1].t = (v.y+v.h)/sh; + vertices[2].s = (v.x+v.w)/sw; + vertices[2].t = (v.y+v.h)/sh; + vertices[3].s = (v.x+v.w)/sw; + vertices[3].t = v.y/sh; +} + +void Quad::setViewport(const Quad::Viewport &v) +{ + refresh(v, sw, sh); +} + +Quad::Viewport Quad::getViewport() const +{ + return viewport; +} + +void Quad::flip(bool x, bool y) +{ + Vertex temp[NUM_VERTICES]; + + if (x) + { + memcpy(temp, vertices, sizeof(Vertex) * NUM_VERTICES); + vertices[0].s = temp[3].s; + vertices[0].t = temp[3].t; + vertices[1].s = temp[2].s; + vertices[1].t = temp[2].t; + vertices[2].s = temp[1].s; + vertices[2].t = temp[1].t; + vertices[3].s = temp[0].s; + vertices[3].t = temp[0].t; + } + + if (y) + { + memcpy(temp, vertices, sizeof(Vertex) * NUM_VERTICES); + vertices[0].s = temp[1].s; + vertices[0].t = temp[1].t; + vertices[1].s = temp[0].s; + vertices[1].t = temp[0].t; + vertices[2].s = temp[3].s; + vertices[2].t = temp[3].t; + vertices[3].s = temp[2].s; + vertices[3].t = temp[2].t; + } +} + +const Vertex *Quad::getVertices() const +{ + return vertices; +} + +} // graphics +} // love diff --git a/src/modules/graphics/Quad.h b/src/modules/graphics/Quad.h new file mode 100644 index 000000000..ee9cc2048 --- /dev/null +++ b/src/modules/graphics/Quad.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2006-2013 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_GRAPHICS_QUAD_H +#define LOVE_GRAPHICS_QUAD_H + +// LOVE +#include "common/Object.h" +#include "common/math.h" + +namespace love +{ +namespace graphics +{ + +class Quad : public Object +{ +public: + + struct Viewport + { + float x, y; + float w, h; + }; + + static const size_t NUM_VERTICES = 4; + + Quad(const Viewport &v, float sw, float sh); + virtual ~Quad(); + + void refresh(const Viewport &v, float sw, float sh); + void setViewport(const Viewport &v); + Viewport getViewport() const; + + void flip(bool x, bool y); + + const Vertex *getVertices() const; + +private: + + Vertex vertices[NUM_VERTICES]; + + Viewport viewport; + float sw; + float sh; + +}; // Quad + +} // graphics +} // love + +#endif // LOVE_GRAPHICS_QUAD_H diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index 307e40289..a5900e7ed 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -607,52 +607,20 @@ void Canvas::draw(float x, float y, float angle, float sx, float sy, float ox, f drawv(t, vertices); } -void Canvas::drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const +void Canvas::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const { static Matrix t; t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); - // flip texture coordinates vertically - size_t vcount = geom->getVertexCount(); - const Vertex *w = geom->getVertexArray(); - Vertex *v = new Vertex[vcount]; - for (size_t i = 0; i < vcount; ++i) - { - v[i] = w[i]; - v[i].t = 1. - v[i].t; - } + const Vertex *v = quad->getVertices(); - // use colors stored in geometry (horrible, horrible hack) - if (geom->hasVertexColors()) - { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), (GLvoid *)&v->r); - } + // flip texture coordinates vertically. + Vertex w[4]; + memcpy(w, v, sizeof(Vertex) * 4); + for (size_t i = 0; i < 4; i++) + w[i].t = 1.0f - w[i].t; - GLenum glmode; - switch (geom->getDrawMode()) - { - case Geometry::DRAW_MODE_FAN: - default: - glmode = GL_TRIANGLE_FAN; - break; - case Geometry::DRAW_MODE_STRIP: - glmode = GL_TRIANGLE_STRIP; - break; - case Geometry::DRAW_MODE_TRIANGLES: - glmode = GL_TRIANGLES; - break; - } - - drawv(t, v, vcount, glmode, geom->getElementArray(), geom->getElementCount()); - - if (geom->hasVertexColors()) - { - glDisableClientState(GL_COLOR_ARRAY); - gl.setColor(gl.getColor()); - } - - delete[] v; + drawv(t, w); } bool Canvas::checkCreateStencil() @@ -785,7 +753,7 @@ int Canvas::getHeight() return height; } -void Canvas::drawv(const Matrix &t, const Vertex *v, GLsizei count, GLenum mode, const uint16 *e, GLsizei ecount) const +void Canvas::drawv(const Matrix &t, const Vertex *v) const { glPushMatrix(); @@ -796,17 +764,10 @@ void Canvas::drawv(const Matrix &t, const Vertex *v, GLsizei count, GLenum mode, glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - // XXX: drawg() enables/disables GL_COLOR_ARRAY in order to use the color - // defined in the geometry to draw itself. - // if the drawing method below is changed to use something other than - // glDrawArrays(), drawg() needs to be updated accordingly! glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].x); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].s); - if (e != 0 && ecount > 0) - glDrawElements(mode, ecount, GL_UNSIGNED_SHORT, (GLvoid *) e); - else - glDrawArrays(mode, 0, count); + glDrawArrays(GL_QUADS, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); diff --git a/src/modules/graphics/opengl/Canvas.h b/src/modules/graphics/opengl/Canvas.h index 20ad89703..ef5de47c2 100644 --- a/src/modules/graphics/opengl/Canvas.h +++ b/src/modules/graphics/opengl/Canvas.h @@ -21,7 +21,7 @@ #ifndef LOVE_GRAPHICS_OPENGL_CANVAS_H #define LOVE_GRAPHICS_OPENGL_CANVAS_H -#include "graphics/DrawGable.h" +#include "graphics/DrawQable.h" #include "graphics/Volatile.h" #include "graphics/Image.h" #include "graphics/Color.h" @@ -38,7 +38,7 @@ namespace graphics namespace opengl { -class Canvas : public DrawGable, public Volatile +class Canvas : public DrawQable, public Volatile { public: @@ -65,9 +65,9 @@ public: virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; /** - * @copydoc DrawGable::drawg() + * @copydoc DrawQable::drawq() **/ - void drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; + void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; /** * Create and attach a stencil buffer to this Canvas' framebuffer, if necessary. @@ -142,7 +142,7 @@ private: std::vector attachedCanvases; void setupGrab(); - void drawv(const Matrix &t, const Vertex *v, GLsizei count = 4, GLenum mode = GL_QUADS, const uint16 *e = 0, GLsizei ecount = 0) const; + void drawv(const Matrix &t, const Vertex *v) const; static StringMap::Entry textureTypeEntries[]; static StringMap textureTypes; diff --git a/src/modules/graphics/opengl/Font.cpp b/src/modules/graphics/opengl/Font.cpp index 05c1c2d79..961430240 100644 --- a/src/modules/graphics/opengl/Font.cpp +++ b/src/modules/graphics/opengl/Font.cpp @@ -20,7 +20,6 @@ #include "common/config.h" #include "Font.h" #include "font/GlyphData.h" -#include "modules/graphics/Geometry.h" #include "Image.h" #include "libraries/utf8/utf8.h" diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 5515b699a..529ae76f1 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -369,14 +369,9 @@ Image *Graphics::newImage(love::image::CompressedData *cdata) return image; } -Geometry *Graphics::newGeometry(const std::vector &vertices, const std::vector &vertexmap, Geometry::DrawMode mode) +Quad *Graphics::newQuad(Quad::Viewport v, float sw, float sh) { - return new Geometry(vertices, vertexmap, mode); -} - -Geometry *Graphics::newQuad(float x, float y, float w, float h, float sw, float sh) -{ - return new Geometry(x, y, w, h, sw, sh); + return new Quad(v, sw, sh); } Font *Graphics::newFont(love::font::Rasterizer *r, const Image::Filter &filter) @@ -457,6 +452,11 @@ Shader *Graphics::newShader(const Shader::ShaderSources &sources) return new Shader(sources); } +Mesh *Graphics::newMesh(const std::vector &vertices, Mesh::DrawMode mode) +{ + return new Mesh(vertices, mode); +} + void Graphics::setColor(const Color &c) { gl.setColor(c); diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index c204494e5..360d5d8d2 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -40,11 +40,12 @@ #include "Font.h" #include "Image.h" -#include "graphics/Geometry.h" +#include "graphics/Quad.h" #include "SpriteBatch.h" #include "ParticleSystem.h" #include "Canvas.h" #include "Shader.h" +#include "Mesh.h" using love::window::WindowFlags; @@ -199,15 +200,7 @@ public: Image *newImage(love::image::ImageData *data); Image *newImage(love::image::CompressedData *cdata); - /** - * Creates a Geometry object. - **/ - Geometry *newGeometry(const std::vector &vertices, const std::vector &vertexmap, Geometry::DrawMode mode); - - /** - * Creates a quadliteral Geometry object. - **/ - Geometry *newQuad(float x, float y, float w, float h, float sw, float sh); + Quad *newQuad(Quad::Viewport v, float sw, float sh); /** * Creates a Font object. @@ -222,6 +215,8 @@ public: Shader *newShader(const Shader::ShaderSources &sources); + Mesh *newMesh(const std::vector &vertices, Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN); + /** * Sets the foreground color. * @param c The new foreground color. diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 424b79893..bdcbd20c0 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -108,51 +108,32 @@ void Image::draw(float x, float y, float angle, float sx, float sy, float ox, fl drawv(t, vertices); } -void Image::drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const +void Image::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const { static Matrix t; t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); - const Vertex *v = geom->getVertexArray(); - size_t vertcount = geom->getVertexCount(); + const Vertex *v = quad->getVertices(); - // Padded NPOT images require texture coordinate scaling with Geometry. + // Padded NPOT images require texture coordinate scaling with Quads. if (!hasNpot()) - v = scaleNPOT(v, vertcount); - - // use colors stored in geometry (horrible, horrible hack) - if (geom->hasVertexColors()) { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), (GLvoid *) &v[0].r); - } + Vertex w[4]; + love::Vector scale = getTexCoordScale(); - GLenum glmode; - switch (geom->getDrawMode()) + for (int i = 0; i < 4; i++) + { + w[i] = v[i]; + w[i].s *= scale.x; + w[i].t *= scale.y; + } + + drawv(t, w); + } + else { - case Geometry::DRAW_MODE_FAN: - default: - glmode = GL_TRIANGLE_FAN; - break; - case Geometry::DRAW_MODE_STRIP: - glmode = GL_TRIANGLE_STRIP; - break; - case Geometry::DRAW_MODE_TRIANGLES: - glmode = GL_TRIANGLES; - break; + drawv(t, v); } - - drawv(t, v, vertcount, glmode, geom->getElementArray(), geom->getElementCount()); - - if (geom->hasVertexColors()) - { - glDisableClientState(GL_COLOR_ARRAY); - gl.setColor(gl.getColor()); - } - - // If we made new verts with scaled texcoords then we should clean them up. - if (!hasNpot()) - delete[] v; } void Image::uploadCompressedMipmaps() @@ -602,22 +583,7 @@ love::Vector Image::getTexCoordScale() const return love::Vector(vertices[2].s, vertices[2].t); } -Vertex *Image::scaleNPOT(const love::Vertex *v, size_t count) const -{ - Vertex *newverts = new Vertex[count]; - love::Vector scale = getTexCoordScale(); - - for (size_t i = 0; i < count; i++) - { - newverts[i] = v[i]; - newverts[i].s *= scale.x; - newverts[i].t *= scale.y; - } - - return newverts; -} - -void Image::drawv(const Matrix &t, const Vertex *v, GLsizei count, GLenum mode, const uint16 *e, GLsizei ecount) const +void Image::drawv(const Matrix &t, const Vertex *v) const { bind(); @@ -628,17 +594,10 @@ void Image::drawv(const Matrix &t, const Vertex *v, GLsizei count, GLenum mode, glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - // XXX: drawg() enables/disables GL_COLOR_ARRAY in order to use the color - // defined in the geometry to draw itself. - // if the drawing method below is changed to use something other than - // glDrawArrays(), drawg() needs to be updated accordingly! glVertexPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].x); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (GLvoid *)&v[0].s); - if (e != 0 && ecount > 0) - glDrawElements(mode, ecount, GL_UNSIGNED_SHORT, (GLvoid *) e); - else - glDrawArrays(mode, 0, count); + glDrawArrays(GL_QUADS, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); diff --git a/src/modules/graphics/opengl/Image.h b/src/modules/graphics/opengl/Image.h index aacb01e1e..382bf99f1 100644 --- a/src/modules/graphics/opengl/Image.h +++ b/src/modules/graphics/opengl/Image.h @@ -84,9 +84,9 @@ public: void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; /** - * @copydoc DrawGable::drawg() + * @copydoc DrawQable::drawq() **/ - void drawg(love::graphics::Geometry *geom, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; + void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; /** * Sets the filter mode. @@ -145,10 +145,9 @@ public: private: - Vertex *scaleNPOT(const Vertex *v, size_t count) const; void uploadDefaultTexture(); - void drawv(const Matrix &t, const Vertex *v, GLsizei count = 4, GLenum mode = GL_QUADS, const uint16 *e = 0, GLsizei ecount = 0) const; + void drawv(const Matrix &t, const Vertex *v) const; friend class Shader; GLuint getTextureName() const diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp new file mode 100644 index 000000000..e1b77f733 --- /dev/null +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -0,0 +1,213 @@ +/** + * Copyright (c) 2006-2013 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +// LOVE +#include "Mesh.h" +#include "common/Matrix.h" +#include "common/Exception.h" + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +Mesh::Mesh(const std::vector &verts, Mesh::DrawMode mode) + : draw_mode(mode) + , image(0) +{ + setVertices(verts); +} + +void Mesh::setVertices(const std::vector &verts) +{ + if (verts.size() < 3) + throw love::Exception("At least 3 vertices are required."); + + vertices = verts; +} + +const std::vector &Mesh::getVertices() const +{ + return vertices; +} + +void Mesh::setVertex(size_t i, Vertex v) +{ + if (i >= vertices.size()) + throw love::Exception("Invalid index."); + + vertices[i] = v; +} + +Vertex Mesh::getVertex(size_t i) const +{ + if (i >= vertices.size()) + throw love::Exception("Invalid index."); + + return vertices[i]; +} + +size_t Mesh::getVertexCount() const +{ + return vertices.size(); +} + +void Mesh::setVertexMap(const std::vector &map) +{ + for (size_t i = 0; i < map.size(); i++) + { + if (map[i] >= vertices.size()) + throw love::Exception("Invalid vertex map value: %d", map[i]); + } + + vertex_map = map; +} + +const std::vector &Mesh::getVertexMap() const +{ + return vertex_map; +} + +Mesh::~Mesh() +{ +} + +void Mesh::setImage(Image *img) +{ + img->retain(); + + if (image) + image->release(); + + image = img; +} + +void Mesh::setImage() +{ + if (image) + image->release(); + + image = 0; +} + +Image *Mesh::getImage() const +{ + return image; +} + +void Mesh::setDrawMode(Mesh::DrawMode mode) +{ + draw_mode = mode; +} + +Mesh::DrawMode Mesh::getDrawMode() const +{ + return draw_mode; +} + +void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const +{ + if (vertices.size() == 0) + return; + + if (image) + image->bind(); + else + gl.bindTexture(0); + + Matrix m; + m.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); + + glPushMatrix(); + glMultMatrixf(m.getElements()); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &(vertices[0].x)); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &(vertices[0].s)); + + { + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &(vertices[0].r)); + } + + GLenum gl_draw_mode = getGLDrawMode(draw_mode); + + if (vertex_map.size() > 0) + glDrawElements(gl_draw_mode, vertex_map.size(), GL_UNSIGNED_SHORT, &vertex_map[0]); + else + glDrawArrays(gl_draw_mode, 0, vertices.size()); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + { + glDisableClientState(GL_COLOR_ARRAY); + gl.setColor(gl.getColor()); + } + + glPopMatrix(); +} + +GLenum Mesh::getGLDrawMode(Mesh::DrawMode mode) const +{ + switch (mode) + { + case DRAW_MODE_FAN: + return GL_TRIANGLE_FAN; + case DRAW_MODE_STRIP: + return GL_TRIANGLE_STRIP; + case DRAW_MODE_TRIANGLES: + return GL_TRIANGLES; + case DRAW_MODE_POINTS: + return GL_POINTS; + default: + break; + } + + return GL_TRIANGLES; +} + +bool Mesh::getConstant(const char *in, Mesh::DrawMode &out) +{ + return drawModes.find(in, out); +} + +bool Mesh::getConstant(Mesh::DrawMode in, const char *&out) +{ + return drawModes.find(in, out); +} + +StringMap::Entry Mesh::drawModeEntries[] = +{ + {"fan", Mesh::DRAW_MODE_FAN}, + {"strip", Mesh::DRAW_MODE_STRIP}, + {"triangles", Mesh::DRAW_MODE_TRIANGLES}, + {"points", Mesh::DRAW_MODE_POINTS}, +}; + +StringMap Mesh::drawModes(Mesh::drawModeEntries, sizeof(Mesh::drawModeEntries)); + +} // opengl +} // graphics +} // love diff --git a/src/modules/graphics/opengl/Mesh.h b/src/modules/graphics/opengl/Mesh.h new file mode 100644 index 000000000..8e1983bc0 --- /dev/null +++ b/src/modules/graphics/opengl/Mesh.h @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2006-2013 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_GRAPHICS_OPENGL_MESH_H +#define LOVE_GRAPHICS_OPENGL_MESH_H + +// LOVE +#include "common/int.h" +#include "common/math.h" +#include "common/StringMap.h" +#include "graphics/Volatile.h" +#include "graphics/Drawable.h" +#include "graphics/opengl/Image.h" + +// C++ +#include + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +/** + * Holds and draws arbitrary vertex geometry. + * Each vertex in a Mesh has a position, texture coordinate, and color. + **/ +class Mesh : public Drawable +{ +public: + + // How the Mesh's vertices are used when drawing. + // http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png + enum DrawMode + { + DRAW_MODE_FAN, + DRAW_MODE_STRIP, + DRAW_MODE_TRIANGLES, + DRAW_MODE_POINTS, + DRAW_MODE_MAX_ENUM + }; + + /** + * Constructor. + * @param verts The vertices to use in the Mesh. + * @param mode The draw mode to use when drawing the Mesh. + **/ + Mesh(const std::vector &verts, DrawMode mode = DRAW_MODE_FAN); + virtual ~Mesh(); + + /** + * Replaces all the vertices in the Mesh with a new set of vertices. + **/ + void setVertices(const std::vector &verts); + + /** + * Gets a reference to the vertices used in the Mesh. + **/ + const std::vector &getVertices() const; + + /** + * Sets an individual vertex in the Mesh. + * @param i The index into the list of vertices to use. + * @param v The new vertex. + **/ + void setVertex(size_t i, Vertex v); + Vertex getVertex(size_t i) const; + + /** + * Gets the total number of vertices in the Mesh. + **/ + size_t getVertexCount() const; + + /** + * Sets the vertex map to use when drawing the Mesh. The vertex map + * determines the order in which vertices are used by the draw mode. + * A 0-element vector is equivalent to the default vertex map: + * {0, 1, 2, 3, 4, ...} + **/ + void setVertexMap(const std::vector &map); + const std::vector &getVertexMap() const; + + /** + * Sets the Image used when drawing the Mesh. + **/ + void setImage(Image *img); + + /** + * Disables any Image from being used when drawing the Mesh. + **/ + void setImage(); + + /** + * Gets the Image used when drawing the Mesh. May return null if no Image is + * set. + **/ + Image *getImage() const; + + /** + * Sets the draw mode used when drawing the Mesh. + **/ + void setDrawMode(DrawMode mode); + DrawMode getDrawMode() const; + + // Implements Drawable. + void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; + + static bool getConstant(const char *in, DrawMode &out); + static bool getConstant(DrawMode in, const char *&out); + +private: + + GLenum getGLDrawMode(DrawMode mode) const; + + std::vector vertices; + std::vector vertex_map; + + DrawMode draw_mode; + + Image *image; + + static StringMap::Entry drawModeEntries[]; + static StringMap drawModes; + +}; // 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 c388b4e6d..88dbfa4f5 100644 --- a/src/modules/graphics/opengl/SpriteBatch.cpp +++ b/src/modules/graphics/opengl/SpriteBatch.cpp @@ -26,7 +26,6 @@ // LOVE #include "Image.h" -#include "modules/graphics/Geometry.h" #include "VertexBuffer.h" // C++ @@ -129,39 +128,20 @@ int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, fl return index; } -int SpriteBatch::addg(Geometry *geom, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/) +int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/) { // Only do this if there's a free slot. if ((index == -1 && next >= size) || index < -1 || index >= next) return -1; - size_t vertexcount = geom->getVertexCount(); - if (vertexcount > 4) - throw love::Exception("Cannot add Geometries with more than 4 vertices to SpriteBatch"); - - // Which vertices to add to the SpriteBatch. - size_t vertex_indices[4] = {0, 1, 2, 3}; - - if (geom->getDrawMode() == Geometry::DRAW_MODE_STRIP) - { - // We have to do some vertex reordering shenanigans to get 4-vertex - // triangle strip Geometries to render properly. - std::swap(vertex_indices[0], vertex_indices[1]); - } - - // If the Geometry has 3 vertices, then 2 triangles will be added to the - // SpriteBatch: 0-1-2 and 0-2-0. 0-2-0 will get ignored during rasterization. - for (size_t i = geom->getVertexCount(); i < 4; i++) - vertex_indices[i] = vertex_indices[0]; - - for (size_t i = 0; i < 4; i++) - sprite[i] = geom->getVertex(vertex_indices[i]); + // Needed for colors. + memcpy(sprite, quad->getVertices(), sizeof(Vertex) * 4); static Matrix t; t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky); t.transform(sprite, sprite, 4); - if (color && !geom->hasVertexColors()) + if (color) setColorv(sprite, *color); // Auto-padded NPOT images require texcoord scaling for their vertices. @@ -169,10 +149,6 @@ int SpriteBatch::addg(Geometry *geom, float x, float y, float a, float sx, float addv(sprite, (index == -1) ? next : index); - // Make sure SpriteBatch colors are enabled if the Geometry has custom colors. - if (!color && geom->hasVertexColors()) - setColor(Color(255, 255, 255, 255)); - // Increment counter. if (index == -1) return next++; diff --git a/src/modules/graphics/opengl/SpriteBatch.h b/src/modules/graphics/opengl/SpriteBatch.h index 01f775459..75d676d15 100644 --- a/src/modules/graphics/opengl/SpriteBatch.h +++ b/src/modules/graphics/opengl/SpriteBatch.h @@ -32,7 +32,7 @@ #include "graphics/Drawable.h" #include "graphics/Volatile.h" #include "graphics/Color.h" -#include "graphics/Geometry.h" +#include "graphics/Quad.h" namespace love { @@ -62,7 +62,7 @@ public: virtual ~SpriteBatch(); int add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1); - int addg(Geometry *geom, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1); + int addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1); void clear(); void *lock(); @@ -72,16 +72,16 @@ public: Image *getImage(); /** - * Set the current color for this SpriteBatch. The geometry added + * Set the current color for this SpriteBatch. The sprites added * after this call will use this color. Note that global color * will not longer apply to the SpriteBatch if this is used. * - * @param color The color to use for the following geometry. + * @param color The color to use for the following sprites. */ void setColor(const Color &color); /** - * Disable per-geometry colors for this SpriteBatch. The next call to + * Disable per-sprite colors for this SpriteBatch. The next call to * draw will use the global color for all sprites. */ void setColor(); @@ -140,7 +140,7 @@ private: Vertex sprite[4]; // Current color. This color, if present, will be applied to the next - // added geometry. + // added sprite. Color *color; VertexBuffer *array_buf; diff --git a/src/modules/graphics/opengl/wrap_Geometry.cpp b/src/modules/graphics/opengl/wrap_Geometry.cpp deleted file mode 100644 index c6a4dee6b..000000000 --- a/src/modules/graphics/opengl/wrap_Geometry.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Copyright (c) 2006-2013 LOVE Development Team - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - **/ - -// LOVE -#include "wrap_Geometry.h" -#include "common/Exception.h" - -namespace love -{ -namespace graphics -{ -namespace opengl -{ - -Geometry *luax_checkgeometry(lua_State *L, int idx) -{ - return luax_checktype(L, idx, "Geometry", GRAPHICS_GEOMETRY_T); -} - -int w_Geometry_getVertexCount(lua_State *L) -{ - Geometry *geom = luax_checkgeometry(L, 1); - lua_pushinteger(L, geom->getVertexCount()); - return 1; -} - -int w_Geometry_getVertex(lua_State *L) -{ - Geometry *geom = luax_checkgeometry(L, 1); - size_t i = size_t(luaL_checkinteger(L, 2)); - - EXCEPT_GUARD( - const Vertex &v = geom->getVertex(i-1); - lua_pushnumber(L, v.x); - lua_pushnumber(L, v.y); - lua_pushnumber(L, v.s); - lua_pushnumber(L, v.t); - lua_pushnumber(L, v.r); - lua_pushnumber(L, v.g); - lua_pushnumber(L, v.b); - lua_pushnumber(L, v.a); - ) - - return 8; -} - -int w_Geometry_setVertex(lua_State *L) -{ - Geometry *geom = luax_checkgeometry(L, 1); - size_t i = size_t(luaL_checkinteger(L, 2)); - - Vertex v; - - if (lua_istable(L, 3)) - { - for (int i = 1; i <= 8; i++) - lua_rawgeti(L, 3, i); - - v.x = luaL_checknumber(L, -8); - v.y = luaL_checknumber(L, -7); - v.s = luaL_checknumber(L, -6); - v.t = luaL_checknumber(L, -5); - v.r = luaL_optinteger(L, -4, 255); - v.g = luaL_optinteger(L, -3, 255); - v.b = luaL_optinteger(L, -2, 255); - v.a = luaL_optinteger(L, -1, 255); - - lua_pop(L, 8); - } - else - { - v.x = luaL_checknumber(L, 3); - v.y = luaL_checknumber(L, 4); - v.s = luaL_checknumber(L, 5); - v.t = luaL_checknumber(L, 6); - v.r = luaL_optinteger(L, 7, 255); - v.g = luaL_optinteger(L, 8, 255); - v.b = luaL_optinteger(L, 9, 255); - v.a = luaL_optinteger(L, 10, 255); - } - - EXCEPT_GUARD(geom->setVertex(i-1, v);) - - if (v.r != 255 || v.g != 255 || v.b != 255 || v.a != 255) - geom->setVertexColors(true); - - return 0; -} - -int w_Geometry_setVertexColors(lua_State *L) -{ - Geometry *geom = luax_checkgeometry(L, 1); - geom->setVertexColors(luax_toboolean(L, 2)); - return 0; -} - -int w_Geometry_hasVertexColors(lua_State *L) -{ - Geometry *geom = luax_checkgeometry(L, 1); - luax_pushboolean(L, geom->hasVertexColors()); - return 1; -} - -int w_Geometry_getDrawMode(lua_State *L) -{ - Geometry *geom = luax_checkgeometry(L, 1); - - Geometry::DrawMode mode = geom->getDrawMode(); - const char *str; - - if (!Geometry::getConstant(mode, str)) - return luaL_error(L, "Unknown Geometry draw mode"); - - lua_pushstring(L, str); - - return 1; -} - -int w_Geometry_getVertexMap(lua_State *L) -{ - Geometry *g = luax_checkgeometry(L, 1); - - size_t elemcount = g->getElementCount(); - const uint16 *elements = g->getElementArray(); - - if (elemcount == 0) - elemcount = g->getVertexCount(); - - lua_createtable(L, elemcount, 0); - for (size_t i = 0; i < elemcount; i++) - { - if (elements) - lua_pushinteger(L, elements[i] + 1); - else - lua_pushinteger(L, i + 1); - - lua_rawseti(L, -2, i + 1); - } - - return 1; -} - -int w_Geometry_setVertexMap(lua_State *L) -{ - Geometry *g = luax_checkgeometry(L, 1); - - for (int i = lua_gettop(L); i >= 2; i--) - { - if (lua_isnil(L, i)) - lua_pop(L, 1); - else - break; - } - - bool is_table = lua_istable(L, 2); - int nargs = is_table ? lua_objlen(L, 2) : lua_gettop(L) - 1; - - std::vector vertexmap; - vertexmap.reserve(nargs); - - for (int i = 0; i < nargs; i++) - { - if (is_table) - { - lua_rawgeti(L, 2, i + 1); - vertexmap.push_back(luaL_checkinteger(L, -1) - 1); - lua_pop(L, 1); - } - else - vertexmap.push_back(luaL_checkinteger(L, i + 2) - 1); - } - - EXCEPT_GUARD(g->setElementArray(&vertexmap[0], vertexmap.size());) - return 0; -} - -static const luaL_Reg w_Geometry_functions[] = -{ - { "getVertexCount", w_Geometry_getVertexCount }, - { "getVertex", w_Geometry_getVertex }, - { "setVertex", w_Geometry_setVertex }, - { "setVertexColors", w_Geometry_setVertexColors }, - { "hasVertexColors", w_Geometry_hasVertexColors }, - { "getDrawMode", w_Geometry_getDrawMode }, - { "getVertexMap", w_Geometry_getVertexMap }, - { "setVertexMap", w_Geometry_setVertexMap }, - { 0, 0 } -}; - -extern "C" int luaopen_geometry(lua_State *L) -{ - return luax_register_type(L, "Geometry", w_Geometry_functions); -} - -} // opengl -} // graphics -} // love diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 144f9c382..984fd9d69 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -20,7 +20,7 @@ #include "wrap_Graphics.h" #include "OpenGL.h" -#include "graphics/DrawGable.h" +#include "graphics/DrawQable.h" #include "image/ImageData.h" #include "font/Rasterizer.h" @@ -194,156 +194,19 @@ int w_newImage(lua_State *L) return 1; } -int w_newGeometry(lua_State *L) -{ - luaL_checktype(L, 1, LUA_TTABLE); - - // Determine whether a table of vertices is being given. We assume it is if - // type(args[1][1]) == "table", otherwise assume the args are the verts. - lua_rawgeti(L, 1, 1); - bool is_table = lua_istable(L, -1); - lua_pop(L, 1); - - // Get rid of any trailing nils in the arg list (it messes with our style.) - for (int i = lua_gettop(L); i >= 2; i--) - { - if (lua_isnil(L, i)) - lua_pop(L, 1); - else - break; - } - - Geometry::DrawMode mode = Geometry::DRAW_MODE_FAN; - std::string txt; - bool has_vertexmap = false; - - // The last argument (or second-last) may be an optional draw mode. - if (lua_type(L, -1) == LUA_TSTRING) - { - txt = luaL_checkstring(L, -1); - lua_remove(L, -1); - } - else if (lua_type(L, -2) == LUA_TSTRING && lua_istable(L, -1)) - { - txt = luaL_checkstring(L, -2); - lua_remove(L, -2); - - // If the draw mode is the second-last argument, the last argument will - // be the vertex map. - has_vertexmap = true; - } - - if (txt.length() > 0 && !Geometry::getConstant(txt.c_str(), mode)) - return luaL_error(L, "Invalid Geometry draw mode: %s", txt.c_str()); - - std::vector vertexmap; - - // Get the vertex map table, if it exists. - if (has_vertexmap) - { - // It will always be the last argument. - int tableidx = lua_gettop(L); - - size_t elementcount = lua_objlen(L, -1); - vertexmap.reserve(elementcount); - - for (size_t i = 0; i < elementcount; i++) - { - lua_rawgeti(L, tableidx, i + 1); - if (!lua_isnumber(L, -1)) - return luaL_argerror(L, tableidx + 1, "vertex index expected"); - - vertexmap.push_back(lua_tointeger(L, -1) - 1); - lua_pop(L, 1); - } - - // We don't want to read the vertex map as a vertex table later. - lua_remove(L, -1); - } - - size_t vertexcount = is_table ? lua_objlen(L, 1) : lua_gettop(L); - if (vertexcount < 3) - return luaL_error(L, "At least three points are needed to construct a Geometry."); - - if (!lua_checkstack(L, 9)) - return luaL_error(L, "Too many arguments!"); - - bool hasvertexcolors = false; - - std::vector vertices; - vertices.reserve(vertexcount); - - for (size_t i = 0; i < vertexcount; ++i) - { - Vertex v; - - if (is_table) - { - lua_rawgeti(L, 1, i+1); - if (!lua_istable(L, -1)) - return luax_typerror(L, 1, "table of tables"); - } - else - { - // Push the vertex table at this arg index to the top of the stack. - luaL_checktype(L, i + 1, LUA_TTABLE); - lua_pushvalue(L, i + 1); - } - - for (int j = 1; j <= 8; j++) - lua_rawgeti(L, -j, j); - - v.x = luaL_checknumber(L, -8); - v.y = luaL_checknumber(L, -7); - - v.s = luaL_checknumber(L, -6); - v.t = luaL_checknumber(L, -5); - - v.r = luaL_optinteger(L, -4, 255); - v.g = luaL_optinteger(L, -3, 255); - v.b = luaL_optinteger(L, -2, 255); - v.a = luaL_optinteger(L, -1, 255); - - lua_pop(L, 9); - - // Custom vertex colors are disabled by default unless a unique color - // is used for at least one vertex. - if (v.r != 255 || v.g != 255 || v.b != 255 || v.a != 255) - hasvertexcolors = true; - - vertices.push_back(v); - } - - Geometry *geom = 0; - EXCEPT_GUARD(geom = instance->newGeometry(vertices, vertexmap, mode);) - - if (geom == 0) - return luaL_error(L, "Could not create geometry."); - - geom->setVertexColors(hasvertexcolors); - - // Note: This should be changed to luax_pushtype if the new Geometry is ever - // expected to be pushed to Lua from another C++ function! - // We're only using rawnewtype instead of pushtype for performance. - luax_rawnewtype(L, "Geometry", GRAPHICS_GEOMETRY_T, geom); - return 1; -} - int w_newQuad(lua_State *L) { - float x = (float) luaL_checknumber(L, 1); - float y = (float) luaL_checknumber(L, 2); - float w = (float) luaL_checknumber(L, 3); - float h = (float) luaL_checknumber(L, 4); - float sw = (float) luaL_checknumber(L, 5); - float sh = (float) luaL_checknumber(L, 6); + Quad::Viewport v; + v.x = (float) luaL_checknumber(L, 1); + v.y = (float) luaL_checknumber(L, 1); + v.w = (float) luaL_checknumber(L, 1); + v.h = (float) luaL_checknumber(L, 1); - Geometry *quad = instance->newQuad(x, y, w, h, sw, sh); + float sw = (float) luaL_checknumber(L, 1); + float sh = (float) luaL_checknumber(L, 1); - // Note: This should be changed to luax_pushtype if the new Geometry is ever - // expected to be pushed to Lua from another C++ function! - // We're only using rawnewtype instead of pushtype for performance. - luax_rawnewtype(L, "Geometry", GRAPHICS_GEOMETRY_T, quad); + Quad *quad = instance->newQuad(v, sw, sh); + luax_pushtype(L, "Quad", GRAPHICS_QUAD_T, quad); return 1; } @@ -568,6 +431,66 @@ int w_newShader(lua_State *L) return 1; } +int w_newMesh(lua_State *L) +{ + // Check first argument: mandatory table of vertices. + luaL_checktype(L, 1, LUA_TTABLE); + + // Second argument: optional image. + Image *img = 0; + if (!lua_isnoneornil(L, 2)) + img = luax_checkimage(L, 2); + + // Third argument: optional draw mode. + const char *str = 0; + Mesh::DrawMode mode = Mesh::DRAW_MODE_FAN; + str = lua_isnoneornil(L, 3) ? 0 : luaL_checkstring(L, 3); + + if (str && !Mesh::getConstant(str, mode)) + return luaL_error(L, "Invalid mesh draw mode: %s", str); + + size_t vertex_count = lua_objlen(L, 1); + std::vector vertices; + vertices.reserve(vertex_count); + + // Get the vertices from the table. + for (size_t i = 1; i <= vertex_count; i++) + { + lua_rawgeti(L, 1, i); + + if (lua_type(L, -1) != LUA_TTABLE) + return luax_typerror(L, 2, "table of tables"); + + for (int j = 1; j <= 8; j++) + lua_rawgeti(L, -j, j); + + Vertex v; + + v.x = (float) luaL_checknumber(L, -8); + v.y = (float) luaL_checknumber(L, -7); + + v.s = (float) luaL_checknumber(L, -6); + v.t = (float) luaL_checknumber(L, -5); + + v.r = (unsigned char) luaL_optinteger(L, -4, 255); + v.g = (unsigned char) luaL_optinteger(L, -3, 255); + v.b = (unsigned char) luaL_optinteger(L, -2, 255); + v.a = (unsigned char) luaL_optinteger(L, -1, 255); + + lua_pop(L, 9); + vertices.push_back(v); + } + + Mesh *t = 0; + EXCEPT_GUARD(t = instance->newMesh(vertices, mode);) + + if (img) + t->setImage(img); + + luax_pushtype(L, "Mesh", GRAPHICS_MESH_T, t); + return 1; +} + int w_setColor(lua_State *L) { Color c; @@ -1076,14 +999,14 @@ int w_getRendererInfo(lua_State *L) int w_draw(lua_State *L) { Drawable *drawable = 0; - DrawGable *drawgable = 0; - Geometry *geom = 0; + DrawQable *drawqable = 0; + Quad *quad = 0; int startidx = 2; - if (luax_istype(L, 2, GRAPHICS_GEOMETRY_T)) + if (luax_istype(L, 2, GRAPHICS_QUAD_T)) { - drawgable = luax_checktype(L, 1, "DrawGable", GRAPHICS_DRAWGABLE_T); - geom = luax_totype(L, 2, "Geometry", GRAPHICS_GEOMETRY_T); + drawqable = luax_checktype(L, 1, "DrawQable", GRAPHICS_DRAWQABLE_T); + quad = luax_totype(L, 2, "Quad", GRAPHICS_QUAD_T); startidx = 3; } else @@ -1102,8 +1025,8 @@ int w_draw(lua_State *L) float kx = (float) luaL_optnumber(L, startidx + 7, 0.0); float ky = (float) luaL_optnumber(L, startidx + 8, 0.0); - if (drawgable && geom) - drawgable->drawg(geom, x, y, a, sx, sy, ox, oy, kx, ky); + if (drawqable && quad) + drawqable->drawq(quad, x, y, a, sx, sy, ox, oy, kx, ky); else if (drawable) drawable->draw(x, y, a, sx, sy, ox, oy, kx, ky); @@ -1371,13 +1294,13 @@ static const luaL_Reg functions[] = { "newImage", w_newImage }, { "newQuad", w_newQuad }, - { "newGeometry", w_newGeometry }, { "newFont", w_newFont }, { "newImageFont", w_newImageFont }, { "newSpriteBatch", w_newSpriteBatch }, { "newParticleSystem", w_newParticleSystem }, { "newCanvas", w_newCanvas }, { "newShader", w_newShader }, + { "newMesh", w_newMesh }, { "setColor", w_setColor }, { "getColor", w_getColor }, @@ -1457,11 +1380,12 @@ static const lua_CFunction types[] = { luaopen_font, luaopen_image, - luaopen_geometry, + luaopen_quad, luaopen_spritebatch, luaopen_particlesystem, luaopen_canvas, luaopen_shader, + luaopen_mesh, 0 }; diff --git a/src/modules/graphics/opengl/wrap_Graphics.h b/src/modules/graphics/opengl/wrap_Graphics.h index 5bc069bff..c6c4fe785 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.h +++ b/src/modules/graphics/opengl/wrap_Graphics.h @@ -24,11 +24,12 @@ // LOVE #include "wrap_Font.h" #include "wrap_Image.h" -#include "wrap_Geometry.h" +#include "wrap_Quad.h" #include "wrap_SpriteBatch.h" #include "wrap_ParticleSystem.h" #include "wrap_Canvas.h" #include "wrap_Shader.h" +#include "wrap_Mesh.h" #include "Graphics.h" namespace love @@ -50,7 +51,6 @@ int w_getScissor(lua_State *L); int w_setStencil(lua_State *L); int w_getMaxImageSize(lua_State *L); int w_newImage(lua_State *L); -int w_newGeometry(lua_State *L); int w_newQuad(lua_State *L); int w_newFont(lua_State *L); int w_newImageFont(lua_State *L); @@ -58,6 +58,7 @@ int w_newSpriteBatch(lua_State *L); int w_newParticleSystem(lua_State *L); int w_newCanvas(lua_State *L); // comments in function int w_newShader(lua_State *L); +int w_newMesh(lua_State *L); int w_setColor(lua_State *L); int w_getColor(lua_State *L); int w_setBackgroundColor(lua_State *L); @@ -91,7 +92,6 @@ int w_getShader(lua_State *L); int w_isSupported(lua_State *L); int w_getRendererInfo(lua_State *L); int w_draw(lua_State *L); -int w_drawg(lua_State *L); int w_print(lua_State *L); int w_printf(lua_State *L); int w_point(lua_State *L); diff --git a/src/modules/graphics/opengl/wrap_Mesh.cpp b/src/modules/graphics/opengl/wrap_Mesh.cpp new file mode 100644 index 000000000..32ed7a8e0 --- /dev/null +++ b/src/modules/graphics/opengl/wrap_Mesh.cpp @@ -0,0 +1,263 @@ +/** + * Copyright (c) 2006-2013 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +// LOVE +#include "wrap_Mesh.h" +#include "wrap_Image.h" + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +Mesh *luax_checkmesh(lua_State *L, int idx) +{ + return luax_checktype(L, idx, "Mesh", GRAPHICS_MESH_T); +} + +int w_Mesh_setVertex(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + size_t i = size_t(luaL_checkinteger(L, 2) - 1); + + Vertex v; + + if (lua_istable(L, 3)) + { + for (int i = 1; i <= 8; i++) + lua_rawgeti(L, 3, i); + + v.x = luaL_checknumber(L, -8); + v.y = luaL_checknumber(L, -7); + v.s = luaL_checknumber(L, -6); + v.t = luaL_checknumber(L, -5); + v.r = luaL_optinteger(L, -4, 255); + v.g = luaL_optinteger(L, -3, 255); + v.b = luaL_optinteger(L, -2, 255); + v.a = luaL_optinteger(L, -1, 255); + + lua_pop(L, 8); + } + else + { + v.x = luaL_checknumber(L, 3); + v.y = luaL_checknumber(L, 4); + v.s = luaL_checknumber(L, 5); + v.t = luaL_checknumber(L, 6); + v.r = luaL_optinteger(L, 7, 255); + v.g = luaL_optinteger(L, 8, 255); + v.b = luaL_optinteger(L, 9, 255); + v.a = luaL_optinteger(L, 10, 255); + } + + EXCEPT_GUARD(t->setVertex(i, v);) + return 0; +} + +int w_Mesh_getVertex(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + size_t i = (size_t) (luaL_checkinteger(L, 2) - 1); + + Vertex v; + EXCEPT_GUARD(v = t->getVertex(i);) + + lua_pushnumber(L, v.x); + lua_pushnumber(L, v.y); + lua_pushnumber(L, v.s); + lua_pushnumber(L, v.t); + lua_pushnumber(L, v.r); + lua_pushnumber(L, v.g); + lua_pushnumber(L, v.b); + lua_pushnumber(L, v.a); + + return 8; +} + +int w_Mesh_getVertices(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + const std::vector &vertices = t->getVertices(); + + lua_createtable(L, vertices.size(), 0); + + for (size_t i = 0; i < vertices.size(); i++) + { + lua_createtable(L, 8, 0); + const Vertex &v = vertices[i]; + + lua_pushnumber(L, v.x); + lua_rawseti(L, -2, 1); + + lua_pushnumber(L, v.y); + lua_rawseti(L, -2, 2); + + lua_pushnumber(L, v.s); + lua_rawseti(L, -2, 3); + + lua_pushnumber(L, v.t); + lua_rawseti(L, -2, 4); + + lua_pushnumber(L, v.r); + lua_rawseti(L, -2, 5); + + lua_pushnumber(L, v.g); + lua_rawseti(L, -2, 6); + + lua_pushnumber(L, v.b); + lua_rawseti(L, -2, 7); + + lua_pushnumber(L, v.a); + lua_rawseti(L, -2, 8); + + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +int w_Mesh_getVertexCount(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + lua_pushinteger(L, t->getVertexCount()); + return 1; +} + +int w_Mesh_setVertexMap(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + + bool is_table = lua_istable(L, 2); + int nargs = is_table ? lua_objlen(L, 2) : lua_gettop(L) - 1; + + std::vector vertexmap; + vertexmap.reserve(nargs); + + for (int i = 0; i < nargs; i++) + { + if (is_table) + { + lua_rawgeti(L, 2, i + 1); + vertexmap.push_back(uint16(luaL_checkinteger(L, -1) - 1)); + lua_pop(L, 1); + } + else + vertexmap.push_back(uint16(luaL_checkinteger(L, i + 2) - 1)); + } + + EXCEPT_GUARD(t->setVertexMap(vertexmap);) + return 0; +} + +int w_Mesh_getVertexMap(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + + const std::vector &map = t->getVertexMap(); + lua_createtable(L, map.size(), 0); + + for (size_t i = 0; i < map.size(); i++) + { + lua_pushinteger(L, map[i] + 1); + lua_rawseti(L, -2, i + 1); + } + + return 1; +} + +int w_Mesh_setImage(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + + if (lua_isnoneornil(L, 2)) + t->setImage(); + else + { + Image *img = luax_checkimage(L, 2); + t->setImage(img); + } + + return 0; +} + +int w_Mesh_getImage(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + Image *img = t->getImage(); + + if (img == NULL) + return 0; + + img->retain(); + luax_pushtype(L, "Image", GRAPHICS_IMAGE_T, img); + return 1; +} + +int w_Mesh_setDrawMode(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + const char *str = luaL_checkstring(L, 2); + Mesh::DrawMode mode; + + if (!Mesh::getConstant(str, mode)) + return luaL_error(L, "Invalid mesh draw mode: %s", str); + + t->setDrawMode(mode); + return 0; +} + +int w_Mesh_getDrawMode(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + Mesh::DrawMode mode = t->getDrawMode(); + const char *str; + + if (!Mesh::getConstant(mode, str)) + return luaL_error(L, "Unknown mesh draw mode."); + + lua_pushstring(L, str); + return 1; +} + +static const luaL_Reg functions[] = +{ + { "setVertex", w_Mesh_setVertex }, + { "getVertex", w_Mesh_getVertex }, + { "getVertices", w_Mesh_getVertices }, + { "getVertexCount", w_Mesh_getVertexCount }, + { "setVertexMap", w_Mesh_setVertexMap }, + { "getVertexMap", w_Mesh_getVertexMap }, + { "setImage", w_Mesh_setImage }, + { "getImage", w_Mesh_getImage }, + { "setDrawMode", w_Mesh_setDrawMode }, + { "getDrawMode", w_Mesh_getDrawMode }, + { 0, 0 } +}; + +extern "C" int luaopen_mesh(lua_State *L) +{ + return luax_register_type(L, "Mesh", functions); +} + +} // opengl +} // graphics +} // love diff --git a/src/modules/graphics/opengl/wrap_Geometry.h b/src/modules/graphics/opengl/wrap_Mesh.h similarity index 63% rename from src/modules/graphics/opengl/wrap_Geometry.h rename to src/modules/graphics/opengl/wrap_Mesh.h index b6f800e78..b6e09c924 100644 --- a/src/modules/graphics/opengl/wrap_Geometry.h +++ b/src/modules/graphics/opengl/wrap_Mesh.h @@ -18,12 +18,12 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#ifndef LOVE_GRAPHICS_OPENGL_WRAP_GEOMETRY_H -#define LOVE_GRAPHICS_OPENGL_WRAP_GEOMETRY_H +#ifndef LOVE_GRAPHICS_OPENGL_WRAP_MESH_H +#define LOVE_GRAPHICS_OPENGL_WRAP_MESH_H // LOVE #include "common/runtime.h" -#include "graphics/Geometry.h" +#include "Mesh.h" namespace love { @@ -32,19 +32,23 @@ namespace graphics namespace opengl { -Geometry *luax_checkgeometry(lua_State *L, int idx); -int w_Geometry_getVertexCount(lua_State *L); -int w_Geometry_getVertex(lua_State *L); -int w_Geometry_setVertex(lua_State *L); -int w_Geometry_setVertexColors(lua_State *L); -int w_Geometry_hasVertexColors(lua_State *L); -int w_Geometry_getDrawMode(lua_State *L); -int w_Geometry_getVertexMap(lua_State *L); -int w_Geometry_setVertexMap(lua_State *L); -extern "C" int luaopen_geometry(lua_State *L); +Mesh *luax_checkmesh(lua_State *L, int idx); + +int w_Mesh_setVertex(lua_State *L); +int w_Mesh_getVertex(lua_State *L); +int w_Mesh_getVertices(lua_State *L); +int w_Mesh_getVertexCount(lua_State *L); +int w_Mesh_setVertexMap(lua_State *L); +int w_Mesh_getVertexMap(lua_State *L); +int w_Mesh_setImage(lua_State *L); +int w_Mesh_getImage(lua_State *L); +int w_Mesh_setDrawMode(lua_State *L); +int w_Mesh_getDrawMode(lua_State *L); + +extern "C" int luaopen_mesh(lua_State *L); } // opengl } // graphics } // love -#endif // LOVE_GRAPHICS_OPENGL_WRAP_GEOMETRY_H +#endif // LOVE_GRAPHICS_OPENGL_WRAP_MESH_H diff --git a/src/modules/graphics/opengl/wrap_Quad.cpp b/src/modules/graphics/opengl/wrap_Quad.cpp new file mode 100644 index 000000000..be03344f2 --- /dev/null +++ b/src/modules/graphics/opengl/wrap_Quad.cpp @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2006-2013 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +// LOVE +#include "wrap_Quad.h" + +namespace love +{ +namespace graphics +{ +namespace opengl +{ + +Quad *luax_checkquad(lua_State *L, int idx) +{ + return luax_checktype(L, idx, "Quad", GRAPHICS_QUAD_T); +} + +int w_Quad_flip(lua_State *L) +{ + Quad *quad = luax_checkquad(L, 1); + quad->flip(luax_toboolean(L, 2), luax_toboolean(L, 3)); + return 0; +} + +int w_Quad_setViewport(lua_State *L) +{ + Quad *quad = luax_checkquad(L, 1); + + Quad::Viewport v; + v.x = (float) luaL_checknumber(L, 2); + v.y = (float) luaL_checknumber(L, 3); + v.w = (float) luaL_checknumber(L, 4); + v.h = (float) luaL_checknumber(L, 5); + + if (lua_isnoneornil(L, 6)) + quad->setViewport(v); + else + { + float sw = (float) luaL_checknumber(L, 6); + float sh = (float) luaL_checknumber(L, 7); + quad->refresh(v, sw, sh); + } + + return 0; +} + +int w_Quad_getViewport(lua_State *L) +{ + Quad *quad = luax_checkquad(L, 1); + Quad::Viewport v = quad->getViewport(); + lua_pushnumber(L, v.x); + lua_pushnumber(L, v.y); + lua_pushnumber(L, v.w); + lua_pushnumber(L, v.h); + return 4; +} + +static const luaL_Reg functions[] = +{ + { "flip", w_Quad_flip }, + { "setViewport", w_Quad_setViewport }, + { "getViewport", w_Quad_getViewport }, + { 0, 0 } +}; + +extern "C" int luaopen_quad(lua_State *L) +{ + return luax_register_type(L, "Quad", functions); +} + +} // opengl +} // graphics +} // love diff --git a/src/modules/graphics/DrawGable.cpp b/src/modules/graphics/opengl/wrap_Quad.h similarity index 70% rename from src/modules/graphics/DrawGable.cpp rename to src/modules/graphics/opengl/wrap_Quad.h index 4c1aa5aac..55a9377f8 100644 --- a/src/modules/graphics/DrawGable.cpp +++ b/src/modules/graphics/opengl/wrap_Quad.h @@ -18,16 +18,28 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -#include "DrawGable.h" +#ifndef LOVE_GRAPHICS_OPENGL_WRAP_QUAD_H +#define LOVE_GRAPHICS_OPENGL_WRAP_QUAD_H + +// LOVE +#include "common/runtime.h" +#include "graphics/Quad.h" namespace love { namespace graphics { - -DrawGable::~DrawGable() +namespace opengl { -} +Quad *luax_checkquad(lua_State *L, int idx); +int w_Quad_flip(lua_State *L); +int w_Quad_setViewport(lua_State *L); +int w_Quad_getViewport(lua_State *L); +extern "C" int luaopen_quad(lua_State *L); + +} // opengl } // graphics } // love + +#endif // LOVE_GRAPHICS_OPENGL_WRAP_QUAD_H diff --git a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp b/src/modules/graphics/opengl/wrap_SpriteBatch.cpp index 5968877c8..7656b7492 100644 --- a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp +++ b/src/modules/graphics/opengl/wrap_SpriteBatch.cpp @@ -36,12 +36,12 @@ SpriteBatch *luax_checkspritebatch(lua_State *L, int idx) int w_SpriteBatch_add(lua_State *L) { SpriteBatch *t = luax_checkspritebatch(L, 1); - Geometry *geom = 0; + Quad *quad = 0; int startidx = 2; - if (luax_istype(L, 2, GRAPHICS_GEOMETRY_T)) + if (luax_istype(L, 2, GRAPHICS_QUAD_T)) { - geom = luax_totype(L, 2, "Geometry", GRAPHICS_GEOMETRY_T); + quad = luax_totype(L, 2, "Quad", GRAPHICS_QUAD_T); startidx = 3; } @@ -57,8 +57,8 @@ int w_SpriteBatch_add(lua_State *L) int id = 0; EXCEPT_GUARD( - if (geom) - id = t->addg(geom, x, y, a, sx, sy, ox, oy, kx, ky); + if (quad) + id = t->addq(quad, x, y, a, sx, sy, ox, oy, kx, ky); else id = t->add(x, y, a, sx, sy, ox, oy, kx, ky); ) @@ -72,12 +72,12 @@ int w_SpriteBatch_set(lua_State *L) SpriteBatch *t = luax_checkspritebatch(L, 1); int id = luaL_checkinteger(L, 2); - Geometry *geom = 0; + Quad *quad = 0; int startidx = 3; - if (luax_istype(L, 3, GRAPHICS_GEOMETRY_T)) + if (luax_istype(L, 3, GRAPHICS_QUAD_T)) { - geom = luax_totype(L, 3, "Geometry", GRAPHICS_GEOMETRY_T); + quad = luax_totype(L, 3, "Quad", GRAPHICS_QUAD_T); startidx = 4; } @@ -92,8 +92,8 @@ int w_SpriteBatch_set(lua_State *L) float ky = (float) luaL_optnumber(L, startidx + 8, 0.0); EXCEPT_GUARD( - if (geom) - t->addg(geom, x, y, a, sx, sy, ox, oy, kx, ky, id); + if (quad) + t->addq(quad, x, y, a, sx, sy, ox, oy, kx, ky, id); else t->add(x, y, a, sx, sy, ox, oy, kx, ky, id); ) From b59e3d9c35e5318966d999d0033ac27d76002126 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 29 Sep 2013 21:24:19 -0300 Subject: [PATCH 2/5] Meshes now use vertex buffers for more efficient drawing. --HG-- branch : Mesh --- src/modules/graphics/opengl/Mesh.cpp | 159 ++++++++++++++---- src/modules/graphics/opengl/Mesh.h | 49 ++++-- src/modules/graphics/opengl/VertexBuffer.cpp | 53 +++--- src/modules/graphics/opengl/VertexBuffer.h | 52 ++++-- src/modules/graphics/opengl/wrap_Graphics.cpp | 8 + src/modules/graphics/opengl/wrap_Mesh.cpp | 69 +++----- src/modules/graphics/opengl/wrap_Mesh.h | 3 +- 7 files changed, 268 insertions(+), 125 deletions(-) diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp index e1b77f733..deb54e9b4 100644 --- a/src/modules/graphics/opengl/Mesh.cpp +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -31,64 +31,131 @@ namespace opengl { Mesh::Mesh(const std::vector &verts, Mesh::DrawMode mode) - : draw_mode(mode) + : vbo(0) + , vertex_count(0) + , ibo(0) + , element_count(0) + , draw_mode(mode) , image(0) + , colors_enabled(false) { setVertices(verts); } +Mesh::~Mesh() +{ + delete vbo; + delete ibo; +} + void Mesh::setVertices(const std::vector &verts) { if (verts.size() < 3) throw love::Exception("At least 3 vertices are required."); - vertices = verts; + size_t size = sizeof(Vertex) * verts.size(); + + if (vbo && size > vbo->getSize()) + { + delete vbo; + vbo = 0; + } + + if (!vbo) + { + // Full memory backing because we might access the data at any time. + vbo = VertexBuffer::Create(size, GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, VertexBuffer::BACKING_FULL); + } + + vertex_count = verts.size(); + + VertexBuffer::Bind vbo_bind(*vbo); + VertexBuffer::Mapper vbo_mapper(*vbo); + + // Fill the buffer with the vertices. + memcpy(vbo_mapper.get(), &verts[0], size); } -const std::vector &Mesh::getVertices() const +void Mesh::setVertex(size_t index, const Vertex &v) { - return vertices; + if (index >= vertex_count) + throw love::Exception("Invalid vertex index: %ld", index); + + VertexBuffer::Bind vbo_bind(*vbo); + + // We unmap the vertex buffer in Mesh::draw. This lets us coalesce the + // buffer transfer calls. + Vertex *vertices = (Vertex *) vbo->map(); + vertices[index] = v; } -void Mesh::setVertex(size_t i, Vertex v) +Vertex Mesh::getVertex(size_t index) const { - if (i >= vertices.size()) - throw love::Exception("Invalid index."); + if (index >= vertex_count) + throw love::Exception("Invalid vertex index: %ld", index); - vertices[i] = v; -} + VertexBuffer::Bind vbo_bind(*vbo); -Vertex Mesh::getVertex(size_t i) const -{ - if (i >= vertices.size()) - throw love::Exception("Invalid index."); - - return vertices[i]; + // We unmap the vertex buffer in Mesh::draw. + Vertex *vertices = (Vertex *) vbo->map(); + return vertices[index]; } size_t Mesh::getVertexCount() const { - return vertices.size(); + return vertex_count; } void Mesh::setVertexMap(const std::vector &map) { for (size_t i = 0; i < map.size(); i++) { - if (map[i] >= vertices.size()) + if (map[i] >= vertex_count) throw love::Exception("Invalid vertex map value: %d", map[i]); } - vertex_map = map; + size_t size = sizeof(uint16) * map.size(); + + if (ibo && size > ibo->getSize()) + { + delete ibo; + ibo = 0; + } + + if (!ibo) + { + // Full memory backing because we might access the data at any time. + ibo = VertexBuffer::Create(size, GL_ELEMENT_ARRAY_BUFFER, GL_DYNAMIC_DRAW, VertexBuffer::BACKING_FULL); + } + + element_count = map.size(); + + if (element_count > 0) + { + VertexBuffer::Bind ibo_bind(*ibo); + VertexBuffer::Mapper ibo_map(*ibo); + + // Fill the buffer. + memcpy(ibo_map.get(), &map[0], size); + } } -const std::vector &Mesh::getVertexMap() const +const uint16 *Mesh::getVertexMap() const { - return vertex_map; + if (ibo && element_count > 0) + { + VertexBuffer::Bind ibo_bind(*ibo); + + // We unmap the buffer in Mesh::draw and Mesh::setVertexMap. + return (uint16 *) ibo->map(); + } + + return 0; } -Mesh::~Mesh() +size_t Mesh::getVertexMapCount() const { + return element_count; } void Mesh::setImage(Image *img) @@ -124,9 +191,23 @@ Mesh::DrawMode Mesh::getDrawMode() const return draw_mode; } +void Mesh::setVertexColors(bool enable) +{ + colors_enabled = enable; +} + +bool Mesh::hasVertexColors() const +{ + return colors_enabled; +} + void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const { - if (vertices.size() == 0) + const size_t pos_offset = offsetof(Vertex, x); + const size_t tex_offset = offsetof(Vertex, s); + const size_t color_offset = offsetof(Vertex, r); + + if (vertex_count == 0) return; if (image) @@ -140,29 +221,49 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo glPushMatrix(); glMultMatrixf(m.getElements()); + VertexBuffer::Bind vbo_bind(*vbo); + + // Make sure the VBO isn't mapped when we draw (sends data to GPU if needed.) + vbo->unmap(); + glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &(vertices[0].x)); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &(vertices[0].s)); + glVertexPointer(2, GL_FLOAT, sizeof(Vertex), vbo->getPointer(pos_offset)); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), vbo->getPointer(tex_offset)); + if (hasVertexColors()) { + // Per-vertex colors. glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), &(vertices[0].r)); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), vbo->getPointer(color_offset)); } - GLenum gl_draw_mode = getGLDrawMode(draw_mode); + GLenum mode = getGLDrawMode(draw_mode); - if (vertex_map.size() > 0) - glDrawElements(gl_draw_mode, vertex_map.size(), GL_UNSIGNED_SHORT, &vertex_map[0]); + if (element_count > 0) + { + VertexBuffer::Bind ibo_bind(*ibo); + + // Make sure the index buffer isn't mapped (sends data to GPU if needed.) + ibo->unmap(); + + // Use the custom vertex map to draw the vertices. + glDrawElements(mode, element_count, GL_UNSIGNED_SHORT, ibo->getPointer(0)); + } else - glDrawArrays(gl_draw_mode, 0, vertices.size()); + { + // Normal non-indexed drawing (no custom vertex map.) + glDrawArrays(mode, 0, vertex_count); + } glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); + if (hasVertexColors()) { glDisableClientState(GL_COLOR_ARRAY); + // Using the color array leaves the GL constant color undefined. gl.setColor(gl.getColor()); } diff --git a/src/modules/graphics/opengl/Mesh.h b/src/modules/graphics/opengl/Mesh.h index 8e1983bc0..4515bd2c4 100644 --- a/src/modules/graphics/opengl/Mesh.h +++ b/src/modules/graphics/opengl/Mesh.h @@ -25,9 +25,9 @@ #include "common/int.h" #include "common/math.h" #include "common/StringMap.h" -#include "graphics/Volatile.h" #include "graphics/Drawable.h" -#include "graphics/opengl/Image.h" +#include "Image.h" +#include "VertexBuffer.h" // C++ #include @@ -41,7 +41,7 @@ namespace opengl /** * Holds and draws arbitrary vertex geometry. - * Each vertex in a Mesh has a position, texture coordinate, and color. + * Each vertex in the Mesh has a position, texture coordinate, and color. **/ class Mesh : public Drawable { @@ -71,18 +71,13 @@ public: **/ void setVertices(const std::vector &verts); - /** - * Gets a reference to the vertices used in the Mesh. - **/ - const std::vector &getVertices() const; - /** * Sets an individual vertex in the Mesh. - * @param i The index into the list of vertices to use. + * @param index The index into the list of vertices to use. * @param v The new vertex. **/ - void setVertex(size_t i, Vertex v); - Vertex getVertex(size_t i) const; + void setVertex(size_t index, const Vertex &v); + Vertex getVertex(size_t index) const; /** * Gets the total number of vertices in the Mesh. @@ -96,7 +91,18 @@ public: * {0, 1, 2, 3, 4, ...} **/ void setVertexMap(const std::vector &map); - const std::vector &getVertexMap() const; + + /** + * Gets a pointer to the vertex map array. The pointer is only valid until + * the next function call in the graphics module. + * May return null if the vertex map is empty. + **/ + const uint16 *getVertexMap() const; + + /** + * Gets the total number of elements in the vertex map array. + **/ + size_t getVertexMapCount() const; /** * Sets the Image used when drawing the Mesh. @@ -120,6 +126,13 @@ public: void setDrawMode(DrawMode mode); DrawMode getDrawMode() const; + /** + * Sets whether per-vertex colors are enabled. If this is disabled, the + * global color (love.graphics.setColor) will be used for the entire Mesh. + **/ + void setVertexColors(bool enable); + bool hasVertexColors() const; + // Implements Drawable. void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; @@ -130,13 +143,21 @@ private: GLenum getGLDrawMode(DrawMode mode) const; - std::vector vertices; - std::vector vertex_map; + // Vertex buffer. + VertexBuffer *vbo; + size_t vertex_count; + + // Element (vertex index) buffer, for the vertex map. + VertexBuffer *ibo; + size_t element_count; DrawMode draw_mode; Image *image; + // Whether the per-vertex colors are used when drawing. + bool colors_enabled; + static StringMap::Entry drawModeEntries[]; static StringMap drawModes; diff --git a/src/modules/graphics/opengl/VertexBuffer.cpp b/src/modules/graphics/opengl/VertexBuffer.cpp index bac1a8e13..fa45a8bbb 100644 --- a/src/modules/graphics/opengl/VertexBuffer.cpp +++ b/src/modules/graphics/opengl/VertexBuffer.cpp @@ -42,25 +42,27 @@ namespace opengl // VertexBuffer -VertexBuffer *VertexBuffer::Create(size_t size, GLenum target, GLenum usage) +VertexBuffer *VertexBuffer::Create(size_t size, GLenum target, GLenum usage, MemoryBacking backing) { try { // Try to create a VBO. - return new VBO(size, target, usage); + return new VBO(size, target, usage, backing); } catch(const love::Exception &) { // VBO not supported ... create regular array. - return new VertexArray(size, target, usage); + return new VertexArray(size, target, usage, backing); } } -VertexBuffer::VertexBuffer(size_t size, GLenum target, GLenum usage) +VertexBuffer::VertexBuffer(size_t size, GLenum target, GLenum usage, MemoryBacking backing) : is_bound(false) + , is_mapped(false) , size(size) , target(target) , usage(usage) + , backing(backing) { } @@ -70,8 +72,8 @@ VertexBuffer::~VertexBuffer() // VertexArray -VertexArray::VertexArray(size_t size, GLenum target, GLenum usage) - : VertexBuffer(size, target, usage) +VertexArray::VertexArray(size_t size, GLenum target, GLenum usage, MemoryBacking backing) + : VertexBuffer(size, target, usage, backing) , buf(new char[size]) { } @@ -83,11 +85,13 @@ VertexArray::~VertexArray() void *VertexArray::map() { + is_mapped = true; return buf; } void VertexArray::unmap() { + is_mapped = false; } void VertexArray::bind() @@ -112,20 +116,25 @@ const void *VertexArray::getPointer(size_t offset) const // VBO -VBO::VBO(size_t size, GLenum target, GLenum usage) - : VertexBuffer(size, target, usage) +VBO::VBO(size_t size, GLenum target, GLenum usage, MemoryBacking backing) + : VertexBuffer(size, target, usage, backing) , vbo(0) , memory_map(0) - , is_mapped(false) , is_dirty(true) { if (!(GLEE_ARB_vertex_buffer_object || GLEE_VERSION_1_5)) throw love::Exception("Not supported"); + if (getMemoryBacking() == BACKING_FULL) + memory_map = malloc(getSize()); + bool ok = load(false); if (!ok) + { + free(memory_map); throw love::Exception("Could not load VBO."); + } } VBO::~VBO() @@ -150,10 +159,12 @@ void *VBO::map() } if (is_dirty) + { glGetBufferSubDataARB(getTarget(), 0, getSize(), memory_map); + is_dirty = false; + } is_mapped = true; - is_dirty = false; return memory_map; } @@ -198,11 +209,10 @@ void VBO::unbind() void VBO::fill(size_t offset, size_t size, const void *data) { - if (is_mapped) - { + if (is_mapped || getMemoryBacking() == BACKING_FULL) memcpy(static_cast(memory_map) + offset, data, size); - } - else + + if (!is_mapped) { // Not all systems have access to some faster paths... if (GLEE_APPLE_flush_buffer_range) @@ -226,7 +236,8 @@ void VBO::fill(size_t offset, size_t size, const void *data) glBufferSubDataARB(getTarget(), offset, size, data); } - is_dirty = true; + if (getMemoryBacking() != BACKING_FULL) + is_dirty = true; } } @@ -257,23 +268,23 @@ bool VBO::load(bool restore) while (GL_NO_ERROR != glGetError()) /* clear error messages */; - // Note that if 'src' is '0', no data will be copied. - glBufferDataARB(getTarget(), getSize(), src, getUsage()); - GLenum err = glGetError(); - // We don't want to flush the entire buffer when we just modify a small // portion of it (VBO::fill without VBO::map), so we'll handle the flushing // ourselves when we can. if (GLEE_APPLE_flush_buffer_range) glBufferParameteriAPPLE(getTarget(), GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE); + // Note that if 'src' is '0', no data will be copied. + glBufferDataARB(getTarget(), getSize(), src, getUsage()); + GLenum err = glGetError(); + return (GL_NO_ERROR == err); } void VBO::unload(bool save) { - // Save data before unloading. - if (save) + // Save data before unloading, if we need to. + if (save && getMemoryBacking() == BACKING_PARTIAL) { VertexBuffer::Bind bind(*this); diff --git a/src/modules/graphics/opengl/VertexBuffer.h b/src/modules/graphics/opengl/VertexBuffer.h index 4e9c8f474..61b098172 100644 --- a/src/modules/graphics/opengl/VertexBuffer.h +++ b/src/modules/graphics/opengl/VertexBuffer.h @@ -48,6 +48,18 @@ class VertexBuffer { public: + // Different guarantees for VertexBuffer data storage. + enum MemoryBacking + { + // The VertexBuffer is will have a valid copy of its data in main memory + // at all times. + BACKING_FULL, + + // The VertexBuffer will have a valid copy of its data in main memory + // when it needs to be reloaded and when it's mapped. + BACKING_PARTIAL + }; + /** * Create a new VertexBuffer (either a plain vertex array, or a VBO), * based on what's supported on the system. @@ -58,9 +70,10 @@ public: * @param size The size of the VertexBuffer (in bytes). * @param target GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER. * @param usage GL_DYNAMIC_DRAW, etc. + * @param backing Determines what guarantees are placed on the data. * @return A new VertexBuffer. */ - static VertexBuffer *Create(size_t size, GLenum target, GLenum usage); + static VertexBuffer *Create(size_t size, GLenum target, GLenum usage, MemoryBacking backing = BACKING_PARTIAL); /** * Constructor. @@ -68,8 +81,9 @@ public: * @param size The size of the VertexBuffer in bytes. * @param target The target VertexBuffer object, e.g. GL_ARRAY_BUFFER. * @param usage Usage hint, e.g. GL_DYNAMIC_DRAW. + * @param backing Determines what guarantees are placed on the data. */ - VertexBuffer(size_t size, GLenum target, GLenum usage); + VertexBuffer(size_t size, GLenum target, GLenum usage, MemoryBacking backing = BACKING_PARTIAL); /** * Destructor. Does nothing, but must be declared virtual. @@ -111,6 +125,16 @@ public: return is_bound; } + bool isMapped() const + { + return is_mapped; + } + + MemoryBacking getMemoryBacking() const + { + return backing; + } + /** * Map the VertexBuffer to client memory. * @@ -230,6 +254,9 @@ protected: // Whether the buffer is currently bound. bool is_bound; + // Whether the buffer is currently mapped to main memory. + bool is_mapped; + private: // The size of the buffer, in bytes. @@ -240,6 +267,9 @@ private: // Usage hint. GL_[DYNAMIC, STATIC, STREAM]_DRAW. GLenum usage; + + // + MemoryBacking backing; }; /** @@ -253,9 +283,9 @@ class VertexArray : public VertexBuffer public: /** - * @copydoc VertexBuffer(int, GLenum, GLenum) + * @copydoc VertexBuffer(int, GLenum, GLenum, Backing) */ - VertexArray(size_t size, GLenum target, GLenum usage); + VertexArray(size_t size, GLenum target, GLenum usage, MemoryBacking backing); /** * Frees the data we've allocated. @@ -281,19 +311,19 @@ private: * This will be used on all systems that support it. It's in general * faster than vertex arrays, but especially in use-cases where there * is no need to update the data every frame. - */ + **/ class VBO : public VertexBuffer, public Volatile { public: /** - * @copydoc VertexBuffer(size_t, GLenum, GLenum) - */ - VBO(size_t size, GLenum target, GLenum usage); + * @copydoc VertexBuffer(size_t, GLenum, GLenum, Backing) + **/ + VBO(size_t size, GLenum target, GLenum usage, MemoryBacking backing); /** * Deletes the VBOs from OpenGL. - */ + **/ virtual ~VBO(); // Implements VertexBuffer. @@ -332,10 +362,6 @@ private: // call to map(). void *memory_map; - // Set if the vbo currently operates on main instead of gpu - // memory. - bool is_mapped; - // Set if the buffer was modified while operating on gpu memory // and needs to be synchronized. bool is_dirty; diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index ad4b16eea..fa2c9bda8 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -453,6 +453,8 @@ int w_newMesh(lua_State *L) std::vector vertices; vertices.reserve(vertex_count); + bool use_colors = false; + // Get the vertices from the table. for (size_t i = 1; i <= vertex_count; i++) { @@ -477,6 +479,10 @@ int w_newMesh(lua_State *L) v.b = (unsigned char) luaL_optinteger(L, -2, 255); v.a = (unsigned char) luaL_optinteger(L, -1, 255); + // Enable per-vertex coloring if any color is not the default. + if (!use_colors && (v.r != 255 || v.g != 255 || v.b != 255 || v.a != 255)) + use_colors = true; + lua_pop(L, 9); vertices.push_back(v); } @@ -487,6 +493,8 @@ int w_newMesh(lua_State *L) if (img) t->setImage(img); + t->setVertexColors(use_colors); + luax_pushtype(L, "Mesh", GRAPHICS_MESH_T, t); return 1; } diff --git a/src/modules/graphics/opengl/wrap_Mesh.cpp b/src/modules/graphics/opengl/wrap_Mesh.cpp index 32ed7a8e0..41ebf0055 100644 --- a/src/modules/graphics/opengl/wrap_Mesh.cpp +++ b/src/modules/graphics/opengl/wrap_Mesh.cpp @@ -93,48 +93,6 @@ int w_Mesh_getVertex(lua_State *L) return 8; } -int w_Mesh_getVertices(lua_State *L) -{ - Mesh *t = luax_checkmesh(L, 1); - const std::vector &vertices = t->getVertices(); - - lua_createtable(L, vertices.size(), 0); - - for (size_t i = 0; i < vertices.size(); i++) - { - lua_createtable(L, 8, 0); - const Vertex &v = vertices[i]; - - lua_pushnumber(L, v.x); - lua_rawseti(L, -2, 1); - - lua_pushnumber(L, v.y); - lua_rawseti(L, -2, 2); - - lua_pushnumber(L, v.s); - lua_rawseti(L, -2, 3); - - lua_pushnumber(L, v.t); - lua_rawseti(L, -2, 4); - - lua_pushnumber(L, v.r); - lua_rawseti(L, -2, 5); - - lua_pushnumber(L, v.g); - lua_rawseti(L, -2, 6); - - lua_pushnumber(L, v.b); - lua_rawseti(L, -2, 7); - - lua_pushnumber(L, v.a); - lua_rawseti(L, -2, 8); - - lua_rawseti(L, -2, i + 1); - } - - return 1; -} - int w_Mesh_getVertexCount(lua_State *L) { Mesh *t = luax_checkmesh(L, 1); @@ -172,12 +130,14 @@ int w_Mesh_getVertexMap(lua_State *L) { Mesh *t = luax_checkmesh(L, 1); - const std::vector &map = t->getVertexMap(); - lua_createtable(L, map.size(), 0); + const uint16 *vertex_map = t->getVertexMap(); + size_t elements = t->getVertexMapCount(); - for (size_t i = 0; i < map.size(); i++) + lua_createtable(L, elements, 0); + + for (size_t i = 0; i < elements; i++) { - lua_pushinteger(L, map[i] + 1); + lua_pushinteger(L, lua_Integer(vertex_map[i]) + 1); lua_rawseti(L, -2, i + 1); } @@ -238,11 +198,24 @@ int w_Mesh_getDrawMode(lua_State *L) return 1; } +int w_Mesh_setVertexColors(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + t->setVertexColors(luax_toboolean(L, 2)); + return 0; +} + +int w_Mesh_hasVertexColors(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + luax_pushboolean(L, t->hasVertexColors()); + return 1; +} + static const luaL_Reg functions[] = { { "setVertex", w_Mesh_setVertex }, { "getVertex", w_Mesh_getVertex }, - { "getVertices", w_Mesh_getVertices }, { "getVertexCount", w_Mesh_getVertexCount }, { "setVertexMap", w_Mesh_setVertexMap }, { "getVertexMap", w_Mesh_getVertexMap }, @@ -250,6 +223,8 @@ static const luaL_Reg functions[] = { "getImage", w_Mesh_getImage }, { "setDrawMode", w_Mesh_setDrawMode }, { "getDrawMode", w_Mesh_getDrawMode }, + { "setVertexColors", w_Mesh_setVertexColors }, + { "hasVertexColors", w_Mesh_hasVertexColors }, { 0, 0 } }; diff --git a/src/modules/graphics/opengl/wrap_Mesh.h b/src/modules/graphics/opengl/wrap_Mesh.h index b6e09c924..7fa112a31 100644 --- a/src/modules/graphics/opengl/wrap_Mesh.h +++ b/src/modules/graphics/opengl/wrap_Mesh.h @@ -36,7 +36,6 @@ Mesh *luax_checkmesh(lua_State *L, int idx); int w_Mesh_setVertex(lua_State *L); int w_Mesh_getVertex(lua_State *L); -int w_Mesh_getVertices(lua_State *L); int w_Mesh_getVertexCount(lua_State *L); int w_Mesh_setVertexMap(lua_State *L); int w_Mesh_getVertexMap(lua_State *L); @@ -44,6 +43,8 @@ int w_Mesh_setImage(lua_State *L); int w_Mesh_getImage(lua_State *L); int w_Mesh_setDrawMode(lua_State *L); int w_Mesh_getDrawMode(lua_State *L); +int w_Mesh_setVertexColors(lua_State *L); +int w_Mesh_hasVertexColors(lua_State *L); extern "C" int luaopen_mesh(lua_State *L); From c426998b046a11b9530592b9081f2b01c7e067da Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 30 Sep 2013 04:30:17 -0300 Subject: [PATCH 3/5] Fixed Mesh:setVertexMap when the mesh has more than 2^16-1 vertices (still needs more work to make it use smaller data types when available), added Mesh:setVertices --HG-- branch : Mesh --- src/modules/graphics/opengl/Mesh.cpp | 24 ++++----- src/modules/graphics/opengl/Mesh.h | 4 +- src/modules/graphics/opengl/wrap_Graphics.cpp | 2 +- src/modules/graphics/opengl/wrap_Mesh.cpp | 49 +++++++++++++++++-- src/modules/graphics/opengl/wrap_Mesh.h | 1 + 5 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp index deb54e9b4..92be5bf78 100644 --- a/src/modules/graphics/opengl/Mesh.cpp +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -31,12 +31,12 @@ namespace opengl { Mesh::Mesh(const std::vector &verts, Mesh::DrawMode mode) - : vbo(0) + : vbo(nullptr) , vertex_count(0) - , ibo(0) + , ibo(nullptr) , element_count(0) , draw_mode(mode) - , image(0) + , image(nullptr) , colors_enabled(false) { setVertices(verts); @@ -58,7 +58,7 @@ void Mesh::setVertices(const std::vector &verts) if (vbo && size > vbo->getSize()) { delete vbo; - vbo = 0; + vbo = nullptr; } if (!vbo) @@ -84,7 +84,7 @@ void Mesh::setVertex(size_t index, const Vertex &v) VertexBuffer::Bind vbo_bind(*vbo); // We unmap the vertex buffer in Mesh::draw. This lets us coalesce the - // buffer transfer calls. + // buffer transfer calls into just one. Vertex *vertices = (Vertex *) vbo->map(); vertices[index] = v; } @@ -106,7 +106,7 @@ size_t Mesh::getVertexCount() const return vertex_count; } -void Mesh::setVertexMap(const std::vector &map) +void Mesh::setVertexMap(const std::vector &map) { for (size_t i = 0; i < map.size(); i++) { @@ -114,12 +114,12 @@ void Mesh::setVertexMap(const std::vector &map) throw love::Exception("Invalid vertex map value: %d", map[i]); } - size_t size = sizeof(uint16) * map.size(); + size_t size = sizeof(uint32) * map.size(); if (ibo && size > ibo->getSize()) { delete ibo; - ibo = 0; + ibo = nullptr; } if (!ibo) @@ -140,14 +140,14 @@ void Mesh::setVertexMap(const std::vector &map) } } -const uint16 *Mesh::getVertexMap() const +const uint32 *Mesh::getVertexMap() const { if (ibo && element_count > 0) { VertexBuffer::Bind ibo_bind(*ibo); // We unmap the buffer in Mesh::draw and Mesh::setVertexMap. - return (uint16 *) ibo->map(); + return (uint32 *) ibo->map(); } return 0; @@ -173,7 +173,7 @@ void Mesh::setImage() if (image) image->release(); - image = 0; + image = nullptr; } Image *Mesh::getImage() const @@ -249,7 +249,7 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo ibo->unmap(); // Use the custom vertex map to draw the vertices. - glDrawElements(mode, element_count, GL_UNSIGNED_SHORT, ibo->getPointer(0)); + glDrawElements(mode, element_count, GL_UNSIGNED_INT, ibo->getPointer(0)); } else { diff --git a/src/modules/graphics/opengl/Mesh.h b/src/modules/graphics/opengl/Mesh.h index 4515bd2c4..8d30f5e20 100644 --- a/src/modules/graphics/opengl/Mesh.h +++ b/src/modules/graphics/opengl/Mesh.h @@ -90,14 +90,14 @@ public: * A 0-element vector is equivalent to the default vertex map: * {0, 1, 2, 3, 4, ...} **/ - void setVertexMap(const std::vector &map); + void setVertexMap(const std::vector &map); /** * Gets a pointer to the vertex map array. The pointer is only valid until * the next function call in the graphics module. * May return null if the vertex map is empty. **/ - const uint16 *getVertexMap() const; + const uint32 *getVertexMap() const; /** * Gets the total number of elements in the vertex map array. diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index fa2c9bda8..e6e954b01 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -461,7 +461,7 @@ int w_newMesh(lua_State *L) lua_rawgeti(L, 1, i); if (lua_type(L, -1) != LUA_TTABLE) - return luax_typerror(L, 2, "table of tables"); + return luax_typerror(L, 1, "table of tables"); for (int j = 1; j <= 8; j++) lua_rawgeti(L, -j, j); diff --git a/src/modules/graphics/opengl/wrap_Mesh.cpp b/src/modules/graphics/opengl/wrap_Mesh.cpp index 41ebf0055..1c662f954 100644 --- a/src/modules/graphics/opengl/wrap_Mesh.cpp +++ b/src/modules/graphics/opengl/wrap_Mesh.cpp @@ -93,6 +93,46 @@ int w_Mesh_getVertex(lua_State *L) return 8; } +int w_Mesh_setVertices(lua_State *L) +{ + Mesh *t = luax_checkmesh(L, 1); + + size_t vertex_count = lua_objlen(L, 2); + std::vector vertices; + vertices.reserve(vertex_count); + + // Get the vertices from the table. + for (size_t i = 1; i <= vertex_count; i++) + { + lua_rawgeti(L, 2, i); + + if (lua_type(L, -1) != LUA_TTABLE) + return luax_typerror(L, 2, "table of tables"); + + for (int j = 1; j <= 8; j++) + lua_rawgeti(L, -j, j); + + Vertex v; + + v.x = (float) luaL_checknumber(L, -8); + v.y = (float) luaL_checknumber(L, -7); + + v.s = (float) luaL_checknumber(L, -6); + v.t = (float) luaL_checknumber(L, -5); + + v.r = (unsigned char) luaL_optinteger(L, -4, 255); + v.g = (unsigned char) luaL_optinteger(L, -3, 255); + v.b = (unsigned char) luaL_optinteger(L, -2, 255); + v.a = (unsigned char) luaL_optinteger(L, -1, 255); + + lua_pop(L, 9); + vertices.push_back(v); + } + + EXCEPT_GUARD(t->setVertices(vertices);) + return 0; +} + int w_Mesh_getVertexCount(lua_State *L) { Mesh *t = luax_checkmesh(L, 1); @@ -107,7 +147,7 @@ int w_Mesh_setVertexMap(lua_State *L) bool is_table = lua_istable(L, 2); int nargs = is_table ? lua_objlen(L, 2) : lua_gettop(L) - 1; - std::vector vertexmap; + std::vector vertexmap; vertexmap.reserve(nargs); for (int i = 0; i < nargs; i++) @@ -115,11 +155,11 @@ int w_Mesh_setVertexMap(lua_State *L) if (is_table) { lua_rawgeti(L, 2, i + 1); - vertexmap.push_back(uint16(luaL_checkinteger(L, -1) - 1)); + vertexmap.push_back(uint32(luaL_checkinteger(L, -1) - 1)); lua_pop(L, 1); } else - vertexmap.push_back(uint16(luaL_checkinteger(L, i + 2) - 1)); + vertexmap.push_back(uint32(luaL_checkinteger(L, i + 2) - 1)); } EXCEPT_GUARD(t->setVertexMap(vertexmap);) @@ -130,7 +170,7 @@ int w_Mesh_getVertexMap(lua_State *L) { Mesh *t = luax_checkmesh(L, 1); - const uint16 *vertex_map = t->getVertexMap(); + const uint32 *vertex_map = t->getVertexMap(); size_t elements = t->getVertexMapCount(); lua_createtable(L, elements, 0); @@ -216,6 +256,7 @@ static const luaL_Reg functions[] = { { "setVertex", w_Mesh_setVertex }, { "getVertex", w_Mesh_getVertex }, + { "setVertices", w_Mesh_setVertices }, { "getVertexCount", w_Mesh_getVertexCount }, { "setVertexMap", w_Mesh_setVertexMap }, { "getVertexMap", w_Mesh_getVertexMap }, diff --git a/src/modules/graphics/opengl/wrap_Mesh.h b/src/modules/graphics/opengl/wrap_Mesh.h index 7fa112a31..fd584b1ce 100644 --- a/src/modules/graphics/opengl/wrap_Mesh.h +++ b/src/modules/graphics/opengl/wrap_Mesh.h @@ -36,6 +36,7 @@ Mesh *luax_checkmesh(lua_State *L, int idx); int w_Mesh_setVertex(lua_State *L); int w_Mesh_getVertex(lua_State *L); +int w_Mesh_setVertices(lua_State *L); int w_Mesh_getVertexCount(lua_State *L); int w_Mesh_setVertexMap(lua_State *L); int w_Mesh_getVertexMap(lua_State *L); From d161d5c0fc653296e04b77cc009a73c8ba7e8892 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 1 Oct 2013 23:52:20 -0300 Subject: [PATCH 4/5] Fixed an uncaught exception in Mesh:getVertexMap --HG-- branch : Mesh --- src/modules/graphics/opengl/wrap_Mesh.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/graphics/opengl/wrap_Mesh.cpp b/src/modules/graphics/opengl/wrap_Mesh.cpp index 1c662f954..4419995b8 100644 --- a/src/modules/graphics/opengl/wrap_Mesh.cpp +++ b/src/modules/graphics/opengl/wrap_Mesh.cpp @@ -169,8 +169,9 @@ int w_Mesh_setVertexMap(lua_State *L) int w_Mesh_getVertexMap(lua_State *L) { Mesh *t = luax_checkmesh(L, 1); + const uint32 *vertex_map = 0; - const uint32 *vertex_map = t->getVertexMap(); + EXCEPT_GUARD(vertex_map = t->getVertexMap();) size_t elements = t->getVertexMapCount(); lua_createtable(L, elements, 0); From fb34f5bc9e4901379c38e4bd5a5923296389f987 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 6 Oct 2013 23:25:29 -0300 Subject: [PATCH 5/5] Auto-padded NPOT images' texture coordinates are now scaled at draw time via the texture matrix (fixes auto-padded images with Meshes.) Also fixed love.graphics.newQuad. --HG-- branch : Mesh --- src/modules/graphics/opengl/Image.cpp | 52 +++++++++---------- src/modules/graphics/opengl/Image.h | 17 +++--- src/modules/graphics/opengl/Mesh.cpp | 5 +- .../graphics/opengl/ParticleSystem.cpp | 4 +- src/modules/graphics/opengl/SpriteBatch.cpp | 27 ++-------- src/modules/graphics/opengl/SpriteBatch.h | 2 - src/modules/graphics/opengl/wrap_Graphics.cpp | 10 ++-- 7 files changed, 52 insertions(+), 65 deletions(-) diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index bdcbd20c0..e475c8f36 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -42,6 +42,7 @@ Image::Image(love::image::ImageData *data) , width((float)(data->getWidth())) , height((float)(data->getHeight())) , texture(0) + , texCoordScale(1.0, 1.0) , mipmapSharpness(defaultMipmapSharpness) , mipmapsCreated(false) , compressed(false) @@ -114,25 +115,30 @@ void Image::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); const Vertex *v = quad->getVertices(); + drawv(t, v); +} - // Padded NPOT images require texture coordinate scaling with Quads. - if (!hasNpot()) +void Image::predraw() const +{ + bind(); + + if (texCoordScale.x < 1.0f || texCoordScale.y < 1.0f) { - Vertex w[4]; - love::Vector scale = getTexCoordScale(); - - for (int i = 0; i < 4; i++) - { - w[i] = v[i]; - w[i].s *= scale.x; - w[i].t *= scale.y; - } - - drawv(t, w); + // NPOT image but no NPOT support, so the texcoords should be scaled. + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glScalef(texCoordScale.x, texCoordScale.y, 0.0f); + glMatrixMode(GL_MODELVIEW); } - else +} + +void Image::postdraw() const +{ + if (texCoordScale.x < 1.0f || texCoordScale.y < 1.0f) { - drawv(t, v); + glMatrixMode(GL_TEXTURE); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); } } @@ -385,10 +391,8 @@ bool Image::loadVolatilePOT() return true; } - vertices[1].t = t; - vertices[2].t = t; - vertices[2].s = s; - vertices[3].s = s; + texCoordScale.x = s; + texCoordScale.y = t; // We want this lock to potentially cover mipmap creation as well. love::thread::EmptyLock lock; @@ -577,15 +581,9 @@ void Image::uploadDefaultTexture() glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, px); } -love::Vector Image::getTexCoordScale() const -{ - // FIXME: this should be changed if Image::loadVolatilePOT changes. - return love::Vector(vertices[2].s, vertices[2].t); -} - void Image::drawv(const Matrix &t, const Vertex *v) const { - bind(); + predraw(); glPushMatrix(); @@ -603,6 +601,8 @@ void Image::drawv(const Matrix &t, const Vertex *v) const glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); + + postdraw(); } void Image::setDefaultMipmapSharpness(float sharpness) diff --git a/src/modules/graphics/opengl/Image.h b/src/modules/graphics/opengl/Image.h index 382bf99f1..81d9d6d6d 100644 --- a/src/modules/graphics/opengl/Image.h +++ b/src/modules/graphics/opengl/Image.h @@ -88,6 +88,14 @@ public: **/ void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const; + /** + * Call before using this Image's texture to draw. Binds the texture, + * globally scales texture coordinates if the Image has NPOT dimensions and + * NPOT isn't supported, etc. + **/ + void predraw() const; + void postdraw() const; + /** * Sets the filter mode. * @param f The filter mode. @@ -124,12 +132,6 @@ public: **/ bool refresh(); - /** - * Gets the texture coordinate scale used for drawing auto-padded NPOT - * images correctly. - **/ - love::Vector getTexCoordScale() const; - static void setDefaultMipmapSharpness(float sharpness); static float getDefaultMipmapSharpness(); static void setDefaultMipmapFilter(FilterMode f); @@ -172,6 +174,9 @@ private: // The source vertices of the image. Vertex vertices[4]; + // The scale applied to texcoords for NPOT images without NPOT support. + love::Vector texCoordScale; + // Mipmap texture LOD bias (sharpness) value. float mipmapSharpness; diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp index 92be5bf78..32f04b371 100644 --- a/src/modules/graphics/opengl/Mesh.cpp +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -211,7 +211,7 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo return; if (image) - image->bind(); + image->predraw(); else gl.bindTexture(0); @@ -268,6 +268,9 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo } glPopMatrix(); + + if (image) + image->postdraw(); } GLenum Mesh::getGLDrawMode(Mesh::DrawMode mode) const diff --git a/src/modules/graphics/opengl/ParticleSystem.cpp b/src/modules/graphics/opengl/ParticleSystem.cpp index 8cebeae7a..6b257927a 100644 --- a/src/modules/graphics/opengl/ParticleSystem.cpp +++ b/src/modules/graphics/opengl/ParticleSystem.cpp @@ -779,7 +779,7 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo p = p->next; } - image->bind(); + image->predraw(); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); @@ -795,6 +795,8 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); + image->postdraw(); + glPopMatrix(); gl.setColor(curcolor); diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp index 88dbfa4f5..0298cbbf0 100644 --- a/src/modules/graphics/opengl/SpriteBatch.cpp +++ b/src/modules/graphics/opengl/SpriteBatch.cpp @@ -116,9 +116,6 @@ int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, fl if (color) setColorv(sprite, *color); - // Auto-padded NPOT images require texcoord scaling for their vertices. - scaleNPOT(sprite, 4); - addv(sprite, (index == -1) ? next : index); // Increment counter. @@ -144,9 +141,6 @@ int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy, if (color) setColorv(sprite, *color); - // Auto-padded NPOT images require texcoord scaling for their vertices. - scaleNPOT(sprite, 4); - addv(sprite, (index == -1) ? next : index); // Increment counter. @@ -285,7 +279,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); glMultMatrixf((const GLfloat *)t.getElements()); - image->bind(); + image->predraw(); VertexBuffer::Bind array_bind(*array_buf); VertexBuffer::Bind element_bind(*element_buf->getVertexBuffer()); @@ -316,26 +310,11 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float gl.setColor(curcolor); } + image->postdraw(); + glPopMatrix(); } -void SpriteBatch::scaleNPOT(Vertex *v, size_t count) -{ - if (Image::hasNpot()) - return; - - love::Vector scale = image->getTexCoordScale(); - - if (scale.x == 1.0f && scale.y == 1.0f) - return; - - for (size_t i = 0; i < count; i++) - { - v[i].s *= scale.x; - v[i].t *= scale.y; - } -} - void SpriteBatch::addv(const Vertex *v, int index) { static const int sprite_size = 4 * sizeof(Vertex); // bytecount diff --git a/src/modules/graphics/opengl/SpriteBatch.h b/src/modules/graphics/opengl/SpriteBatch.h index 75d676d15..f3ac4fe5d 100644 --- a/src/modules/graphics/opengl/SpriteBatch.h +++ b/src/modules/graphics/opengl/SpriteBatch.h @@ -116,8 +116,6 @@ public: private: - void scaleNPOT(Vertex *v, size_t count); - void addv(const Vertex *v, int index); /** diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index e6e954b01..e325beb9a 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -198,12 +198,12 @@ int w_newQuad(lua_State *L) { Quad::Viewport v; v.x = (float) luaL_checknumber(L, 1); - v.y = (float) luaL_checknumber(L, 1); - v.w = (float) luaL_checknumber(L, 1); - v.h = (float) luaL_checknumber(L, 1); + v.y = (float) luaL_checknumber(L, 2); + v.w = (float) luaL_checknumber(L, 3); + v.h = (float) luaL_checknumber(L, 4); - float sw = (float) luaL_checknumber(L, 1); - float sh = (float) luaL_checknumber(L, 1); + float sw = (float) luaL_checknumber(L, 5); + float sh = (float) luaL_checknumber(L, 6); Quad *quad = instance->newQuad(v, sw, sh); luax_pushtype(L, "Quad", GRAPHICS_QUAD_T, quad);