mirror of
https://github.com/love2d/love.git
synced 2026-08-20 04:30:09 +02:00
merge
--HG-- branch : minor
This commit is contained in:
+6
-10
@@ -255,6 +255,7 @@ endfunction()
|
|||||||
set(LOVE_SRC_COMMON
|
set(LOVE_SRC_COMMON
|
||||||
src/common/b64.cpp
|
src/common/b64.cpp
|
||||||
src/common/b64.h
|
src/common/b64.h
|
||||||
|
src/common/Color.h
|
||||||
src/common/config.h
|
src/common/config.h
|
||||||
src/common/Data.cpp
|
src/common/Data.cpp
|
||||||
src/common/Data.h
|
src/common/Data.h
|
||||||
@@ -474,7 +475,6 @@ set(LOVE_SRC_MODULE_GRAPHICS_ROOT
|
|||||||
src/modules/graphics/Buffer.h
|
src/modules/graphics/Buffer.h
|
||||||
src/modules/graphics/Canvas.cpp
|
src/modules/graphics/Canvas.cpp
|
||||||
src/modules/graphics/Canvas.h
|
src/modules/graphics/Canvas.h
|
||||||
src/modules/graphics/Color.h
|
|
||||||
src/modules/graphics/depthstencil.cpp
|
src/modules/graphics/depthstencil.cpp
|
||||||
src/modules/graphics/depthstencil.h
|
src/modules/graphics/depthstencil.h
|
||||||
src/modules/graphics/Drawable.cpp
|
src/modules/graphics/Drawable.cpp
|
||||||
@@ -575,8 +575,13 @@ source_group("modules\\graphics\\opengl" FILES ${LOVE_SRC_MODULE_GRAPHICS_OPENGL
|
|||||||
#
|
#
|
||||||
|
|
||||||
set(LOVE_SRC_MODULE_IMAGE_ROOT
|
set(LOVE_SRC_MODULE_IMAGE_ROOT
|
||||||
|
src/modules/image/CompressedFormatHandler.h
|
||||||
src/modules/image/CompressedImageData.cpp
|
src/modules/image/CompressedImageData.cpp
|
||||||
src/modules/image/CompressedImageData.h
|
src/modules/image/CompressedImageData.h
|
||||||
|
src/modules/image/CompressedSlice.cpp
|
||||||
|
src/modules/image/CompressedSlice.h
|
||||||
|
src/modules/image/FormatHandler.cpp
|
||||||
|
src/modules/image/FormatHandler.h
|
||||||
src/modules/image/Image.cpp
|
src/modules/image/Image.cpp
|
||||||
src/modules/image/Image.h
|
src/modules/image/Image.h
|
||||||
src/modules/image/ImageData.cpp
|
src/modules/image/ImageData.cpp
|
||||||
@@ -594,19 +599,10 @@ set(LOVE_SRC_MODULE_IMAGE_ROOT
|
|||||||
set(LOVE_SRC_MODULE_IMAGE_MAGPIE
|
set(LOVE_SRC_MODULE_IMAGE_MAGPIE
|
||||||
src/modules/image/magpie/ASTCHandler.cpp
|
src/modules/image/magpie/ASTCHandler.cpp
|
||||||
src/modules/image/magpie/ASTCHandler.h
|
src/modules/image/magpie/ASTCHandler.h
|
||||||
src/modules/image/magpie/CompressedImageData.cpp
|
|
||||||
src/modules/image/magpie/CompressedImageData.h
|
|
||||||
src/modules/image/magpie/CompressedFormatHandler.h
|
|
||||||
src/modules/image/magpie/ddsHandler.cpp
|
src/modules/image/magpie/ddsHandler.cpp
|
||||||
src/modules/image/magpie/ddsHandler.h
|
src/modules/image/magpie/ddsHandler.h
|
||||||
src/modules/image/magpie/EXRHandler.cpp
|
src/modules/image/magpie/EXRHandler.cpp
|
||||||
src/modules/image/magpie/EXRHandler.h
|
src/modules/image/magpie/EXRHandler.h
|
||||||
src/modules/image/magpie/FormatHandler.cpp
|
|
||||||
src/modules/image/magpie/FormatHandler.h
|
|
||||||
src/modules/image/magpie/Image.cpp
|
|
||||||
src/modules/image/magpie/Image.h
|
|
||||||
src/modules/image/magpie/ImageData.cpp
|
|
||||||
src/modules/image/magpie/ImageData.h
|
|
||||||
src/modules/image/magpie/KTXHandler.cpp
|
src/modules/image/magpie/KTXHandler.cpp
|
||||||
src/modules/image/magpie/KTXHandler.h
|
src/modules/image/magpie/KTXHandler.h
|
||||||
src/modules/image/magpie/PKMHandler.cpp
|
src/modules/image/magpie/PKMHandler.cpp
|
||||||
|
|||||||
+40
-9
@@ -3,54 +3,80 @@ LOVE 0.11.0 []
|
|||||||
|
|
||||||
Released: N/A
|
Released: N/A
|
||||||
|
|
||||||
|
* Added Object:release.
|
||||||
|
* Added Data:clone.
|
||||||
|
* Added queueable audio sources.
|
||||||
|
* Added audio input support.
|
||||||
|
* Added Source filters: low gain, high gain and band pass.
|
||||||
|
* Added audio effect APIs (reverb, echo, etc.)
|
||||||
* Added a variant to World:update, which accepts the number of iterations to run. The defaults are now 8 and 3.
|
* Added a variant to World:update, which accepts the number of iterations to run. The defaults are now 8 and 3.
|
||||||
* Added a click count argument to love.mousepressed and love.mousereleased.
|
* Added a click count argument to love.mousepressed and love.mousereleased.
|
||||||
* Added love.filesystem.get/setCRequirePath, and use that to find c libraries for require.
|
* Added love.filesystem.get/setCRequirePath, and use that to find c libraries for require.
|
||||||
* Added Channel:hasRead, which checks if a message has been read. Takes an id, which Channel:push will now return.
|
* Added Channel:hasRead, which checks if a message has been read. Takes an id, which Channel:push will now return.
|
||||||
* Added love.math.encode/decode, which support hex and base64.
|
* Added love.math.encode/decode, which support hex and base64.
|
||||||
* Added love.math.hash, which supports MD5, SHA-1 and the SHA-2 family.
|
* Added love.math.hash, which supports MD5, SHA-1 and the SHA-2 family.
|
||||||
|
* Added Transform objects to love.math.
|
||||||
* Added support for different ImageData formats, including RGBA8 (the default), RGBA16, RGBA16F, and RGBA32F.
|
* Added support for different ImageData formats, including RGBA8 (the default), RGBA16, RGBA16F, and RGBA32F.
|
||||||
* Added the ability to load Radiance HDR, OpenEXR, and 16 bit PNG images.
|
* Added the ability to load Radiance HDR, OpenEXR, and 16 bit PNG images.
|
||||||
* Added love.graphics.getImageFormats (replaces love.graphics.getCompressedImageFormats).
|
* Added love.graphics.getImageFormats (replaces love.graphics.getCompressedImageFormats).
|
||||||
* Added the ability to specify a per-object pixel density scale factor when creating Images, Canvases, Fonts, and Videos. Affects drawing.
|
* Added the ability to specify a per-object pixel density scale factor when creating Images, Canvases, Fonts, and Videos. Affects drawing.
|
||||||
* Added Texture:getPixelWidth/Height and love.graphics.getPixelWidth/Height.
|
* Added Texture:getPixelWidth/Height and love.graphics.getPixelWidth/Height.
|
||||||
* Added Texture:getPixelDensity, love.graphics.getPixelDensity, and Font:getPixelDensity.
|
* Added Texture:getPixelDensity, love.graphics.getPixelDensity, and Font:getPixelDensity.
|
||||||
|
* Added Array, Cubemap, and Volume texture types and corresponding Image and Canvas APIs.
|
||||||
|
* Added love.graphics.getTextureTypes, returns a table with fields indicating support for each texture type.
|
||||||
|
* Added mipmapping support to Canvases, including both auto-generated mipmaps and manually rendering to a specific mipmap level.
|
||||||
|
* Added 'stencil8', 'depth24stencil8', 'depth32fstencil8', 'depth16', 'depth24', and 'depth32f' pixel formats for Canvases.
|
||||||
|
* Added optional 'readable' boolean field to the table passed into love.graphics.newCanvas.
|
||||||
|
* Added optional 'depthstencil' field to the table passed into love.graphics.setCanvas, for using a depth/stencil Canvas.
|
||||||
|
* Added optional 'depth' and 'stencil' boolean fields to the table passed into setCanvas, for enabling depth and stencil buffers if 'depthstencil' isn't used.
|
||||||
|
* Added shadow sampler support for Canvases.
|
||||||
|
* Added variant of love.graphics.getCanvasFormats which takes a 'readable' boolean.
|
||||||
|
* Added love.graphics.drawLayer and SpriteBatch:add/setLayer for easily drawing layers of Array Textures.
|
||||||
|
* Added variants of love.graphics.print and printf which take a Font argument.
|
||||||
|
* Added variants of love.graphics.clear to control how the active depth and stencil buffers are cleared.
|
||||||
|
* Added love.graphics.flushBatch for manually flushing automatically batched draws.
|
||||||
* Added SpriteBatch:setDrawRange.
|
* Added SpriteBatch:setDrawRange.
|
||||||
* Added per-shader opt in support for the GLSL 3.30 and GLSL ES 3.00 shading languages.
|
* Added per-shader opt in support for the GLSL 3.30 and GLSL ES 3.00 shading languages.
|
||||||
|
* Added 'void effect()' pixel shader entry point.
|
||||||
* Added love.graphics.validateShader.
|
* Added love.graphics.validateShader.
|
||||||
* Added Shader:hasUniform.
|
* Added Shader:hasUniform.
|
||||||
* Added support for non-square shader uniform matrices on desktop platforms and on mobile GLSL 3.
|
* Added support for non-square shader uniform matrices on desktop platforms and on mobile GLSL 3.
|
||||||
* Added Shader:send(matrixname, is_column_major, matrix, ...) which specifies how to interpret the matrix table arguments.
|
* Added Shader:send(matrixname, is_column_major, matrix, ...) which specifies how to interpret the matrix table arguments.
|
||||||
|
* Added 'borderellipse' and 'borderrectangle' ParticleSystem distributions.
|
||||||
|
* Added ParticleSystem:set/getAreaSpreadAngle and set/getAreaSpreadIsRelativeDirection.
|
||||||
* Added love.graphics.captureScreenshot (replaces love.graphics.newScreenshot).
|
* Added love.graphics.captureScreenshot (replaces love.graphics.newScreenshot).
|
||||||
* Added love.window.updateMode.
|
* Added 'glsl3', 'instancing', 'fullnpot','pixelshaderhighp', and 'shaderderivatives' graphics features.
|
||||||
* Added the ability to prevent love from creating a stencil buffer for the window.
|
|
||||||
* Added Object:release.
|
|
||||||
* Added queueable audio sources.
|
|
||||||
* Added audio input support.
|
|
||||||
* Added Transform objects to love.math.
|
|
||||||
* Added 'glsl3', 'instancing', 'fullnpot', and 'pixelshaderhighp' graphics features.
|
|
||||||
* Added 'anisotropy' graphics limit.
|
* Added 'anisotropy' graphics limit.
|
||||||
* Added Mesh instancing support.
|
* Added Mesh instancing support via love.graphics.drawInstanced and Mesh:attachAttribute.
|
||||||
* Added a Mesh:attachAttribute variant that takes a different target attribute name.
|
* Added a Mesh:attachAttribute variant that takes a different target attribute name.
|
||||||
* Added Mesh:detachAttribute.
|
* Added Mesh:detachAttribute.
|
||||||
* Added a variant of Mesh:setVertexMap which accepts a Data object.
|
* Added a variant of Mesh:setVertexMap which accepts a Data object.
|
||||||
* Added Source filters: low gain, high gain and band pass.
|
* Added love.window.updateMode.
|
||||||
|
* Added the ability to prevent love from creating a stencil buffer for the window.
|
||||||
|
|
||||||
* Changed all color values to be in the range 0-1, rather than 0-255.
|
* Changed all color values to be in the range 0-1, rather than 0-255.
|
||||||
* Changed high-dpi functionality to require much less code (often none at all) for things to appear at the correct sizes and positions.
|
* Changed high-dpi functionality to require much less code (often none at all) for things to appear at the correct sizes and positions.
|
||||||
* Changed love.graphics.print and friends to ignore carriage returns.
|
* Changed love.graphics.print and friends to ignore carriage returns.
|
||||||
* Changed the 'multiply' blend mode to error if not used with the 'premultiplied' blend alpha mode, since the formula only works with that anyway.
|
* Changed the 'multiply' blend mode to error if not used with the 'premultiplied' blend alpha mode, since the formula only works with that anyway.
|
||||||
* Changed some love.graphics, love.window, and love.event APIs to cause an error if a Canvas is active.
|
* Changed some love.graphics, love.window, and love.event APIs to cause an error if a Canvas is active.
|
||||||
|
* Changed stenciling functionality with a Canvas active to require stencil=true (or a custom stencil-formatted Canvas) to be set in setCanvas.
|
||||||
* Changed Mesh:setDrawRange to take 'start' and 'count' parameters instead of 'min' and 'max'.
|
* Changed Mesh:setDrawRange to take 'start' and 'count' parameters instead of 'min' and 'max'.
|
||||||
* Changed the 'vsync' field of love.window.setMode and t.window in love.conf. It's now an integer with 0 disabling vsync.
|
* Changed the 'vsync' field of love.window.setMode and t.window in love.conf. It's now an integer with 0 disabling vsync.
|
||||||
* Changed the audio playback APIs drastically.
|
* Changed the audio playback APIs drastically.
|
||||||
* Changed enet to no longer set the 'enet' global, again matching luasocket.
|
* Changed enet to no longer set the 'enet' global, again matching luasocket.
|
||||||
* Changed Source seeking behaviour, all kinds of Sources now behave similarly when seeking past the boundaries.
|
* Changed Source seeking behaviour, all kinds of Sources now behave similarly when seeking past the boundaries.
|
||||||
|
|
||||||
|
* Fixed a memory leak when sending love objects to threads which never load that object's module.
|
||||||
|
* Fixed os.execute always returning -1 in Linux.
|
||||||
|
* Fixed the default reference angle for WeldJoint, PrismaticJoint, and RevoluteJoint.
|
||||||
|
* Fixed love.graphics.set/getClipboard text to error instead of crashing, when a window hasn't been created.
|
||||||
* Fixed Joystick:getGamepadMapping to work with xinput controllers.
|
* Fixed Joystick:getGamepadMapping to work with xinput controllers.
|
||||||
|
* Fixed baseline calculation when rendering text.
|
||||||
|
* Fixed VaryingTexCoords and love_ScreenSize in shaders to be 'highp' in OpenGL ES, when supported.
|
||||||
|
|
||||||
* Improved performance when drawing textures, shapes, lines, and points by automatically batching their draw calls together when possible.
|
* Improved performance when drawing textures, shapes, lines, and points by automatically batching their draw calls together when possible.
|
||||||
* Improved performance of Shader:send when the Shader is not active.
|
* Improved performance of Shader:send when the Shader is not active.
|
||||||
|
* Improved performance of love.math.randomNormal when LuaJIT's JIT compiler is enabled.
|
||||||
|
|
||||||
* Renamed love.window.getPixelScale to love.window.getPixelDensity.
|
* Renamed love.window.getPixelScale to love.window.getPixelDensity.
|
||||||
|
|
||||||
@@ -58,6 +84,7 @@ Released: N/A
|
|||||||
* Removed variant of love.filesystem.newFileData which takes base64 data, use love.math.decode instead.
|
* Removed variant of love.filesystem.newFileData which takes base64 data, use love.math.decode instead.
|
||||||
* Removed the no-argument variant of Text:set, use Text:clear instead.
|
* Removed the no-argument variant of Text:set, use Text:clear instead.
|
||||||
* Removed love.graphics.getCompressedImageFormats, use love.graphics.getImageFormats instead.
|
* Removed love.graphics.getCompressedImageFormats, use love.graphics.getImageFormats instead.
|
||||||
|
* Removed the 'void effects(...)' pixel shader entry point. Use the new 'void effect()' instead.
|
||||||
* Removed Shader:getExternVariable, use Shader:hasUniform instead.
|
* Removed Shader:getExternVariable, use Shader:hasUniform instead.
|
||||||
* Removed love.graphics.newScreenshot, use love.graphics.captureScreenshot instead.
|
* Removed love.graphics.newScreenshot, use love.graphics.captureScreenshot instead.
|
||||||
* Removed deprecated enet function host:socket_get_address.
|
* Removed deprecated enet function host:socket_get_address.
|
||||||
@@ -66,9 +93,12 @@ Released: N/A
|
|||||||
* Removed love.window.isCreated (use love.window.isOpen instead).
|
* Removed love.window.isCreated (use love.window.isOpen instead).
|
||||||
|
|
||||||
* Updated Source:seek to work if the Source isn't playing.
|
* Updated Source:seek to work if the Source isn't playing.
|
||||||
|
* Updated love.event.poll to stop allocating memory unnecessarily.
|
||||||
* Updated love.math.random to have improved numeric distribution.
|
* Updated love.math.random to have improved numeric distribution.
|
||||||
* Updated love.graphics to support Core Profile OpenGL 3.3+ when available.
|
* Updated love.graphics to support Core Profile OpenGL 3.3+ when available.
|
||||||
|
* Updated shaders to always expose derivative functions (dFdx, dFdy, fwidth) when available in OpenGL ES.
|
||||||
* Updated love.graphics.circle/ellipse/arc/rectangle to take transformation scale into account when determining the number of segments to use.
|
* Updated love.graphics.circle/ellipse/arc/rectangle to take transformation scale into account when determining the number of segments to use.
|
||||||
|
* Updated Font glyph generation to improve antialiasing.
|
||||||
* Updated Canvas:newImageData to return an ImageData with a format that matches the Canvas' as closely as possible.
|
* Updated Canvas:newImageData to return an ImageData with a format that matches the Canvas' as closely as possible.
|
||||||
* Updated love.graphics.newImage to treat file names ending with "@2x", "@3x", etc. as a pixel density scale factor if none is explicitly supplied.
|
* Updated love.graphics.newImage to treat file names ending with "@2x", "@3x", etc. as a pixel density scale factor if none is explicitly supplied.
|
||||||
* Updated luasocket to version 3.0rc1.
|
* Updated luasocket to version 3.0rc1.
|
||||||
@@ -83,6 +113,7 @@ Released: N/A
|
|||||||
* Fixed Shader:send and Shader:sendColor ignoring the last argument for an array.
|
* Fixed Shader:send and Shader:sendColor ignoring the last argument for an array.
|
||||||
* Fixed a crash when love.graphics.pop is called after a love.window.setMode while the transformation stack was not empty.
|
* Fixed a crash when love.graphics.pop is called after a love.window.setMode while the transformation stack was not empty.
|
||||||
* Fixed BezierCurves to error instead of hanging in some situations.
|
* Fixed BezierCurves to error instead of hanging in some situations.
|
||||||
|
* Fixed compilation of luasocket with newer luajit 2.1.0 beta versions.
|
||||||
|
|
||||||
* Improved command line argument handling.
|
* Improved command line argument handling.
|
||||||
* Improved seeking support, especially for short video files.
|
* Improved seeking support, especially for short video files.
|
||||||
|
|||||||
+149
-73
@@ -23,9 +23,9 @@ distribution.
|
|||||||
|
|
||||||
---------
|
---------
|
||||||
|
|
||||||
This software uses LuaJIT:
|
This software uses ENet:
|
||||||
|
|
||||||
LuaJIT is Copyright (c) 2005-2016 Mike Pall
|
Copyright (c) 2002-2016 Lee Salzman
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -47,6 +47,31 @@ THE SOFTWARE.
|
|||||||
|
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
This software uses GLAD:
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 David Herberth, modified by Alex Szpakowski
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
---------
|
||||||
|
|
||||||
This software uses glslang:
|
This software uses glslang:
|
||||||
|
|
||||||
Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
@@ -85,30 +110,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
---------
|
---------
|
||||||
|
|
||||||
This software uses ENet:
|
|
||||||
|
|
||||||
Copyright (c) 2002-2016 Lee Salzman
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
---------
|
|
||||||
|
|
||||||
This software uses lua-enet:
|
This software uses lua-enet:
|
||||||
|
|
||||||
Copyright (C) 2011 by Leaf Corcoran
|
Copyright (C) 2011 by Leaf Corcoran
|
||||||
@@ -133,30 +134,76 @@ THE SOFTWARE.
|
|||||||
|
|
||||||
---------
|
---------
|
||||||
|
|
||||||
This software uses UTF8-CPP:
|
This software uses LuaJIT:
|
||||||
|
|
||||||
Copyright 2006 Nemanja Trifunovic
|
LuaJIT is Copyright (c) 2005-2016 Mike Pall
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
in the Software without restriction, including without limitation the rights
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
do so, all subject to the following:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
The above copyright notice and this permission notice shall be included in
|
||||||
the above license grant, this restriction and the following disclaimer,
|
all copies or substantial portions of the Software.
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
---------
|
||||||
|
|
||||||
|
This software uses Lua's UTF-8 module:
|
||||||
|
|
||||||
|
Copyright (C) 1994-2015 Lua.org, PUC-Rio, 2015 LOVE Development Team.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
---------
|
||||||
|
|
||||||
|
This software uses luasocket:
|
||||||
|
|
||||||
|
LuaSocket 3.0 license
|
||||||
|
Copyright (C) 2004-2013 Diego Nehab
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
DEALINGS IN THE SOFTWARE.
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
---------
|
---------
|
||||||
@@ -197,6 +244,63 @@ You can contact the author at :
|
|||||||
|
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
This software uses TinyEXR:
|
||||||
|
|
||||||
|
Copyright (c) 2014 - 2016, Syoyo Fujita
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the <organization> nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
---------
|
||||||
|
|
||||||
|
This software uses UTF8-CPP:
|
||||||
|
|
||||||
|
Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
---------
|
||||||
|
|
||||||
This software uses xxHash:
|
This software uses xxHash:
|
||||||
|
|
||||||
xxHash - Extremely Fast Hash algorithm
|
xxHash - Extremely Fast Hash algorithm
|
||||||
@@ -232,41 +336,13 @@ You can contact the author at :
|
|||||||
|
|
||||||
---------
|
---------
|
||||||
|
|
||||||
This software uses TinyEXR:
|
|
||||||
|
|
||||||
Copyright (c) 2014 - 2016, Syoyo Fujita
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the <organization> nor the
|
|
||||||
names of its contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
---------
|
|
||||||
|
|
||||||
This software uses the following LGPL libraries on Windows, Mac OS X, Linux,
|
This software uses the following LGPL libraries on Windows, Mac OS X, Linux,
|
||||||
and Android:
|
and Android:
|
||||||
|
|
||||||
- libmpg123
|
- libmpg123
|
||||||
Website: http://www.mpg123.de/
|
Website: http://www.mpg123.de/
|
||||||
Source download: http://sourceforge.net/projects/mpg123/files/latest/download
|
Source download: http://sourceforge.net/projects/mpg123/files/latest/download
|
||||||
|
|
||||||
- OpenAL Soft
|
- OpenAL Soft
|
||||||
Website: http://kcat.strangesoft.net/openal.html
|
Website: http://kcat.strangesoft.net/openal.html
|
||||||
Source download: http://kcat.strangesoft.net/openal.html#download
|
Source download: http://kcat.strangesoft.net/openal.html#download
|
||||||
|
|||||||
@@ -415,7 +415,6 @@
|
|||||||
FA0B7D2B1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B851A95902C000E1D17 /* wrap_Rasterizer.cpp */; };
|
FA0B7D2B1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B851A95902C000E1D17 /* wrap_Rasterizer.cpp */; };
|
||||||
FA0B7D2C1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B851A95902C000E1D17 /* wrap_Rasterizer.cpp */; };
|
FA0B7D2C1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B851A95902C000E1D17 /* wrap_Rasterizer.cpp */; };
|
||||||
FA0B7D2D1A95902C000E1D17 /* wrap_Rasterizer.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B861A95902C000E1D17 /* wrap_Rasterizer.h */; };
|
FA0B7D2D1A95902C000E1D17 /* wrap_Rasterizer.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B861A95902C000E1D17 /* wrap_Rasterizer.h */; };
|
||||||
FA0B7D2E1A95902C000E1D17 /* Color.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B881A95902C000E1D17 /* Color.h */; };
|
|
||||||
FA0B7D2F1A95902C000E1D17 /* Drawable.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B891A95902C000E1D17 /* Drawable.h */; };
|
FA0B7D2F1A95902C000E1D17 /* Drawable.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7B891A95902C000E1D17 /* Drawable.h */; };
|
||||||
FA0B7D301A95902C000E1D17 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B8A1A95902C000E1D17 /* Graphics.cpp */; };
|
FA0B7D301A95902C000E1D17 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B8A1A95902C000E1D17 /* Graphics.cpp */; };
|
||||||
FA0B7D311A95902C000E1D17 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B8A1A95902C000E1D17 /* Graphics.cpp */; };
|
FA0B7D311A95902C000E1D17 /* Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7B8A1A95902C000E1D17 /* Graphics.cpp */; };
|
||||||
@@ -469,22 +468,9 @@
|
|||||||
FA0B7D861A95902C000E1D17 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BC61A95902C000E1D17 /* ImageData.cpp */; };
|
FA0B7D861A95902C000E1D17 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BC61A95902C000E1D17 /* ImageData.cpp */; };
|
||||||
FA0B7D871A95902C000E1D17 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BC61A95902C000E1D17 /* ImageData.cpp */; };
|
FA0B7D871A95902C000E1D17 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BC61A95902C000E1D17 /* ImageData.cpp */; };
|
||||||
FA0B7D881A95902C000E1D17 /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BC71A95902C000E1D17 /* ImageData.h */; };
|
FA0B7D881A95902C000E1D17 /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BC71A95902C000E1D17 /* ImageData.h */; };
|
||||||
FA0B7D891A95902C000E1D17 /* CompressedImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BC91A95902C000E1D17 /* CompressedImageData.cpp */; };
|
|
||||||
FA0B7D8A1A95902C000E1D17 /* CompressedImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BC91A95902C000E1D17 /* CompressedImageData.cpp */; };
|
|
||||||
FA0B7D8B1A95902C000E1D17 /* CompressedImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BCA1A95902C000E1D17 /* CompressedImageData.h */; };
|
|
||||||
FA0B7D8C1A95902C000E1D17 /* CompressedFormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BCB1A95902C000E1D17 /* CompressedFormatHandler.h */; };
|
|
||||||
FA0B7D8D1A95902C000E1D17 /* ddsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */; };
|
FA0B7D8D1A95902C000E1D17 /* ddsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */; };
|
||||||
FA0B7D8E1A95902C000E1D17 /* ddsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */; };
|
FA0B7D8E1A95902C000E1D17 /* ddsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */; };
|
||||||
FA0B7D8F1A95902C000E1D17 /* ddsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BCD1A95902C000E1D17 /* ddsHandler.h */; };
|
FA0B7D8F1A95902C000E1D17 /* ddsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BCD1A95902C000E1D17 /* ddsHandler.h */; };
|
||||||
FA0B7D901A95902C000E1D17 /* FormatHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BCE1A95902C000E1D17 /* FormatHandler.cpp */; };
|
|
||||||
FA0B7D911A95902C000E1D17 /* FormatHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BCE1A95902C000E1D17 /* FormatHandler.cpp */; };
|
|
||||||
FA0B7D921A95902C000E1D17 /* FormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BCF1A95902C000E1D17 /* FormatHandler.h */; };
|
|
||||||
FA0B7D931A95902C000E1D17 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD01A95902C000E1D17 /* Image.cpp */; };
|
|
||||||
FA0B7D941A95902C000E1D17 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD01A95902C000E1D17 /* Image.cpp */; };
|
|
||||||
FA0B7D951A95902C000E1D17 /* Image.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BD11A95902C000E1D17 /* Image.h */; };
|
|
||||||
FA0B7D961A95902C000E1D17 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD21A95902C000E1D17 /* ImageData.cpp */; };
|
|
||||||
FA0B7D971A95902C000E1D17 /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD21A95902C000E1D17 /* ImageData.cpp */; };
|
|
||||||
FA0B7D981A95902C000E1D17 /* ImageData.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BD31A95902C000E1D17 /* ImageData.h */; };
|
|
||||||
FA0B7D9F1A95902C000E1D17 /* KTXHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */; };
|
FA0B7D9F1A95902C000E1D17 /* KTXHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */; };
|
||||||
FA0B7DA01A95902C000E1D17 /* KTXHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */; };
|
FA0B7DA01A95902C000E1D17 /* KTXHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */; };
|
||||||
FA0B7DA11A95902C000E1D17 /* KTXHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BD91A95902C000E1D17 /* KTXHandler.h */; };
|
FA0B7DA11A95902C000E1D17 /* KTXHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B7BD91A95902C000E1D17 /* KTXHandler.h */; };
|
||||||
@@ -938,6 +924,7 @@
|
|||||||
FA620A371AA2F8DB005DB4C2 /* wrap_Texture.h in Headers */ = {isa = PBXBuildFile; fileRef = FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */; };
|
FA620A371AA2F8DB005DB4C2 /* wrap_Texture.h in Headers */ = {isa = PBXBuildFile; fileRef = FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */; };
|
||||||
FA620A3A1AA305F6005DB4C2 /* types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA620A391AA305F6005DB4C2 /* types.cpp */; };
|
FA620A3A1AA305F6005DB4C2 /* types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA620A391AA305F6005DB4C2 /* types.cpp */; };
|
||||||
FA620A3B1AA305F6005DB4C2 /* types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA620A391AA305F6005DB4C2 /* types.cpp */; };
|
FA620A3B1AA305F6005DB4C2 /* types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA620A391AA305F6005DB4C2 /* types.cpp */; };
|
||||||
|
FA6BDE5C1F31725300786805 /* Color.h in Headers */ = {isa = PBXBuildFile; fileRef = FA6BDE5B1F31725300786805 /* Color.h */; };
|
||||||
FA7550A81AEBE276003E311E /* libluajit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA7550A71AEBE276003E311E /* libluajit.a */; };
|
FA7550A81AEBE276003E311E /* libluajit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA7550A71AEBE276003E311E /* libluajit.a */; };
|
||||||
FA76344A1E28722A0066EF9E /* StreamBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7634481E28722A0066EF9E /* StreamBuffer.cpp */; };
|
FA76344A1E28722A0066EF9E /* StreamBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7634481E28722A0066EF9E /* StreamBuffer.cpp */; };
|
||||||
FA76344B1E28722A0066EF9E /* StreamBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7634481E28722A0066EF9E /* StreamBuffer.cpp */; };
|
FA76344B1E28722A0066EF9E /* StreamBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7634481E28722A0066EF9E /* StreamBuffer.cpp */; };
|
||||||
@@ -948,6 +935,9 @@
|
|||||||
FA91591E1CF1ED7500A7053F /* halffloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91591C1CF1ED7500A7053F /* halffloat.cpp */; };
|
FA91591E1CF1ED7500A7053F /* halffloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91591C1CF1ED7500A7053F /* halffloat.cpp */; };
|
||||||
FA91591F1CF1ED7500A7053F /* halffloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91591C1CF1ED7500A7053F /* halffloat.cpp */; };
|
FA91591F1CF1ED7500A7053F /* halffloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91591C1CF1ED7500A7053F /* halffloat.cpp */; };
|
||||||
FA9159201CF1ED7500A7053F /* halffloat.h in Headers */ = {isa = PBXBuildFile; fileRef = FA91591D1CF1ED7500A7053F /* halffloat.h */; };
|
FA9159201CF1ED7500A7053F /* halffloat.h in Headers */ = {isa = PBXBuildFile; fileRef = FA91591D1CF1ED7500A7053F /* halffloat.h */; };
|
||||||
|
FA93C4521F315B960087CCD4 /* CompressedFormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA93C44F1F315B960087CCD4 /* CompressedFormatHandler.h */; };
|
||||||
|
FA93C4531F315B960087CCD4 /* FormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA93C4501F315B960087CCD4 /* FormatHandler.h */; };
|
||||||
|
FA93C4541F315B960087CCD4 /* FormatHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA93C4511F315B960087CCD4 /* FormatHandler.cpp */; };
|
||||||
FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; };
|
FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; };
|
||||||
FA9D8DD11DEB56C3002CD881 /* pixelformat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */; };
|
FA9D8DD11DEB56C3002CD881 /* pixelformat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */; };
|
||||||
FA9D8DD21DEB56C3002CD881 /* pixelformat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */; };
|
FA9D8DD21DEB56C3002CD881 /* pixelformat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */; };
|
||||||
@@ -1036,6 +1026,10 @@
|
|||||||
FADF543D1E3DAFF700012CC0 /* wrap_Graphics.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF543A1E3DAFF700012CC0 /* wrap_Graphics.h */; };
|
FADF543D1E3DAFF700012CC0 /* wrap_Graphics.h in Headers */ = {isa = PBXBuildFile; fileRef = FADF543A1E3DAFF700012CC0 /* wrap_Graphics.h */; };
|
||||||
FAE272521C05A15B00A67640 /* ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE272501C05A15B00A67640 /* ParticleSystem.cpp */; };
|
FAE272521C05A15B00A67640 /* ParticleSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAE272501C05A15B00A67640 /* ParticleSystem.cpp */; };
|
||||||
FAE272531C05A15B00A67640 /* ParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE272511C05A15B00A67640 /* ParticleSystem.h */; };
|
FAE272531C05A15B00A67640 /* ParticleSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE272511C05A15B00A67640 /* ParticleSystem.h */; };
|
||||||
|
FAECA1B21F3164700095D008 /* CompressedSlice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAECA1B01F3164700095D008 /* CompressedSlice.cpp */; };
|
||||||
|
FAECA1B31F3164700095D008 /* CompressedSlice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAECA1B01F3164700095D008 /* CompressedSlice.cpp */; };
|
||||||
|
FAECA1B41F3164700095D008 /* CompressedSlice.h in Headers */ = {isa = PBXBuildFile; fileRef = FAECA1B11F3164700095D008 /* CompressedSlice.h */; };
|
||||||
|
FAECA1B51F31648A0095D008 /* FormatHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA93C4511F315B960087CCD4 /* FormatHandler.cpp */; };
|
||||||
FAF140531E20934C00F898D2 /* CodeGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FC21E20934C00F898D2 /* CodeGen.cpp */; };
|
FAF140531E20934C00F898D2 /* CodeGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FC21E20934C00F898D2 /* CodeGen.cpp */; };
|
||||||
FAF140541E20934C00F898D2 /* CodeGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FC21E20934C00F898D2 /* CodeGen.cpp */; };
|
FAF140541E20934C00F898D2 /* CodeGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FC21E20934C00F898D2 /* CodeGen.cpp */; };
|
||||||
FAF140551E20934C00F898D2 /* Link.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FC31E20934C00F898D2 /* Link.cpp */; };
|
FAF140551E20934C00F898D2 /* Link.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF13FC31E20934C00F898D2 /* Link.cpp */; };
|
||||||
@@ -1445,7 +1439,6 @@
|
|||||||
FA0B7B841A95902C000E1D17 /* wrap_GlyphData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_GlyphData.h; sourceTree = "<group>"; };
|
FA0B7B841A95902C000E1D17 /* wrap_GlyphData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_GlyphData.h; sourceTree = "<group>"; };
|
||||||
FA0B7B851A95902C000E1D17 /* wrap_Rasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Rasterizer.cpp; sourceTree = "<group>"; };
|
FA0B7B851A95902C000E1D17 /* wrap_Rasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Rasterizer.cpp; sourceTree = "<group>"; };
|
||||||
FA0B7B861A95902C000E1D17 /* wrap_Rasterizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Rasterizer.h; sourceTree = "<group>"; };
|
FA0B7B861A95902C000E1D17 /* wrap_Rasterizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Rasterizer.h; sourceTree = "<group>"; };
|
||||||
FA0B7B881A95902C000E1D17 /* Color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Color.h; sourceTree = "<group>"; };
|
|
||||||
FA0B7B891A95902C000E1D17 /* Drawable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Drawable.h; sourceTree = "<group>"; };
|
FA0B7B891A95902C000E1D17 /* Drawable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Drawable.h; sourceTree = "<group>"; };
|
||||||
FA0B7B8A1A95902C000E1D17 /* Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Graphics.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
|
FA0B7B8A1A95902C000E1D17 /* Graphics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = Graphics.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
|
||||||
FA0B7B8B1A95902C000E1D17 /* Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Graphics.h; sourceTree = "<group>"; };
|
FA0B7B8B1A95902C000E1D17 /* Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Graphics.h; sourceTree = "<group>"; };
|
||||||
@@ -1482,17 +1475,8 @@
|
|||||||
FA0B7BC51A95902C000E1D17 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
|
FA0B7BC51A95902C000E1D17 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
|
||||||
FA0B7BC61A95902C000E1D17 /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = "<group>"; };
|
FA0B7BC61A95902C000E1D17 /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = "<group>"; };
|
||||||
FA0B7BC71A95902C000E1D17 /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = "<group>"; };
|
FA0B7BC71A95902C000E1D17 /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = "<group>"; };
|
||||||
FA0B7BC91A95902C000E1D17 /* CompressedImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedImageData.cpp; sourceTree = "<group>"; };
|
|
||||||
FA0B7BCA1A95902C000E1D17 /* CompressedImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedImageData.h; sourceTree = "<group>"; };
|
|
||||||
FA0B7BCB1A95902C000E1D17 /* CompressedFormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedFormatHandler.h; sourceTree = "<group>"; };
|
|
||||||
FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsHandler.cpp; sourceTree = "<group>"; };
|
FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ddsHandler.cpp; sourceTree = "<group>"; };
|
||||||
FA0B7BCD1A95902C000E1D17 /* ddsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsHandler.h; sourceTree = "<group>"; };
|
FA0B7BCD1A95902C000E1D17 /* ddsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ddsHandler.h; sourceTree = "<group>"; };
|
||||||
FA0B7BCE1A95902C000E1D17 /* FormatHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormatHandler.cpp; sourceTree = "<group>"; };
|
|
||||||
FA0B7BCF1A95902C000E1D17 /* FormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatHandler.h; sourceTree = "<group>"; };
|
|
||||||
FA0B7BD01A95902C000E1D17 /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = "<group>"; };
|
|
||||||
FA0B7BD11A95902C000E1D17 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
|
|
||||||
FA0B7BD21A95902C000E1D17 /* ImageData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageData.cpp; sourceTree = "<group>"; };
|
|
||||||
FA0B7BD31A95902C000E1D17 /* ImageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageData.h; sourceTree = "<group>"; };
|
|
||||||
FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KTXHandler.cpp; sourceTree = "<group>"; };
|
FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KTXHandler.cpp; sourceTree = "<group>"; };
|
||||||
FA0B7BD91A95902C000E1D17 /* KTXHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTXHandler.h; sourceTree = "<group>"; };
|
FA0B7BD91A95902C000E1D17 /* KTXHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTXHandler.h; sourceTree = "<group>"; };
|
||||||
FA0B7BDA1A95902C000E1D17 /* PKMHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PKMHandler.cpp; sourceTree = "<group>"; };
|
FA0B7BDA1A95902C000E1D17 /* PKMHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PKMHandler.cpp; sourceTree = "<group>"; };
|
||||||
@@ -1800,6 +1784,7 @@
|
|||||||
FA620A301AA2F8DB005DB4C2 /* wrap_Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Texture.cpp; sourceTree = "<group>"; };
|
FA620A301AA2F8DB005DB4C2 /* wrap_Texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Texture.cpp; sourceTree = "<group>"; };
|
||||||
FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Texture.h; sourceTree = "<group>"; };
|
FA620A311AA2F8DB005DB4C2 /* wrap_Texture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Texture.h; sourceTree = "<group>"; };
|
||||||
FA620A391AA305F6005DB4C2 /* types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = types.cpp; sourceTree = "<group>"; };
|
FA620A391AA305F6005DB4C2 /* types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = types.cpp; sourceTree = "<group>"; };
|
||||||
|
FA6BDE5B1F31725300786805 /* Color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Color.h; sourceTree = "<group>"; };
|
||||||
FA7550A71AEBE276003E311E /* libluajit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libluajit.a; sourceTree = "<group>"; };
|
FA7550A71AEBE276003E311E /* libluajit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libluajit.a; sourceTree = "<group>"; };
|
||||||
FA7634481E28722A0066EF9E /* StreamBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StreamBuffer.cpp; sourceTree = "<group>"; };
|
FA7634481E28722A0066EF9E /* StreamBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StreamBuffer.cpp; sourceTree = "<group>"; };
|
||||||
FA7634491E28722A0066EF9E /* StreamBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamBuffer.h; sourceTree = "<group>"; };
|
FA7634491E28722A0066EF9E /* StreamBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamBuffer.h; sourceTree = "<group>"; };
|
||||||
@@ -1808,6 +1793,9 @@
|
|||||||
FA8951A11AA2EDF300EC385A /* wrap_Event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Event.h; sourceTree = "<group>"; };
|
FA8951A11AA2EDF300EC385A /* wrap_Event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Event.h; sourceTree = "<group>"; };
|
||||||
FA91591C1CF1ED7500A7053F /* halffloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = halffloat.cpp; sourceTree = "<group>"; };
|
FA91591C1CF1ED7500A7053F /* halffloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = halffloat.cpp; sourceTree = "<group>"; };
|
||||||
FA91591D1CF1ED7500A7053F /* halffloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = halffloat.h; sourceTree = "<group>"; };
|
FA91591D1CF1ED7500A7053F /* halffloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = halffloat.h; sourceTree = "<group>"; };
|
||||||
|
FA93C44F1F315B960087CCD4 /* CompressedFormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedFormatHandler.h; sourceTree = "<group>"; };
|
||||||
|
FA93C4501F315B960087CCD4 /* FormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatHandler.h; sourceTree = "<group>"; };
|
||||||
|
FA93C4511F315B960087CCD4 /* FormatHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormatHandler.cpp; sourceTree = "<group>"; };
|
||||||
FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = "<absolute>"; };
|
FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = "<absolute>"; };
|
||||||
FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pixelformat.cpp; sourceTree = "<group>"; };
|
FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pixelformat.cpp; sourceTree = "<group>"; };
|
||||||
FA9D8DD01DEB56C3002CD881 /* pixelformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pixelformat.h; sourceTree = "<group>"; };
|
FA9D8DD01DEB56C3002CD881 /* pixelformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pixelformat.h; sourceTree = "<group>"; };
|
||||||
@@ -1870,6 +1858,8 @@
|
|||||||
FADF543A1E3DAFF700012CC0 /* wrap_Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Graphics.h; sourceTree = "<group>"; };
|
FADF543A1E3DAFF700012CC0 /* wrap_Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Graphics.h; sourceTree = "<group>"; };
|
||||||
FAE272501C05A15B00A67640 /* ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cpp; sourceTree = "<group>"; };
|
FAE272501C05A15B00A67640 /* ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cpp; sourceTree = "<group>"; };
|
||||||
FAE272511C05A15B00A67640 /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = "<group>"; };
|
FAE272511C05A15B00A67640 /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = "<group>"; };
|
||||||
|
FAECA1B01F3164700095D008 /* CompressedSlice.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedSlice.cpp; sourceTree = "<group>"; };
|
||||||
|
FAECA1B11F3164700095D008 /* CompressedSlice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CompressedSlice.h; sourceTree = "<group>"; };
|
||||||
FAF13FC21E20934C00F898D2 /* CodeGen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGen.cpp; sourceTree = "<group>"; };
|
FAF13FC21E20934C00F898D2 /* CodeGen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGen.cpp; sourceTree = "<group>"; };
|
||||||
FAF13FC31E20934C00F898D2 /* Link.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Link.cpp; sourceTree = "<group>"; };
|
FAF13FC31E20934C00F898D2 /* Link.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Link.cpp; sourceTree = "<group>"; };
|
||||||
FAF13FC51E20934C00F898D2 /* arrays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arrays.h; sourceTree = "<group>"; };
|
FAF13FC51E20934C00F898D2 /* arrays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = arrays.h; sourceTree = "<group>"; };
|
||||||
@@ -2029,6 +2019,7 @@
|
|||||||
FAA3A9AD1B7D465A00CED060 /* android.h */,
|
FAA3A9AD1B7D465A00CED060 /* android.h */,
|
||||||
FA0B78F71A958E3B000E1D17 /* b64.cpp */,
|
FA0B78F71A958E3B000E1D17 /* b64.cpp */,
|
||||||
FA0B78F81A958E3B000E1D17 /* b64.h */,
|
FA0B78F81A958E3B000E1D17 /* b64.h */,
|
||||||
|
FA6BDE5B1F31725300786805 /* Color.h */,
|
||||||
FA0B78F91A958E3B000E1D17 /* config.h */,
|
FA0B78F91A958E3B000E1D17 /* config.h */,
|
||||||
FA9D8DD41DEF8411002CD881 /* Data.cpp */,
|
FA9D8DD41DEF8411002CD881 /* Data.cpp */,
|
||||||
FA0B78FA1A958E3B000E1D17 /* Data.h */,
|
FA0B78FA1A958E3B000E1D17 /* Data.h */,
|
||||||
@@ -2660,7 +2651,6 @@
|
|||||||
FADF53F71E3C7ACD00012CC0 /* Buffer.h */,
|
FADF53F71E3C7ACD00012CC0 /* Buffer.h */,
|
||||||
FA1BA0A51E16F20600AA2803 /* Canvas.cpp */,
|
FA1BA0A51E16F20600AA2803 /* Canvas.cpp */,
|
||||||
FA1BA0A61E16F20600AA2803 /* Canvas.h */,
|
FA1BA0A61E16F20600AA2803 /* Canvas.h */,
|
||||||
FA0B7B881A95902C000E1D17 /* Color.h */,
|
|
||||||
FAF1889E1E9DBC4B008C1479 /* depthstencil.cpp */,
|
FAF1889E1E9DBC4B008C1479 /* depthstencil.cpp */,
|
||||||
FAF1889D1E9DBBC8008C1479 /* depthstencil.h */,
|
FAF1889D1E9DBBC8008C1479 /* depthstencil.h */,
|
||||||
FA9D8DDC1DEF842A002CD881 /* Drawable.cpp */,
|
FA9D8DDC1DEF842A002CD881 /* Drawable.cpp */,
|
||||||
@@ -2760,8 +2750,13 @@
|
|||||||
FA0B7BC21A95902C000E1D17 /* image */ = {
|
FA0B7BC21A95902C000E1D17 /* image */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
FA93C44F1F315B960087CCD4 /* CompressedFormatHandler.h */,
|
||||||
FA0B7BC31A95902C000E1D17 /* CompressedImageData.cpp */,
|
FA0B7BC31A95902C000E1D17 /* CompressedImageData.cpp */,
|
||||||
FA0B7BC41A95902C000E1D17 /* CompressedImageData.h */,
|
FA0B7BC41A95902C000E1D17 /* CompressedImageData.h */,
|
||||||
|
FAECA1B01F3164700095D008 /* CompressedSlice.cpp */,
|
||||||
|
FAECA1B11F3164700095D008 /* CompressedSlice.h */,
|
||||||
|
FA93C4511F315B960087CCD4 /* FormatHandler.cpp */,
|
||||||
|
FA93C4501F315B960087CCD4 /* FormatHandler.h */,
|
||||||
FA9D8DDF1DEF843D002CD881 /* Image.cpp */,
|
FA9D8DDF1DEF843D002CD881 /* Image.cpp */,
|
||||||
FA0B7BC51A95902C000E1D17 /* Image.h */,
|
FA0B7BC51A95902C000E1D17 /* Image.h */,
|
||||||
FA0B7BC61A95902C000E1D17 /* ImageData.cpp */,
|
FA0B7BC61A95902C000E1D17 /* ImageData.cpp */,
|
||||||
@@ -2785,19 +2780,10 @@
|
|||||||
children = (
|
children = (
|
||||||
FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */,
|
FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */,
|
||||||
FA41A3C71C0A1F950084430C /* ASTCHandler.h */,
|
FA41A3C71C0A1F950084430C /* ASTCHandler.h */,
|
||||||
FA0B7BCB1A95902C000E1D17 /* CompressedFormatHandler.h */,
|
|
||||||
FA0B7BC91A95902C000E1D17 /* CompressedImageData.cpp */,
|
|
||||||
FA0B7BCA1A95902C000E1D17 /* CompressedImageData.h */,
|
|
||||||
FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */,
|
FA0B7BCC1A95902C000E1D17 /* ddsHandler.cpp */,
|
||||||
FA0B7BCD1A95902C000E1D17 /* ddsHandler.h */,
|
FA0B7BCD1A95902C000E1D17 /* ddsHandler.h */,
|
||||||
FA1557C11CE90BD200AFF582 /* EXRHandler.cpp */,
|
FA1557C11CE90BD200AFF582 /* EXRHandler.cpp */,
|
||||||
FA1557C21CE90BD200AFF582 /* EXRHandler.h */,
|
FA1557C21CE90BD200AFF582 /* EXRHandler.h */,
|
||||||
FA0B7BCE1A95902C000E1D17 /* FormatHandler.cpp */,
|
|
||||||
FA0B7BCF1A95902C000E1D17 /* FormatHandler.h */,
|
|
||||||
FA0B7BD01A95902C000E1D17 /* Image.cpp */,
|
|
||||||
FA0B7BD11A95902C000E1D17 /* Image.h */,
|
|
||||||
FA0B7BD21A95902C000E1D17 /* ImageData.cpp */,
|
|
||||||
FA0B7BD31A95902C000E1D17 /* ImageData.h */,
|
|
||||||
FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */,
|
FA0B7BD81A95902C000E1D17 /* KTXHandler.cpp */,
|
||||||
FA0B7BD91A95902C000E1D17 /* KTXHandler.h */,
|
FA0B7BD91A95902C000E1D17 /* KTXHandler.h */,
|
||||||
FA0B7BDA1A95902C000E1D17 /* PKMHandler.cpp */,
|
FA0B7BDA1A95902C000E1D17 /* PKMHandler.cpp */,
|
||||||
@@ -3550,7 +3536,6 @@
|
|||||||
FA76344C1E28722A0066EF9E /* StreamBuffer.h in Headers */,
|
FA76344C1E28722A0066EF9E /* StreamBuffer.h in Headers */,
|
||||||
217DFBF31D9F6D490055D849 /* mime.h in Headers */,
|
217DFBF31D9F6D490055D849 /* mime.h in Headers */,
|
||||||
FA0B7B361A958EA3000E1D17 /* wuff_convert.h in Headers */,
|
FA0B7B361A958EA3000E1D17 /* wuff_convert.h in Headers */,
|
||||||
FA0B7D981A95902C000E1D17 /* ImageData.h in Headers */,
|
|
||||||
FA0B7CDE1A95902C000E1D17 /* Source.h in Headers */,
|
FA0B7CDE1A95902C000E1D17 /* Source.h in Headers */,
|
||||||
FA0B7E141A95902C000E1D17 /* GearJoint.h in Headers */,
|
FA0B7E141A95902C000E1D17 /* GearJoint.h in Headers */,
|
||||||
FA0B7D051A95902C000E1D17 /* wrap_DroppedFile.h in Headers */,
|
FA0B7D051A95902C000E1D17 /* wrap_DroppedFile.h in Headers */,
|
||||||
@@ -3612,6 +3597,7 @@
|
|||||||
FA0B7CD21A95902C000E1D17 /* Audio.h in Headers */,
|
FA0B7CD21A95902C000E1D17 /* Audio.h in Headers */,
|
||||||
FA0B79421A958E3B000E1D17 /* utf8.h in Headers */,
|
FA0B79421A958E3B000E1D17 /* utf8.h in Headers */,
|
||||||
FA0B7D171A95902C000E1D17 /* Font.h in Headers */,
|
FA0B7D171A95902C000E1D17 /* Font.h in Headers */,
|
||||||
|
FAECA1B41F3164700095D008 /* CompressedSlice.h in Headers */,
|
||||||
FA0B7A6D1A958EA3000E1D17 /* b2World.h in Headers */,
|
FA0B7A6D1A958EA3000E1D17 /* b2World.h in Headers */,
|
||||||
FA0B7EAE1A95902C000E1D17 /* wrap_SoundData.h in Headers */,
|
FA0B7EAE1A95902C000E1D17 /* wrap_SoundData.h in Headers */,
|
||||||
FA0B7CFF1A95902C000E1D17 /* File.h in Headers */,
|
FA0B7CFF1A95902C000E1D17 /* File.h in Headers */,
|
||||||
@@ -3661,6 +3647,7 @@
|
|||||||
FA0B7E351A95902C000E1D17 /* WeldJoint.h in Headers */,
|
FA0B7E351A95902C000E1D17 /* WeldJoint.h in Headers */,
|
||||||
FA0B7E2F1A95902C000E1D17 /* RopeJoint.h in Headers */,
|
FA0B7E2F1A95902C000E1D17 /* RopeJoint.h in Headers */,
|
||||||
FA0B7D141A95902C000E1D17 /* Font.h in Headers */,
|
FA0B7D141A95902C000E1D17 /* Font.h in Headers */,
|
||||||
|
FA93C4521F315B960087CCD4 /* CompressedFormatHandler.h in Headers */,
|
||||||
FA0B7D411A95902C000E1D17 /* Mesh.h in Headers */,
|
FA0B7D411A95902C000E1D17 /* Mesh.h in Headers */,
|
||||||
FA0B7E591A95902C000E1D17 /* wrap_Joint.h in Headers */,
|
FA0B7E591A95902C000E1D17 /* wrap_Joint.h in Headers */,
|
||||||
FA0B79351A958E3B000E1D17 /* macosx.h in Headers */,
|
FA0B79351A958E3B000E1D17 /* macosx.h in Headers */,
|
||||||
@@ -3668,6 +3655,7 @@
|
|||||||
FA0B7E771A95902C000E1D17 /* wrap_WeldJoint.h in Headers */,
|
FA0B7E771A95902C000E1D17 /* wrap_WeldJoint.h in Headers */,
|
||||||
FA0B7A911A958EA3000E1D17 /* b2FrictionJoint.h in Headers */,
|
FA0B7A911A958EA3000E1D17 /* b2FrictionJoint.h in Headers */,
|
||||||
FA0B7E291A95902C000E1D17 /* PulleyJoint.h in Headers */,
|
FA0B7E291A95902C000E1D17 /* PulleyJoint.h in Headers */,
|
||||||
|
FA6BDE5C1F31725300786805 /* Color.h in Headers */,
|
||||||
FA0B7D471A95902C000E1D17 /* ParticleSystem.h in Headers */,
|
FA0B7D471A95902C000E1D17 /* ParticleSystem.h in Headers */,
|
||||||
FA0B7E231A95902C000E1D17 /* PolygonShape.h in Headers */,
|
FA0B7E231A95902C000E1D17 /* PolygonShape.h in Headers */,
|
||||||
FA0B791E1A958E3B000E1D17 /* config.h in Headers */,
|
FA0B791E1A958E3B000E1D17 /* config.h in Headers */,
|
||||||
@@ -3720,6 +3708,7 @@
|
|||||||
FA0B7ECD1A95902C000E1D17 /* wrap_Channel.h in Headers */,
|
FA0B7ECD1A95902C000E1D17 /* wrap_Channel.h in Headers */,
|
||||||
FAF140AF1E20934C00F898D2 /* osinclude.h in Headers */,
|
FAF140AF1E20934C00F898D2 /* osinclude.h in Headers */,
|
||||||
FA0B7A431A958EA3000E1D17 /* b2CircleShape.h in Headers */,
|
FA0B7A431A958EA3000E1D17 /* b2CircleShape.h in Headers */,
|
||||||
|
FA93C4531F315B960087CCD4 /* FormatHandler.h in Headers */,
|
||||||
FA0B7CD81A95902C000E1D17 /* Audio.h in Headers */,
|
FA0B7CD81A95902C000E1D17 /* Audio.h in Headers */,
|
||||||
FA0B7CF61A95902C000E1D17 /* File.h in Headers */,
|
FA0B7CF61A95902C000E1D17 /* File.h in Headers */,
|
||||||
FA0B7E961A95902C000E1D17 /* Mpg123Decoder.h in Headers */,
|
FA0B7E961A95902C000E1D17 /* Mpg123Decoder.h in Headers */,
|
||||||
@@ -3728,7 +3717,6 @@
|
|||||||
FA0B7DD51A95902C000E1D17 /* BezierCurve.h in Headers */,
|
FA0B7DD51A95902C000E1D17 /* BezierCurve.h in Headers */,
|
||||||
FA0B79271A958E3B000E1D17 /* int.h in Headers */,
|
FA0B79271A958E3B000E1D17 /* int.h in Headers */,
|
||||||
FA27B3A21B498151008A9DCE /* VideoStream.h in Headers */,
|
FA27B3A21B498151008A9DCE /* VideoStream.h in Headers */,
|
||||||
FA0B7D8C1A95902C000E1D17 /* CompressedFormatHandler.h in Headers */,
|
|
||||||
FA0B7E531A95902C000E1D17 /* wrap_FrictionJoint.h in Headers */,
|
FA0B7E531A95902C000E1D17 /* wrap_FrictionJoint.h in Headers */,
|
||||||
FA0B7EB71A95902C000E1D17 /* wrap_System.h in Headers */,
|
FA0B7EB71A95902C000E1D17 /* wrap_System.h in Headers */,
|
||||||
FA27B3A91B498151008A9DCE /* Video.h in Headers */,
|
FA27B3A91B498151008A9DCE /* Video.h in Headers */,
|
||||||
@@ -3738,7 +3726,6 @@
|
|||||||
FAB17BF21ABFB37500F9BA27 /* wrap_CompressedData.h in Headers */,
|
FAB17BF21ABFB37500F9BA27 /* wrap_CompressedData.h in Headers */,
|
||||||
FA0B7E801A95902C000E1D17 /* Joint.h in Headers */,
|
FA0B7E801A95902C000E1D17 /* Joint.h in Headers */,
|
||||||
FA0B7D2F1A95902C000E1D17 /* Drawable.h in Headers */,
|
FA0B7D2F1A95902C000E1D17 /* Drawable.h in Headers */,
|
||||||
FA0B7D951A95902C000E1D17 /* Image.h in Headers */,
|
|
||||||
217DFBE21D9F6D490055D849 /* ftp.lua.h in Headers */,
|
217DFBE21D9F6D490055D849 /* ftp.lua.h in Headers */,
|
||||||
FA0B7EC41A95902C000E1D17 /* Thread.h in Headers */,
|
FA0B7EC41A95902C000E1D17 /* Thread.h in Headers */,
|
||||||
FA0B7DFF1A95902C000E1D17 /* ChainShape.h in Headers */,
|
FA0B7DFF1A95902C000E1D17 /* ChainShape.h in Headers */,
|
||||||
@@ -3794,7 +3781,6 @@
|
|||||||
FA0B7CF91A95902C000E1D17 /* FileData.h in Headers */,
|
FA0B7CF91A95902C000E1D17 /* FileData.h in Headers */,
|
||||||
FA0B7DA71A95902C000E1D17 /* PNGHandler.h in Headers */,
|
FA0B7DA71A95902C000E1D17 /* PNGHandler.h in Headers */,
|
||||||
FA0B7AC41A958EA3000E1D17 /* protocol.h in Headers */,
|
FA0B7AC41A958EA3000E1D17 /* protocol.h in Headers */,
|
||||||
FA0B7D8B1A95902C000E1D17 /* CompressedImageData.h in Headers */,
|
|
||||||
FAF140601E20934C00F898D2 /* revision.h in Headers */,
|
FAF140601E20934C00F898D2 /* revision.h in Headers */,
|
||||||
FAF140A21E20934C00F898D2 /* RemoveTree.h in Headers */,
|
FAF140A21E20934C00F898D2 /* RemoveTree.h in Headers */,
|
||||||
FA0B7A8E1A958EA3000E1D17 /* b2DistanceJoint.h in Headers */,
|
FA0B7A8E1A958EA3000E1D17 /* b2DistanceJoint.h in Headers */,
|
||||||
@@ -3876,7 +3862,6 @@
|
|||||||
FA9D8DD31DEB56C3002CD881 /* pixelformat.h in Headers */,
|
FA9D8DD31DEB56C3002CD881 /* pixelformat.h in Headers */,
|
||||||
FAF140A61E20934C00F898D2 /* ScanContext.h in Headers */,
|
FAF140A61E20934C00F898D2 /* ScanContext.h in Headers */,
|
||||||
FA0B7E4A1A95902C000E1D17 /* wrap_DistanceJoint.h in Headers */,
|
FA0B7E4A1A95902C000E1D17 /* wrap_DistanceJoint.h in Headers */,
|
||||||
FA0B7D2E1A95902C000E1D17 /* Color.h in Headers */,
|
|
||||||
FA0B7A6A1A958EA3000E1D17 /* b2TimeStep.h in Headers */,
|
FA0B7A6A1A958EA3000E1D17 /* b2TimeStep.h in Headers */,
|
||||||
FA0B7A281A958EA3000E1D17 /* Box2D.h in Headers */,
|
FA0B7A281A958EA3000E1D17 /* Box2D.h in Headers */,
|
||||||
FA0B7DE41A95902C000E1D17 /* wrap_RandomGenerator.h in Headers */,
|
FA0B7DE41A95902C000E1D17 /* wrap_RandomGenerator.h in Headers */,
|
||||||
@@ -3895,7 +3880,6 @@
|
|||||||
FADF54041E3D77B500012CC0 /* wrap_Text.h in Headers */,
|
FADF54041E3D77B500012CC0 /* wrap_Text.h in Headers */,
|
||||||
FA0B7ED31A95902C000E1D17 /* wrap_ThreadModule.h in Headers */,
|
FA0B7ED31A95902C000E1D17 /* wrap_ThreadModule.h in Headers */,
|
||||||
FA0B7A511A958EA3000E1D17 /* b2GrowableStack.h in Headers */,
|
FA0B7A511A958EA3000E1D17 /* b2GrowableStack.h in Headers */,
|
||||||
FA0B7D921A95902C000E1D17 /* FormatHandler.h in Headers */,
|
|
||||||
FAC756F61E4F99B400B91289 /* Effect.h in Headers */,
|
FAC756F61E4F99B400B91289 /* Effect.h in Headers */,
|
||||||
FA0B7ADD1A958EA3000E1D17 /* gladfuncs.hpp in Headers */,
|
FA0B7ADD1A958EA3000E1D17 /* gladfuncs.hpp in Headers */,
|
||||||
FAF1405D1E20934C00F898D2 /* intermediate.h in Headers */,
|
FAF1405D1E20934C00F898D2 /* intermediate.h in Headers */,
|
||||||
@@ -4051,7 +4035,6 @@
|
|||||||
FA0B7ABE1A958EA3000E1D17 /* compress.c in Sources */,
|
FA0B7ABE1A958EA3000E1D17 /* compress.c in Sources */,
|
||||||
FA0B7CF21A95902C000E1D17 /* DroppedFile.cpp in Sources */,
|
FA0B7CF21A95902C000E1D17 /* DroppedFile.cpp in Sources */,
|
||||||
FA4F2C141DE936FE00CA37D7 /* usocket.c in Sources */,
|
FA4F2C141DE936FE00CA37D7 /* usocket.c in Sources */,
|
||||||
FA0B7D8A1A95902C000E1D17 /* CompressedImageData.cpp in Sources */,
|
|
||||||
FAF140831E20934C00F898D2 /* ParseContextBase.cpp in Sources */,
|
FAF140831E20934C00F898D2 /* ParseContextBase.cpp in Sources */,
|
||||||
FA0B7AD21A958EA3000E1D17 /* protocol.c in Sources */,
|
FA0B7AD21A958EA3000E1D17 /* protocol.c in Sources */,
|
||||||
FAF140A41E20934C00F898D2 /* Scan.cpp in Sources */,
|
FAF140A41E20934C00F898D2 /* Scan.cpp in Sources */,
|
||||||
@@ -4190,15 +4173,14 @@
|
|||||||
FADF54211E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */,
|
FADF54211E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */,
|
||||||
FA0B791C1A958E3B000E1D17 /* b64.cpp in Sources */,
|
FA0B791C1A958E3B000E1D17 /* b64.cpp in Sources */,
|
||||||
FA1E88851DF363E100E808AA /* Filter.cpp in Sources */,
|
FA1E88851DF363E100E808AA /* Filter.cpp in Sources */,
|
||||||
FA0B7D941A95902C000E1D17 /* Image.cpp in Sources */,
|
|
||||||
FA0B7DA01A95902C000E1D17 /* KTXHandler.cpp in Sources */,
|
FA0B7DA01A95902C000E1D17 /* KTXHandler.cpp in Sources */,
|
||||||
FA27B3A11B498151008A9DCE /* VideoStream.cpp in Sources */,
|
FA27B3A11B498151008A9DCE /* VideoStream.cpp in Sources */,
|
||||||
FA0B7A5C1A958EA3000E1D17 /* b2Timer.cpp in Sources */,
|
FA0B7A5C1A958EA3000E1D17 /* b2Timer.cpp in Sources */,
|
||||||
FA0B7CEC1A95902C000E1D17 /* Event.cpp in Sources */,
|
FA0B7CEC1A95902C000E1D17 /* Event.cpp in Sources */,
|
||||||
FA27B3AB1B498151008A9DCE /* VideoStream.cpp in Sources */,
|
FA27B3AB1B498151008A9DCE /* VideoStream.cpp in Sources */,
|
||||||
FA0B7A7E1A958EA3000E1D17 /* b2ContactSolver.cpp in Sources */,
|
FA0B7A7E1A958EA3000E1D17 /* b2ContactSolver.cpp in Sources */,
|
||||||
FA0B7D971A95902C000E1D17 /* ImageData.cpp in Sources */,
|
|
||||||
FA0B7E581A95902C000E1D17 /* wrap_Joint.cpp in Sources */,
|
FA0B7E581A95902C000E1D17 /* wrap_Joint.cpp in Sources */,
|
||||||
|
FAECA1B51F31648A0095D008 /* FormatHandler.cpp in Sources */,
|
||||||
FA4F2C0A1DE936E600CA37D7 /* mime.c in Sources */,
|
FA4F2C0A1DE936E600CA37D7 /* mime.c in Sources */,
|
||||||
FA0B7E311A95902C000E1D17 /* Shape.cpp in Sources */,
|
FA0B7E311A95902C000E1D17 /* Shape.cpp in Sources */,
|
||||||
FA0B7E491A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */,
|
FA0B7E491A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */,
|
||||||
@@ -4287,13 +4269,13 @@
|
|||||||
FA0B7DB21A95902C000E1D17 /* wrap_Image.cpp in Sources */,
|
FA0B7DB21A95902C000E1D17 /* wrap_Image.cpp in Sources */,
|
||||||
FA0B7E891A95902C000E1D17 /* Decoder.cpp in Sources */,
|
FA0B7E891A95902C000E1D17 /* Decoder.cpp in Sources */,
|
||||||
FA0B7A591A958EA3000E1D17 /* b2StackAllocator.cpp in Sources */,
|
FA0B7A591A958EA3000E1D17 /* b2StackAllocator.cpp in Sources */,
|
||||||
|
FAECA1B31F3164700095D008 /* CompressedSlice.cpp in Sources */,
|
||||||
FA0B7E3D1A95902C000E1D17 /* wrap_Body.cpp in Sources */,
|
FA0B7E3D1A95902C000E1D17 /* wrap_Body.cpp in Sources */,
|
||||||
FA0B7D7A1A95902C000E1D17 /* Quad.cpp in Sources */,
|
FA0B7D7A1A95902C000E1D17 /* Quad.cpp in Sources */,
|
||||||
FA620A3B1AA305F6005DB4C2 /* types.cpp in Sources */,
|
FA620A3B1AA305F6005DB4C2 /* types.cpp in Sources */,
|
||||||
FA0B7DD41A95902C000E1D17 /* BezierCurve.cpp in Sources */,
|
FA0B7DD41A95902C000E1D17 /* BezierCurve.cpp in Sources */,
|
||||||
FA0B7E7C1A95902C000E1D17 /* wrap_World.cpp in Sources */,
|
FA0B7E7C1A95902C000E1D17 /* wrap_World.cpp in Sources */,
|
||||||
FA4F2C0E1DE936FE00CA37D7 /* tcp.c in Sources */,
|
FA4F2C0E1DE936FE00CA37D7 /* tcp.c in Sources */,
|
||||||
FA0B7D911A95902C000E1D17 /* FormatHandler.cpp in Sources */,
|
|
||||||
FA0B7D431A95902C000E1D17 /* OpenGL.cpp in Sources */,
|
FA0B7D431A95902C000E1D17 /* OpenGL.cpp in Sources */,
|
||||||
FA0B7DBF1A95902C000E1D17 /* JoystickModule.cpp in Sources */,
|
FA0B7DBF1A95902C000E1D17 /* JoystickModule.cpp in Sources */,
|
||||||
FA0B7D4F1A95902C000E1D17 /* SpriteBatch.cpp in Sources */,
|
FA0B7D4F1A95902C000E1D17 /* SpriteBatch.cpp in Sources */,
|
||||||
@@ -4410,7 +4392,6 @@
|
|||||||
FA0B7D091A95902C000E1D17 /* wrap_FileData.cpp in Sources */,
|
FA0B7D091A95902C000E1D17 /* wrap_FileData.cpp in Sources */,
|
||||||
FA0B7B341A958EA3000E1D17 /* wuff_convert.c in Sources */,
|
FA0B7B341A958EA3000E1D17 /* wuff_convert.c in Sources */,
|
||||||
FA0B7CF11A95902C000E1D17 /* DroppedFile.cpp in Sources */,
|
FA0B7CF11A95902C000E1D17 /* DroppedFile.cpp in Sources */,
|
||||||
FA0B7D891A95902C000E1D17 /* CompressedImageData.cpp in Sources */,
|
|
||||||
FAF140821E20934C00F898D2 /* ParseContextBase.cpp in Sources */,
|
FAF140821E20934C00F898D2 /* ParseContextBase.cpp in Sources */,
|
||||||
FA0B7D1E1A95902C000E1D17 /* ImageRasterizer.cpp in Sources */,
|
FA0B7D1E1A95902C000E1D17 /* ImageRasterizer.cpp in Sources */,
|
||||||
FAF140A31E20934C00F898D2 /* Scan.cpp in Sources */,
|
FAF140A31E20934C00F898D2 /* Scan.cpp in Sources */,
|
||||||
@@ -4545,7 +4526,6 @@
|
|||||||
FA0B7A4E1A958EA3000E1D17 /* b2Draw.cpp in Sources */,
|
FA0B7A4E1A958EA3000E1D17 /* b2Draw.cpp in Sources */,
|
||||||
FAD19A171DFF8CA200D5398A /* ImageDataBase.cpp in Sources */,
|
FAD19A171DFF8CA200D5398A /* ImageDataBase.cpp in Sources */,
|
||||||
FA27B3C01B4985BF008A9DCE /* wrap_VideoStream.cpp in Sources */,
|
FA27B3C01B4985BF008A9DCE /* wrap_VideoStream.cpp in Sources */,
|
||||||
FA0B7D931A95902C000E1D17 /* Image.cpp in Sources */,
|
|
||||||
FADF54201E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */,
|
FADF54201E3DA52C00012CC0 /* wrap_ParticleSystem.cpp in Sources */,
|
||||||
FA0B7D9F1A95902C000E1D17 /* KTXHandler.cpp in Sources */,
|
FA0B7D9F1A95902C000E1D17 /* KTXHandler.cpp in Sources */,
|
||||||
FA1E88831DF363DB00E808AA /* Filter.cpp in Sources */,
|
FA1E88831DF363DB00E808AA /* Filter.cpp in Sources */,
|
||||||
@@ -4554,9 +4534,9 @@
|
|||||||
FA0B7CEB1A95902C000E1D17 /* Event.cpp in Sources */,
|
FA0B7CEB1A95902C000E1D17 /* Event.cpp in Sources */,
|
||||||
FA1557C31CE90BD200AFF582 /* EXRHandler.cpp in Sources */,
|
FA1557C31CE90BD200AFF582 /* EXRHandler.cpp in Sources */,
|
||||||
FA27B3AA1B498151008A9DCE /* VideoStream.cpp in Sources */,
|
FA27B3AA1B498151008A9DCE /* VideoStream.cpp in Sources */,
|
||||||
FA0B7D961A95902C000E1D17 /* ImageData.cpp in Sources */,
|
|
||||||
FA0B7E571A95902C000E1D17 /* wrap_Joint.cpp in Sources */,
|
FA0B7E571A95902C000E1D17 /* wrap_Joint.cpp in Sources */,
|
||||||
FA0B7E301A95902C000E1D17 /* Shape.cpp in Sources */,
|
FA0B7E301A95902C000E1D17 /* Shape.cpp in Sources */,
|
||||||
|
FA93C4541F315B960087CCD4 /* FormatHandler.cpp in Sources */,
|
||||||
FA0B7E481A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */,
|
FA0B7E481A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */,
|
||||||
FA0B7A8F1A958EA3000E1D17 /* b2FrictionJoint.cpp in Sources */,
|
FA0B7A8F1A958EA3000E1D17 /* b2FrictionJoint.cpp in Sources */,
|
||||||
FA0B792F1A958E3B000E1D17 /* Module.cpp in Sources */,
|
FA0B792F1A958E3B000E1D17 /* Module.cpp in Sources */,
|
||||||
@@ -4597,6 +4577,7 @@
|
|||||||
FA0B7E8B1A95902C000E1D17 /* FLACDecoder.cpp in Sources */,
|
FA0B7E8B1A95902C000E1D17 /* FLACDecoder.cpp in Sources */,
|
||||||
FA0B7B3A1A958EA3000E1D17 /* wuff_memory.c in Sources */,
|
FA0B7B3A1A958EA3000E1D17 /* wuff_memory.c in Sources */,
|
||||||
FA0B7A381A958EA3000E1D17 /* b2DynamicTree.cpp in Sources */,
|
FA0B7A381A958EA3000E1D17 /* b2DynamicTree.cpp in Sources */,
|
||||||
|
FAECA1B21F3164700095D008 /* CompressedSlice.cpp in Sources */,
|
||||||
FA0B7D481A95902C000E1D17 /* Polyline.cpp in Sources */,
|
FA0B7D481A95902C000E1D17 /* Polyline.cpp in Sources */,
|
||||||
217DFC111D9F6D490055D849 /* usocket.c in Sources */,
|
217DFC111D9F6D490055D849 /* usocket.c in Sources */,
|
||||||
FAF140751E20934C00F898D2 /* IntermTraverse.cpp in Sources */,
|
FAF140751E20934C00F898D2 /* IntermTraverse.cpp in Sources */,
|
||||||
@@ -4647,7 +4628,6 @@
|
|||||||
FA91591E1CF1ED7500A7053F /* halffloat.cpp in Sources */,
|
FA91591E1CF1ED7500A7053F /* halffloat.cpp in Sources */,
|
||||||
FA0B7E7B1A95902C000E1D17 /* wrap_World.cpp in Sources */,
|
FA0B7E7B1A95902C000E1D17 /* wrap_World.cpp in Sources */,
|
||||||
FA0B7B281A958EA3000E1D17 /* simplexnoise1234.cpp in Sources */,
|
FA0B7B281A958EA3000E1D17 /* simplexnoise1234.cpp in Sources */,
|
||||||
FA0B7D901A95902C000E1D17 /* FormatHandler.cpp in Sources */,
|
|
||||||
FA0B7D421A95902C000E1D17 /* OpenGL.cpp in Sources */,
|
FA0B7D421A95902C000E1D17 /* OpenGL.cpp in Sources */,
|
||||||
FA0B7A671A958EA3000E1D17 /* b2Island.cpp in Sources */,
|
FA0B7A671A958EA3000E1D17 /* b2Island.cpp in Sources */,
|
||||||
FA0B7DBE1A95902C000E1D17 /* JoystickModule.cpp in Sources */,
|
FA0B7DBE1A95902C000E1D17 /* JoystickModule.cpp in Sources */,
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
A9D307F2106635D3004FEDF8 /* physfs.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9D307E9106635C3004FEDF8 /* physfs.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
A9D307F2106635D3004FEDF8 /* physfs.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9D307E9106635C3004FEDF8 /* physfs.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
A9F169AC109E825000FC83D1 /* mpg123.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F169A6109E824900FC83D1 /* mpg123.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
A9F169AC109E825000FC83D1 /* mpg123.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F169A6109E824900FC83D1 /* mpg123.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F16926109E7BAD00FC83D1 /* libmodplug.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F16926109E7BAD00FC83D1 /* libmodplug.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
|
CE73F8001EEB64150052DAB3 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE73F7FF1EEB64150052DAB3 /* AVFoundation.framework */; };
|
||||||
FA0797991BF480A200034B7C /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA0797981BF480A200034B7C /* GameController.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
FA0797991BF480A200034B7C /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA0797981BF480A200034B7C /* GameController.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||||
FA08F69616C766E000F007B5 /* love.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; };
|
FA08F69616C766E000F007B5 /* love.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; };
|
||||||
FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
@@ -110,6 +111,7 @@
|
|||||||
A9D307E9106635C3004FEDF8 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = "<absolute>"; };
|
A9D307E9106635C3004FEDF8 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = "<absolute>"; };
|
||||||
A9F16926109E7BAD00FC83D1 /* libmodplug.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libmodplug.framework; path = /Library/Frameworks/libmodplug.framework; sourceTree = "<absolute>"; };
|
A9F16926109E7BAD00FC83D1 /* libmodplug.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libmodplug.framework; path = /Library/Frameworks/libmodplug.framework; sourceTree = "<absolute>"; };
|
||||||
A9F169A6109E824900FC83D1 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = "<absolute>"; };
|
A9F169A6109E824900FC83D1 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = "<absolute>"; };
|
||||||
|
CE73F7FF1EEB64150052DAB3 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
FA0797981BF480A200034B7C /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.1.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; };
|
FA0797981BF480A200034B7C /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.1.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
FA08F69116C765A200F007B5 /* love.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
FA08F69116C765A200F007B5 /* love.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
FA0B7F061A95AAF3000E1D17 /* love.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = love.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
FA0B7F061A95AAF3000E1D17 /* love.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = love.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -149,6 +151,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
CE73F8001EEB64150052DAB3 /* AVFoundation.framework in Frameworks */,
|
||||||
FA5D24D11A96E73300C6FC8F /* liblove.a in Frameworks */,
|
FA5D24D11A96E73300C6FC8F /* liblove.a in Frameworks */,
|
||||||
FA5D24C21A96D78000C6FC8F /* Foundation.framework in Frameworks */,
|
FA5D24C21A96D78000C6FC8F /* Foundation.framework in Frameworks */,
|
||||||
FA5D24961A96CAC200C6FC8F /* CoreMotion.framework in Frameworks */,
|
FA5D24961A96CAC200C6FC8F /* CoreMotion.framework in Frameworks */,
|
||||||
@@ -169,6 +172,7 @@
|
|||||||
1058C7A0FEA54F0111CA2CBB /* Frameworks */ = {
|
1058C7A0FEA54F0111CA2CBB /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
CE73F7FF1EEB64150052DAB3 /* AVFoundation.framework */,
|
||||||
FA5D24801A96C97900C6FC8F /* ios */,
|
FA5D24801A96C97900C6FC8F /* ios */,
|
||||||
FA0B7EEC1A959249000E1D17 /* macosx */,
|
FA0B7EEC1A959249000E1D17 /* macosx */,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -18,13 +18,11 @@
|
|||||||
* 3. This notice may not be removed or altered from any source distribution.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef LOVE_GRAPHICS_COLOR_H
|
#ifndef LOVE_COLOR_H
|
||||||
#define LOVE_GRAPHICS_COLOR_H
|
#define LOVE_COLOR_H
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
namespace graphics
|
|
||||||
{
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct ColorT
|
struct ColorT
|
||||||
@@ -153,7 +151,6 @@ inline Colorf toColorf(Color c)
|
|||||||
return Colorf(c.r / 255.0f, c.g / 255.0f, c.b / 255.0f, c.a / 255.0f);
|
return Colorf(c.r / 255.0f, c.g / 255.0f, c.b / 255.0f, c.a / 255.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // graphics
|
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
#endif // LOVE_GRAPHICS_COLOR_H
|
#endif // LOVE_COLOR_H
|
||||||
@@ -225,6 +225,22 @@ bool createStorageDirectories()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasBackgroundMusic()
|
||||||
|
{
|
||||||
|
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
|
||||||
|
jobject activity = (jobject) SDL_AndroidGetActivity();
|
||||||
|
|
||||||
|
jclass clazz(env->GetObjectClass(activity));
|
||||||
|
jmethodID method_id = env->GetMethodID(clazz, "hasBackgroundMusic", "()Z");
|
||||||
|
|
||||||
|
jboolean result = env->CallBooleanMethod(activity, method_id);
|
||||||
|
|
||||||
|
env->DeleteLocalRef(activity);
|
||||||
|
env->DeleteLocalRef(clazz);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // android
|
} // android
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ bool mkdir(const char *path);
|
|||||||
|
|
||||||
bool createStorageDirectories();
|
bool createStorageDirectories();
|
||||||
|
|
||||||
|
bool hasBackgroundMusic();
|
||||||
|
|
||||||
} // android
|
} // android
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,16 @@ std::string getExecutablePath();
|
|||||||
**/
|
**/
|
||||||
void vibrate();
|
void vibrate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable mix mode (e.g. with background music apps) and playback with a muted device.
|
||||||
|
**/
|
||||||
|
void setAudioMixWithOthers(bool mixEnabled);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether another application is playing audio.
|
||||||
|
**/
|
||||||
|
bool hasBackgroundMusic();
|
||||||
|
|
||||||
} // ios
|
} // ios
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
#import <AudioToolbox/AudioServices.h>
|
#import <AudioToolbox/AudioServices.h>
|
||||||
|
#import <AVFoundation/AVFoundation.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -344,6 +345,28 @@ void vibrate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setAudioMixWithOthers(bool mixEnabled)
|
||||||
|
{
|
||||||
|
@autoreleasepool
|
||||||
|
{
|
||||||
|
NSString *category = AVAudioSessionCategorySoloAmbient;
|
||||||
|
NSError *err;
|
||||||
|
|
||||||
|
if (mixEnabled)
|
||||||
|
category = AVAudioSessionCategoryAmbient;
|
||||||
|
|
||||||
|
if (![[AVAudioSession sharedInstance] setCategory:category error:&err])
|
||||||
|
NSLog(@"Error in AVAudioSession setCategory: %@", [err localizedDescription]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasBackgroundMusic()
|
||||||
|
{
|
||||||
|
if ([[AVAudioSession sharedInstance] respondsToSelector:@selector(secondaryAudioShouldBeSilencedHint)])
|
||||||
|
return [[AVAudioSession sharedInstance] secondaryAudioShouldBeSilencedHint];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // ios
|
} // ios
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,23 @@
|
|||||||
/**
|
/**
|
||||||
* Simple DDS data parser for compressed 2D textures.
|
* Simple DDS data parser for compressed 2D textures.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013 Alexander Szpakowski.
|
* Copyright (c) 2013-2017 Alex Szpakowski
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* This software is provided 'as-is', without any express or implied
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
* in the Software without restriction, including without limitation the rights
|
* arising from the use of this software.
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
* all copies or substantial portions of the Software.
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* claim that you wrote the original software. If you use this software
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* appreciated but is not required.
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* misrepresented as being the original software.
|
||||||
* THE SOFTWARE.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Enums and structs copied from Microsoft.
|
* Enums and structs copied from Microsoft.
|
||||||
|
|||||||
@@ -1,25 +1,23 @@
|
|||||||
/**
|
/**
|
||||||
* Simple DDS data parser for compressed 2D textures.
|
* Simple DDS data parser for compressed 2D textures.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013 Alexander Szpakowski.
|
* Copyright (c) 2013-2017 Alex Szpakowski
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* This software is provided 'as-is', without any express or implied
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
* in the Software without restriction, including without limitation the rights
|
* arising from the use of this software.
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
* all copies or substantial portions of the Software.
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* claim that you wrote the original software. If you use this software
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* appreciated but is not required.
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* misrepresented as being the original software.
|
||||||
* THE SOFTWARE.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include "ddsparse.h"
|
#include "ddsparse.h"
|
||||||
|
|||||||
@@ -1,25 +1,23 @@
|
|||||||
/**
|
/**
|
||||||
* Simple DDS data parser for compressed 2D textures.
|
* Simple DDS data parser for compressed 2D textures.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013 Alexander Szpakowski.
|
* Copyright (c) 2013-2017 Alex Szpakowski
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* This software is provided 'as-is', without any express or implied
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
* in the Software without restriction, including without limitation the rights
|
* arising from the use of this software.
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
* all copies or substantial portions of the Software.
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* claim that you wrote the original software. If you use this software
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* appreciated but is not required.
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* misrepresented as being the original software.
|
||||||
* THE SOFTWARE.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef DDS_PARSE_H
|
#ifndef DDS_PARSE_H
|
||||||
|
|||||||
+991
-569
File diff suppressed because it is too large
Load Diff
@@ -13,18 +13,34 @@
|
|||||||
* claim that you wrote the original software. If you use this software
|
* claim that you wrote the original software. If you use this software
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
* appreciated but is not required.
|
* appreciated but is not required.
|
||||||
* 2. Altered Audio versions must be plainly marked as such, and must not be
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
* misrepresented as being the original software.
|
* misrepresented as being the original software.
|
||||||
* 3. This notice may not be removed or altered from any Audio distribution.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include "Audio.h"
|
#include "Audio.h"
|
||||||
|
#include "common/config.h"
|
||||||
|
|
||||||
|
#ifdef LOVE_IOS
|
||||||
|
#include "common/ios.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
namespace audio
|
namespace audio
|
||||||
{
|
{
|
||||||
|
|
||||||
|
bool Audio::setMixWithSystem(bool mix)
|
||||||
|
{
|
||||||
|
#ifdef LOVE_IOS
|
||||||
|
love::ios::setAudioMixWithOthers(mix);
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
LOVE_UNUSED(mix);
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
StringMap<Audio::DistanceModel, Audio::DISTANCE_MAX_ENUM>::Entry Audio::distanceModelEntries[] =
|
StringMap<Audio::DistanceModel, Audio::DISTANCE_MAX_ENUM>::Entry Audio::distanceModelEntries[] =
|
||||||
{
|
{
|
||||||
{"none", Audio::DISTANCE_NONE},
|
{"none", Audio::DISTANCE_NONE},
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* including commercial applications, and to alter it and redistribute it
|
* including commercial applications, and to alter it and redistribute it
|
||||||
* freely, subject to the following restrictions:
|
* freely, subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* 1. The origin of this software must not be misrepresented = 0; you must not
|
* 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
|
* claim that you wrote the original software. If you use this software
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
* appreciated but is not required.
|
* appreciated but is not required.
|
||||||
@@ -236,7 +236,7 @@ public:
|
|||||||
* @param list List of EFX names to fill.
|
* @param list List of EFX names to fill.
|
||||||
* @return true if effect was present, false otherwise.
|
* @return true if effect was present, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool getEffectsList(std::vector<std::string> &list) = 0;
|
virtual bool getActiveEffects(std::vector<std::string> &list) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets maximum number of scene EFX effects.
|
* Gets maximum number of scene EFX effects.
|
||||||
@@ -256,6 +256,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool isEFXsupported() const = 0;
|
virtual bool isEFXsupported() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether audio from other apps mixes with love.audio or is muted,
|
||||||
|
* on supported platforms.
|
||||||
|
**/
|
||||||
|
bool setMixWithSystem(bool mix);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static StringMap<DistanceModel, DISTANCE_MAX_ENUM>::Entry distanceModelEntries[];
|
static StringMap<DistanceModel, DISTANCE_MAX_ENUM>::Entry distanceModelEntries[];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2006-2016 LOVE Development Team
|
* Copyright (c) 2006-2017 LOVE Development Team
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2006-2016 LOVE Development Team
|
* Copyright (c) 2006-2017 LOVE Development Team
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* including commercial applications, and to alter it and redistribute it
|
* including commercial applications, and to alter it and redistribute it
|
||||||
* freely, subject to the following restrictions:
|
* freely, subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* 1. The origin of this software must not be misrepresented = 0; you must not
|
* 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
|
* claim that you wrote the original software. If you use this software
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
* appreciated but is not required.
|
* appreciated but is not required.
|
||||||
@@ -37,15 +37,14 @@ public:
|
|||||||
|
|
||||||
static love::Type type;
|
static love::Type type;
|
||||||
|
|
||||||
|
static const int DEFAULT_SAMPLES = 8192;
|
||||||
|
static const int DEFAULT_SAMPLE_RATE = 8000;
|
||||||
|
static const int DEFAULT_BIT_DEPTH = 16;
|
||||||
|
static const int DEFAULT_CHANNELS = 1;
|
||||||
|
|
||||||
RecordingDevice();
|
RecordingDevice();
|
||||||
virtual ~RecordingDevice();
|
virtual ~RecordingDevice();
|
||||||
|
|
||||||
/**
|
|
||||||
* Begins audio input recording process. using default (previous) parameters.
|
|
||||||
* @return True if recording started successfully.
|
|
||||||
**/
|
|
||||||
virtual bool start() = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begins audio input recording process.
|
* Begins audio input recording process.
|
||||||
* @param samples Number of samples to buffer.
|
* @param samples Number of samples to buffer.
|
||||||
@@ -77,6 +76,11 @@ public:
|
|||||||
**/
|
**/
|
||||||
virtual int getSampleCount() const = 0;
|
virtual int getSampleCount() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the maximum number of samples that will be buffered, as set by start().
|
||||||
|
**/
|
||||||
|
virtual int getMaxSamples() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Sample rate for recording.
|
* @return Sample rate for recording.
|
||||||
**/
|
**/
|
||||||
@@ -96,6 +100,7 @@ public:
|
|||||||
* @return True if currently recording.
|
* @return True if currently recording.
|
||||||
**/
|
**/
|
||||||
virtual bool isRecording() const = 0;
|
virtual bool isRecording() const = 0;
|
||||||
|
|
||||||
}; //RecordingDevice
|
}; //RecordingDevice
|
||||||
|
|
||||||
} //audio
|
} //audio
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ public:
|
|||||||
virtual bool setEffect(const char *effect, const std::map<Filter::Parameter, float> ¶ms) = 0;
|
virtual bool setEffect(const char *effect, const std::map<Filter::Parameter, float> ¶ms) = 0;
|
||||||
virtual bool unsetEffect(const char *effect) = 0;
|
virtual bool unsetEffect(const char *effect) = 0;
|
||||||
virtual bool getEffect(const char *effect, std::map<Filter::Parameter, float> ¶ms) = 0;
|
virtual bool getEffect(const char *effect, std::map<Filter::Parameter, float> ¶ms) = 0;
|
||||||
virtual bool getEffectsList(std::vector<std::string> &list) = 0;
|
virtual bool getActiveEffects(std::vector<std::string> &list) const = 0;
|
||||||
|
|
||||||
virtual int getFreeBufferCount() const = 0;
|
virtual int getFreeBufferCount() const = 0;
|
||||||
virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels) = 0;
|
virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels) = 0;
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ bool Audio::getEffect(const char *, std::map<Effect::Parameter, float> &)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Audio::getEffectsList(std::vector<std::string> &list)
|
bool Audio::getActiveEffects(std::vector<std::string> &) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public:
|
|||||||
bool setEffect(const char *, std::map<Effect::Parameter, float> ¶ms);
|
bool setEffect(const char *, std::map<Effect::Parameter, float> ¶ms);
|
||||||
bool unsetEffect(const char *);
|
bool unsetEffect(const char *);
|
||||||
bool getEffect(const char *, std::map<Effect::Parameter, float> ¶ms);
|
bool getEffect(const char *, std::map<Effect::Parameter, float> ¶ms);
|
||||||
bool getEffectsList(std::vector<std::string> &list);
|
bool getActiveEffects(std::vector<std::string> &list) const;
|
||||||
int getMaxSceneEffects() const;
|
int getMaxSceneEffects() const;
|
||||||
int getMaxSourceEffects() const;
|
int getMaxSourceEffects() const;
|
||||||
bool isEFXsupported() const;
|
bool isEFXsupported() const;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* including commercial applications, and to alter it and redistribute it
|
* including commercial applications, and to alter it and redistribute it
|
||||||
* freely, subject to the following restrictions:
|
* freely, subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* 1. The origin of this software must not be misrepresented = 0; you must not
|
* 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
|
* claim that you wrote the original software. If you use this software
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
* appreciated but is not required.
|
* appreciated but is not required.
|
||||||
@@ -38,11 +38,6 @@ RecordingDevice::~RecordingDevice()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RecordingDevice::start()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RecordingDevice::start(int, int, int, int)
|
bool RecordingDevice::start(int, int, int, int)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -62,19 +57,24 @@ int RecordingDevice::getSampleCount() const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RecordingDevice::getMaxSamples() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int RecordingDevice::getSampleRate() const
|
int RecordingDevice::getSampleRate() const
|
||||||
{
|
{
|
||||||
return 8000;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RecordingDevice::getBitDepth() const
|
int RecordingDevice::getBitDepth() const
|
||||||
{
|
{
|
||||||
return 16;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RecordingDevice::getChannels() const
|
int RecordingDevice::getChannels() const
|
||||||
{
|
{
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *RecordingDevice::getName() const
|
const char *RecordingDevice::getName() const
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* including commercial applications, and to alter it and redistribute it
|
* including commercial applications, and to alter it and redistribute it
|
||||||
* freely, subject to the following restrictions:
|
* freely, subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* 1. The origin of this software must not be misrepresented = 0; you must not
|
* 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
|
* claim that you wrote the original software. If you use this software
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
* appreciated but is not required.
|
* appreciated but is not required.
|
||||||
@@ -36,11 +36,11 @@ class RecordingDevice : public love::audio::RecordingDevice
|
|||||||
public:
|
public:
|
||||||
RecordingDevice(const char *name);
|
RecordingDevice(const char *name);
|
||||||
virtual ~RecordingDevice();
|
virtual ~RecordingDevice();
|
||||||
virtual bool start();
|
|
||||||
virtual bool start(int samples, int sampleRate, int bitDepth, int channels);
|
virtual bool start(int samples, int sampleRate, int bitDepth, int channels);
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
virtual love::sound::SoundData *getData();
|
virtual love::sound::SoundData *getData();
|
||||||
virtual const char *getName() const;
|
virtual const char *getName() const;
|
||||||
|
virtual int getMaxSamples() const;
|
||||||
virtual int getSampleCount() const;
|
virtual int getSampleCount() const;
|
||||||
virtual int getSampleRate() const;
|
virtual int getSampleRate() const;
|
||||||
virtual int getBitDepth() const;
|
virtual int getBitDepth() const;
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ bool Source::getEffect(const char *, std::map<Filter::Parameter, float> &)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Source::getEffectsList(std::vector<std::string> &)
|
bool Source::getActiveEffects(std::vector<std::string> &) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public:
|
|||||||
virtual bool setEffect(const char *effect, const std::map<Filter::Parameter, float> ¶ms);
|
virtual bool setEffect(const char *effect, const std::map<Filter::Parameter, float> ¶ms);
|
||||||
virtual bool unsetEffect(const char *effect);
|
virtual bool unsetEffect(const char *effect);
|
||||||
virtual bool getEffect(const char *effect, std::map<Filter::Parameter, float> ¶ms);
|
virtual bool getEffect(const char *effect, std::map<Filter::Parameter, float> ¶ms);
|
||||||
virtual bool getEffectsList(std::vector<std::string> &list);
|
virtual bool getActiveEffects(std::vector<std::string> &list) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -543,7 +543,7 @@ bool Audio::getEffect(const char *name, std::map<Effect::Parameter, float> ¶
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Audio::getEffectsList(std::vector<std::string> &list)
|
bool Audio::getActiveEffects(std::vector<std::string> &list) const
|
||||||
{
|
{
|
||||||
if (effectmap.empty())
|
if (effectmap.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ public:
|
|||||||
bool setEffect(const char *name, std::map<Effect::Parameter, float> ¶ms);
|
bool setEffect(const char *name, std::map<Effect::Parameter, float> ¶ms);
|
||||||
bool unsetEffect(const char *name);
|
bool unsetEffect(const char *name);
|
||||||
bool getEffect(const char *name, std::map<Effect::Parameter, float> ¶ms);
|
bool getEffect(const char *name, std::map<Effect::Parameter, float> ¶ms);
|
||||||
bool getEffectsList(std::vector<std::string> &list);
|
bool getActiveEffects(std::vector<std::string> &list) const;
|
||||||
int getMaxSceneEffects() const;
|
int getMaxSceneEffects() const;
|
||||||
int getMaxSourceEffects() const;
|
int getMaxSourceEffects() const;
|
||||||
bool isEFXsupported() const;
|
bool isEFXsupported() const;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* including commercial applications, and to alter it and redistribute it
|
* including commercial applications, and to alter it and redistribute it
|
||||||
* freely, subject to the following restrictions:
|
* freely, subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* 1. The origin of this software must not be misrepresented = 0; you must not
|
* 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
|
* claim that you wrote the original software. If you use this software
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
* appreciated but is not required.
|
* appreciated but is not required.
|
||||||
@@ -49,26 +49,11 @@ RecordingDevice::RecordingDevice(const char *name)
|
|||||||
|
|
||||||
RecordingDevice::~RecordingDevice()
|
RecordingDevice::~RecordingDevice()
|
||||||
{
|
{
|
||||||
if (!isRecording())
|
stop();
|
||||||
return;
|
|
||||||
|
|
||||||
alcCaptureStop(device);
|
|
||||||
alcCaptureCloseDevice(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RecordingDevice::start()
|
|
||||||
{
|
|
||||||
return start(samples, sampleRate, bitDepth, channels);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RecordingDevice::start(int samples, int sampleRate, int bitDepth, int channels)
|
bool RecordingDevice::start(int samples, int sampleRate, int bitDepth, int channels)
|
||||||
{
|
{
|
||||||
if (isRecording())
|
|
||||||
{
|
|
||||||
alcCaptureStop(device);
|
|
||||||
alcCaptureCloseDevice(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
ALenum format = Audio::getFormat(bitDepth, channels);
|
ALenum format = Audio::getFormat(bitDepth, channels);
|
||||||
if (format == AL_NONE)
|
if (format == AL_NONE)
|
||||||
throw InvalidFormatException(channels, bitDepth);
|
throw InvalidFormatException(channels, bitDepth);
|
||||||
@@ -79,15 +64,20 @@ bool RecordingDevice::start(int samples, int sampleRate, int bitDepth, int chann
|
|||||||
if (sampleRate <= 0)
|
if (sampleRate <= 0)
|
||||||
throw love::Exception("Invalid sample rate.");
|
throw love::Exception("Invalid sample rate.");
|
||||||
|
|
||||||
|
if (isRecording())
|
||||||
|
stop();
|
||||||
|
|
||||||
device = alcCaptureOpenDevice(name.c_str(), sampleRate, format, samples);
|
device = alcCaptureOpenDevice(name.c_str(), sampleRate, format, samples);
|
||||||
if (device == nullptr)
|
if (device == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
alcCaptureStart(device);
|
alcCaptureStart(device);
|
||||||
|
|
||||||
this->samples = samples;
|
this->samples = samples;
|
||||||
this->sampleRate = sampleRate;
|
this->sampleRate = sampleRate;
|
||||||
this->bitDepth = bitDepth;
|
this->bitDepth = bitDepth;
|
||||||
this->channels = channels;
|
this->channels = channels;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +117,11 @@ int RecordingDevice::getSampleCount() const
|
|||||||
return (int)samples;
|
return (int)samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RecordingDevice::getMaxSamples() const
|
||||||
|
{
|
||||||
|
return samples;
|
||||||
|
}
|
||||||
|
|
||||||
int RecordingDevice::getSampleRate() const
|
int RecordingDevice::getSampleRate() const
|
||||||
{
|
{
|
||||||
return sampleRate;
|
return sampleRate;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* including commercial applications, and to alter it and redistribute it
|
* including commercial applications, and to alter it and redistribute it
|
||||||
* freely, subject to the following restrictions:
|
* freely, subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* 1. The origin of this software must not be misrepresented = 0; you must not
|
* 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
|
* claim that you wrote the original software. If you use this software
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
* appreciated but is not required.
|
* appreciated but is not required.
|
||||||
@@ -49,26 +49,30 @@ namespace openal
|
|||||||
class RecordingDevice : public love::audio::RecordingDevice
|
class RecordingDevice : public love::audio::RecordingDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RecordingDevice(const char *name);
|
RecordingDevice(const char *name);
|
||||||
virtual ~RecordingDevice();
|
virtual ~RecordingDevice();
|
||||||
virtual bool start();
|
|
||||||
virtual bool start(int samples, int sampleRate, int bitDepth, int channels);
|
virtual bool start(int samples, int sampleRate, int bitDepth, int channels);
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
virtual love::sound::SoundData *getData();
|
virtual love::sound::SoundData *getData();
|
||||||
virtual const char *getName() const;
|
virtual const char *getName() const;
|
||||||
virtual int getSampleCount() const;
|
virtual int getSampleCount() const;
|
||||||
|
virtual int getMaxSamples() const;
|
||||||
virtual int getSampleRate() const;
|
virtual int getSampleRate() const;
|
||||||
virtual int getBitDepth() const;
|
virtual int getBitDepth() const;
|
||||||
virtual int getChannels() const;
|
virtual int getChannels() const;
|
||||||
virtual bool isRecording() const;
|
virtual bool isRecording() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int samples = 8192;
|
|
||||||
int sampleRate = 8000;
|
int samples = DEFAULT_SAMPLES;
|
||||||
int bitDepth = 16;
|
int sampleRate = DEFAULT_SAMPLE_RATE;
|
||||||
int channels = 1;
|
int bitDepth = DEFAULT_BIT_DEPTH;
|
||||||
|
int channels = DEFAULT_CHANNELS;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
ALCdevice *device = nullptr;
|
ALCdevice *device = nullptr;
|
||||||
|
|
||||||
}; //RecordingDevice
|
}; //RecordingDevice
|
||||||
|
|
||||||
} //openal
|
} //openal
|
||||||
|
|||||||
@@ -1041,7 +1041,7 @@ void Source::stop(const std::vector<love::audio::Source*> &sources)
|
|||||||
sourceIds.push_back(source->source);
|
sourceIds.push_back(source->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
alSourceStopv((ALsizei) sources.size(), &sourceIds[0]);
|
alSourceStopv((ALsizei) sourceIds.size(), &sourceIds[0]);
|
||||||
|
|
||||||
for (auto &_source : sources)
|
for (auto &_source : sources)
|
||||||
{
|
{
|
||||||
@@ -1068,7 +1068,7 @@ void Source::pause(const std::vector<love::audio::Source*> &sources)
|
|||||||
sourceIds.push_back(source->source);
|
sourceIds.push_back(source->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
alSourcePausev((ALsizei) sources.size(), &sourceIds[0]);
|
alSourcePausev((ALsizei) sourceIds.size(), &sourceIds[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<love::audio::Source*> Source::pause(Pool *pool)
|
std::vector<love::audio::Source*> Source::pause(Pool *pool)
|
||||||
@@ -1488,7 +1488,7 @@ bool Source::getEffect(const char *name, std::map<Filter::Parameter, float> &par
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Source::getEffectsList(std::vector<std::string> &list)
|
bool Source::getActiveEffects(std::vector<std::string> &list) const
|
||||||
{
|
{
|
||||||
if (effectmap.empty())
|
if (effectmap.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ public:
|
|||||||
virtual bool setEffect(const char *effect, const std::map<Filter::Parameter, float> ¶ms);
|
virtual bool setEffect(const char *effect, const std::map<Filter::Parameter, float> ¶ms);
|
||||||
virtual bool unsetEffect(const char *effect);
|
virtual bool unsetEffect(const char *effect);
|
||||||
virtual bool getEffect(const char *effect, std::map<Filter::Parameter, float> ¶ms);
|
virtual bool getEffect(const char *effect, std::map<Filter::Parameter, float> ¶ms);
|
||||||
virtual bool getEffectsList(std::vector<std::string> &list);
|
virtual bool getActiveEffects(std::vector<std::string> &list) const;
|
||||||
|
|
||||||
virtual int getFreeBufferCount() const;
|
virtual int getFreeBufferCount() const;
|
||||||
virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels);
|
virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels);
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ int w_newQueueableSource(lua_State *L)
|
|||||||
Source *t = nullptr;
|
Source *t = nullptr;
|
||||||
|
|
||||||
luax_catchexcept(L, [&]() {
|
luax_catchexcept(L, [&]() {
|
||||||
t = instance()->newSource((int)luaL_checknumber(L, 1), (int)luaL_checknumber(L, 2), (int)luaL_checknumber(L, 3), (int)luaL_optnumber(L, 4, 0));
|
t = instance()->newSource((int)luaL_checkinteger(L, 1), (int)luaL_checkinteger(L, 2), (int)luaL_checkinteger(L, 3), (int)luaL_optinteger(L, 4, 0));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (t != nullptr)
|
if (t != nullptr)
|
||||||
@@ -115,16 +115,34 @@ static std::vector<Source*> readSourceList(lua_State *L, int n)
|
|||||||
return sources;
|
return sources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::vector<Source*> readSourceVararg(lua_State *L, int i)
|
||||||
|
{
|
||||||
|
const int top = lua_gettop(L);
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
i += top + 1;
|
||||||
|
|
||||||
|
int items = top - i + 1;
|
||||||
|
std::vector<Source*> sources(items);
|
||||||
|
|
||||||
|
for (int pos = 0; i <= top; i++, pos++)
|
||||||
|
sources[pos] = luax_checksource(L, i);
|
||||||
|
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
|
||||||
int w_play(lua_State *L)
|
int w_play(lua_State *L)
|
||||||
{
|
{
|
||||||
if (lua_istable(L, 1))
|
if (lua_istable(L, 1))
|
||||||
{
|
|
||||||
luax_pushboolean(L, instance()->play(readSourceList(L, 1)));
|
luax_pushboolean(L, instance()->play(readSourceList(L, 1)));
|
||||||
return 1;
|
else if (lua_gettop(L) > 1)
|
||||||
|
luax_pushboolean(L, instance()->play(readSourceVararg(L, 1)));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Source *s = luax_checksource(L, 1);
|
||||||
|
luax_pushboolean(L, instance()->play(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
Source *s = luax_checksource(L, 1);
|
|
||||||
luax_pushboolean(L, instance()->play(s));
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,6 +152,8 @@ int w_stop(lua_State *L)
|
|||||||
instance()->stop();
|
instance()->stop();
|
||||||
else if (lua_istable(L, 1))
|
else if (lua_istable(L, 1))
|
||||||
instance()->stop(readSourceList(L, 1));
|
instance()->stop(readSourceList(L, 1));
|
||||||
|
else if (lua_gettop(L) > 1)
|
||||||
|
instance()->stop(readSourceVararg(L, 1));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Source *s = luax_checksource(L, 1);
|
Source *s = luax_checksource(L, 1);
|
||||||
@@ -158,6 +178,8 @@ int w_pause(lua_State *L)
|
|||||||
}
|
}
|
||||||
else if (lua_istable(L, 1))
|
else if (lua_istable(L, 1))
|
||||||
instance()->pause(readSourceList(L, 1));
|
instance()->pause(readSourceList(L, 1));
|
||||||
|
else if (lua_gettop(L) > 1)
|
||||||
|
instance()->pause(readSourceVararg(L, 1));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Source *s = luax_checksource(L, 1);
|
Source *s = luax_checksource(L, 1);
|
||||||
@@ -463,14 +485,13 @@ int w_getEffect(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_getEffectsList(lua_State *L)
|
int w_getActiveEffects(lua_State *L)
|
||||||
{
|
{
|
||||||
std::vector<std::string> list;
|
std::vector<std::string> list;
|
||||||
if (!instance()->getEffectsList(list))
|
instance()->getActiveEffects(list);
|
||||||
return 0;
|
|
||||||
|
|
||||||
lua_createtable(L, 0, list.size());
|
lua_createtable(L, 0, (int) list.size());
|
||||||
for (unsigned int i = 0; i < list.size(); i++)
|
for (int i = 0; i < (int) list.size(); i++)
|
||||||
{
|
{
|
||||||
lua_pushnumber(L, i + 1);
|
lua_pushnumber(L, i + 1);
|
||||||
lua_pushstring(L, list[i].c_str());
|
lua_pushstring(L, list[i].c_str());
|
||||||
@@ -497,6 +518,12 @@ int w_isEffectsSupported(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int w_setMixWithSystem(lua_State *L)
|
||||||
|
{
|
||||||
|
luax_pushboolean(L, instance()->setMixWithSystem(luax_toboolean(L, 1)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// List of functions to wrap.
|
// List of functions to wrap.
|
||||||
static const luaL_Reg functions[] =
|
static const luaL_Reg functions[] =
|
||||||
{
|
{
|
||||||
@@ -523,10 +550,11 @@ static const luaL_Reg functions[] =
|
|||||||
{ "getRecordingDevices", w_getRecordingDevices },
|
{ "getRecordingDevices", w_getRecordingDevices },
|
||||||
{ "setEffect", w_setEffect },
|
{ "setEffect", w_setEffect },
|
||||||
{ "getEffect", w_getEffect },
|
{ "getEffect", w_getEffect },
|
||||||
{ "getEffectsList", w_getEffectsList },
|
{ "getActiveEffects", w_getActiveEffects },
|
||||||
{ "getMaxSceneEffects", w_getMaxSceneEffects },
|
{ "getMaxSceneEffects", w_getMaxSceneEffects },
|
||||||
{ "getMaxSourceEffects", w_getMaxSourceEffects },
|
{ "getMaxSourceEffects", w_getMaxSourceEffects },
|
||||||
{ "isEffectsSupported", w_isEffectsSupported },
|
{ "isEffectsSupported", w_isEffectsSupported },
|
||||||
|
{ "setMixWithSystem", w_setMixWithSystem },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -35,19 +35,24 @@ RecordingDevice *luax_checkrecordingdevice(lua_State *L, int idx)
|
|||||||
int w_RecordingDevice_start(lua_State *L)
|
int w_RecordingDevice_start(lua_State *L)
|
||||||
{
|
{
|
||||||
RecordingDevice *d = luax_checkrecordingdevice(L, 1);
|
RecordingDevice *d = luax_checkrecordingdevice(L, 1);
|
||||||
|
|
||||||
|
int samples = d->getMaxSamples();
|
||||||
|
int samplerate = d->getSampleRate();
|
||||||
|
int bitdepth = d->getBitDepth();
|
||||||
|
int channels = d->getChannels();
|
||||||
|
|
||||||
if (lua_gettop(L) > 1)
|
if (lua_gettop(L) > 1)
|
||||||
{
|
{
|
||||||
int samples = (int) luaL_checkinteger(L, 2);
|
samples = (int) luaL_checkinteger(L, 2);
|
||||||
int sampleRate = (int) luaL_checkinteger(L, 3);
|
samplerate = (int) luaL_optinteger(L, 3, RecordingDevice::DEFAULT_SAMPLE_RATE);
|
||||||
int bitDepth = (int) luaL_checkinteger(L, 4);
|
bitdepth = (int) luaL_optinteger(L, 4, RecordingDevice::DEFAULT_BIT_DEPTH);
|
||||||
int channels = (int) luaL_checkinteger(L, 5);
|
channels = (int) (int) luaL_optinteger(L, 5, RecordingDevice::DEFAULT_CHANNELS);
|
||||||
luax_catchexcept(L, [&](){
|
|
||||||
lua_pushboolean(L, d->start(samples, sampleRate, bitDepth, channels));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
luax_catchexcept(L, [&](){ lua_pushboolean(L, d->start()); });
|
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
luax_catchexcept(L, [&]() { success = d->start(samples, samplerate, bitdepth, channels); });
|
||||||
|
|
||||||
|
luax_pushboolean(L, success);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -493,15 +493,15 @@ int w_Source_getEffect(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_Source_getEffectsList(lua_State *L)
|
int w_Source_getActiveEffects(lua_State *L)
|
||||||
{
|
{
|
||||||
Source *t = luax_checksource(L, 1);
|
Source *t = luax_checksource(L, 1);
|
||||||
std::vector<std::string> list;
|
|
||||||
if (!t->getEffectsList(list))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
lua_createtable(L, 0, list.size());
|
std::vector<std::string> list;
|
||||||
for (unsigned int i = 0; i < list.size(); i++)
|
t->getActiveEffects(list);
|
||||||
|
|
||||||
|
lua_createtable(L, 0, (int) list.size());
|
||||||
|
for (int i = 0; i < (int) list.size(); i++)
|
||||||
{
|
{
|
||||||
lua_pushnumber(L, i + 1);
|
lua_pushnumber(L, i + 1);
|
||||||
lua_pushstring(L, list[i].c_str());
|
lua_pushstring(L, list[i].c_str());
|
||||||
@@ -624,7 +624,7 @@ static const luaL_Reg w_Source_functions[] =
|
|||||||
{ "getFilter", w_Source_getFilter },
|
{ "getFilter", w_Source_getFilter },
|
||||||
{ "setEffect", w_Source_setEffect },
|
{ "setEffect", w_Source_setEffect },
|
||||||
{ "getEffect", w_Source_getEffect },
|
{ "getEffect", w_Source_getEffect },
|
||||||
{ "getEffectsList", w_Source_getEffectsList },
|
{ "getActiveEffects", w_Source_getActiveEffects },
|
||||||
|
|
||||||
{ "getFreeBufferCount", w_Source_getFreeBufferCount },
|
{ "getFreeBufferCount", w_Source_getFreeBufferCount },
|
||||||
{ "queue", w_Source_queue },
|
{ "queue", w_Source_queue },
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ bool File::open(Mode mode)
|
|||||||
throw love::Exception("Could not open file %s. Does not exist.", filename.c_str());
|
throw love::Exception("Could not open file %s. Does not exist.", filename.c_str());
|
||||||
|
|
||||||
// Check whether the write directory is set.
|
// Check whether the write directory is set.
|
||||||
if ((mode == MODE_APPEND || mode == MODE_WRITE) && (PHYSFS_getWriteDir() == 0) && !hack_setupWriteDirectory())
|
if ((mode == MODE_APPEND || mode == MODE_WRITE) && (PHYSFS_getWriteDir() == nullptr) && !hack_setupWriteDirectory())
|
||||||
throw love::Exception("Could not set write directory.");
|
throw love::Exception("Could not set write directory.");
|
||||||
|
|
||||||
// File already open?
|
// File already open?
|
||||||
@@ -151,8 +151,6 @@ int64 File::read(void *dst, int64 size)
|
|||||||
int64 max = (int64)PHYSFS_fileLength(file);
|
int64 max = (int64)PHYSFS_fileLength(file);
|
||||||
size = (size == ALL) ? max : size;
|
size = (size == ALL) ? max : size;
|
||||||
size = (size > max) ? max : size;
|
size = (size > max) ? max : size;
|
||||||
// Sadly, we'll have to clamp to 32 bits here
|
|
||||||
size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size;
|
|
||||||
|
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
throw love::Exception("Invalid read size.");
|
throw love::Exception("Invalid read size.");
|
||||||
@@ -160,6 +158,8 @@ int64 File::read(void *dst, int64 size)
|
|||||||
#ifdef LOVE_USE_PHYSFS_2_1
|
#ifdef LOVE_USE_PHYSFS_2_1
|
||||||
int64 read = PHYSFS_readBytes(file, dst, (PHYSFS_uint64) size);
|
int64 read = PHYSFS_readBytes(file, dst, (PHYSFS_uint64) size);
|
||||||
#else
|
#else
|
||||||
|
// Sadly, we'll have to clamp to 32 bits here
|
||||||
|
size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size;
|
||||||
int64 read = (int64)PHYSFS_read(file, dst, 1, (PHYSFS_uint32) size);
|
int64 read = (int64)PHYSFS_read(file, dst, 1, (PHYSFS_uint32) size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -171,9 +171,6 @@ bool File::write(const void *data, int64 size)
|
|||||||
if (!file || (mode != MODE_WRITE && mode != MODE_APPEND))
|
if (!file || (mode != MODE_WRITE && mode != MODE_APPEND))
|
||||||
throw love::Exception("File is not opened for writing.");
|
throw love::Exception("File is not opened for writing.");
|
||||||
|
|
||||||
// Another clamp, for the time being.
|
|
||||||
size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size;
|
|
||||||
|
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
throw love::Exception("Invalid write size.");
|
throw love::Exception("Invalid write size.");
|
||||||
|
|
||||||
@@ -181,6 +178,8 @@ bool File::write(const void *data, int64 size)
|
|||||||
#ifdef LOVE_USE_PHYSFS_2_1
|
#ifdef LOVE_USE_PHYSFS_2_1
|
||||||
int64 written = PHYSFS_writeBytes(file, data, (PHYSFS_uint64) size);
|
int64 written = PHYSFS_writeBytes(file, data, (PHYSFS_uint64) size);
|
||||||
#else
|
#else
|
||||||
|
// Another clamp, for the time being.
|
||||||
|
size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size;
|
||||||
int64 written = (int64) PHYSFS_write(file, data, 1, (PHYSFS_uint32) size);
|
int64 written = (int64) PHYSFS_write(file, data, 1, (PHYSFS_uint32) size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -191,7 +190,7 @@ bool File::write(const void *data, int64 size)
|
|||||||
// Manually flush the buffer in BUFFER_LINE mode if we find a newline.
|
// Manually flush the buffer in BUFFER_LINE mode if we find a newline.
|
||||||
if (bufferMode == BUFFER_LINE && bufferSize > size)
|
if (bufferMode == BUFFER_LINE && bufferSize > size)
|
||||||
{
|
{
|
||||||
if (memchr(data, '\n', (size_t) size) != NULL)
|
if (memchr(data, '\n', (size_t) size) != nullptr)
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ int w_read(lua_State *L)
|
|||||||
const char *filename = luaL_checkstring(L, 1);
|
const char *filename = luaL_checkstring(L, 1);
|
||||||
int64 len = (int64) luaL_optinteger(L, 2, File::ALL);
|
int64 len = (int64) luaL_optinteger(L, 2, File::ALL);
|
||||||
|
|
||||||
Data *data = 0;
|
Data *data = nullptr;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
data = instance()->read(filename, len);
|
data = instance()->read(filename, len);
|
||||||
@@ -376,7 +376,7 @@ int w_read(lua_State *L)
|
|||||||
return luax_ioError(L, "%s", e.what());
|
return luax_ioError(L, "%s", e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data == 0)
|
if (data == nullptr)
|
||||||
return luax_ioError(L, "File could not be read.");
|
return luax_ioError(L, "File could not be read.");
|
||||||
|
|
||||||
// Push the string.
|
// Push the string.
|
||||||
@@ -395,7 +395,7 @@ static int w_write_or_append(lua_State *L, File::Mode mode)
|
|||||||
{
|
{
|
||||||
const char *filename = luaL_checkstring(L, 1);
|
const char *filename = luaL_checkstring(L, 1);
|
||||||
|
|
||||||
const char *input = 0;
|
const char *input = nullptr;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if (luax_istype(L, 2, love::Data::type))
|
if (luax_istype(L, 2, love::Data::type))
|
||||||
@@ -459,11 +459,9 @@ int w_getDirectoryItems(lua_State *L)
|
|||||||
|
|
||||||
int w_lines(lua_State *L)
|
int w_lines(lua_State *L)
|
||||||
{
|
{
|
||||||
File *file;
|
|
||||||
|
|
||||||
if (lua_isstring(L, 1))
|
if (lua_isstring(L, 1))
|
||||||
{
|
{
|
||||||
file = instance()->newFile(lua_tostring(L, 1));
|
File *file = instance()->newFile(lua_tostring(L, 1));
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
luax_catchexcept(L, [&](){ success = file->open(File::MODE_READ); });
|
luax_catchexcept(L, [&](){ success = file->open(File::MODE_READ); });
|
||||||
@@ -488,7 +486,7 @@ int w_load(lua_State *L)
|
|||||||
{
|
{
|
||||||
std::string filename = std::string(luaL_checkstring(L, 1));
|
std::string filename = std::string(luaL_checkstring(L, 1));
|
||||||
|
|
||||||
Data *data = 0;
|
Data *data = nullptr;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
data = instance()->read(filename.c_str());
|
data = instance()->read(filename.c_str());
|
||||||
@@ -634,6 +632,22 @@ int w_setCRequirePath(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void replaceAll(std::string &str, const std::string &substr, const std::string &replacement)
|
||||||
|
{
|
||||||
|
std::vector<size_t> locations;
|
||||||
|
size_t pos = 0;
|
||||||
|
size_t sublen = substr.length();
|
||||||
|
|
||||||
|
while ((pos = str.find(substr, pos)) != std::string::npos)
|
||||||
|
{
|
||||||
|
locations.push_back(pos);
|
||||||
|
pos += sublen;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = (int) locations.size() - 1; i >= 0; i--)
|
||||||
|
str.replace(locations[i], sublen, replacement);
|
||||||
|
}
|
||||||
|
|
||||||
int loader(lua_State *L)
|
int loader(lua_State *L)
|
||||||
{
|
{
|
||||||
std::string modulename = luax_tostring(L, 1);
|
std::string modulename = luax_tostring(L, 1);
|
||||||
@@ -647,9 +661,7 @@ int loader(lua_State *L)
|
|||||||
auto *inst = instance();
|
auto *inst = instance();
|
||||||
for (std::string element : inst->getRequirePath())
|
for (std::string element : inst->getRequirePath())
|
||||||
{
|
{
|
||||||
size_t pos = 0;
|
replaceAll(element, "?", modulename);
|
||||||
while ((pos = element.find('?', pos)) != std::string::npos)
|
|
||||||
element.replace(pos, 1, modulename);
|
|
||||||
|
|
||||||
if (inst->isFile(element.c_str()))
|
if (inst->isFile(element.c_str()))
|
||||||
{
|
{
|
||||||
@@ -665,14 +677,16 @@ int loader(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char *library_extension()
|
static const char *library_extensions[] =
|
||||||
{
|
{
|
||||||
#ifdef LOVE_WINDOWS
|
#ifdef LOVE_WINDOWS
|
||||||
return ".dll";
|
".dll"
|
||||||
|
#elif defined(LOVE_MACOSX) || defined(LOVE_IOS)
|
||||||
|
".dylib", ".so"
|
||||||
#else
|
#else
|
||||||
return ".so";
|
".so"
|
||||||
#endif
|
#endif
|
||||||
}
|
};
|
||||||
|
|
||||||
int extloader(lua_State *L)
|
int extloader(lua_State *L)
|
||||||
{
|
{
|
||||||
@@ -694,25 +708,31 @@ int extloader(lua_State *L)
|
|||||||
|
|
||||||
void *handle = nullptr;
|
void *handle = nullptr;
|
||||||
auto *inst = instance();
|
auto *inst = instance();
|
||||||
for (std::string element : inst->getCRequirePath())
|
|
||||||
|
for (const std::string &el : inst->getCRequirePath())
|
||||||
{
|
{
|
||||||
// Replace ?? with the filename and extension
|
for (const char *ext : library_extensions)
|
||||||
size_t pos = element.find("??");
|
{
|
||||||
if (pos != std::string::npos)
|
std::string element = el;
|
||||||
element.replace(pos, 2, tokenized_name + library_extension());
|
|
||||||
// Or ? with just the filename
|
|
||||||
pos = element.find('?');
|
|
||||||
if (pos != std::string::npos)
|
|
||||||
element.replace(pos, 1, tokenized_name);
|
|
||||||
|
|
||||||
if (!inst->isFile(element.c_str()))
|
// Replace ?? with the filename and extension
|
||||||
continue;
|
replaceAll(element, "??", tokenized_name + ext);
|
||||||
|
|
||||||
// Now resolve the full path, as we're bypassing physfs for the next part.
|
// And ? with just the filename
|
||||||
element = inst->getRealDirectory(element.c_str()) + LOVE_PATH_SEPARATOR + element;
|
replaceAll(element, "?", tokenized_name);
|
||||||
|
|
||||||
|
if (!inst->isFile(element.c_str()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Now resolve the full path, as we're bypassing physfs for the next part.
|
||||||
|
std::string filepath = inst->getRealDirectory(element.c_str()) + LOVE_PATH_SEPARATOR + element;
|
||||||
|
|
||||||
|
handle = SDL_LoadObject(filepath.c_str());
|
||||||
|
// Can fail, for instance if it turned out the source was a zip
|
||||||
|
if (handle)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
handle = SDL_LoadObject(element.c_str());
|
|
||||||
// Can fail, for instance if it turned out the source was a zip
|
|
||||||
if (handle)
|
if (handle)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,12 @@ BMFontRasterizer::BMFontRasterizer(love::filesystem::FileData *fontdef, const st
|
|||||||
|
|
||||||
// The parseConfig function will try to load any missing page images.
|
// The parseConfig function will try to load any missing page images.
|
||||||
for (int i = 0; i < (int) imagelist.size(); i++)
|
for (int i = 0; i < (int) imagelist.size(); i++)
|
||||||
|
{
|
||||||
|
if (imagelist[i]->getFormat() != PIXELFORMAT_RGBA8)
|
||||||
|
throw love::Exception("Only 32-bit RGBA images are supported in BMFonts.");
|
||||||
|
|
||||||
images[i] = imagelist[i];
|
images[i] = imagelist[i];
|
||||||
|
}
|
||||||
|
|
||||||
std::string configtext((const char *) fontdef->getData(), fontdef->getSize());
|
std::string configtext((const char *) fontdef->getData(), fontdef->getSize());
|
||||||
|
|
||||||
@@ -296,29 +301,26 @@ GlyphData *BMFontRasterizer::getGlyphData(uint32 glyph) const
|
|||||||
return new GlyphData(glyph, GlyphMetrics(), PIXELFORMAT_RGBA8);
|
return new GlyphData(glyph, GlyphMetrics(), PIXELFORMAT_RGBA8);
|
||||||
|
|
||||||
const BMFontCharacter &c = it->second;
|
const BMFontCharacter &c = it->second;
|
||||||
GlyphData *g = new GlyphData(glyph, c.metrics, PIXELFORMAT_RGBA8);
|
|
||||||
|
|
||||||
const auto &imagepair = images.find(c.page);
|
const auto &imagepair = images.find(c.page);
|
||||||
|
|
||||||
if (imagepair == images.end())
|
if (imagepair == images.end())
|
||||||
{
|
|
||||||
g->release();
|
|
||||||
return new GlyphData(glyph, GlyphMetrics(), PIXELFORMAT_RGBA8);
|
return new GlyphData(glyph, GlyphMetrics(), PIXELFORMAT_RGBA8);
|
||||||
}
|
|
||||||
|
|
||||||
image::ImageData *imagedata = imagepair->second.get();
|
image::ImageData *imagedata = imagepair->second.get();
|
||||||
|
GlyphData *g = new GlyphData(glyph, c.metrics, PIXELFORMAT_RGBA8);
|
||||||
|
|
||||||
size_t pixelsize = imagedata->getPixelSize();
|
size_t pixelsize = imagedata->getPixelSize();
|
||||||
image::pixel *pixels = (image::pixel *) g->getData();
|
|
||||||
const image::pixel *ipixels = (const image::pixel *) imagedata->getData();
|
uint8 *pixels = (uint8 *) g->getData();
|
||||||
|
const uint8 *ipixels = (const uint8 *) imagedata->getData();
|
||||||
|
|
||||||
love::thread::Lock lock(imagedata->getMutex());
|
love::thread::Lock lock(imagedata->getMutex());
|
||||||
|
|
||||||
// Copy the subsection of the texture from the ImageData to the GlyphData.
|
// Copy the subsection of the texture from the ImageData to the GlyphData.
|
||||||
for (int y = 0; y < c.metrics.height; y++)
|
for (int y = 0; y < c.metrics.height; y++)
|
||||||
{
|
{
|
||||||
size_t idindex = (c.y + y) * imagedata->getWidth() + c.x;
|
size_t idindex = ((c.y + y) * imagedata->getWidth() + c.x) * pixelsize;
|
||||||
memcpy(&pixels[y * c.metrics.width], &ipixels[idindex], pixelsize * c.metrics.width);
|
memcpy(&pixels[y * c.metrics.width * pixelsize], &ipixels[idindex], pixelsize * c.metrics.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
return g;
|
return g;
|
||||||
|
|||||||
@@ -29,10 +29,7 @@ namespace love
|
|||||||
namespace font
|
namespace font
|
||||||
{
|
{
|
||||||
|
|
||||||
inline bool equal(const love::image::pixel &a, const love::image::pixel &b)
|
static_assert(sizeof(Color) == 4, "sizeof(Color) must equal 4 bytes!");
|
||||||
{
|
|
||||||
return (a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageRasterizer::ImageRasterizer(love::image::ImageData *data, uint32 *glyphs, int numglyphs, int extraspacing, float pixeldensity)
|
ImageRasterizer::ImageRasterizer(love::image::ImageData *data, uint32 *glyphs, int numglyphs, int extraspacing, float pixeldensity)
|
||||||
: imageData(data)
|
: imageData(data)
|
||||||
@@ -79,17 +76,17 @@ GlyphData *ImageRasterizer::getGlyphData(uint32 glyph) const
|
|||||||
// We don't want another thread modifying our ImageData mid-copy.
|
// We don't want another thread modifying our ImageData mid-copy.
|
||||||
love::thread::Lock lock(imageData->getMutex());
|
love::thread::Lock lock(imageData->getMutex());
|
||||||
|
|
||||||
love::image::pixel *gdpixels = (love::image::pixel *) g->getData();
|
Color *gdpixels = (Color *) g->getData();
|
||||||
love::image::pixel *imagepixels = (love::image::pixel *) imageData->getData();
|
const Color *imagepixels = (const Color *) imageData->getData();
|
||||||
|
|
||||||
// copy glyph pixels from imagedata to glyphdata
|
// copy glyph pixels from imagedata to glyphdata
|
||||||
for (int i = 0; i < g->getWidth() * g->getHeight(); i++)
|
for (int i = 0; i < g->getWidth() * g->getHeight(); i++)
|
||||||
{
|
{
|
||||||
love::image::pixel p = imagepixels[it->second.x + (i % gm.width) + (imageData->getWidth() * (i / gm.width))];
|
Color p = imagepixels[it->second.x + (i % gm.width) + (imageData->getWidth() * (i / gm.width))];
|
||||||
|
|
||||||
// Use transparency instead of the spacer color
|
// Use transparency instead of the spacer color
|
||||||
if (equal(p, spacer))
|
if (p == spacer)
|
||||||
gdpixels[i].r = gdpixels[i].g = gdpixels[i].b = gdpixels[i].a = 0;
|
gdpixels[i] = Color(0, 0, 0, 0);
|
||||||
else
|
else
|
||||||
gdpixels[i] = p;
|
gdpixels[i] = p;
|
||||||
}
|
}
|
||||||
@@ -99,7 +96,7 @@ GlyphData *ImageRasterizer::getGlyphData(uint32 glyph) const
|
|||||||
|
|
||||||
void ImageRasterizer::load()
|
void ImageRasterizer::load()
|
||||||
{
|
{
|
||||||
love::image::pixel *pixels = (love::image::pixel *) imageData->getData();
|
const Color *pixels = (const Color *) imageData->getData();
|
||||||
|
|
||||||
int imgw = imageData->getWidth();
|
int imgw = imageData->getWidth();
|
||||||
int imgh = imageData->getHeight();
|
int imgh = imageData->getHeight();
|
||||||
@@ -121,13 +118,13 @@ void ImageRasterizer::load()
|
|||||||
start = end;
|
start = end;
|
||||||
|
|
||||||
// Finds out where the first character starts
|
// Finds out where the first character starts
|
||||||
while (start < imgw && equal(pixels[start], spacer))
|
while (start < imgw && pixels[start] == spacer)
|
||||||
++start;
|
++start;
|
||||||
|
|
||||||
end = start;
|
end = start;
|
||||||
|
|
||||||
// Find where glyph ends.
|
// Find where glyph ends.
|
||||||
while (end < imgw && !equal(pixels[end], spacer))
|
while (end < imgw && pixels[end] != spacer)
|
||||||
++end;
|
++end;
|
||||||
|
|
||||||
if (start >= end)
|
if (start >= end)
|
||||||
|
|||||||
@@ -22,9 +22,9 @@
|
|||||||
#define LOVE_FONT_IMAGE_RASTERIZER_H
|
#define LOVE_FONT_IMAGE_RASTERIZER_H
|
||||||
|
|
||||||
// LOVE
|
// LOVE
|
||||||
#include "filesystem/File.h"
|
|
||||||
#include "font/Rasterizer.h"
|
#include "font/Rasterizer.h"
|
||||||
#include "image/ImageData.h"
|
#include "image/ImageData.h"
|
||||||
|
#include "common/Color.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ private:
|
|||||||
std::map<uint32, ImageGlyphData> imageGlyphs;
|
std::map<uint32, ImageGlyphData> imageGlyphs;
|
||||||
|
|
||||||
// Color used to identify glyph separation in the source ImageData
|
// Color used to identify glyph separation in the source ImageData
|
||||||
love::image::pixel spacer;
|
Color spacer;
|
||||||
|
|
||||||
}; // ImageRasterizer
|
}; // ImageRasterizer
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ int w_newTrueTypeRasterizer(lua_State *L)
|
|||||||
if (lua_type(L, 1) == LUA_TNUMBER || lua_isnone(L, 1))
|
if (lua_type(L, 1) == LUA_TNUMBER || lua_isnone(L, 1))
|
||||||
{
|
{
|
||||||
// First argument is a number: use the default TrueType font.
|
// First argument is a number: use the default TrueType font.
|
||||||
int size = (int) luaL_optnumber(L, 1, 12);
|
int size = (int) luaL_optinteger(L, 1, 12);
|
||||||
|
|
||||||
const char *hintstr = lua_isnoneornil(L, 2) ? nullptr : luaL_checkstring(L, 2);
|
const char *hintstr = lua_isnoneornil(L, 2) ? nullptr : luaL_checkstring(L, 2);
|
||||||
if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, hinting))
|
if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, hinting))
|
||||||
@@ -98,7 +98,7 @@ int w_newTrueTypeRasterizer(lua_State *L)
|
|||||||
else
|
else
|
||||||
d = filesystem::luax_getfiledata(L, 1);
|
d = filesystem::luax_getfiledata(L, 1);
|
||||||
|
|
||||||
int size = (int) luaL_optnumber(L, 2, 12);
|
int size = (int) luaL_optinteger(L, 2, 12);
|
||||||
|
|
||||||
const char *hintstr = lua_isnoneornil(L, 3) ? nullptr : luaL_checkstring(L, 3);
|
const char *hintstr = lua_isnoneornil(L, 3) ? nullptr : luaL_checkstring(L, 3);
|
||||||
if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, hinting))
|
if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, hinting))
|
||||||
@@ -180,7 +180,7 @@ int w_newImageRasterizer(lua_State *L)
|
|||||||
|
|
||||||
image::ImageData *d = luax_checktype<image::ImageData>(L, 1);
|
image::ImageData *d = luax_checktype<image::ImageData>(L, 1);
|
||||||
std::string glyphs = luax_checkstring(L, 2);
|
std::string glyphs = luax_checkstring(L, 2);
|
||||||
int extraspacing = (int) luaL_optnumber(L, 3, 0);
|
int extraspacing = (int) luaL_optinteger(L, 3, 0);
|
||||||
float pixeldensity = (float) luaL_optnumber(L, 4, 1.0);
|
float pixeldensity = (float) luaL_optnumber(L, 4, 1.0);
|
||||||
|
|
||||||
luax_catchexcept(L, [&](){ t = instance()->newImageRasterizer(d, glyphs, extraspacing, pixeldensity); });
|
luax_catchexcept(L, [&](){ t = instance()->newImageRasterizer(d, glyphs, extraspacing, pixeldensity); });
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ IndexDataType QuadIndices::getType(size_t s) const
|
|||||||
return vertex::getIndexDataTypeFromMax(getIndexCount(s));
|
return vertex::getIndexDataTypeFromMax(getIndexCount(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t QuadIndices::getElementSize()
|
size_t QuadIndices::getElementSize() const
|
||||||
{
|
{
|
||||||
return elementSize;
|
return elementSize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ public:
|
|||||||
* Can be used with getPointer to calculate an offset into the array based
|
* Can be used with getPointer to calculate an offset into the array based
|
||||||
* on a number of elements.
|
* on a number of elements.
|
||||||
**/
|
**/
|
||||||
size_t getElementSize();
|
size_t getElementSize() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the pointer to the Buffer.
|
* Returns the pointer to the Buffer.
|
||||||
|
|||||||
@@ -97,43 +97,7 @@ Canvas::Canvas(const Settings &settings)
|
|||||||
throw love::Exception("%s textures are not supported on this system!", textypestr);
|
throw love::Exception("%s textures are not supported on this system!", textypestr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxsize = 0;
|
validateDimensions(true);
|
||||||
switch (texType)
|
|
||||||
{
|
|
||||||
case TEXTURE_2D:
|
|
||||||
maxsize = (int) caps.limits[Graphics::LIMIT_TEXTURE_SIZE];
|
|
||||||
if (pixelWidth > maxsize)
|
|
||||||
throw TextureTooLargeException("width", pixelWidth);
|
|
||||||
else if (pixelHeight > maxsize)
|
|
||||||
throw TextureTooLargeException("height", pixelHeight);
|
|
||||||
break;
|
|
||||||
case TEXTURE_VOLUME:
|
|
||||||
maxsize = (int) caps.limits[Graphics::LIMIT_VOLUME_TEXTURE_SIZE];
|
|
||||||
if (pixelWidth > maxsize)
|
|
||||||
throw TextureTooLargeException("width", pixelWidth);
|
|
||||||
else if (pixelHeight > maxsize)
|
|
||||||
throw TextureTooLargeException("height", pixelHeight);
|
|
||||||
else if (depth > maxsize)
|
|
||||||
throw TextureTooLargeException("depth", depth);
|
|
||||||
break;
|
|
||||||
case TEXTURE_2D_ARRAY:
|
|
||||||
maxsize = (int) caps.limits[Graphics::LIMIT_TEXTURE_SIZE];
|
|
||||||
if (pixelWidth > maxsize)
|
|
||||||
throw TextureTooLargeException("width", pixelWidth);
|
|
||||||
else if (pixelHeight > maxsize)
|
|
||||||
throw TextureTooLargeException("height", pixelHeight);
|
|
||||||
else if (layers > (int) caps.limits[Graphics::LIMIT_TEXTURE_LAYERS])
|
|
||||||
throw TextureTooLargeException("array layer count", layers);
|
|
||||||
break;
|
|
||||||
case TEXTURE_CUBE:
|
|
||||||
if (pixelWidth != pixelHeight)
|
|
||||||
throw love::Exception("Cubemap textures must have equal width and height.");
|
|
||||||
else if (pixelWidth > (int) caps.limits[Graphics::LIMIT_CUBE_TEXTURE_SIZE])
|
|
||||||
throw TextureTooLargeException("width", pixelWidth);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
canvasCount++;
|
canvasCount++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ Graphics::Graphics()
|
|||||||
, streamBufferState()
|
, streamBufferState()
|
||||||
, projectionMatrix()
|
, projectionMatrix()
|
||||||
, canvasSwitchCount(0)
|
, canvasSwitchCount(0)
|
||||||
|
, drawCallsBatched(0)
|
||||||
, capabilities()
|
, capabilities()
|
||||||
{
|
{
|
||||||
transformStack.reserve(16);
|
transformStack.reserve(16);
|
||||||
@@ -430,6 +431,128 @@ void Graphics::setCanvas(const RenderTargetsStrongRef &rts)
|
|||||||
return setCanvas(targets);
|
return setCanvas(targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::setCanvas(const RenderTargets &rts)
|
||||||
|
{
|
||||||
|
DisplayState &state = states.back();
|
||||||
|
int ncanvases = (int) rts.colors.size();
|
||||||
|
|
||||||
|
if (ncanvases == 0 && rts.depthStencil.canvas == nullptr)
|
||||||
|
return setCanvas();
|
||||||
|
else if (ncanvases == 0)
|
||||||
|
throw love::Exception("At least one color render target is required when using a custom depth/stencil buffer.");
|
||||||
|
|
||||||
|
const auto &prevRTs = state.renderTargets;
|
||||||
|
|
||||||
|
if (ncanvases == (int) prevRTs.colors.size())
|
||||||
|
{
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < ncanvases; i++)
|
||||||
|
{
|
||||||
|
if (rts.colors[i].canvas != prevRTs.colors[i].canvas.get()
|
||||||
|
|| rts.colors[i].slice != prevRTs.colors[i].slice
|
||||||
|
|| rts.colors[i].mipmap != prevRTs.colors[i].mipmap)
|
||||||
|
{
|
||||||
|
modified = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!modified && (rts.depthStencil.canvas != prevRTs.depthStencil.canvas
|
||||||
|
|| rts.depthStencil.slice != prevRTs.depthStencil.slice
|
||||||
|
|| rts.depthStencil.mipmap != prevRTs.depthStencil.mipmap))
|
||||||
|
{
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rts.temporaryRTFlags != prevRTs.temporaryRTFlags)
|
||||||
|
modified = true;
|
||||||
|
|
||||||
|
if (!modified)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ncanvases > capabilities.limits[LIMIT_MULTI_CANVAS])
|
||||||
|
throw love::Exception("This system can't simultaneously render to %d canvases.", ncanvases);
|
||||||
|
|
||||||
|
love::graphics::Canvas *firstcanvas = rts.colors[0].canvas;
|
||||||
|
|
||||||
|
bool multiformatsupported = capabilities.features[FEATURE_MULTI_CANVAS_FORMATS];
|
||||||
|
PixelFormat firstformat = firstcanvas->getPixelFormat();
|
||||||
|
|
||||||
|
if (isPixelFormatDepthStencil(firstformat))
|
||||||
|
throw love::Exception("Depth/stencil format Canvases must be used with the 'depthstencil' field of the table passed into setCanvas.");
|
||||||
|
|
||||||
|
if (rts.colors[0].mipmap < 0 || rts.colors[0].mipmap >= firstcanvas->getMipmapCount())
|
||||||
|
throw love::Exception("Invalid mipmap level %d.", rts.colors[0].mipmap + 1);
|
||||||
|
|
||||||
|
bool hasSRGBcanvas = firstformat == PIXELFORMAT_sRGBA8;
|
||||||
|
int pixelw = firstcanvas->getPixelWidth(rts.colors[0].mipmap);
|
||||||
|
int pixelh = firstcanvas->getPixelHeight(rts.colors[0].mipmap);
|
||||||
|
|
||||||
|
for (int i = 1; i < ncanvases; i++)
|
||||||
|
{
|
||||||
|
love::graphics::Canvas *c = rts.colors[i].canvas;
|
||||||
|
PixelFormat format = c->getPixelFormat();
|
||||||
|
int mip = rts.colors[i].mipmap;
|
||||||
|
|
||||||
|
if (mip < 0 || mip >= c->getMipmapCount())
|
||||||
|
throw love::Exception("Invalid mipmap level %d.", mip + 1);
|
||||||
|
|
||||||
|
if (c->getPixelWidth(mip) != pixelw || c->getPixelHeight(mip) != pixelh)
|
||||||
|
throw love::Exception("All canvases must have the same pixel dimensions.");
|
||||||
|
|
||||||
|
if (!multiformatsupported && format != firstformat)
|
||||||
|
throw love::Exception("This system doesn't support multi-canvas rendering with different canvas formats.");
|
||||||
|
|
||||||
|
if (c->getRequestedMSAA() != firstcanvas->getRequestedMSAA())
|
||||||
|
throw love::Exception("All Canvases must have the same MSAA value.");
|
||||||
|
|
||||||
|
if (isPixelFormatDepthStencil(format))
|
||||||
|
throw love::Exception("Depth/stencil format Canvases must be used with the 'depthstencil' field of the table passed into setCanvas.");
|
||||||
|
|
||||||
|
if (format == PIXELFORMAT_sRGBA8)
|
||||||
|
hasSRGBcanvas = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rts.depthStencil.canvas != nullptr)
|
||||||
|
{
|
||||||
|
love::graphics::Canvas *c = rts.depthStencil.canvas;
|
||||||
|
int mip = rts.depthStencil.mipmap;
|
||||||
|
|
||||||
|
if (!isPixelFormatDepthStencil(c->getPixelFormat()))
|
||||||
|
throw love::Exception("Only depth/stencil format Canvases can be used with the 'depthstencil' field of the table passed into setCanvas.");
|
||||||
|
|
||||||
|
if (c->getPixelWidth(mip) != pixelw || c->getPixelHeight(mip) != pixelh)
|
||||||
|
throw love::Exception("All canvases must have the same pixel dimensions.");
|
||||||
|
|
||||||
|
if (c->getRequestedMSAA() != firstcanvas->getRequestedMSAA())
|
||||||
|
throw love::Exception("All Canvases must have the same MSAA value.");
|
||||||
|
|
||||||
|
if (mip < 0 || mip >= c->getMipmapCount())
|
||||||
|
throw love::Exception("Invalid mipmap level %d.", mip + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int w = firstcanvas->getWidth(rts.colors[0].mipmap);
|
||||||
|
int h = firstcanvas->getHeight(rts.colors[0].mipmap);
|
||||||
|
|
||||||
|
flushStreamDraws();
|
||||||
|
setCanvasInternal(rts, w, h, pixelw, pixelh, hasSRGBcanvas);
|
||||||
|
|
||||||
|
RenderTargetsStrongRef refs;
|
||||||
|
refs.colors.reserve(rts.colors.size());
|
||||||
|
|
||||||
|
for (auto c : rts.colors)
|
||||||
|
refs.colors.emplace_back(c.canvas, c.slice);
|
||||||
|
|
||||||
|
refs.depthStencil = RenderTargetStrongRef(rts.depthStencil.canvas, rts.depthStencil.slice);
|
||||||
|
refs.temporaryRTFlags = rts.temporaryRTFlags;
|
||||||
|
|
||||||
|
std::swap(state.renderTargets, refs);
|
||||||
|
|
||||||
|
canvasSwitchCount++;
|
||||||
|
}
|
||||||
|
|
||||||
Graphics::RenderTargets Graphics::getCanvas() const
|
Graphics::RenderTargets Graphics::getCanvas() const
|
||||||
{
|
{
|
||||||
const auto &curRTs = states.back().renderTargets;
|
const auto &curRTs = states.back().renderTargets;
|
||||||
@@ -757,6 +880,9 @@ Graphics::StreamVertexData Graphics::requestStreamDraw(const StreamDrawRequest &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state.vertexCount > 0)
|
||||||
|
drawCallsBatched++;
|
||||||
|
|
||||||
state.vertexCount += req.vertexCount;
|
state.vertexCount += req.vertexCount;
|
||||||
state.indexCount += reqIndexCount;
|
state.indexCount += reqIndexCount;
|
||||||
|
|
||||||
@@ -829,7 +955,7 @@ void Graphics::printf(const std::vector<Font::ColoredString> &str, Font *font, f
|
|||||||
* Primitives (points, shapes, lines).
|
* Primitives (points, shapes, lines).
|
||||||
**/
|
**/
|
||||||
|
|
||||||
void Graphics::points(const float *coords, const Colorf *colors, size_t numpoints)
|
void Graphics::points(const Vector2 *positions, const Colorf *colors, size_t numpoints)
|
||||||
{
|
{
|
||||||
const Matrix4 &t = getTransform();
|
const Matrix4 &t = getTransform();
|
||||||
bool is2D = t.isAffine2DTransform();
|
bool is2D = t.isAffine2DTransform();
|
||||||
@@ -843,9 +969,9 @@ void Graphics::points(const float *coords, const Colorf *colors, size_t numpoint
|
|||||||
StreamVertexData data = requestStreamDraw(req);
|
StreamVertexData data = requestStreamDraw(req);
|
||||||
|
|
||||||
if (is2D)
|
if (is2D)
|
||||||
t.transformXY((Vector2 *) data.stream[0], (const Vector2 *) coords, req.vertexCount);
|
t.transformXY((Vector2 *) data.stream[0], positions, req.vertexCount);
|
||||||
else
|
else
|
||||||
t.transformXY0((Vector3 *) data.stream[0], (const Vector2 *) coords, req.vertexCount);
|
t.transformXY0((Vector3 *) data.stream[0], positions, req.vertexCount);
|
||||||
|
|
||||||
Color *colordata = (Color *) data.stream[1];
|
Color *colordata = (Color *) data.stream[1];
|
||||||
|
|
||||||
@@ -886,7 +1012,7 @@ int Graphics::calculateEllipsePoints(float rx, float ry) const
|
|||||||
return std::max(points, 8);
|
return std::max(points, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::polyline(const float *coords, size_t count)
|
void Graphics::polyline(const Vector2 *vertices, size_t count)
|
||||||
{
|
{
|
||||||
float halfwidth = getLineWidth() * 0.5f;
|
float halfwidth = getLineWidth() * 0.5f;
|
||||||
LineJoin linejoin = getLineJoin();
|
LineJoin linejoin = getLineJoin();
|
||||||
@@ -897,27 +1023,27 @@ void Graphics::polyline(const float *coords, size_t count)
|
|||||||
if (linejoin == LINE_JOIN_NONE)
|
if (linejoin == LINE_JOIN_NONE)
|
||||||
{
|
{
|
||||||
NoneJoinPolyline line;
|
NoneJoinPolyline line;
|
||||||
line.render(coords, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
|
line.render(vertices, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
|
||||||
line.draw(this);
|
line.draw(this);
|
||||||
}
|
}
|
||||||
else if (linejoin == LINE_JOIN_BEVEL)
|
else if (linejoin == LINE_JOIN_BEVEL)
|
||||||
{
|
{
|
||||||
BevelJoinPolyline line;
|
BevelJoinPolyline line;
|
||||||
line.render(coords, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
|
line.render(vertices, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
|
||||||
line.draw(this);
|
line.draw(this);
|
||||||
}
|
}
|
||||||
else if (linejoin == LINE_JOIN_MITER)
|
else if (linejoin == LINE_JOIN_MITER)
|
||||||
{
|
{
|
||||||
MiterJoinPolyline line;
|
MiterJoinPolyline line;
|
||||||
line.render(coords, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
|
line.render(vertices, count, halfwidth, pixelsize, linestyle == LINE_SMOOTH);
|
||||||
line.draw(this);
|
line.draw(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h)
|
void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h)
|
||||||
{
|
{
|
||||||
float coords[] = {x,y, x,y+h, x+w,y+h, x+w,y, x,y};
|
Vector2 coords[] = {Vector2(x,y), Vector2(x,y+h), Vector2(x+w,y+h), Vector2(x+w,y), Vector2(x,y)};
|
||||||
polygon(mode, coords, 5 * 2);
|
polygon(mode, coords, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h, float rx, float ry, int points)
|
void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h, float rx, float ry, int points)
|
||||||
@@ -940,44 +1066,43 @@ void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h, floa
|
|||||||
const float half_pi = static_cast<float>(LOVE_M_PI / 2);
|
const float half_pi = static_cast<float>(LOVE_M_PI / 2);
|
||||||
float angle_shift = half_pi / ((float) points + 1.0f);
|
float angle_shift = half_pi / ((float) points + 1.0f);
|
||||||
|
|
||||||
int num_coords = (points + 2) * 8;
|
int num_coords = (points + 2) * 4;
|
||||||
float *coords = getScratchBuffer<float>(num_coords + 2);
|
Vector2 *coords = getScratchBuffer<Vector2>(num_coords + 1);
|
||||||
float phi = .0f;
|
float phi = .0f;
|
||||||
|
|
||||||
for (int i = 0; i <= points + 2; ++i, phi += angle_shift)
|
for (int i = 0; i <= points + 2; ++i, phi += angle_shift)
|
||||||
{
|
{
|
||||||
coords[2 * i + 0] = x + rx * (1 - cosf(phi));
|
coords[i].x = x + rx * (1 - cosf(phi));
|
||||||
coords[2 * i + 1] = y + ry * (1 - sinf(phi));
|
coords[i].y = y + ry * (1 - sinf(phi));
|
||||||
}
|
}
|
||||||
|
|
||||||
phi = half_pi;
|
phi = half_pi;
|
||||||
|
|
||||||
for (int i = points + 2; i <= 2 * (points + 2); ++i, phi += angle_shift)
|
for (int i = points + 2; i <= 2 * (points + 2); ++i, phi += angle_shift)
|
||||||
{
|
{
|
||||||
coords[2 * i + 0] = x + w - rx * (1 + cosf(phi));
|
coords[i].x = x + w - rx * (1 + cosf(phi));
|
||||||
coords[2 * i + 1] = y + ry * (1 - sinf(phi));
|
coords[i].y = y + ry * (1 - sinf(phi));
|
||||||
}
|
}
|
||||||
|
|
||||||
phi = 2 * half_pi;
|
phi = 2 * half_pi;
|
||||||
|
|
||||||
for (int i = 2 * (points + 2); i <= 3 * (points + 2); ++i, phi += angle_shift)
|
for (int i = 2 * (points + 2); i <= 3 * (points + 2); ++i, phi += angle_shift)
|
||||||
{
|
{
|
||||||
coords[2 * i + 0] = x + w - rx * (1 + cosf(phi));
|
coords[i].x = x + w - rx * (1 + cosf(phi));
|
||||||
coords[2 * i + 1] = y + h - ry * (1 + sinf(phi));
|
coords[i].y = y + h - ry * (1 + sinf(phi));
|
||||||
}
|
}
|
||||||
|
|
||||||
phi = 3 * half_pi;
|
phi = 3 * half_pi;
|
||||||
|
|
||||||
for (int i = 3 * (points + 2); i <= 4 * (points + 2); ++i, phi += angle_shift)
|
for (int i = 3 * (points + 2); i <= 4 * (points + 2); ++i, phi += angle_shift)
|
||||||
{
|
{
|
||||||
coords[2 * i + 0] = x + rx * (1 - cosf(phi));
|
coords[i].x = x + rx * (1 - cosf(phi));
|
||||||
coords[2 * i + 1] = y + h - ry * (1 + sinf(phi));
|
coords[i].y = y + h - ry * (1 + sinf(phi));
|
||||||
}
|
}
|
||||||
|
|
||||||
coords[num_coords + 0] = coords[0];
|
coords[num_coords] = coords[0];
|
||||||
coords[num_coords + 1] = coords[1];
|
|
||||||
|
|
||||||
polygon(mode, coords, num_coords + 2);
|
polygon(mode, coords, num_coords + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h, float rx, float ry)
|
void Graphics::rectangle(DrawMode mode, float x, float y, float w, float h, float rx, float ry)
|
||||||
@@ -1002,17 +1127,16 @@ void Graphics::ellipse(DrawMode mode, float x, float y, float a, float b, int po
|
|||||||
float angle_shift = (two_pi / points);
|
float angle_shift = (two_pi / points);
|
||||||
float phi = .0f;
|
float phi = .0f;
|
||||||
|
|
||||||
float *coords = getScratchBuffer<float>(2 * (points + 1));
|
Vector2 *coords = getScratchBuffer<Vector2>(points + 1);
|
||||||
for (int i = 0; i < points; ++i, phi += angle_shift)
|
for (int i = 0; i < points; ++i, phi += angle_shift)
|
||||||
{
|
{
|
||||||
coords[2*i+0] = x + a * cosf(phi);
|
coords[i].x = x + a * cosf(phi);
|
||||||
coords[2*i+1] = y + b * sinf(phi);
|
coords[i].y = y + b * sinf(phi);
|
||||||
}
|
}
|
||||||
|
|
||||||
coords[2*points+0] = coords[0];
|
coords[points] = coords[0];
|
||||||
coords[2*points+1] = coords[1];
|
|
||||||
|
|
||||||
polygon(mode, coords, (points + 1) * 2);
|
polygon(mode, coords, points + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::ellipse(DrawMode mode, float x, float y, float a, float b)
|
void Graphics::ellipse(DrawMode mode, float x, float y, float a, float b)
|
||||||
@@ -1051,45 +1175,43 @@ void Graphics::arc(DrawMode drawmode, ArcMode arcmode, float x, float y, float r
|
|||||||
|
|
||||||
float phi = angle1;
|
float phi = angle1;
|
||||||
|
|
||||||
float *coords = nullptr;
|
Vector2 *coords = nullptr;
|
||||||
int num_coords = 0;
|
int num_coords = 0;
|
||||||
|
|
||||||
const auto createPoints = [&](float *coordinates)
|
const auto createPoints = [&](Vector2 *coordinates)
|
||||||
{
|
{
|
||||||
for (int i = 0; i <= points; ++i, phi += angle_shift)
|
for (int i = 0; i <= points; ++i, phi += angle_shift)
|
||||||
{
|
{
|
||||||
coordinates[2 * i + 0] = x + radius * cosf(phi);
|
coordinates[i].x = x + radius * cosf(phi);
|
||||||
coordinates[2 * i + 1] = y + radius * sinf(phi);
|
coordinates[i].y = y + radius * sinf(phi);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (arcmode == ARC_PIE)
|
if (arcmode == ARC_PIE)
|
||||||
{
|
{
|
||||||
num_coords = (points + 3) * 2;
|
num_coords = points + 3;
|
||||||
coords = getScratchBuffer<float>(num_coords);
|
coords = getScratchBuffer<Vector2>(num_coords);
|
||||||
|
|
||||||
coords[0] = coords[num_coords - 2] = x;
|
coords[0] = coords[num_coords - 1] = Vector2(x, y);
|
||||||
coords[1] = coords[num_coords - 1] = y;
|
|
||||||
|
|
||||||
createPoints(coords + 2);
|
createPoints(coords + 1);
|
||||||
}
|
}
|
||||||
else if (arcmode == ARC_OPEN)
|
else if (arcmode == ARC_OPEN)
|
||||||
{
|
{
|
||||||
num_coords = (points + 1) * 2;
|
num_coords = points + 1;
|
||||||
coords = getScratchBuffer<float>(num_coords);
|
coords = getScratchBuffer<Vector2>(num_coords);
|
||||||
|
|
||||||
createPoints(coords);
|
createPoints(coords);
|
||||||
}
|
}
|
||||||
else // ARC_CLOSED
|
else // ARC_CLOSED
|
||||||
{
|
{
|
||||||
num_coords = (points + 2) * 2;
|
num_coords = points + 2;
|
||||||
coords = getScratchBuffer<float>(num_coords);
|
coords = getScratchBuffer<Vector2>(num_coords);
|
||||||
|
|
||||||
createPoints(coords);
|
createPoints(coords);
|
||||||
|
|
||||||
// Connect the ends of the arc.
|
// Connect the ends of the arc.
|
||||||
coords[num_coords - 2] = coords[0];
|
coords[num_coords - 1] = coords[0];
|
||||||
coords[num_coords - 1] = coords[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
polygon(drawmode, coords, num_coords);
|
polygon(drawmode, coords, num_coords);
|
||||||
@@ -1107,13 +1229,10 @@ void Graphics::arc(DrawMode drawmode, ArcMode arcmode, float x, float y, float r
|
|||||||
arc(drawmode, arcmode, x, y, radius, angle1, angle2, (int) (points + 0.5f));
|
arc(drawmode, arcmode, x, y, radius, angle1, angle2, (int) (points + 0.5f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param mode the draw mode
|
void Graphics::polygon(DrawMode mode, const Vector2 *coords, size_t count)
|
||||||
/// @param coords the coordinate array
|
|
||||||
/// @param count the number of coordinates/size of the array
|
|
||||||
void Graphics::polygon(DrawMode mode, const float *coords, size_t count)
|
|
||||||
{
|
{
|
||||||
// coords is an array of a closed loop of vertices, i.e.
|
// coords is an array of a closed loop of vertices, i.e.
|
||||||
// coords[count-2] = coords[0], coords[count-1] = coords[1]
|
// coords[count-1] == coords[0]
|
||||||
if (mode == DRAW_LINE)
|
if (mode == DRAW_LINE)
|
||||||
{
|
{
|
||||||
polyline(coords, count);
|
polyline(coords, count);
|
||||||
@@ -1127,14 +1246,14 @@ void Graphics::polygon(DrawMode mode, const float *coords, size_t count)
|
|||||||
req.formats[0] = vertex::getSinglePositionFormat(is2D);
|
req.formats[0] = vertex::getSinglePositionFormat(is2D);
|
||||||
req.formats[1] = vertex::CommonFormat::RGBAub;
|
req.formats[1] = vertex::CommonFormat::RGBAub;
|
||||||
req.indexMode = vertex::TriangleIndexMode::FAN;
|
req.indexMode = vertex::TriangleIndexMode::FAN;
|
||||||
req.vertexCount = (int)count/2 - 1;
|
req.vertexCount = (int)count - 1;
|
||||||
|
|
||||||
StreamVertexData data = requestStreamDraw(req);
|
StreamVertexData data = requestStreamDraw(req);
|
||||||
|
|
||||||
if (is2D)
|
if (is2D)
|
||||||
t.transformXY((Vector2 *) data.stream[0], (const Vector2 *) coords, req.vertexCount);
|
t.transformXY((Vector2 *) data.stream[0], coords, req.vertexCount);
|
||||||
else
|
else
|
||||||
t.transformXY0((Vector3 *) data.stream[0], (const Vector2 *) coords, req.vertexCount);
|
t.transformXY0((Vector3 *) data.stream[0], coords, req.vertexCount);
|
||||||
|
|
||||||
Color c = toColor(getColor());
|
Color c = toColor(getColor());
|
||||||
Color *colordata = (Color *) data.stream[1];
|
Color *colordata = (Color *) data.stream[1];
|
||||||
@@ -1158,6 +1277,7 @@ Graphics::Stats Graphics::getStats() const
|
|||||||
stats.drawCalls++;
|
stats.drawCalls++;
|
||||||
|
|
||||||
stats.canvasSwitches = canvasSwitchCount;
|
stats.canvasSwitches = canvasSwitchCount;
|
||||||
|
stats.drawCallsBatched = drawCallsBatched;
|
||||||
stats.canvases = Canvas::canvasCount;
|
stats.canvases = Canvas::canvasCount;
|
||||||
stats.images = Image::imageCount;
|
stats.images = Image::imageCount;
|
||||||
stats.fonts = Font::fontCount;
|
stats.fonts = Font::fontCount;
|
||||||
|
|||||||
@@ -28,9 +28,9 @@
|
|||||||
#include "common/Vector.h"
|
#include "common/Vector.h"
|
||||||
#include "common/Optional.h"
|
#include "common/Optional.h"
|
||||||
#include "common/int.h"
|
#include "common/int.h"
|
||||||
|
#include "common/Color.h"
|
||||||
#include "StreamBuffer.h"
|
#include "StreamBuffer.h"
|
||||||
#include "vertex.h"
|
#include "vertex.h"
|
||||||
#include "Color.h"
|
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "Canvas.h"
|
#include "Canvas.h"
|
||||||
#include "Font.h"
|
#include "Font.h"
|
||||||
@@ -216,6 +216,7 @@ public:
|
|||||||
struct Stats
|
struct Stats
|
||||||
{
|
{
|
||||||
int drawCalls;
|
int drawCalls;
|
||||||
|
int drawCallsBatched;
|
||||||
int canvasSwitches;
|
int canvasSwitches;
|
||||||
int shaderSwitches;
|
int shaderSwitches;
|
||||||
int canvases;
|
int canvases;
|
||||||
@@ -478,7 +479,7 @@ public:
|
|||||||
Shader *getShader() const;
|
Shader *getShader() const;
|
||||||
|
|
||||||
void setCanvas(RenderTarget rt, uint32 temporaryRTFlags);
|
void setCanvas(RenderTarget rt, uint32 temporaryRTFlags);
|
||||||
virtual void setCanvas(const RenderTargets &rts) = 0;
|
void setCanvas(const RenderTargets &rts);
|
||||||
void setCanvas(const RenderTargetsStrongRef &rts);
|
void setCanvas(const RenderTargetsStrongRef &rts);
|
||||||
virtual void setCanvas() = 0;
|
virtual void setCanvas() = 0;
|
||||||
|
|
||||||
@@ -620,18 +621,16 @@ public:
|
|||||||
void printf(const std::vector<Font::ColoredString> &str, Font *font, float wrap, Font::AlignMode align, const Matrix4 &m);
|
void printf(const std::vector<Font::ColoredString> &str, Font *font, float wrap, Font::AlignMode align, const Matrix4 &m);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a point at (x,y).
|
* Draws a series of points at the specified positions.
|
||||||
* @param x Point along x-axis.
|
|
||||||
* @param y Point along y-axis.
|
|
||||||
**/
|
**/
|
||||||
void points(const float *coords, const Colorf *colors, size_t numpoints);
|
void points(const Vector2 *positions, const Colorf *colors, size_t numpoints);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a series of lines connecting the given vertices.
|
* Draws a series of lines connecting the given vertices.
|
||||||
* @param coords Vertex components (x1, y1, ..., xn, yn). If x1,y1 == xn,yn the line will be drawn closed.
|
* @param coords Vertex positions (v1, ..., vn). If v1 == vn the line will be drawn closed.
|
||||||
* @param count Number of items in the array, i.e. count = 2 * n
|
* @param count Number of vertices.
|
||||||
**/
|
**/
|
||||||
void polyline(const float *coords, size_t count);
|
void polyline(const Vector2 *vertices, size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a rectangle.
|
* Draws a rectangle.
|
||||||
@@ -696,10 +695,10 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Draws a polygon with an arbitrary number of vertices.
|
* Draws a polygon with an arbitrary number of vertices.
|
||||||
* @param mode The type of drawing (line/filled).
|
* @param mode The type of drawing (line/filled).
|
||||||
* @param coords Vertex components (x1, y1, x2, y2, etc.)
|
* @param coords Vertex positions.
|
||||||
* @param count Coord array size
|
* @param count Vertex array size.
|
||||||
**/
|
**/
|
||||||
void polygon(DrawMode mode, const float *coords, size_t count);
|
void polygon(DrawMode mode, const Vector2 *vertices, size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the graphics capabilities (feature support, limit values, and
|
* Gets the graphics capabilities (feature support, limit values, and
|
||||||
@@ -861,6 +860,8 @@ protected:
|
|||||||
|
|
||||||
virtual StreamBuffer *newStreamBuffer(BufferType type, size_t size) = 0;
|
virtual StreamBuffer *newStreamBuffer(BufferType type, size_t size) = 0;
|
||||||
|
|
||||||
|
virtual void setCanvasInternal(const RenderTargets &rts, int w, int h, int pixelw, int pixelh, bool hasSRGBcanvas) = 0;
|
||||||
|
|
||||||
virtual void initCapabilities() = 0;
|
virtual void initCapabilities() = 0;
|
||||||
virtual void getAPIStats(int &drawcalls, int &shaderswitches) const = 0;
|
virtual void getAPIStats(int &drawcalls, int &shaderswitches) const = 0;
|
||||||
|
|
||||||
@@ -900,6 +901,7 @@ protected:
|
|||||||
std::vector<Canvas *> temporaryCanvases;
|
std::vector<Canvas *> temporaryCanvases;
|
||||||
|
|
||||||
int canvasSwitchCount;
|
int canvasSwitchCount;
|
||||||
|
int drawCallsBatched;
|
||||||
|
|
||||||
Capabilities capabilities;
|
Capabilities capabilities;
|
||||||
|
|
||||||
|
|||||||
@@ -564,11 +564,88 @@ bool Mesh::getDrawRange(int &start, int &count) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::draw(love::graphics::Graphics *gfx, const love::Matrix4 &m)
|
void Mesh::draw(Graphics *gfx, const love::Matrix4 &m)
|
||||||
{
|
{
|
||||||
drawInstanced(gfx, m, 1);
|
drawInstanced(gfx, m, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount)
|
||||||
|
{
|
||||||
|
if (vertexCount <= 0 || instancecount <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (instancecount > 1 && !gfx->getCapabilities().features[Graphics::FEATURE_INSTANCING])
|
||||||
|
throw love::Exception("Instancing is not supported on this system.");
|
||||||
|
|
||||||
|
gfx->flushStreamDraws();
|
||||||
|
|
||||||
|
if (Shader::isDefaultActive())
|
||||||
|
Shader::attachDefault(Shader::STANDARD_DEFAULT);
|
||||||
|
|
||||||
|
if (Shader::current && texture.get())
|
||||||
|
Shader::current->checkMainTexture(texture);
|
||||||
|
|
||||||
|
uint32 enabledattribs = 0;
|
||||||
|
uint32 instancedattribs = 0;
|
||||||
|
|
||||||
|
for (const auto &attrib : attachedAttributes)
|
||||||
|
{
|
||||||
|
if (!attrib.second.enabled)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
love::graphics::Mesh *mesh = attrib.second.mesh;
|
||||||
|
int location = mesh->bindAttributeToShaderInput(attrib.second.index, attrib.first);
|
||||||
|
|
||||||
|
if (location >= 0)
|
||||||
|
{
|
||||||
|
uint32 bit = 1u << (uint32) location;
|
||||||
|
|
||||||
|
enabledattribs |= bit;
|
||||||
|
|
||||||
|
if (attrib.second.step == STEP_PER_INSTANCE)
|
||||||
|
instancedattribs |= bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not supported on all platforms or GL versions, I believe.
|
||||||
|
if (!(enabledattribs & ATTRIBFLAG_POS))
|
||||||
|
throw love::Exception("Mesh must have an enabled VertexPosition attribute to be drawn.");
|
||||||
|
|
||||||
|
bool useindexbuffer = useIndexBuffer && ibo != nullptr && elementCount > 0;
|
||||||
|
|
||||||
|
int start = 0;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if (useindexbuffer)
|
||||||
|
{
|
||||||
|
// Make sure the index buffer isn't mapped (sends data to GPU if needed.)
|
||||||
|
ibo->unmap();
|
||||||
|
|
||||||
|
start = std::min(std::max(0, rangeStart), (int) elementCount - 1);
|
||||||
|
|
||||||
|
count = (int) elementCount;
|
||||||
|
if (rangeCount > 0)
|
||||||
|
count = std::min(count, rangeCount);
|
||||||
|
|
||||||
|
count = std::min(count, (int) elementCount - start);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start = std::min(std::max(0, rangeStart), (int) vertexCount - 1);
|
||||||
|
|
||||||
|
count = (int) vertexCount;
|
||||||
|
if (rangeCount > 0)
|
||||||
|
count = std::min(count, rangeCount);
|
||||||
|
|
||||||
|
count = std::min(count, (int) vertexCount - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics::TempTransform transform(gfx, m);
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
drawInternal(start, count, instancecount, useindexbuffer, enabledattribs, instancedattribs);
|
||||||
|
}
|
||||||
|
|
||||||
size_t Mesh::getAttribFormatSize(const AttribFormat &format)
|
size_t Mesh::getAttribFormatSize(const AttribFormat &format)
|
||||||
{
|
{
|
||||||
switch (format.type)
|
switch (format.type)
|
||||||
|
|||||||
@@ -195,11 +195,11 @@ public:
|
|||||||
|
|
||||||
virtual int bindAttributeToShaderInput(int attributeindex, const std::string &inputname) = 0;
|
virtual int bindAttributeToShaderInput(int attributeindex, const std::string &inputname) = 0;
|
||||||
|
|
||||||
virtual void drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount) = 0;
|
|
||||||
|
|
||||||
// Implements Drawable.
|
// Implements Drawable.
|
||||||
void draw(Graphics *gfx, const Matrix4 &m) override;
|
void draw(Graphics *gfx, const Matrix4 &m) override;
|
||||||
|
|
||||||
|
void drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount);
|
||||||
|
|
||||||
static bool getConstant(const char *in, DrawMode &out);
|
static bool getConstant(const char *in, DrawMode &out);
|
||||||
static bool getConstant(DrawMode in, const char *&out);
|
static bool getConstant(DrawMode in, const char *&out);
|
||||||
|
|
||||||
@@ -223,6 +223,8 @@ protected:
|
|||||||
void calculateAttributeSizes();
|
void calculateAttributeSizes();
|
||||||
size_t getAttributeOffset(size_t attribindex) const;
|
size_t getAttributeOffset(size_t attribindex) const;
|
||||||
|
|
||||||
|
virtual void drawInternal(int start, int count, int instancecount, bool useindexbuffer, uint32 attribflags, uint32 instancedattribflags) const = 0;
|
||||||
|
|
||||||
static size_t getAttribFormatSize(const AttribFormat &format);
|
static size_t getAttribFormatSize(const AttribFormat &format);
|
||||||
static std::vector<AttribFormat> getDefaultVertexFormat();
|
static std::vector<AttribFormat> getDefaultVertexFormat();
|
||||||
|
|
||||||
|
|||||||
@@ -1048,15 +1048,21 @@ void ParticleSystem::update(float dt)
|
|||||||
prevPosition = position;
|
prevPosition = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParticleSystem::prepareDraw(Graphics *gfx)
|
void ParticleSystem::draw(Graphics *gfx, const Matrix4 &m)
|
||||||
{
|
{
|
||||||
uint32 pCount = getCount();
|
uint32 pCount = getCount();
|
||||||
|
|
||||||
if (pCount == 0 || texture.get() == nullptr || pMem == nullptr || buffer == nullptr)
|
if (pCount == 0 || texture.get() == nullptr || pMem == nullptr || buffer == nullptr)
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
gfx->flushStreamDraws();
|
gfx->flushStreamDraws();
|
||||||
|
|
||||||
|
if (Shader::isDefaultActive())
|
||||||
|
Shader::attachDefault(Shader::STANDARD_DEFAULT);
|
||||||
|
|
||||||
|
if (Shader::current && texture.get())
|
||||||
|
Shader::current->checkMainTexture(texture);
|
||||||
|
|
||||||
const Vector2 *positions = texture->getQuad()->getVertexPositions();
|
const Vector2 *positions = texture->getQuad()->getVertexPositions();
|
||||||
const Vector2 *texcoords = texture->getQuad()->getVertexTexCoords();
|
const Vector2 *texcoords = texture->getQuad()->getVertexTexCoords();
|
||||||
|
|
||||||
@@ -1098,7 +1104,8 @@ bool ParticleSystem::prepareDraw(Graphics *gfx)
|
|||||||
|
|
||||||
buffer->unmap();
|
buffer->unmap();
|
||||||
|
|
||||||
return true;
|
Graphics::TempTransform transform(gfx, m);
|
||||||
|
drawInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParticleSystem::getConstant(const char *in, AreaSpreadDistribution &out)
|
bool ParticleSystem::getConstant(const char *in, AreaSpreadDistribution &out)
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
#include "common/int.h"
|
#include "common/int.h"
|
||||||
#include "common/math.h"
|
#include "common/math.h"
|
||||||
#include "common/Vector.h"
|
#include "common/Vector.h"
|
||||||
|
#include "common/Color.h"
|
||||||
#include "Drawable.h"
|
#include "Drawable.h"
|
||||||
#include "Color.h"
|
|
||||||
#include "Quad.h"
|
#include "Quad.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "Buffer.h"
|
#include "Buffer.h"
|
||||||
@@ -569,6 +569,9 @@ public:
|
|||||||
**/
|
**/
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
|
|
||||||
|
// Implements Drawable.
|
||||||
|
void draw(Graphics *gfx, const Matrix4 &m) override;
|
||||||
|
|
||||||
static bool getConstant(const char *in, AreaSpreadDistribution &out);
|
static bool getConstant(const char *in, AreaSpreadDistribution &out);
|
||||||
static bool getConstant(AreaSpreadDistribution in, const char *&out);
|
static bool getConstant(AreaSpreadDistribution in, const char *&out);
|
||||||
|
|
||||||
@@ -612,7 +615,7 @@ protected:
|
|||||||
int quadIndex;
|
int quadIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool prepareDraw(Graphics *gfx);
|
virtual void drawInternal() const = 0;
|
||||||
|
|
||||||
// Pointer to the beginning of the allocated memory.
|
// Pointer to the beginning of the allocated memory.
|
||||||
Particle *pMem;
|
Particle *pMem;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace love
|
|||||||
namespace graphics
|
namespace graphics
|
||||||
{
|
{
|
||||||
|
|
||||||
void Polyline::render(const float *coords, size_t count, size_t size_hint, float halfwidth, float pixel_size, bool draw_overdraw)
|
void Polyline::render(const Vector2 *coords, size_t count, size_t size_hint, float halfwidth, float pixel_size, bool draw_overdraw)
|
||||||
{
|
{
|
||||||
static std::vector<Vector2> anchors;
|
static std::vector<Vector2> anchors;
|
||||||
anchors.clear();
|
anchors.clear();
|
||||||
@@ -48,26 +48,26 @@ void Polyline::render(const float *coords, size_t count, size_t size_hint, float
|
|||||||
halfwidth -= pixel_size * 0.3f;
|
halfwidth -= pixel_size * 0.3f;
|
||||||
|
|
||||||
// compute sleeve
|
// compute sleeve
|
||||||
bool is_looping = (coords[0] == coords[count - 2]) && (coords[1] == coords[count - 1]);
|
bool is_looping = (coords[0] == coords[count - 1]);
|
||||||
Vector2 s;
|
Vector2 s;
|
||||||
if (!is_looping) // virtual starting point at second point mirrored on first point
|
if (!is_looping) // virtual starting point at second point mirrored on first point
|
||||||
s = Vector2(coords[2] - coords[0], coords[3] - coords[1]);
|
s = coords[1] - coords[0];
|
||||||
else // virtual starting point at last vertex
|
else // virtual starting point at last vertex
|
||||||
s = Vector2(coords[0] - coords[count - 4], coords[1] - coords[count - 3]);
|
s = coords[0] - coords[count - 2];
|
||||||
|
|
||||||
float len_s = s.getLength();
|
float len_s = s.getLength();
|
||||||
Vector2 ns = s.getNormal(halfwidth / len_s);
|
Vector2 ns = s.getNormal(halfwidth / len_s);
|
||||||
|
|
||||||
Vector2 q, r(coords[0], coords[1]);
|
Vector2 q, r(coords[0]);
|
||||||
for (size_t i = 0; i + 3 < count; i += 2)
|
for (size_t i = 0; i + 1 < count; i++)
|
||||||
{
|
{
|
||||||
q = r;
|
q = r;
|
||||||
r = Vector2(coords[i + 2], coords[i + 3]);
|
r = coords[i + 1];
|
||||||
renderEdge(anchors, normals, s, len_s, ns, q, r, halfwidth);
|
renderEdge(anchors, normals, s, len_s, ns, q, r, halfwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
q = r;
|
q = r;
|
||||||
r = is_looping ? Vector2(coords[2], coords[3]) : r + s;
|
r = is_looping ? coords[1] : r + s;
|
||||||
renderEdge(anchors, normals, s, len_s, ns, q, r, halfwidth);
|
renderEdge(anchors, normals, s, len_s, ns, q, r, halfwidth);
|
||||||
|
|
||||||
vertex_count = normals.size();
|
vertex_count = normals.size();
|
||||||
|
|||||||
@@ -57,13 +57,13 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param vertices Vertices defining the core line segments
|
* @param vertices Vertices defining the core line segments
|
||||||
* @param count Number of coordinates (= size of the array vertices)
|
* @param count Number of vertices
|
||||||
* @param size_hint Expected number of vertices of the rendering sleeve around the core line.
|
* @param size_hint Expected number of vertices of the rendering sleeve around the core line.
|
||||||
* @param halfwidth linewidth / 2.
|
* @param halfwidth linewidth / 2.
|
||||||
* @param pixel_size Dimension of one pixel on the screen in world coordinates.
|
* @param pixel_size Dimension of one pixel on the screen in world coordinates.
|
||||||
* @param draw_overdraw Fake antialias the line.
|
* @param draw_overdraw Fake antialias the line.
|
||||||
*/
|
*/
|
||||||
void render(const float *vertices, size_t count, size_t size_hint, float halfwidth, float pixel_size, bool draw_overdraw);
|
void render(const Vector2 *vertices, size_t count, size_t size_hint, float halfwidth, float pixel_size, bool draw_overdraw);
|
||||||
|
|
||||||
/** Draws the line on the screen
|
/** Draws the line on the screen
|
||||||
*/
|
*/
|
||||||
@@ -112,9 +112,9 @@ public:
|
|||||||
: Polyline(vertex::TriangleIndexMode::QUADS)
|
: Polyline(vertex::TriangleIndexMode::QUADS)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void render(const float *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
|
void render(const Vector2 *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
|
||||||
{
|
{
|
||||||
Polyline::render(vertices, count, 2 * count - 4, halfwidth, pixel_size, draw_overdraw);
|
Polyline::render(vertices, count, 4 * count - 4, halfwidth, pixel_size, draw_overdraw);
|
||||||
|
|
||||||
// discard the first and last two vertices. (these are redundant)
|
// discard the first and last two vertices. (these are redundant)
|
||||||
for (size_t i = 0; i < vertex_count - 4; ++i)
|
for (size_t i = 0; i < vertex_count - 4; ++i)
|
||||||
@@ -149,9 +149,9 @@ class MiterJoinPolyline : public Polyline
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void render(const float *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
|
void render(const Vector2 *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
|
||||||
{
|
{
|
||||||
Polyline::render(vertices, count, count, halfwidth, pixel_size, draw_overdraw);
|
Polyline::render(vertices, count, 2 * count, halfwidth, pixel_size, draw_overdraw);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -171,9 +171,9 @@ class BevelJoinPolyline : public Polyline
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void render(const float *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
|
void render(const Vector2 *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)
|
||||||
{
|
{
|
||||||
Polyline::render(vertices, count, 2 * count - 4, halfwidth, pixel_size, draw_overdraw);
|
Polyline::render(vertices, count, 4 * count - 4, halfwidth, pixel_size, draw_overdraw);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -351,16 +351,16 @@ StringMap<Shader::ShaderStage, Shader::STAGE_MAX_ENUM> Shader::stageNames(Shader
|
|||||||
|
|
||||||
StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM>::Entry Shader::builtinNameEntries[] =
|
StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM>::Entry Shader::builtinNameEntries[] =
|
||||||
{
|
{
|
||||||
{ "MainTex", BUILTIN_TEXTURE_MAIN },
|
{ "MainTex", BUILTIN_TEXTURE_MAIN },
|
||||||
{ "love_VideoYChannel", BUILTIN_TEXTURE_VIDEO_Y },
|
{ "love_VideoYChannel", BUILTIN_TEXTURE_VIDEO_Y },
|
||||||
{ "love_VideoCbChannel", BUILTIN_TEXTURE_VIDEO_CB },
|
{ "love_VideoCbChannel", BUILTIN_TEXTURE_VIDEO_CB },
|
||||||
{ "love_VideoCrChannel", BUILTIN_TEXTURE_VIDEO_CR },
|
{ "love_VideoCrChannel", BUILTIN_TEXTURE_VIDEO_CR },
|
||||||
{ "TransformMatrix", BUILTIN_MATRIX_TRANSFORM },
|
{ "ViewSpaceFromLocal", BUILTIN_MATRIX_VIEW_FROM_LOCAL },
|
||||||
{ "ProjectionMatrix", BUILTIN_MATRIX_PROJECTION },
|
{ "ClipSpaceFromView", BUILTIN_MATRIX_CLIP_FROM_VIEW },
|
||||||
{ "TransformProjectionMatrix", BUILTIN_MATRIX_TRANSFORM_PROJECTION },
|
{ "ClipSpaceFromLocal", BUILTIN_MATRIX_CLIP_FROM_LOCAL },
|
||||||
{ "NormalMatrix", BUILTIN_MATRIX_NORMAL },
|
{ "ViewNormalFromLocal", BUILTIN_MATRIX_VIEW_NORMAL_FROM_LOCAL },
|
||||||
{ "love_PointSize", BUILTIN_POINT_SIZE },
|
{ "love_PointSize", BUILTIN_POINT_SIZE },
|
||||||
{ "love_ScreenSize", BUILTIN_SCREEN_SIZE },
|
{ "love_ScreenSize", BUILTIN_SCREEN_SIZE },
|
||||||
};
|
};
|
||||||
|
|
||||||
StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM> Shader::builtinNames(Shader::builtinNameEntries, sizeof(Shader::builtinNameEntries));
|
StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM> Shader::builtinNames(Shader::builtinNameEntries, sizeof(Shader::builtinNameEntries));
|
||||||
|
|||||||
@@ -73,10 +73,10 @@ public:
|
|||||||
BUILTIN_TEXTURE_VIDEO_Y,
|
BUILTIN_TEXTURE_VIDEO_Y,
|
||||||
BUILTIN_TEXTURE_VIDEO_CB,
|
BUILTIN_TEXTURE_VIDEO_CB,
|
||||||
BUILTIN_TEXTURE_VIDEO_CR,
|
BUILTIN_TEXTURE_VIDEO_CR,
|
||||||
BUILTIN_MATRIX_TRANSFORM,
|
BUILTIN_MATRIX_VIEW_FROM_LOCAL,
|
||||||
BUILTIN_MATRIX_PROJECTION,
|
BUILTIN_MATRIX_CLIP_FROM_VIEW,
|
||||||
BUILTIN_MATRIX_TRANSFORM_PROJECTION,
|
BUILTIN_MATRIX_CLIP_FROM_LOCAL,
|
||||||
BUILTIN_MATRIX_NORMAL,
|
BUILTIN_MATRIX_VIEW_NORMAL_FROM_LOCAL,
|
||||||
BUILTIN_POINT_SIZE,
|
BUILTIN_POINT_SIZE,
|
||||||
BUILTIN_SCREEN_SIZE,
|
BUILTIN_SCREEN_SIZE,
|
||||||
BUILTIN_MAX_ENUM
|
BUILTIN_MAX_ENUM
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, vertex::Usag
|
|||||||
else
|
else
|
||||||
vertex_format = vertex::CommonFormat::XYf_STf_RGBAub;
|
vertex_format = vertex::CommonFormat::XYf_STf_RGBAub;
|
||||||
|
|
||||||
format_stride = vertex::getFormatStride(vertex_format);
|
vertex_stride = vertex::getFormatStride(vertex_format);
|
||||||
|
|
||||||
size_t vertex_size = format_stride * 4 * size;
|
size_t vertex_size = vertex_stride * 4 * size;
|
||||||
array_buf = gfx->newBuffer(vertex_size, nullptr, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY);
|
array_buf = gfx->newBuffer(vertex_size, nullptr, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ int SpriteBatch::add(Quad *quad, const Matrix4 &m, int index /*= -1*/)
|
|||||||
const Vector2 *quadtexcoords = quad->getVertexTexCoords();
|
const Vector2 *quadtexcoords = quad->getVertexTexCoords();
|
||||||
|
|
||||||
// Always keep the VBO mapped when adding data (it'll be unmapped on draw.)
|
// Always keep the VBO mapped when adding data (it'll be unmapped on draw.)
|
||||||
size_t offset = (index == -1 ? next : index) * format_stride * 4;
|
size_t offset = (index == -1 ? next : index) * vertex_stride * 4;
|
||||||
auto verts = (XYf_STf_RGBAub *) ((uint8 *) array_buf->map() + offset);
|
auto verts = (XYf_STf_RGBAub *) ((uint8 *) array_buf->map() + offset);
|
||||||
|
|
||||||
m.transformXY(verts, quadpositions, 4);
|
m.transformXY(verts, quadpositions, 4);
|
||||||
@@ -107,7 +107,7 @@ int SpriteBatch::add(Quad *quad, const Matrix4 &m, int index /*= -1*/)
|
|||||||
verts[i].color = color;
|
verts[i].color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
array_buf->setMappedRangeModified(offset, format_stride * 4);
|
array_buf->setMappedRangeModified(offset, vertex_stride * 4);
|
||||||
|
|
||||||
// Increment counter.
|
// Increment counter.
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
@@ -141,7 +141,7 @@ int SpriteBatch::addLayer(int layer, Quad *quad, const Matrix4 &m, int index)
|
|||||||
const Vector2 *quadtexcoords = quad->getVertexTexCoords();
|
const Vector2 *quadtexcoords = quad->getVertexTexCoords();
|
||||||
|
|
||||||
// Always keep the VBO mapped when adding data (it'll be unmapped on draw.)
|
// Always keep the VBO mapped when adding data (it'll be unmapped on draw.)
|
||||||
size_t offset = (index == -1 ? next : index) * format_stride * 4;
|
size_t offset = (index == -1 ? next : index) * vertex_stride * 4;
|
||||||
auto verts = (XYf_STPf_RGBAub *) ((uint8 *) array_buf->map() + offset);
|
auto verts = (XYf_STPf_RGBAub *) ((uint8 *) array_buf->map() + offset);
|
||||||
|
|
||||||
m.transformXY(verts, quadpositions, 4);
|
m.transformXY(verts, quadpositions, 4);
|
||||||
@@ -154,7 +154,7 @@ int SpriteBatch::addLayer(int layer, Quad *quad, const Matrix4 &m, int index)
|
|||||||
verts[i].color = color;
|
verts[i].color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
array_buf->setMappedRangeModified(offset, format_stride * 4);
|
array_buf->setMappedRangeModified(offset, vertex_stride * 4);
|
||||||
|
|
||||||
// Increment counter.
|
// Increment counter.
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
@@ -225,7 +225,7 @@ void SpriteBatch::setBufferSize(int newsize)
|
|||||||
if (newsize == size)
|
if (newsize == size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
size_t vertex_size = format_stride * 4 * newsize;
|
size_t vertex_size = vertex_stride * 4 * newsize;
|
||||||
love::graphics::Buffer *new_array_buf = nullptr;
|
love::graphics::Buffer *new_array_buf = nullptr;
|
||||||
|
|
||||||
int new_next = std::min(next, newsize);
|
int new_next = std::min(next, newsize);
|
||||||
@@ -236,7 +236,7 @@ void SpriteBatch::setBufferSize(int newsize)
|
|||||||
new_array_buf = gfx->newBuffer(vertex_size, nullptr, array_buf->getType(), array_buf->getUsage(), array_buf->getMapFlags());
|
new_array_buf = gfx->newBuffer(vertex_size, nullptr, array_buf->getType(), array_buf->getUsage(), array_buf->getMapFlags());
|
||||||
|
|
||||||
// Copy as much of the old data into the new GLBuffer as can fit.
|
// Copy as much of the old data into the new GLBuffer as can fit.
|
||||||
size_t copy_size = format_stride * 4 * new_next;
|
size_t copy_size = vertex_stride * 4 * new_next;
|
||||||
array_buf->copyTo(0, copy_size, new_array_buf, 0);
|
array_buf->copyTo(0, copy_size, new_array_buf, 0);
|
||||||
|
|
||||||
quad_indices = QuadIndices(gfx, newsize);
|
quad_indices = QuadIndices(gfx, newsize);
|
||||||
@@ -307,5 +307,59 @@ bool SpriteBatch::getDrawRange(int &start, int &count) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m)
|
||||||
|
{
|
||||||
|
using namespace vertex;
|
||||||
|
|
||||||
|
if (next == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gfx->flushStreamDraws();
|
||||||
|
|
||||||
|
if (texture.get())
|
||||||
|
{
|
||||||
|
if (Shader::isDefaultActive())
|
||||||
|
{
|
||||||
|
Shader::StandardShader defaultshader = Shader::STANDARD_DEFAULT;
|
||||||
|
if (texture->getTextureType() == TEXTURE_2D_ARRAY)
|
||||||
|
defaultshader = Shader::STANDARD_ARRAY;
|
||||||
|
|
||||||
|
Shader::attachDefault(defaultshader);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Shader::current)
|
||||||
|
Shader::current->checkMainTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the VBO isn't mapped when we draw (sends data to GPU if needed.)
|
||||||
|
array_buf->unmap();
|
||||||
|
|
||||||
|
CommonFormat format = vertex_format;
|
||||||
|
|
||||||
|
if (!color_active)
|
||||||
|
{
|
||||||
|
if (format == CommonFormat::XYf_STPf_RGBAub)
|
||||||
|
format = CommonFormat::XYf_STPf;
|
||||||
|
else
|
||||||
|
format = CommonFormat::XYf_STf;
|
||||||
|
}
|
||||||
|
|
||||||
|
int start = std::min(std::max(0, range_start), next - 1);
|
||||||
|
|
||||||
|
int count = next;
|
||||||
|
if (range_count > 0)
|
||||||
|
count = std::min(count, range_count);
|
||||||
|
|
||||||
|
count = std::min(count, next - start);
|
||||||
|
|
||||||
|
size_t indexbytestart = quad_indices.getIndexCount(start) * quad_indices.getElementSize();
|
||||||
|
size_t indexcount = quad_indices.getIndexCount(count);
|
||||||
|
|
||||||
|
Graphics::TempTransform transform(gfx, m);
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
drawInternal(format, indexbytestart, indexcount);
|
||||||
|
}
|
||||||
|
|
||||||
} // graphics
|
} // graphics
|
||||||
} // love
|
} // love
|
||||||
|
|||||||
@@ -29,9 +29,10 @@
|
|||||||
// LOVE
|
// LOVE
|
||||||
#include "common/math.h"
|
#include "common/math.h"
|
||||||
#include "common/Matrix.h"
|
#include "common/Matrix.h"
|
||||||
|
#include "common/Color.h"
|
||||||
#include "Drawable.h"
|
#include "Drawable.h"
|
||||||
#include "Color.h"
|
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
|
#include "vertex.h"
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
@@ -105,6 +106,9 @@ public:
|
|||||||
void setDrawRange();
|
void setDrawRange();
|
||||||
bool getDrawRange(int &start, int &count) const;
|
bool getDrawRange(int &start, int &count) const;
|
||||||
|
|
||||||
|
// Implements Drawable.
|
||||||
|
void draw(Graphics *gfx, const Matrix4 &m) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
struct AttachedAttribute
|
struct AttachedAttribute
|
||||||
@@ -119,6 +123,8 @@ protected:
|
|||||||
**/
|
**/
|
||||||
void setBufferSize(int newsize);
|
void setBufferSize(int newsize);
|
||||||
|
|
||||||
|
virtual void drawInternal(vertex::CommonFormat format, size_t indexbytestart, size_t indexcount) = 0;
|
||||||
|
|
||||||
StrongRef<Texture> texture;
|
StrongRef<Texture> texture;
|
||||||
|
|
||||||
// Max number of sprites in the batch.
|
// Max number of sprites in the batch.
|
||||||
@@ -133,7 +139,7 @@ protected:
|
|||||||
bool color_active;
|
bool color_active;
|
||||||
|
|
||||||
vertex::CommonFormat vertex_format;
|
vertex::CommonFormat vertex_format;
|
||||||
size_t format_stride;
|
size_t vertex_stride;
|
||||||
|
|
||||||
love::graphics::Buffer *array_buf;
|
love::graphics::Buffer *array_buf;
|
||||||
QuadIndices quad_indices;
|
QuadIndices quad_indices;
|
||||||
|
|||||||
@@ -235,5 +235,36 @@ int Text::getHeight(int index) const
|
|||||||
return text_data[index].text_info.height;
|
return text_data[index].text_info.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Text::draw(Graphics *gfx, const Matrix4 &m)
|
||||||
|
{
|
||||||
|
if (vbo == nullptr || draw_commands.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
gfx->flushStreamDraws();
|
||||||
|
|
||||||
|
if (Shader::isDefaultActive())
|
||||||
|
Shader::attachDefault(Shader::STANDARD_DEFAULT);
|
||||||
|
|
||||||
|
if (Shader::current)
|
||||||
|
Shader::current->checkMainTextureType(TEXTURE_2D, false);
|
||||||
|
|
||||||
|
// Re-generate the text if the Font's texture cache was invalidated.
|
||||||
|
if (font->getTextureCacheID() != texture_cache_id)
|
||||||
|
regenerateVertices();
|
||||||
|
|
||||||
|
int totalverts = 0;
|
||||||
|
for (const Font::DrawCommand &cmd : draw_commands)
|
||||||
|
totalverts = std::max(cmd.startvertex + cmd.vertexcount, totalverts);
|
||||||
|
|
||||||
|
if ((size_t) totalverts / 4 > quadIndices.getSize())
|
||||||
|
quadIndices = QuadIndices(gfx, (size_t) totalverts / 4);
|
||||||
|
|
||||||
|
vbo->unmap(); // Make sure all pending data is flushed to the GPU.
|
||||||
|
|
||||||
|
Graphics::TempTransform transform(gfx, m);
|
||||||
|
|
||||||
|
drawInternal(draw_commands);
|
||||||
|
}
|
||||||
|
|
||||||
} // graphics
|
} // graphics
|
||||||
} // love
|
} // love
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ public:
|
|||||||
**/
|
**/
|
||||||
int getHeight(int index = 0) const;
|
int getHeight(int index = 0) const;
|
||||||
|
|
||||||
|
// Implements Drawable.
|
||||||
|
void draw(love::graphics::Graphics *gfx, const Matrix4 &m) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
struct TextData
|
struct TextData
|
||||||
@@ -80,6 +83,8 @@ protected:
|
|||||||
void regenerateVertices();
|
void regenerateVertices();
|
||||||
void addTextData(const TextData &s);
|
void addTextData(const TextData &s);
|
||||||
|
|
||||||
|
virtual void drawInternal(const std::vector<Font::DrawCommand> &commands) const = 0;
|
||||||
|
|
||||||
StrongRef<Font> font;
|
StrongRef<Font> font;
|
||||||
Buffer *vbo;
|
Buffer *vbo;
|
||||||
QuadIndices quadIndices;
|
QuadIndices quadIndices;
|
||||||
|
|||||||
@@ -317,6 +317,63 @@ int Texture::getMipmapCount(int w, int h, int d)
|
|||||||
return (int) log2(std::max(std::max(w, h), d)) + 1;
|
return (int) log2(std::max(std::max(w, h), d)) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Texture::validateDimensions(bool throwException) const
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||||
|
if (gfx == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const Graphics::Capabilities &caps = gfx->getCapabilities();
|
||||||
|
|
||||||
|
int max2Dsize = (int) caps.limits[Graphics::LIMIT_TEXTURE_SIZE];
|
||||||
|
int max3Dsize = (int) caps.limits[Graphics::LIMIT_VOLUME_TEXTURE_SIZE];
|
||||||
|
int maxcubesize = (int) caps.limits[Graphics::LIMIT_CUBE_TEXTURE_SIZE];
|
||||||
|
int maxlayers = (int) caps.limits[Graphics::LIMIT_TEXTURE_LAYERS];
|
||||||
|
|
||||||
|
int largestdim = 0;
|
||||||
|
const char *largestname = nullptr;
|
||||||
|
|
||||||
|
if ((texType == TEXTURE_2D || texType == TEXTURE_2D_ARRAY) && (pixelWidth > max2Dsize || pixelHeight > max2Dsize))
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
largestdim = std::max(pixelWidth, pixelHeight);
|
||||||
|
largestname = pixelWidth > pixelHeight ? "pixel width" : "pixel height";
|
||||||
|
}
|
||||||
|
else if (texType == TEXTURE_2D_ARRAY && layers > maxlayers)
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
largestdim = layers;
|
||||||
|
largestname = "array layer count";
|
||||||
|
}
|
||||||
|
else if (texType == TEXTURE_CUBE && (pixelWidth > maxcubesize || pixelWidth != pixelHeight))
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
largestdim = std::max(pixelWidth, pixelHeight);
|
||||||
|
largestname = pixelWidth > pixelHeight ? "pixel width" : "pixel height";
|
||||||
|
|
||||||
|
if (throwException && pixelWidth != pixelHeight)
|
||||||
|
throw love::Exception("Cubemap textures must have equal width and height.");
|
||||||
|
}
|
||||||
|
else if (texType == TEXTURE_VOLUME && (pixelWidth > max3Dsize || pixelHeight > max3Dsize || depth > max3Dsize))
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
largestdim = std::max(std::max(pixelWidth, pixelHeight), depth);
|
||||||
|
if (largestdim == pixelWidth)
|
||||||
|
largestname = "pixel width";
|
||||||
|
else if (largestdim == pixelHeight)
|
||||||
|
largestname = "pixel height";
|
||||||
|
else
|
||||||
|
largestname = "pixel depth";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (throwException && largestname != nullptr)
|
||||||
|
throw love::Exception("Cannot create texture: %s of %d is too large for this system.", largestname, largestdim);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
bool Texture::getConstant(const char *in, TextureType &out)
|
bool Texture::getConstant(const char *in, TextureType &out)
|
||||||
{
|
{
|
||||||
return texTypes.find(in, out);
|
return texTypes.find(in, out);
|
||||||
|
|||||||
@@ -174,6 +174,8 @@ protected:
|
|||||||
void initQuad();
|
void initQuad();
|
||||||
void setGraphicsMemorySize(int64 size);
|
void setGraphicsMemorySize(int64 size);
|
||||||
|
|
||||||
|
bool validateDimensions(bool throwException) const;
|
||||||
|
|
||||||
TextureType texType;
|
TextureType texType;
|
||||||
|
|
||||||
PixelFormat format;
|
PixelFormat format;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#define LOVE_GRAPHICS_OPENGL_CANVAS_H
|
#define LOVE_GRAPHICS_OPENGL_CANVAS_H
|
||||||
|
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
#include "graphics/Color.h"
|
#include "common/Color.h"
|
||||||
#include "common/int.h"
|
#include "common/int.h"
|
||||||
#include "graphics/Canvas.h"
|
#include "graphics/Canvas.h"
|
||||||
#include "graphics/Volatile.h"
|
#include "graphics/Volatile.h"
|
||||||
|
|||||||
@@ -492,107 +492,9 @@ void Graphics::setDebug(bool enable)
|
|||||||
::printf("OpenGL debug output enabled (LOVE_GRAPHICS_DEBUG=1)\n");
|
::printf("OpenGL debug output enabled (LOVE_GRAPHICS_DEBUG=1)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::setCanvas(const RenderTargets &rts)
|
void Graphics::setCanvasInternal(const RenderTargets &rts, int w, int h, int pixelw, int pixelh, bool hasSRGBcanvas)
|
||||||
{
|
{
|
||||||
DisplayState &state = states.back();
|
const DisplayState &state = states.back();
|
||||||
int ncanvases = (int) rts.colors.size();
|
|
||||||
|
|
||||||
if (ncanvases == 0 && rts.depthStencil.canvas == nullptr)
|
|
||||||
return setCanvas();
|
|
||||||
else if (ncanvases == 0)
|
|
||||||
throw love::Exception("At least one color render target is required when using a custom depth/stencil buffer.");
|
|
||||||
|
|
||||||
const auto &prevRTs = state.renderTargets;
|
|
||||||
|
|
||||||
if (ncanvases == (int) prevRTs.colors.size())
|
|
||||||
{
|
|
||||||
bool modified = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < ncanvases; i++)
|
|
||||||
{
|
|
||||||
if (rts.colors[i].canvas != prevRTs.colors[i].canvas.get()
|
|
||||||
|| rts.colors[i].slice != prevRTs.colors[i].slice
|
|
||||||
|| rts.colors[i].mipmap != prevRTs.colors[i].mipmap)
|
|
||||||
{
|
|
||||||
modified = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!modified && (rts.depthStencil.canvas != prevRTs.depthStencil.canvas
|
|
||||||
|| rts.depthStencil.slice != prevRTs.depthStencil.slice
|
|
||||||
|| rts.depthStencil.mipmap != prevRTs.depthStencil.mipmap))
|
|
||||||
{
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rts.temporaryRTFlags != prevRTs.temporaryRTFlags)
|
|
||||||
modified = true;
|
|
||||||
|
|
||||||
if (!modified)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ncanvases > gl.getMaxRenderTargets())
|
|
||||||
throw love::Exception("This system can't simultaneously render to %d canvases.", ncanvases);
|
|
||||||
|
|
||||||
love::graphics::Canvas *firstcanvas = rts.colors[0].canvas;
|
|
||||||
|
|
||||||
bool multiformatsupported = Canvas::isMultiFormatMultiCanvasSupported();
|
|
||||||
PixelFormat firstformat = firstcanvas->getPixelFormat();
|
|
||||||
|
|
||||||
if (isPixelFormatDepthStencil(firstformat))
|
|
||||||
throw love::Exception("Depth/stencil format Canvases must be used with the 'depthstencil' field of the table passed into setCanvas.");
|
|
||||||
|
|
||||||
if (rts.colors[0].mipmap < 0 || rts.colors[0].mipmap >= firstcanvas->getMipmapCount())
|
|
||||||
throw love::Exception("Invalid mipmap level %d.", rts.colors[0].mipmap + 1);
|
|
||||||
|
|
||||||
bool hasSRGBcanvas = firstformat == PIXELFORMAT_sRGBA8;
|
|
||||||
int pixelwidth = firstcanvas->getPixelWidth(rts.colors[0].mipmap);
|
|
||||||
int pixelheight = firstcanvas->getPixelHeight(rts.colors[0].mipmap);
|
|
||||||
|
|
||||||
for (int i = 1; i < ncanvases; i++)
|
|
||||||
{
|
|
||||||
love::graphics::Canvas *c = rts.colors[i].canvas;
|
|
||||||
PixelFormat format = c->getPixelFormat();
|
|
||||||
int mip = rts.colors[i].mipmap;
|
|
||||||
|
|
||||||
if (mip < 0 || mip >= c->getMipmapCount())
|
|
||||||
throw love::Exception("Invalid mipmap level %d.", mip + 1);
|
|
||||||
|
|
||||||
if (c->getPixelWidth(mip) != pixelwidth || c->getPixelHeight(mip) != pixelheight)
|
|
||||||
throw love::Exception("All canvases must have the same pixel dimensions.");
|
|
||||||
|
|
||||||
if (!multiformatsupported && format != firstformat)
|
|
||||||
throw love::Exception("This system doesn't support multi-canvas rendering with different canvas formats.");
|
|
||||||
|
|
||||||
if (c->getRequestedMSAA() != firstcanvas->getRequestedMSAA())
|
|
||||||
throw love::Exception("All Canvases must have the same MSAA value.");
|
|
||||||
|
|
||||||
if (isPixelFormatDepthStencil(format))
|
|
||||||
throw love::Exception("Depth/stencil format Canvases must be used with the 'depthstencil' field of the table passed into setCanvas.");
|
|
||||||
|
|
||||||
if (format == PIXELFORMAT_sRGBA8)
|
|
||||||
hasSRGBcanvas = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rts.depthStencil.canvas != nullptr)
|
|
||||||
{
|
|
||||||
love::graphics::Canvas *c = rts.depthStencil.canvas;
|
|
||||||
int mip = rts.depthStencil.mipmap;
|
|
||||||
|
|
||||||
if (!isPixelFormatDepthStencil(c->getPixelFormat()))
|
|
||||||
throw love::Exception("Only depth/stencil format Canvases can be used with the 'depthstencil' field of the table passed into setCanvas.");
|
|
||||||
|
|
||||||
if (c->getPixelWidth(mip) != pixelwidth || c->getPixelHeight(mip) != pixelheight)
|
|
||||||
throw love::Exception("All canvases must have the same pixel dimensions.");
|
|
||||||
|
|
||||||
if (c->getRequestedMSAA() != firstcanvas->getRequestedMSAA())
|
|
||||||
throw love::Exception("All Canvases must have the same MSAA value.");
|
|
||||||
|
|
||||||
if (mip < 0 || mip >= c->getMipmapCount())
|
|
||||||
throw love::Exception("Invalid mipmap level %d.", mip + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenGL::TempDebugGroup debuggroup("setCanvas(...)");
|
OpenGL::TempDebugGroup debuggroup("setCanvas(...)");
|
||||||
|
|
||||||
@@ -600,15 +502,13 @@ void Graphics::setCanvas(const RenderTargets &rts)
|
|||||||
|
|
||||||
bindCachedFBO(rts);
|
bindCachedFBO(rts);
|
||||||
|
|
||||||
gl.setViewport({0, 0, pixelwidth, pixelheight});
|
gl.setViewport({0, 0, pixelw, pixelh});
|
||||||
|
|
||||||
// Re-apply the scissor if it was active, since the rectangle passed to
|
// Re-apply the scissor if it was active, since the rectangle passed to
|
||||||
// glScissor is affected by the viewport dimensions.
|
// glScissor is affected by the viewport dimensions.
|
||||||
if (state.scissor)
|
if (state.scissor)
|
||||||
setScissor(state.scissorRect);
|
setScissor(state.scissorRect);
|
||||||
|
|
||||||
int w = firstcanvas->getWidth(rts.colors[0].mipmap);
|
|
||||||
int h = firstcanvas->getHeight(rts.colors[0].mipmap);
|
|
||||||
projectionMatrix = Matrix4::ortho(0.0, (float) w, 0.0, (float) h);
|
projectionMatrix = Matrix4::ortho(0.0, (float) w, 0.0, (float) h);
|
||||||
|
|
||||||
// Make sure the correct sRGB setting is used when drawing to the canvases.
|
// Make sure the correct sRGB setting is used when drawing to the canvases.
|
||||||
@@ -619,19 +519,6 @@ void Graphics::setCanvas(const RenderTargets &rts)
|
|||||||
else if (!hasSRGBcanvas && gl.hasFramebufferSRGB())
|
else if (!hasSRGBcanvas && gl.hasFramebufferSRGB())
|
||||||
gl.setFramebufferSRGB(false);
|
gl.setFramebufferSRGB(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderTargetsStrongRef refs;
|
|
||||||
refs.colors.reserve(rts.colors.size());
|
|
||||||
|
|
||||||
for (auto c : rts.colors)
|
|
||||||
refs.colors.emplace_back(c.canvas, c.slice);
|
|
||||||
|
|
||||||
refs.depthStencil = RenderTargetStrongRef(rts.depthStencil.canvas, rts.depthStencil.slice);
|
|
||||||
refs.temporaryRTFlags = rts.temporaryRTFlags;
|
|
||||||
|
|
||||||
std::swap(state.renderTargets, refs);
|
|
||||||
|
|
||||||
canvasSwitchCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::setCanvas()
|
void Graphics::setCanvas()
|
||||||
@@ -643,6 +530,7 @@ void Graphics::setCanvas()
|
|||||||
|
|
||||||
OpenGL::TempDebugGroup debuggroup("setCanvas()");
|
OpenGL::TempDebugGroup debuggroup("setCanvas()");
|
||||||
|
|
||||||
|
flushStreamDraws();
|
||||||
endPass();
|
endPass();
|
||||||
|
|
||||||
state.renderTargets = RenderTargetsStrongRef();
|
state.renderTargets = RenderTargetsStrongRef();
|
||||||
@@ -673,8 +561,6 @@ void Graphics::setCanvas()
|
|||||||
|
|
||||||
void Graphics::endPass()
|
void Graphics::endPass()
|
||||||
{
|
{
|
||||||
flushStreamDraws();
|
|
||||||
|
|
||||||
auto &rts = states.back().renderTargets;
|
auto &rts = states.back().renderTargets;
|
||||||
love::graphics::Canvas *depthstencil = rts.depthStencil.canvas.get();
|
love::graphics::Canvas *depthstencil = rts.depthStencil.canvas.get();
|
||||||
|
|
||||||
@@ -1013,6 +899,7 @@ void Graphics::present(void *screenshotCallbackData)
|
|||||||
if (isCanvasActive())
|
if (isCanvasActive())
|
||||||
throw love::Exception("present cannot be called while a Canvas is active.");
|
throw love::Exception("present cannot be called while a Canvas is active.");
|
||||||
|
|
||||||
|
flushStreamDraws();
|
||||||
endPass();
|
endPass();
|
||||||
|
|
||||||
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, gl.getDefaultFBO());
|
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, gl.getDefaultFBO());
|
||||||
@@ -1123,6 +1010,7 @@ void Graphics::present(void *screenshotCallbackData)
|
|||||||
gl.stats.drawCalls = 0;
|
gl.stats.drawCalls = 0;
|
||||||
gl.stats.shaderSwitches = 0;
|
gl.stats.shaderSwitches = 0;
|
||||||
canvasSwitchCount = 0;
|
canvasSwitchCount = 0;
|
||||||
|
drawCallsBatched = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::setScissor(const Rect &rect)
|
void Graphics::setScissor(const Rect &rect)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
// LOVE
|
// LOVE
|
||||||
#include "graphics/Graphics.h"
|
#include "graphics/Graphics.h"
|
||||||
#include "graphics/Color.h"
|
#include "common/Color.h"
|
||||||
|
|
||||||
#include "image/Image.h"
|
#include "image/Image.h"
|
||||||
#include "image/ImageData.h"
|
#include "image/ImageData.h"
|
||||||
@@ -97,7 +97,6 @@ public:
|
|||||||
|
|
||||||
void setColor(Colorf c) override;
|
void setColor(Colorf c) override;
|
||||||
|
|
||||||
void setCanvas(const RenderTargets &rts) override;
|
|
||||||
void setCanvas() override;
|
void setCanvas() override;
|
||||||
|
|
||||||
void setScissor(const Rect &rect) override;
|
void setScissor(const Rect &rect) override;
|
||||||
@@ -128,6 +127,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
love::graphics::StreamBuffer *newStreamBuffer(BufferType type, size_t size) override;
|
love::graphics::StreamBuffer *newStreamBuffer(BufferType type, size_t size) override;
|
||||||
|
void setCanvasInternal(const RenderTargets &rts, int w, int h, int pixelw, int pixelh, bool hasSRGBcanvas) override;
|
||||||
void initCapabilities() override;
|
void initCapabilities() override;
|
||||||
void getAPIStats(int &drawcalls, int &shaderswitches) const override;
|
void getAPIStats(int &drawcalls, int &shaderswitches) const override;
|
||||||
|
|
||||||
|
|||||||
@@ -221,22 +221,8 @@ bool Image::loadVolatile()
|
|||||||
glGenTextures(1, &texture);
|
glGenTextures(1, &texture);
|
||||||
gl.bindTextureToUnit(this, 0, false);
|
gl.bindTextureToUnit(this, 0, false);
|
||||||
|
|
||||||
bool loaddefault = false;
|
|
||||||
|
|
||||||
int max2Dsize = gl.getMax2DTextureSize();
|
|
||||||
int max3Dsize = gl.getMax3DTextureSize();
|
|
||||||
|
|
||||||
if ((texType == TEXTURE_2D || texType == TEXTURE_2D_ARRAY) && (pixelWidth > max2Dsize || pixelHeight > max2Dsize))
|
|
||||||
loaddefault = true;
|
|
||||||
else if (texType == TEXTURE_2D_ARRAY && layers > gl.getMaxTextureLayers())
|
|
||||||
loaddefault = true;
|
|
||||||
else if (texType == TEXTURE_CUBE && (pixelWidth > gl.getMaxCubeTextureSize() || pixelWidth != pixelHeight))
|
|
||||||
loaddefault = true;
|
|
||||||
else if (texType == TEXTURE_VOLUME && (pixelWidth > max3Dsize || pixelHeight > max3Dsize || depth > max3Dsize))
|
|
||||||
loaddefault = true;
|
|
||||||
|
|
||||||
// Use a default texture if the size is too big for the system.
|
// Use a default texture if the size is too big for the system.
|
||||||
if (loaddefault)
|
if (!validateDimensions(false))
|
||||||
{
|
{
|
||||||
loadDefaultTexture();
|
loadDefaultTexture();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -91,94 +91,28 @@ int Mesh::bindAttributeToShaderInput(int attributeindex, const std::string &inpu
|
|||||||
return attriblocation;
|
return attriblocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::drawInstanced(love::graphics::Graphics *gfx, const love::Matrix4 &m, int instancecount)
|
void Mesh::drawInternal(int start, int count, int instancecount, bool useindexbuffer, uint32 attribflags, uint32 instancedattribflags) const
|
||||||
{
|
{
|
||||||
if (vertexCount <= 0 || instancecount <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (instancecount > 1 && !gl.isInstancingSupported())
|
|
||||||
throw love::Exception("Instancing is not supported on this system.");
|
|
||||||
|
|
||||||
gfx->flushStreamDraws();
|
|
||||||
|
|
||||||
if (Shader::isDefaultActive())
|
|
||||||
Shader::attachDefault(Shader::STANDARD_DEFAULT);
|
|
||||||
|
|
||||||
if (Shader::current && texture.get())
|
|
||||||
Shader::current->checkMainTexture(texture);
|
|
||||||
|
|
||||||
OpenGL::TempDebugGroup debuggroup("Mesh draw");
|
OpenGL::TempDebugGroup debuggroup("Mesh draw");
|
||||||
|
|
||||||
uint32 enabledattribs = 0;
|
gl.useVertexAttribArrays(attribflags, instancedattribflags);
|
||||||
uint32 instancedattribs = 0;
|
|
||||||
|
|
||||||
for (const auto &attrib : attachedAttributes)
|
|
||||||
{
|
|
||||||
if (!attrib.second.enabled)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
love::graphics::Mesh *mesh = attrib.second.mesh;
|
|
||||||
int location = mesh->bindAttributeToShaderInput(attrib.second.index, attrib.first);
|
|
||||||
|
|
||||||
if (location >= 0)
|
|
||||||
{
|
|
||||||
uint32 bit = 1u << (uint32) location;
|
|
||||||
|
|
||||||
enabledattribs |= bit;
|
|
||||||
|
|
||||||
if (attrib.second.step == STEP_PER_INSTANCE)
|
|
||||||
instancedattribs |= bit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not supported on all platforms or GL versions, I believe.
|
|
||||||
if (!(enabledattribs & ATTRIBFLAG_POS))
|
|
||||||
throw love::Exception("Mesh must have an enabled VertexPosition attribute to be drawn.");
|
|
||||||
|
|
||||||
gl.useVertexAttribArrays(enabledattribs, instancedattribs);
|
|
||||||
|
|
||||||
gl.bindTextureToUnit(texture, 0, false);
|
gl.bindTextureToUnit(texture, 0, false);
|
||||||
|
|
||||||
Graphics::TempTransform transform(gfx, m);
|
|
||||||
|
|
||||||
gl.prepareDraw();
|
gl.prepareDraw();
|
||||||
|
|
||||||
if (useIndexBuffer && ibo && elementCount > 0)
|
GLenum gldrawmode = getGLDrawMode(drawMode);
|
||||||
|
|
||||||
|
if (useindexbuffer)
|
||||||
{
|
{
|
||||||
// Use the custom vertex map (index buffer) to draw the vertices.
|
|
||||||
gl.bindBuffer(BUFFER_INDEX, (GLuint) ibo->getHandle());
|
|
||||||
|
|
||||||
// Make sure the index buffer isn't mapped (sends data to GPU if needed.)
|
|
||||||
ibo->unmap();
|
|
||||||
|
|
||||||
int start = std::min(std::max(0, rangeStart), (int) elementCount - 1);
|
|
||||||
|
|
||||||
int count = (int) elementCount;
|
|
||||||
if (rangeCount > 0)
|
|
||||||
count = std::min(count, rangeCount);
|
|
||||||
|
|
||||||
count = std::min(count, (int) elementCount - start);
|
|
||||||
|
|
||||||
size_t elementsize = vertex::getIndexDataSize(elementDataType);
|
size_t elementsize = vertex::getIndexDataSize(elementDataType);
|
||||||
const void *indices = BUFFER_OFFSET(start * elementsize);
|
const void *indices = BUFFER_OFFSET(start * elementsize);
|
||||||
GLenum type = OpenGL::getGLIndexDataType(elementDataType);
|
GLenum type = OpenGL::getGLIndexDataType(elementDataType);
|
||||||
|
|
||||||
if (count > 0)
|
gl.bindBuffer(BUFFER_INDEX, (GLuint) ibo->getHandle());
|
||||||
gl.drawElements(getGLDrawMode(drawMode), count, type, indices, instancecount);
|
gl.drawElements(gldrawmode, count, type, indices, instancecount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int start = std::min(std::max(0, rangeStart), (int) vertexCount - 1);
|
gl.drawArrays(gldrawmode, start, count, instancecount);
|
||||||
|
|
||||||
int count = (int) vertexCount;
|
|
||||||
if (rangeCount > 0)
|
|
||||||
count = std::min(count, rangeCount);
|
|
||||||
|
|
||||||
count = std::min(count, (int) vertexCount - start);
|
|
||||||
|
|
||||||
// Normal non-indexed drawing (no custom vertex map.)
|
|
||||||
if (count > 0)
|
|
||||||
gl.drawArrays(getGLDrawMode(drawMode), start, count, instancecount);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,10 @@ public:
|
|||||||
virtual ~Mesh();
|
virtual ~Mesh();
|
||||||
|
|
||||||
int bindAttributeToShaderInput(int attributeindex, const std::string &inputname) override;
|
int bindAttributeToShaderInput(int attributeindex, const std::string &inputname) override;
|
||||||
void drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount) override;
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void drawInternal(int start, int count, int instancecount, bool useindexbuffer, uint32 attribflags, uint32 instancedattribflags) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -261,7 +261,8 @@ void OpenGL::initVendor()
|
|||||||
|
|
||||||
// http://feedback.wildfiregames.com/report/opengl/feature/GL_VENDOR
|
// http://feedback.wildfiregames.com/report/opengl/feature/GL_VENDOR
|
||||||
// http://stackoverflow.com/questions/2093594/opengl-extensions-available-on-different-android-devices
|
// http://stackoverflow.com/questions/2093594/opengl-extensions-available-on-different-android-devices
|
||||||
if (strstr(vstr, "ATI Technologies"))
|
// http://opengl.gpuinfo.org/gl_stats_caps_single.php?listreportsbycap=GL_VENDOR
|
||||||
|
if (strstr(vstr, "ATI Technologies") || strstr(vstr, "AMD") || strstr(vstr, "Advanced Micro Devices"))
|
||||||
vendor = VENDOR_AMD;
|
vendor = VENDOR_AMD;
|
||||||
else if (strstr(vstr, "NVIDIA"))
|
else if (strstr(vstr, "NVIDIA"))
|
||||||
vendor = VENDOR_NVIDIA;
|
vendor = VENDOR_NVIDIA;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
#include "common/int.h"
|
#include "common/int.h"
|
||||||
#include "common/math.h"
|
#include "common/math.h"
|
||||||
#include "graphics/Color.h"
|
#include "common/Color.h"
|
||||||
#include "graphics/Texture.h"
|
#include "graphics/Texture.h"
|
||||||
#include "graphics/vertex.h"
|
#include "graphics/vertex.h"
|
||||||
#include "graphics/depthstencil.h"
|
#include "graphics/depthstencil.h"
|
||||||
|
|||||||
@@ -50,21 +50,10 @@ ParticleSystem *ParticleSystem::clone()
|
|||||||
return new ParticleSystem(*this);
|
return new ParticleSystem(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleSystem::draw(Graphics *gfx, const Matrix4 &m)
|
void ParticleSystem::drawInternal() const
|
||||||
{
|
{
|
||||||
using namespace vertex;
|
using namespace vertex;
|
||||||
|
|
||||||
if (!prepareDraw(gfx))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Graphics::TempTransform transform(gfx, m);
|
|
||||||
|
|
||||||
if (Shader::isDefaultActive())
|
|
||||||
Shader::attachDefault(Shader::STANDARD_DEFAULT);
|
|
||||||
|
|
||||||
if (Shader::current && texture.get())
|
|
||||||
Shader::current->checkMainTexture(texture);
|
|
||||||
|
|
||||||
OpenGL::TempDebugGroup debuggroup("ParticleSystem draw");
|
OpenGL::TempDebugGroup debuggroup("ParticleSystem draw");
|
||||||
|
|
||||||
gl.bindTextureToUnit(texture, 0, false);
|
gl.bindTextureToUnit(texture, 0, false);
|
||||||
|
|||||||
@@ -44,7 +44,10 @@ public:
|
|||||||
virtual ~ParticleSystem();
|
virtual ~ParticleSystem();
|
||||||
|
|
||||||
ParticleSystem *clone() override;
|
ParticleSystem *clone() override;
|
||||||
void draw(Graphics *gfx, const Matrix4 &m) override;
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void drawInternal() const override;
|
||||||
|
|
||||||
}; // ParticleSystem
|
}; // ParticleSystem
|
||||||
|
|
||||||
|
|||||||
@@ -855,14 +855,14 @@ void Shader::updateBuiltinUniforms()
|
|||||||
// Only upload the matrices if they've changed.
|
// Only upload the matrices if they've changed.
|
||||||
if (memcmp(curxform.getElements(), lastTransformMatrix.getElements(), sizeof(float) * 16) != 0)
|
if (memcmp(curxform.getElements(), lastTransformMatrix.getElements(), sizeof(float) * 16) != 0)
|
||||||
{
|
{
|
||||||
GLint location = builtinUniforms[BUILTIN_MATRIX_TRANSFORM];
|
GLint location = builtinUniforms[BUILTIN_MATRIX_VIEW_FROM_LOCAL];
|
||||||
if (location >= 0)
|
if (location >= 0)
|
||||||
glUniformMatrix4fv(location, 1, GL_FALSE, curxform.getElements());
|
glUniformMatrix4fv(location, 1, GL_FALSE, curxform.getElements());
|
||||||
|
|
||||||
// Also upload the re-calculated normal matrix, if possible. The normal
|
// Also upload the re-calculated normal matrix, if possible. The normal
|
||||||
// matrix is the transpose of the inverse of the rotation portion
|
// matrix is the transpose of the inverse of the rotation portion
|
||||||
// (top-left 3x3) of the transform matrix.
|
// (top-left 3x3) of the transform matrix.
|
||||||
location = builtinUniforms[BUILTIN_MATRIX_NORMAL];
|
location = builtinUniforms[BUILTIN_MATRIX_VIEW_NORMAL_FROM_LOCAL];
|
||||||
if (location >= 0)
|
if (location >= 0)
|
||||||
{
|
{
|
||||||
Matrix3 normalmatrix = Matrix3(curxform).transposedInverse();
|
Matrix3 normalmatrix = Matrix3(curxform).transposedInverse();
|
||||||
@@ -875,7 +875,7 @@ void Shader::updateBuiltinUniforms()
|
|||||||
|
|
||||||
if (memcmp(curproj.getElements(), lastProjectionMatrix.getElements(), sizeof(float) * 16) != 0)
|
if (memcmp(curproj.getElements(), lastProjectionMatrix.getElements(), sizeof(float) * 16) != 0)
|
||||||
{
|
{
|
||||||
GLint location = builtinUniforms[BUILTIN_MATRIX_PROJECTION];
|
GLint location = builtinUniforms[BUILTIN_MATRIX_CLIP_FROM_VIEW];
|
||||||
if (location >= 0)
|
if (location >= 0)
|
||||||
glUniformMatrix4fv(location, 1, GL_FALSE, curproj.getElements());
|
glUniformMatrix4fv(location, 1, GL_FALSE, curproj.getElements());
|
||||||
|
|
||||||
@@ -885,7 +885,7 @@ void Shader::updateBuiltinUniforms()
|
|||||||
|
|
||||||
if (tpmatrixneedsupdate)
|
if (tpmatrixneedsupdate)
|
||||||
{
|
{
|
||||||
GLint location = builtinUniforms[BUILTIN_MATRIX_TRANSFORM_PROJECTION];
|
GLint location = builtinUniforms[BUILTIN_MATRIX_CLIP_FROM_LOCAL];
|
||||||
if (location >= 0)
|
if (location >= 0)
|
||||||
{
|
{
|
||||||
Matrix4 tp_matrix(curproj, curxform);
|
Matrix4 tp_matrix(curproj, curxform);
|
||||||
|
|||||||
@@ -51,52 +51,15 @@ SpriteBatch::~SpriteBatch()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m)
|
void SpriteBatch::drawInternal(vertex::CommonFormat format, size_t indexbytestart, size_t indexcount)
|
||||||
{
|
{
|
||||||
using namespace vertex;
|
|
||||||
|
|
||||||
if (next == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
gfx->flushStreamDraws();
|
|
||||||
|
|
||||||
if (texture.get())
|
|
||||||
{
|
|
||||||
if (Shader::isDefaultActive())
|
|
||||||
{
|
|
||||||
Shader::StandardShader defaultshader = Shader::STANDARD_DEFAULT;
|
|
||||||
if (texture->getTextureType() == TEXTURE_2D_ARRAY)
|
|
||||||
defaultshader = Shader::STANDARD_ARRAY;
|
|
||||||
|
|
||||||
Shader::attachDefault(defaultshader);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Shader::current)
|
|
||||||
Shader::current->checkMainTexture(texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenGL::TempDebugGroup debuggroup("SpriteBatch draw");
|
OpenGL::TempDebugGroup debuggroup("SpriteBatch draw");
|
||||||
|
|
||||||
Graphics::TempTransform transform(gfx, m);
|
|
||||||
|
|
||||||
gl.bindTextureToUnit(texture, 0, false);
|
|
||||||
|
|
||||||
// Make sure the VBO isn't mapped when we draw (sends data to GPU if needed.)
|
|
||||||
array_buf->unmap();
|
|
||||||
|
|
||||||
CommonFormat format = vertex_format;
|
|
||||||
|
|
||||||
if (!color_active)
|
|
||||||
{
|
|
||||||
if (format == CommonFormat::XYf_STPf_RGBAub)
|
|
||||||
format = CommonFormat::XYf_STPf;
|
|
||||||
else
|
|
||||||
format = CommonFormat::XYf_STf;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 enabledattribs = getFormatFlags(format);
|
uint32 enabledattribs = getFormatFlags(format);
|
||||||
|
|
||||||
gl.setVertexPointers(format, array_buf, format_stride, 0);
|
// We want attached attributes to override local attributes, so we should
|
||||||
|
// call this before binding attached attributes.
|
||||||
|
gl.setVertexPointers(format, array_buf, vertex_stride, 0);
|
||||||
|
|
||||||
for (const auto &it : attached_attributes)
|
for (const auto &it : attached_attributes)
|
||||||
{
|
{
|
||||||
@@ -114,26 +77,16 @@ void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gl.useVertexAttribArrays(enabledattribs);
|
gl.useVertexAttribArrays(enabledattribs);
|
||||||
|
gl.bindTextureToUnit(texture, 0, false);
|
||||||
|
|
||||||
gl.prepareDraw();
|
gl.prepareDraw();
|
||||||
|
|
||||||
int start = std::min(std::max(0, range_start), next - 1);
|
gl.bindBuffer(BUFFER_INDEX, (GLuint) quad_indices.getBuffer()->getHandle());
|
||||||
|
|
||||||
int count = next;
|
const void *indices = BUFFER_OFFSET(indexbytestart);
|
||||||
if (range_count > 0)
|
GLenum gltype = OpenGL::getGLIndexDataType(quad_indices.getType());
|
||||||
count = std::min(count, range_count);
|
|
||||||
|
|
||||||
count = std::min(count, next - start);
|
gl.drawElements(GL_TRIANGLES, (GLsizei) indexcount, gltype, indices);
|
||||||
|
|
||||||
if (count > 0)
|
|
||||||
{
|
|
||||||
gl.bindBuffer(BUFFER_INDEX, (GLuint) quad_indices.getBuffer()->getHandle());
|
|
||||||
|
|
||||||
const void *indices = BUFFER_OFFSET(start * quad_indices.getElementSize());
|
|
||||||
GLenum gltype = OpenGL::getGLIndexDataType(quad_indices.getType());
|
|
||||||
|
|
||||||
gl.drawElements(GL_TRIANGLES, (GLsizei) quad_indices.getIndexCount(count), gltype, indices);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // opengl
|
} // opengl
|
||||||
|
|||||||
@@ -37,8 +37,9 @@ public:
|
|||||||
SpriteBatch(Graphics *gfx, Texture *texture, int size, vertex::Usage usage);
|
SpriteBatch(Graphics *gfx, Texture *texture, int size, vertex::Usage usage);
|
||||||
virtual ~SpriteBatch();
|
virtual ~SpriteBatch();
|
||||||
|
|
||||||
// Implements Drawable.
|
protected:
|
||||||
void draw(Graphics *gfx, const Matrix4 &m) override;
|
|
||||||
|
void drawInternal(vertex::CommonFormat format, size_t indexbytestart, size_t indexcount) override;
|
||||||
|
|
||||||
}; // SpriteBatch
|
}; // SpriteBatch
|
||||||
|
|
||||||
|
|||||||
@@ -40,36 +40,10 @@ Text::~Text()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::draw(Graphics *gfx, const Matrix4 &m)
|
void Text::drawInternal(const std::vector<Font::DrawCommand> &commands) const
|
||||||
{
|
{
|
||||||
if (vbo == nullptr || draw_commands.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
gfx->flushStreamDraws();
|
|
||||||
|
|
||||||
if (Shader::isDefaultActive())
|
|
||||||
Shader::attachDefault(Shader::STANDARD_DEFAULT);
|
|
||||||
|
|
||||||
if (Shader::current)
|
|
||||||
Shader::current->checkMainTextureType(TEXTURE_2D, false);
|
|
||||||
|
|
||||||
OpenGL::TempDebugGroup debuggroup("Text object draw");
|
OpenGL::TempDebugGroup debuggroup("Text object draw");
|
||||||
|
|
||||||
// Re-generate the text if the Font's texture cache was invalidated.
|
|
||||||
if (font->getTextureCacheID() != texture_cache_id)
|
|
||||||
regenerateVertices();
|
|
||||||
|
|
||||||
int totalverts = 0;
|
|
||||||
for (const Font::DrawCommand &cmd : draw_commands)
|
|
||||||
totalverts = std::max(cmd.startvertex + cmd.vertexcount, totalverts);
|
|
||||||
|
|
||||||
if ((size_t) totalverts / 4 > quadIndices.getSize())
|
|
||||||
quadIndices = QuadIndices(gfx, (size_t) totalverts / 4);
|
|
||||||
|
|
||||||
vbo->unmap(); // Make sure all pending data is flushed to the GPU.
|
|
||||||
|
|
||||||
Graphics::TempTransform transform(gfx, m);
|
|
||||||
|
|
||||||
gl.prepareDraw();
|
gl.prepareDraw();
|
||||||
|
|
||||||
gl.setVertexPointers(Font::vertexFormat, vbo, 0);
|
gl.setVertexPointers(Font::vertexFormat, vbo, 0);
|
||||||
@@ -82,14 +56,12 @@ void Text::draw(Graphics *gfx, const Matrix4 &m)
|
|||||||
|
|
||||||
// We need a separate draw call for every section of the text which uses a
|
// We need a separate draw call for every section of the text which uses a
|
||||||
// different texture than the previous section.
|
// different texture than the previous section.
|
||||||
for (const Font::DrawCommand &cmd : draw_commands)
|
for (const Font::DrawCommand &cmd : commands)
|
||||||
{
|
{
|
||||||
GLsizei count = (cmd.vertexcount / 4) * 6;
|
GLsizei count = (cmd.vertexcount / 4) * 6;
|
||||||
size_t offset = (cmd.startvertex / 4) * 6 * elemsize;
|
size_t offset = (cmd.startvertex / 4) * 6 * elemsize;
|
||||||
|
|
||||||
// TODO: Use glDrawElementsBaseVertex when supported?
|
|
||||||
gl.bindTextureToUnit(cmd.texture, 0, false);
|
gl.bindTextureToUnit(cmd.texture, 0, false);
|
||||||
|
|
||||||
gl.drawElements(GL_TRIANGLES, count, gltype, BUFFER_OFFSET(offset));
|
gl.drawElements(GL_TRIANGLES, count, gltype, BUFFER_OFFSET(offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,9 @@ public:
|
|||||||
Text(love::graphics::Graphics *gfx, love::graphics::Font *font, const std::vector<Font::ColoredString> &text = {});
|
Text(love::graphics::Graphics *gfx, love::graphics::Font *font, const std::vector<Font::ColoredString> &text = {});
|
||||||
virtual ~Text();
|
virtual ~Text();
|
||||||
|
|
||||||
// Implements Drawable.
|
protected:
|
||||||
void draw(love::graphics::Graphics *gfx, const Matrix4 &m) override;
|
|
||||||
|
void drawInternal(const std::vector<Font::DrawCommand> &commands) const override;
|
||||||
|
|
||||||
}; // Text
|
}; // Text
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
// LOVE
|
// LOVE
|
||||||
#include "common/int.h"
|
#include "common/int.h"
|
||||||
#include "Color.h"
|
#include "common/Color.h"
|
||||||
|
|
||||||
// C
|
// C
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ int w_Canvas_renderTo(lua_State *L)
|
|||||||
|
|
||||||
if (rt.canvas->getTextureType() != TEXTURE_2D)
|
if (rt.canvas->getTextureType() != TEXTURE_2D)
|
||||||
{
|
{
|
||||||
rt.slice = (int) luaL_checknumber(L, 2) - 1;
|
rt.slice = (int) luaL_checkinteger(L, 2) - 1;
|
||||||
startidx++;
|
startidx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "image/ImageData.h"
|
#include "image/ImageData.h"
|
||||||
#include "image/Image.h"
|
#include "image/Image.h"
|
||||||
#include "font/Rasterizer.h"
|
#include "font/Rasterizer.h"
|
||||||
|
#include "filesystem/Filesystem.h"
|
||||||
#include "filesystem/wrap_Filesystem.h"
|
#include "filesystem/wrap_Filesystem.h"
|
||||||
#include "video/VideoStream.h"
|
#include "video/VideoStream.h"
|
||||||
#include "image/wrap_Image.h"
|
#include "image/wrap_Image.h"
|
||||||
@@ -321,7 +322,7 @@ int w_setCanvas(lua_State *L)
|
|||||||
|
|
||||||
if (i == 1 && type != TEXTURE_2D)
|
if (i == 1 && type != TEXTURE_2D)
|
||||||
{
|
{
|
||||||
target.slice = (int) luaL_checknumber(L, i + 1) - 1;
|
target.slice = (int) luaL_checkinteger(L, i + 1) - 1;
|
||||||
target.mipmap = (int) luaL_optinteger(L, i + 2, 1) - 1;
|
target.mipmap = (int) luaL_optinteger(L, i + 2, 1) - 1;
|
||||||
targets.colors.push_back(target);
|
targets.colors.push_back(target);
|
||||||
break;
|
break;
|
||||||
@@ -439,8 +440,54 @@ static void screenshotCallback(love::image::ImageData *i, Reference *ref, void *
|
|||||||
delete ref;
|
delete ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int screenshotSaveToFile(lua_State *L)
|
||||||
|
{
|
||||||
|
image::ImageData *id = image::luax_checkimagedata(L, 1);
|
||||||
|
|
||||||
|
const char *filename = luaL_checkstring(L, lua_upvalueindex(1));
|
||||||
|
const char *ext = luaL_checkstring(L, lua_upvalueindex(2));
|
||||||
|
|
||||||
|
image::FormatHandler::EncodedFormat format;
|
||||||
|
if (!image::ImageData::getConstant(ext, format))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
id->encode(format, filename, true);
|
||||||
|
}
|
||||||
|
catch (love::Exception &e)
|
||||||
|
{
|
||||||
|
printf("Screenshot encoding or saving failed: %s", e.what());
|
||||||
|
// Do nothing...
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int w_captureScreenshot(lua_State *L)
|
int w_captureScreenshot(lua_State *L)
|
||||||
{
|
{
|
||||||
|
if (lua_isstring(L, 1))
|
||||||
|
{
|
||||||
|
std::string filename = luax_checkstring(L, 1);
|
||||||
|
std::string ext;
|
||||||
|
|
||||||
|
size_t dotpos = filename.rfind('.');
|
||||||
|
|
||||||
|
if (dotpos != std::string::npos)
|
||||||
|
ext = filename.substr(dotpos + 1);
|
||||||
|
|
||||||
|
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
|
||||||
|
|
||||||
|
image::FormatHandler::EncodedFormat format;
|
||||||
|
if (!image::ImageData::getConstant(ext.c_str(), format))
|
||||||
|
return luaL_error(L, "Invalid encoded image format: %s", ext.c_str());
|
||||||
|
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
luax_pushstring(L, ext);
|
||||||
|
lua_pushcclosure(L, screenshotSaveToFile, 2);
|
||||||
|
lua_replace(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||||
|
|
||||||
Graphics::ScreenshotInfo info;
|
Graphics::ScreenshotInfo info;
|
||||||
@@ -470,10 +517,10 @@ int w_setScissor(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rect rect;
|
Rect rect;
|
||||||
rect.x = (int) luaL_checknumber(L, 1);
|
rect.x = (int) luaL_checkinteger(L, 1);
|
||||||
rect.y = (int) luaL_checknumber(L, 2);
|
rect.y = (int) luaL_checkinteger(L, 2);
|
||||||
rect.w = (int) luaL_checknumber(L, 3);
|
rect.w = (int) luaL_checkinteger(L, 3);
|
||||||
rect.h = (int) luaL_checknumber(L, 4);
|
rect.h = (int) luaL_checkinteger(L, 4);
|
||||||
|
|
||||||
if (rect.w < 0 || rect.h < 0)
|
if (rect.w < 0 || rect.h < 0)
|
||||||
return luaL_error(L, "Can't set scissor with negative width and/or height.");
|
return luaL_error(L, "Can't set scissor with negative width and/or height.");
|
||||||
@@ -485,10 +532,10 @@ int w_setScissor(lua_State *L)
|
|||||||
int w_intersectScissor(lua_State *L)
|
int w_intersectScissor(lua_State *L)
|
||||||
{
|
{
|
||||||
Rect rect;
|
Rect rect;
|
||||||
rect.x = (int) luaL_checknumber(L, 1);
|
rect.x = (int) luaL_checkinteger(L, 1);
|
||||||
rect.y = (int) luaL_checknumber(L, 2);
|
rect.y = (int) luaL_checkinteger(L, 2);
|
||||||
rect.w = (int) luaL_checknumber(L, 3);
|
rect.w = (int) luaL_checkinteger(L, 3);
|
||||||
rect.h = (int) luaL_checknumber(L, 4);
|
rect.h = (int) luaL_checkinteger(L, 4);
|
||||||
|
|
||||||
if (rect.w < 0 || rect.h < 0)
|
if (rect.w < 0 || rect.h < 0)
|
||||||
return luaL_error(L, "Can't set scissor with negative width and/or height.");
|
return luaL_error(L, "Can't set scissor with negative width and/or height.");
|
||||||
@@ -524,7 +571,7 @@ int w_stencil(lua_State *L)
|
|||||||
return luaL_error(L, "Invalid stencil draw action: %s", actionstr);
|
return luaL_error(L, "Invalid stencil draw action: %s", actionstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int stencilvalue = (int) luaL_optnumber(L, 3, 1);
|
int stencilvalue = (int) luaL_optinteger(L, 3, 1);
|
||||||
|
|
||||||
// Fourth argument: whether to keep the contents of the stencil buffer.
|
// Fourth argument: whether to keep the contents of the stencil buffer.
|
||||||
OptionalInt stencilclear;
|
OptionalInt stencilclear;
|
||||||
@@ -561,7 +608,7 @@ int w_setStencilTest(lua_State *L)
|
|||||||
if (!getConstant(comparestr, compare))
|
if (!getConstant(comparestr, compare))
|
||||||
return luaL_error(L, "Invalid compare mode: %s", comparestr);
|
return luaL_error(L, "Invalid compare mode: %s", comparestr);
|
||||||
|
|
||||||
comparevalue = (int) luaL_checknumber(L, 2);
|
comparevalue = (int) luaL_checkinteger(L, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
luax_catchexcept(L, [&](){ instance()->setStencilTest(compare, comparevalue); });
|
luax_catchexcept(L, [&](){ instance()->setStencilTest(compare, comparevalue); });
|
||||||
@@ -942,14 +989,14 @@ int w_newQuad(lua_State *L)
|
|||||||
}
|
}
|
||||||
else if (luax_istype(L, 6, Texture::type))
|
else if (luax_istype(L, 6, Texture::type))
|
||||||
{
|
{
|
||||||
layer = (int) luaL_checknumber(L, 5) - 1;
|
layer = (int) luaL_checkinteger(L, 5) - 1;
|
||||||
Texture *texture = luax_checktexture(L, 6);
|
Texture *texture = luax_checktexture(L, 6);
|
||||||
sw = texture->getWidth();
|
sw = texture->getWidth();
|
||||||
sh = texture->getHeight();
|
sh = texture->getHeight();
|
||||||
}
|
}
|
||||||
else if (!lua_isnoneornil(L, 7))
|
else if (!lua_isnoneornil(L, 7))
|
||||||
{
|
{
|
||||||
layer = (int) luaL_checknumber(L, 5) - 1;
|
layer = (int) luaL_checkinteger(L, 5) - 1;
|
||||||
sw = luaL_checknumber(L, 6);
|
sw = luaL_checknumber(L, 6);
|
||||||
sh = luaL_checknumber(L, 7);
|
sh = luaL_checknumber(L, 7);
|
||||||
}
|
}
|
||||||
@@ -1030,7 +1077,7 @@ int w_newSpriteBatch(lua_State *L)
|
|||||||
luax_checkgraphicscreated(L);
|
luax_checkgraphicscreated(L);
|
||||||
|
|
||||||
Texture *texture = luax_checktexture(L, 1);
|
Texture *texture = luax_checktexture(L, 1);
|
||||||
int size = (int) luaL_optnumber(L, 2, 1000);
|
int size = (int) luaL_optinteger(L, 2, 1000);
|
||||||
vertex::Usage usage = vertex::USAGE_DYNAMIC;
|
vertex::Usage usage = vertex::USAGE_DYNAMIC;
|
||||||
if (lua_gettop(L) > 2)
|
if (lua_gettop(L) > 2)
|
||||||
{
|
{
|
||||||
@@ -1075,8 +1122,8 @@ int w_newCanvas(lua_State *L)
|
|||||||
Canvas::Settings settings;
|
Canvas::Settings settings;
|
||||||
|
|
||||||
// check if width and height are given. else default to screen dimensions.
|
// check if width and height are given. else default to screen dimensions.
|
||||||
settings.width = (int) luaL_optnumber(L, 1, instance()->getWidth());
|
settings.width = (int) luaL_optinteger(L, 1, instance()->getWidth());
|
||||||
settings.height = (int) luaL_optnumber(L, 2, instance()->getHeight());
|
settings.height = (int) luaL_optinteger(L, 2, instance()->getHeight());
|
||||||
|
|
||||||
// Default to the screen's current pixel density scale.
|
// Default to the screen's current pixel density scale.
|
||||||
settings.pixeldensity = instance()->getScreenPixelDensity();
|
settings.pixeldensity = instance()->getScreenPixelDensity();
|
||||||
@@ -1085,7 +1132,7 @@ int w_newCanvas(lua_State *L)
|
|||||||
|
|
||||||
if (lua_isnumber(L, 3))
|
if (lua_isnumber(L, 3))
|
||||||
{
|
{
|
||||||
settings.layers = (int) luaL_checknumber(L, 3);
|
settings.layers = (int) luaL_checkinteger(L, 3);
|
||||||
settings.type = TEXTURE_2D_ARRAY;
|
settings.type = TEXTURE_2D_ARRAY;
|
||||||
startidx = 4;
|
startidx = 4;
|
||||||
}
|
}
|
||||||
@@ -1142,36 +1189,48 @@ int w_newCanvas(lua_State *L)
|
|||||||
|
|
||||||
static int w_getShaderSource(lua_State *L, int startidx, bool gles, Shader::ShaderSource &source)
|
static int w_getShaderSource(lua_State *L, int startidx, bool gles, Shader::ShaderSource &source)
|
||||||
{
|
{
|
||||||
|
using namespace love::filesystem;
|
||||||
|
|
||||||
luax_checkgraphicscreated(L);
|
luax_checkgraphicscreated(L);
|
||||||
|
|
||||||
|
auto fs = Module::getInstance<Filesystem>(Module::M_FILESYSTEM);
|
||||||
|
|
||||||
// read any filepath arguments
|
// read any filepath arguments
|
||||||
for (int i = startidx; i < startidx + 2; i++)
|
for (int i = startidx; i < startidx + 2; i++)
|
||||||
{
|
{
|
||||||
if (!lua_isstring(L, i))
|
if (!lua_isstring(L, i))
|
||||||
continue;
|
|
||||||
|
|
||||||
// call love.filesystem.isFile(arg_i)
|
|
||||||
luax_getfunction(L, "filesystem", "isFile");
|
|
||||||
lua_pushvalue(L, i);
|
|
||||||
lua_call(L, 1, 1);
|
|
||||||
|
|
||||||
bool isFile = luax_toboolean(L, -1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
if (isFile)
|
|
||||||
{
|
{
|
||||||
luax_getfunction(L, "filesystem", "read");
|
if (luax_cangetfiledata(L, i))
|
||||||
lua_pushvalue(L, i);
|
{
|
||||||
lua_call(L, 1, 1);
|
FileData *fd = luax_getfiledata(L, i);
|
||||||
|
|
||||||
|
lua_pushlstring(L, (const char *) fd->getData(), fd->getSize());
|
||||||
|
fd->release();
|
||||||
|
|
||||||
|
lua_replace(L, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t slen = 0;
|
||||||
|
const char *str = lua_tolstring(L, i, &slen);
|
||||||
|
|
||||||
|
if (fs != nullptr && fs->isFile(str))
|
||||||
|
{
|
||||||
|
FileData *fd = nullptr;
|
||||||
|
luax_catchexcept(L, [&](){ fd = fs->read(str); });
|
||||||
|
|
||||||
|
lua_pushlstring(L, (const char *) fd->getData(), fd->getSize());
|
||||||
|
fd->release();
|
||||||
|
|
||||||
lua_replace(L, i);
|
lua_replace(L, i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Check if the argument looks like a filepath - we want a nicer
|
// Check if the argument looks like a filepath - we want a nicer
|
||||||
// error for misspelled filepath arguments.
|
// error for misspelled filepath arguments.
|
||||||
size_t slen = 0;
|
if (slen > 0 && slen < 64 && !strchr(str, '\n'))
|
||||||
const char *str = lua_tolstring(L, i, &slen);
|
|
||||||
if (slen > 0 && slen < 256 && !strchr(str, '\n'))
|
|
||||||
{
|
{
|
||||||
const char *ext = strchr(str, '.');
|
const char *ext = strchr(str, '.');
|
||||||
if (ext != nullptr && !strchr(ext, ';') && !strchr(ext, ' '))
|
if (ext != nullptr && !strchr(ext, ';') && !strchr(ext, ' '))
|
||||||
@@ -1352,7 +1411,7 @@ static Mesh *newStandardMesh(lua_State *L)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int count = (int) luaL_checknumber(L, 1);
|
int count = (int) luaL_checkinteger(L, 1);
|
||||||
luax_catchexcept(L, [&](){ t = instance()->newMesh(count, drawmode, usage); });
|
luax_catchexcept(L, [&](){ t = instance()->newMesh(count, drawmode, usage); });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1397,7 +1456,7 @@ static Mesh *newCustomMesh(lua_State *L)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
format.components = (int) luaL_checknumber(L, -1);
|
format.components = (int) luaL_checkinteger(L, -1);
|
||||||
if (format.components <= 0 || format.components > 4)
|
if (format.components <= 0 || format.components > 4)
|
||||||
{
|
{
|
||||||
luaL_error(L, "Number of vertex attribute components must be between 1 and 4 (got %d)", format.components);
|
luaL_error(L, "Number of vertex attribute components must be between 1 and 4 (got %d)", format.components);
|
||||||
@@ -1410,7 +1469,7 @@ static Mesh *newCustomMesh(lua_State *L)
|
|||||||
|
|
||||||
if (lua_isnumber(L, 2))
|
if (lua_isnumber(L, 2))
|
||||||
{
|
{
|
||||||
int vertexcount = (int) luaL_checknumber(L, 2);
|
int vertexcount = (int) luaL_checkinteger(L, 2);
|
||||||
luax_catchexcept(L, [&](){ t = instance()->newMesh(vertexformat, vertexcount, drawmode, usage); });
|
luax_catchexcept(L, [&](){ t = instance()->newMesh(vertexformat, vertexcount, drawmode, usage); });
|
||||||
}
|
}
|
||||||
else if (luax_istype(L, 2, Data::type))
|
else if (luax_istype(L, 2, Data::type))
|
||||||
@@ -2073,6 +2132,9 @@ int w_getStats(lua_State *L)
|
|||||||
lua_pushinteger(L, stats.drawCalls);
|
lua_pushinteger(L, stats.drawCalls);
|
||||||
lua_setfield(L, -2, "drawcalls");
|
lua_setfield(L, -2, "drawcalls");
|
||||||
|
|
||||||
|
lua_pushinteger(L, stats.drawCallsBatched);
|
||||||
|
lua_setfield(L, -2, "drawcallsbatched");
|
||||||
|
|
||||||
lua_pushinteger(L, stats.canvasSwitches);
|
lua_pushinteger(L, stats.canvasSwitches);
|
||||||
lua_setfield(L, -2, "canvasswitches");
|
lua_setfield(L, -2, "canvasswitches");
|
||||||
|
|
||||||
@@ -2135,7 +2197,7 @@ int w_drawLayer(lua_State *L)
|
|||||||
{
|
{
|
||||||
Texture *texture = luax_checktexture(L, 1);
|
Texture *texture = luax_checktexture(L, 1);
|
||||||
Quad *quad = nullptr;
|
Quad *quad = nullptr;
|
||||||
int layer = (int) luaL_checknumber(L, 2) - 1;
|
int layer = (int) luaL_checkinteger(L, 2) - 1;
|
||||||
int startidx = 3;
|
int startidx = 3;
|
||||||
|
|
||||||
if (luax_istype(L, startidx, Quad::type))
|
if (luax_istype(L, startidx, Quad::type))
|
||||||
@@ -2279,23 +2341,23 @@ int w_points(lua_State *L)
|
|||||||
if (args % 2 != 0 && !is_table_of_tables)
|
if (args % 2 != 0 && !is_table_of_tables)
|
||||||
return luaL_error(L, "Number of vertex components must be a multiple of two");
|
return luaL_error(L, "Number of vertex components must be a multiple of two");
|
||||||
|
|
||||||
int numpoints = args / 2;
|
int numpositions = args / 2;
|
||||||
if (is_table_of_tables)
|
if (is_table_of_tables)
|
||||||
numpoints = args;
|
numpositions = args;
|
||||||
|
|
||||||
float *coords = nullptr;
|
Vector2 *positions = nullptr;
|
||||||
Colorf *colors = nullptr;
|
Colorf *colors = nullptr;
|
||||||
|
|
||||||
if (is_table_of_tables)
|
if (is_table_of_tables)
|
||||||
{
|
{
|
||||||
size_t datasize = (sizeof(float) * 2 + sizeof(Colorf)) * numpoints;
|
size_t datasize = (sizeof(Vector2) + sizeof(Colorf)) * numpositions;
|
||||||
uint8 *data = instance()->getScratchBuffer<uint8>(datasize);
|
uint8 *data = instance()->getScratchBuffer<uint8>(datasize);
|
||||||
|
|
||||||
coords = (float *) data;
|
positions = (Vector2 *) data;
|
||||||
colors = (Colorf *) (data + sizeof(float) * numpoints * 2);
|
colors = (Colorf *) (data + sizeof(Vector2) * numpositions);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
coords = instance()->getScratchBuffer<float>(numpoints * 2);
|
positions = instance()->getScratchBuffer<Vector2>(numpositions);
|
||||||
|
|
||||||
if (is_table)
|
if (is_table)
|
||||||
{
|
{
|
||||||
@@ -2308,13 +2370,13 @@ int w_points(lua_State *L)
|
|||||||
for (int j = 1; j <= 6; j++)
|
for (int j = 1; j <= 6; j++)
|
||||||
lua_rawgeti(L, -j, j);
|
lua_rawgeti(L, -j, j);
|
||||||
|
|
||||||
coords[i * 2 + 0] = luax_tofloat(L, -6);
|
positions[i].x = luax_tofloat(L, -6);
|
||||||
coords[i * 2 + 1] = luax_tofloat(L, -5);
|
positions[i].y = luax_tofloat(L, -5);
|
||||||
|
|
||||||
colors[i].r = luaL_optnumber(L, -4, 1.0);
|
colors[i].r = (float) luaL_optnumber(L, -4, 1.0);
|
||||||
colors[i].g = luaL_optnumber(L, -3, 1.0);
|
colors[i].g = (float) luaL_optnumber(L, -3, 1.0);
|
||||||
colors[i].b = luaL_optnumber(L, -2, 1.0);
|
colors[i].b = (float) luaL_optnumber(L, -2, 1.0);
|
||||||
colors[i].a = luaL_optnumber(L, -1, 1.0);
|
colors[i].a = (float) luaL_optnumber(L, -1, 1.0);
|
||||||
|
|
||||||
lua_pop(L, 7);
|
lua_pop(L, 7);
|
||||||
}
|
}
|
||||||
@@ -2322,21 +2384,26 @@ int w_points(lua_State *L)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// points({x1, y1, x2, y2, ...})
|
// points({x1, y1, x2, y2, ...})
|
||||||
for (int i = 0; i < args; i++)
|
for (int i = 0; i < numpositions; i++)
|
||||||
{
|
{
|
||||||
lua_rawgeti(L, 1, i + 1);
|
lua_rawgeti(L, 1, i * 2 + 1);
|
||||||
coords[i] = luax_tofloat(L, -1);
|
lua_rawgeti(L, 1, i * 2 + 2);
|
||||||
lua_pop(L, 1);
|
positions[i].x = luax_tofloat(L, -2);
|
||||||
|
positions[i].y = luax_tofloat(L, -1);
|
||||||
|
lua_pop(L, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < args; i++)
|
for (int i = 0; i < numpositions; i++)
|
||||||
coords[i] = luax_tofloat(L, i + 1);
|
{
|
||||||
|
positions[i].x = luax_tofloat(L, i * 2 + 1);
|
||||||
|
positions[i].y = luax_tofloat(L, i * 2 + 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
luax_catchexcept(L, [&](){ instance()->points(coords, colors, numpoints); });
|
luax_catchexcept(L, [&](){ instance()->points(positions, colors, numpositions); });
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2355,24 +2422,31 @@ int w_line(lua_State *L)
|
|||||||
else if (args < 4)
|
else if (args < 4)
|
||||||
return luaL_error(L, "Need at least two vertices to draw a line");
|
return luaL_error(L, "Need at least two vertices to draw a line");
|
||||||
|
|
||||||
float *coords = instance()->getScratchBuffer<float>(args);
|
int numvertices = args / 2;
|
||||||
|
|
||||||
|
Vector2 *coords = instance()->getScratchBuffer<Vector2>(numvertices);
|
||||||
if (is_table)
|
if (is_table)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < args; ++i)
|
for (int i = 0; i < numvertices; ++i)
|
||||||
{
|
{
|
||||||
lua_rawgeti(L, 1, i + 1);
|
lua_rawgeti(L, 1, (i * 2) + 1);
|
||||||
coords[i] = luax_tofloat(L, -1);
|
lua_rawgeti(L, 1, (i * 2) + 2);
|
||||||
lua_pop(L, 1);
|
coords[i].x = luax_tofloat(L, -2);
|
||||||
|
coords[i].y = luax_tofloat(L, -1);
|
||||||
|
lua_pop(L, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < args; ++i)
|
for (int i = 0; i < numvertices; ++i)
|
||||||
coords[i] = luax_tofloat(L, i + 1);
|
{
|
||||||
|
coords[i].x = luax_tofloat(L, (i * 2) + 1);
|
||||||
|
coords[i].y = luax_tofloat(L, (i * 2) + 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
luax_catchexcept(L,
|
luax_catchexcept(L,
|
||||||
[&](){ instance()->polyline(coords, args); }
|
[&](){ instance()->polyline(coords, numvertices); }
|
||||||
);
|
);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2403,7 +2477,7 @@ int w_rectangle(lua_State *L)
|
|||||||
luax_catchexcept(L, [&](){ instance()->rectangle(mode, x, y, w, h, rx, ry); });
|
luax_catchexcept(L, [&](){ instance()->rectangle(mode, x, y, w, h, rx, ry); });
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int points = (int) luaL_checknumber(L, 8);
|
int points = (int) luaL_checkinteger(L, 8);
|
||||||
luax_catchexcept(L, [&](){ instance()->rectangle(mode, x, y, w, h, rx, ry, points); });
|
luax_catchexcept(L, [&](){ instance()->rectangle(mode, x, y, w, h, rx, ry, points); });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2425,7 +2499,7 @@ int w_circle(lua_State *L)
|
|||||||
luax_catchexcept(L, [&](){ instance()->circle(mode, x, y, radius); });
|
luax_catchexcept(L, [&](){ instance()->circle(mode, x, y, radius); });
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int points = (int) luaL_checknumber(L, 5);
|
int points = (int) luaL_checkinteger(L, 5);
|
||||||
luax_catchexcept(L, [&](){ instance()->circle(mode, x, y, radius, points); });
|
luax_catchexcept(L, [&](){ instance()->circle(mode, x, y, radius, points); });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2448,7 +2522,7 @@ int w_ellipse(lua_State *L)
|
|||||||
luax_catchexcept(L, [&](){ instance()->ellipse(mode, x, y, a, b); });
|
luax_catchexcept(L, [&](){ instance()->ellipse(mode, x, y, a, b); });
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int points = (int) luaL_checknumber(L, 6);
|
int points = (int) luaL_checkinteger(L, 6);
|
||||||
luax_catchexcept(L, [&](){ instance()->ellipse(mode, x, y, a, b, points); });
|
luax_catchexcept(L, [&](){ instance()->ellipse(mode, x, y, a, b, points); });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2485,7 +2559,7 @@ int w_arc(lua_State *L)
|
|||||||
luax_catchexcept(L, [&](){ instance()->arc(drawmode, arcmode, x, y, radius, angle1, angle2); });
|
luax_catchexcept(L, [&](){ instance()->arc(drawmode, arcmode, x, y, radius, angle1, angle2); });
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int points = (int) luaL_checknumber(L, startidx + 5);
|
int points = (int) luaL_checkinteger(L, startidx + 5);
|
||||||
luax_catchexcept(L, [&](){ instance()->arc(drawmode, arcmode, x, y, radius, angle1, angle2, points); });
|
luax_catchexcept(L, [&](){ instance()->arc(drawmode, arcmode, x, y, radius, angle1, angle2, points); });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2513,28 +2587,34 @@ int w_polygon(lua_State *L)
|
|||||||
else if (args < 6)
|
else if (args < 6)
|
||||||
return luaL_error(L, "Need at least three vertices to draw a polygon");
|
return luaL_error(L, "Need at least three vertices to draw a polygon");
|
||||||
|
|
||||||
|
int numvertices = args / 2;
|
||||||
|
|
||||||
// fetch coords
|
// fetch coords
|
||||||
float *coords = instance()->getScratchBuffer<float>(args + 2);
|
Vector2 *coords = instance()->getScratchBuffer<Vector2>(numvertices + 1);
|
||||||
if (is_table)
|
if (is_table)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < args; ++i)
|
for (int i = 0; i < numvertices; ++i)
|
||||||
{
|
{
|
||||||
lua_rawgeti(L, 2, i + 1);
|
lua_rawgeti(L, 2, (i * 2) + 1);
|
||||||
coords[i] = luax_tofloat(L, -1);
|
lua_rawgeti(L, 2, (i * 2) + 2);
|
||||||
lua_pop(L, 1);
|
coords[i].x = luax_tofloat(L, -2);
|
||||||
|
coords[i].y = luax_tofloat(L, -1);
|
||||||
|
lua_pop(L, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < args; ++i)
|
for (int i = 0; i < numvertices; ++i)
|
||||||
coords[i] = luax_tofloat(L, i + 2);
|
{
|
||||||
|
coords[i].x = luax_tofloat(L, (i * 2) + 2);
|
||||||
|
coords[i].y = luax_tofloat(L, (i * 2) + 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a closed loop
|
// make a closed loop
|
||||||
coords[args] = coords[0];
|
coords[numvertices] = coords[0];
|
||||||
coords[args+1] = coords[1];
|
|
||||||
|
|
||||||
luax_catchexcept(L, [&](){ instance()->polygon(mode, coords, args+2); });
|
luax_catchexcept(L, [&](){ instance()->polygon(mode, coords, numvertices+1); });
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,11 +72,18 @@ GLSL.UNIFORMS = [[
|
|||||||
// According to the GLSL ES 1.0 spec, uniform precision must match between stages,
|
// According to the GLSL ES 1.0 spec, uniform precision must match between stages,
|
||||||
// but we can't guarantee that highp is always supported in fragment shaders...
|
// but we can't guarantee that highp is always supported in fragment shaders...
|
||||||
// We *really* don't want to use mediump for these in vertex shaders though.
|
// We *really* don't want to use mediump for these in vertex shaders though.
|
||||||
uniform LOVE_HIGHP_OR_MEDIUMP mat4 TransformMatrix;
|
uniform LOVE_HIGHP_OR_MEDIUMP mat4 ViewSpaceFromLocal;
|
||||||
uniform LOVE_HIGHP_OR_MEDIUMP mat4 ProjectionMatrix;
|
uniform LOVE_HIGHP_OR_MEDIUMP mat4 ClipSpaceFromView;
|
||||||
uniform LOVE_HIGHP_OR_MEDIUMP mat4 TransformProjectionMatrix;
|
uniform LOVE_HIGHP_OR_MEDIUMP mat4 ClipSpaceFromLocal;
|
||||||
uniform LOVE_HIGHP_OR_MEDIUMP mat3 NormalMatrix;
|
uniform LOVE_HIGHP_OR_MEDIUMP mat3 ViewNormalFromLocal;
|
||||||
uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_ScreenSize;]]
|
uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_ScreenSize;
|
||||||
|
|
||||||
|
// Compatibility
|
||||||
|
#define TransformMatrix ViewSpaceFromLocal
|
||||||
|
#define ProjectionMatrix ClipSpaceFromView
|
||||||
|
#define TransformProjectionMatrix ClipSpaceFromLocal
|
||||||
|
#define NormalMatrix ViewNormalFromLocal
|
||||||
|
]]
|
||||||
|
|
||||||
GLSL.FUNCTIONS = [[
|
GLSL.FUNCTIONS = [[
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
@@ -222,13 +229,13 @@ attribute vec4 ConstantColor;
|
|||||||
varying vec4 VaryingTexCoord;
|
varying vec4 VaryingTexCoord;
|
||||||
varying vec4 VaryingColor;
|
varying vec4 VaryingColor;
|
||||||
|
|
||||||
vec4 position(mat4 transform_proj, vec4 vertpos);
|
vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition);
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
VaryingTexCoord = VertexTexCoord;
|
VaryingTexCoord = VertexTexCoord;
|
||||||
VaryingColor = gammaCorrectColor(VertexColor) * ConstantColor;
|
VaryingColor = gammaCorrectColor(VertexColor) * ConstantColor;
|
||||||
setPointSize();
|
setPointSize();
|
||||||
love_Position = position(TransformProjectionMatrix, VertexPosition);
|
love_Position = position(ClipSpaceFromLocal, VertexPosition);
|
||||||
}]],
|
}]],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,8 +431,8 @@ end
|
|||||||
|
|
||||||
local defaultcode = {
|
local defaultcode = {
|
||||||
vertex = [[
|
vertex = [[
|
||||||
vec4 position(mat4 transform_proj, vec4 vertpos) {
|
vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition) {
|
||||||
return transform_proj * vertpos;
|
return clipSpaceFromLocal * localPosition;
|
||||||
}]],
|
}]],
|
||||||
pixel = [[
|
pixel = [[
|
||||||
vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord) {
|
vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord) {
|
||||||
|
|||||||
@@ -56,12 +56,12 @@ int w_Image_replacePixels(lua_State *L)
|
|||||||
|
|
||||||
if (i->getTextureType() != TEXTURE_2D)
|
if (i->getTextureType() != TEXTURE_2D)
|
||||||
{
|
{
|
||||||
slice = (int) luaL_checknumber(L, 3) - 1;
|
slice = (int) luaL_checkinteger(L, 3) - 1;
|
||||||
if (!reloadmipmaps)
|
if (!reloadmipmaps)
|
||||||
mipmap = (int) luaL_optnumber(L, 4, 1) - 1;
|
mipmap = (int) luaL_optinteger(L, 4, 1) - 1;
|
||||||
}
|
}
|
||||||
else if (!reloadmipmaps)
|
else if (!reloadmipmaps)
|
||||||
mipmap = (int) luaL_optnumber(L, 3, 1) - 1;
|
mipmap = (int) luaL_optinteger(L, 3, 1) - 1;
|
||||||
|
|
||||||
luax_catchexcept(L, [&](){ i->replacePixels(id, slice, mipmap, reloadmipmaps); });
|
luax_catchexcept(L, [&](){ i->replacePixels(id, slice, mipmap, reloadmipmaps); });
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ int w_Mesh_setVertexMap(lua_State *L)
|
|||||||
|
|
||||||
size_t datatypesize = vertex::getIndexDataSize(indextype);
|
size_t datatypesize = vertex::getIndexDataSize(indextype);
|
||||||
|
|
||||||
int indexcount = (int) luaL_optnumber(L, 4, d->getSize() / datatypesize);
|
int indexcount = (int) luaL_optinteger(L, 4, d->getSize() / datatypesize);
|
||||||
|
|
||||||
if (indexcount < 1 || indexcount * datatypesize > d->getSize())
|
if (indexcount < 1 || indexcount * datatypesize > d->getSize())
|
||||||
return luaL_error(L, "Invalid index count: %d", indexcount);
|
return luaL_error(L, "Invalid index count: %d", indexcount);
|
||||||
@@ -515,8 +515,8 @@ int w_Mesh_setDrawRange(lua_State *L)
|
|||||||
t->setDrawRange();
|
t->setDrawRange();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int start = (int) luaL_checknumber(L, 2) - 1;
|
int start = (int) luaL_checkinteger(L, 2) - 1;
|
||||||
int count = (int) luaL_checknumber(L, 3);
|
int count = (int) luaL_checkinteger(L, 3);
|
||||||
luax_catchexcept(L, [&](){ t->setDrawRange(start, count); });
|
luax_catchexcept(L, [&](){ t->setDrawRange(start, count); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -699,7 +699,7 @@ int w_ParticleSystem_reset(lua_State *L)
|
|||||||
int w_ParticleSystem_emit(lua_State *L)
|
int w_ParticleSystem_emit(lua_State *L)
|
||||||
{
|
{
|
||||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||||
int num = (int) luaL_checknumber(L, 2);
|
int num = (int) luaL_checkinteger(L, 2);
|
||||||
t->emit(num);
|
t->emit(num);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ int w_Quad_getTextureDimensions(lua_State *L)
|
|||||||
int w_Quad_setLayer(lua_State *L)
|
int w_Quad_setLayer(lua_State *L)
|
||||||
{
|
{
|
||||||
Quad *quad = luax_checkquad(L, 1);
|
Quad *quad = luax_checkquad(L, 1);
|
||||||
int layer = (int) luaL_checknumber(L, 2) - 1;
|
int layer = (int) luaL_checkinteger(L, 2) - 1;
|
||||||
quad->setLayer(layer);
|
quad->setLayer(layer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ static inline int w_SpriteBatch_add_or_set(lua_State *L, SpriteBatch *t, int sta
|
|||||||
static int w_SpriteBatch_addLayer_or_setLayer(lua_State *L, SpriteBatch *t, int startidx, int index)
|
static int w_SpriteBatch_addLayer_or_setLayer(lua_State *L, SpriteBatch *t, int startidx, int index)
|
||||||
{
|
{
|
||||||
Quad *quad = nullptr;
|
Quad *quad = nullptr;
|
||||||
int layer = (int) luaL_checknumber(L, startidx) - 1;
|
int layer = (int) luaL_checkinteger(L, startidx) - 1;
|
||||||
startidx++;
|
startidx++;
|
||||||
|
|
||||||
if (luax_istype(L, startidx, Quad::type))
|
if (luax_istype(L, startidx, Quad::type))
|
||||||
@@ -101,7 +101,7 @@ int w_SpriteBatch_add(lua_State *L)
|
|||||||
int w_SpriteBatch_set(lua_State *L)
|
int w_SpriteBatch_set(lua_State *L)
|
||||||
{
|
{
|
||||||
SpriteBatch *t = luax_checkspritebatch(L, 1);
|
SpriteBatch *t = luax_checkspritebatch(L, 1);
|
||||||
int index = (int) luaL_checknumber(L, 2) - 1;
|
int index = (int) luaL_checkinteger(L, 2) - 1;
|
||||||
|
|
||||||
w_SpriteBatch_add_or_set(L, t, 3, index);
|
w_SpriteBatch_add_or_set(L, t, 3, index);
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ int w_SpriteBatch_addLayer(lua_State *L)
|
|||||||
int w_SpriteBatch_setLayer(lua_State *L)
|
int w_SpriteBatch_setLayer(lua_State *L)
|
||||||
{
|
{
|
||||||
SpriteBatch *t = luax_checkspritebatch(L, 1);
|
SpriteBatch *t = luax_checkspritebatch(L, 1);
|
||||||
int index = (int) luaL_checknumber(L, 2) - 1;
|
int index = (int) luaL_checkinteger(L, 2) - 1;
|
||||||
|
|
||||||
w_SpriteBatch_addLayer_or_setLayer(L, t, 3, index);
|
w_SpriteBatch_addLayer_or_setLayer(L, t, 3, index);
|
||||||
|
|
||||||
@@ -251,8 +251,8 @@ int w_SpriteBatch_setDrawRange(lua_State *L)
|
|||||||
t->setDrawRange();
|
t->setDrawRange();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int start = (int) luaL_checknumber(L, 2) - 1;
|
int start = (int) luaL_checkinteger(L, 2) - 1;
|
||||||
int count = (int) luaL_checknumber(L, 3);
|
int count = (int) luaL_checkinteger(L, 3);
|
||||||
luax_catchexcept(L, [&](){ t->setDrawRange(start, count); });
|
luax_catchexcept(L, [&](){ t->setDrawRange(start, count); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ int w_Text_getFont(lua_State *L)
|
|||||||
int w_Text_getWidth(lua_State *L)
|
int w_Text_getWidth(lua_State *L)
|
||||||
{
|
{
|
||||||
Text *t = luax_checktext(L, 1);
|
Text *t = luax_checktext(L, 1);
|
||||||
int index = (int) luaL_optnumber(L, 2, 0) - 1;
|
int index = (int) luaL_optinteger(L, 2, 0) - 1;
|
||||||
lua_pushnumber(L, t->getWidth(index));
|
lua_pushnumber(L, t->getWidth(index));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -191,7 +191,7 @@ int w_Text_getWidth(lua_State *L)
|
|||||||
int w_Text_getHeight(lua_State *L)
|
int w_Text_getHeight(lua_State *L)
|
||||||
{
|
{
|
||||||
Text *t = luax_checktext(L, 1);
|
Text *t = luax_checktext(L, 1);
|
||||||
int index = (int) luaL_optnumber(L, 2, 0) - 1;
|
int index = (int) luaL_optinteger(L, 2, 0) - 1;
|
||||||
lua_pushnumber(L, t->getHeight(index));
|
lua_pushnumber(L, t->getHeight(index));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -199,7 +199,7 @@ int w_Text_getHeight(lua_State *L)
|
|||||||
int w_Text_getDimensions(lua_State *L)
|
int w_Text_getDimensions(lua_State *L)
|
||||||
{
|
{
|
||||||
Text *t = luax_checktext(L, 1);
|
Text *t = luax_checktext(L, 1);
|
||||||
int index = (int) luaL_optnumber(L, 2, 0) - 1;
|
int index = (int) luaL_optinteger(L, 2, 0) - 1;
|
||||||
lua_pushnumber(L, t->getWidth(index));
|
lua_pushnumber(L, t->getWidth(index));
|
||||||
lua_pushnumber(L, t->getHeight(index));
|
lua_pushnumber(L, t->getHeight(index));
|
||||||
return 2;
|
return 2;
|
||||||
|
|||||||
+9
-15
@@ -18,20 +18,17 @@
|
|||||||
* 3. This notice may not be removed or altered from any source distribution.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef LOVE_IMAGE_MAGPIE_COMPRESSED_HANDLER_H
|
#pragma once
|
||||||
#define LOVE_IMAGE_MAGPIE_COMPRESSED_HANDLER_H
|
|
||||||
|
|
||||||
// LOVE
|
// LOVE
|
||||||
#include "filesystem/FileData.h"
|
|
||||||
#include "image/CompressedImageData.h"
|
|
||||||
#include "common/Object.h"
|
#include "common/Object.h"
|
||||||
|
#include "filesystem/FileData.h"
|
||||||
|
#include "CompressedSlice.h"
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
namespace image
|
namespace image
|
||||||
{
|
{
|
||||||
namespace magpie
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all CompressedImageData parser library interfaces.
|
* Base class for all CompressedImageData parser library interfaces.
|
||||||
@@ -45,8 +42,8 @@ public:
|
|||||||
virtual ~CompressedFormatHandler() {}
|
virtual ~CompressedFormatHandler() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether a particular FileData can be parsed as CompressedImageData
|
* Determines whether a particular FileData can be parsed as
|
||||||
* by this handler.
|
* CompressedImageData by this handler.
|
||||||
* @param data The data to parse.
|
* @param data The data to parse.
|
||||||
**/
|
**/
|
||||||
virtual bool canParse(const filesystem::FileData *data) = 0;
|
virtual bool canParse(const filesystem::FileData *data) = 0;
|
||||||
@@ -56,21 +53,18 @@ public:
|
|||||||
* a single block of memory containing all the images.
|
* a single block of memory containing all the images.
|
||||||
*
|
*
|
||||||
* @param[in] filedata The data to parse.
|
* @param[in] filedata The data to parse.
|
||||||
* @param[out] images The list of sub-images generated. Byte data is a pointer
|
* @param[out] images The list of sub-images generated. Byte data is a
|
||||||
* to the returned data.
|
* pointer to the returned data.
|
||||||
* @param[out] format The format of the Compressed Data.
|
* @param[out] format The format of the Compressed Data.
|
||||||
* @param[out] sRGB Whether the texture is sRGB-encoded.
|
* @param[out] sRGB Whether the texture is sRGB-encoded.
|
||||||
*
|
*
|
||||||
* @return The single block of memory containing the parsed images.
|
* @return The single block of memory containing the parsed images.
|
||||||
**/
|
**/
|
||||||
virtual StrongRef<CompressedImageData::Memory> parse(filesystem::FileData *filedata,
|
virtual StrongRef<CompressedMemory> parse(filesystem::FileData *filedata,
|
||||||
std::vector<StrongRef<CompressedImageData::Slice>> &images,
|
std::vector<StrongRef<CompressedSlice>> &images,
|
||||||
PixelFormat &format, bool &sRGB) = 0;
|
PixelFormat &format, bool &sRGB) = 0;
|
||||||
|
|
||||||
}; // CompressedFormatHandler
|
}; // CompressedFormatHandler
|
||||||
|
|
||||||
} // magpie
|
|
||||||
} // image
|
} // image
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
#endif // LOVE_IMAGE_MAGPIE_COMPRESSED_HANDLER_H
|
|
||||||
@@ -27,58 +27,54 @@ namespace image
|
|||||||
|
|
||||||
love::Type CompressedImageData::type("CompressedImageData", &Data::type);
|
love::Type CompressedImageData::type("CompressedImageData", &Data::type);
|
||||||
|
|
||||||
CompressedImageData::Memory::Memory(size_t size)
|
CompressedImageData::CompressedImageData(const std::list<CompressedFormatHandler *> &formats, love::filesystem::FileData *filedata)
|
||||||
: data(nullptr)
|
|
||||||
, size(size)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
data = new uint8[size];
|
|
||||||
}
|
|
||||||
catch (std::exception &)
|
|
||||||
{
|
|
||||||
throw love::Exception("Out of memory.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CompressedImageData::Memory::~Memory()
|
|
||||||
{
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
CompressedImageData::Slice::Slice(PixelFormat format, int width, int height, Memory *memory, size_t offset, size_t size)
|
|
||||||
: memory(memory)
|
|
||||||
, offset(offset)
|
|
||||||
, dataSize(size)
|
|
||||||
{
|
|
||||||
this->format = format;
|
|
||||||
this->width = width;
|
|
||||||
this->height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
CompressedImageData::Slice::Slice(const Slice &s)
|
|
||||||
: memory(s.memory)
|
|
||||||
, offset(s.offset)
|
|
||||||
, dataSize(s.dataSize)
|
|
||||||
{
|
|
||||||
this->format = s.getFormat();
|
|
||||||
this->width = s.getWidth();
|
|
||||||
this->height = s.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
CompressedImageData::Slice::~Slice()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CompressedImageData::Slice *CompressedImageData::Slice::clone() const
|
|
||||||
{
|
|
||||||
return new Slice(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
CompressedImageData::CompressedImageData()
|
|
||||||
: format(PIXELFORMAT_UNKNOWN)
|
: format(PIXELFORMAT_UNKNOWN)
|
||||||
, sRGB(false)
|
, sRGB(false)
|
||||||
{
|
{
|
||||||
|
CompressedFormatHandler *parser = nullptr;
|
||||||
|
|
||||||
|
for (CompressedFormatHandler *handler : formats)
|
||||||
|
{
|
||||||
|
if (handler->canParse(filedata))
|
||||||
|
{
|
||||||
|
parser = handler;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parser == nullptr)
|
||||||
|
throw love::Exception("Could not parse compressed data: Unknown format.");
|
||||||
|
|
||||||
|
memory = parser->parse(filedata, dataImages, format, sRGB);
|
||||||
|
|
||||||
|
if (memory == nullptr)
|
||||||
|
throw love::Exception("Could not parse compressed data.");
|
||||||
|
|
||||||
|
if (format == PIXELFORMAT_UNKNOWN)
|
||||||
|
throw love::Exception("Could not parse compressed data: Unknown format.");
|
||||||
|
|
||||||
|
if (dataImages.size() == 0 || memory->size == 0)
|
||||||
|
throw love::Exception("Could not parse compressed data: No valid data?");
|
||||||
|
}
|
||||||
|
|
||||||
|
CompressedImageData::CompressedImageData(const CompressedImageData &c)
|
||||||
|
: format(c.format)
|
||||||
|
, sRGB(c.sRGB)
|
||||||
|
{
|
||||||
|
memory.set(new CompressedMemory(c.memory->size), Acquire::NORETAIN);
|
||||||
|
memcpy(memory->data, c.memory->data, memory->size);
|
||||||
|
|
||||||
|
for (const auto &i : c.dataImages)
|
||||||
|
{
|
||||||
|
auto slice = new CompressedSlice(i->getFormat(), i->getWidth(), i->getHeight(), memory, i->getOffset(), i->getSize());
|
||||||
|
dataImages.push_back(slice);
|
||||||
|
slice->release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompressedImageData *CompressedImageData::clone() const
|
||||||
|
{
|
||||||
|
return new CompressedImageData(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompressedImageData::~CompressedImageData()
|
CompressedImageData::~CompressedImageData()
|
||||||
@@ -143,7 +139,7 @@ bool CompressedImageData::isSRGB() const
|
|||||||
return sRGB;
|
return sRGB;
|
||||||
}
|
}
|
||||||
|
|
||||||
CompressedImageData::Slice *CompressedImageData::getSlice(int slice, int miplevel) const
|
CompressedSlice *CompressedImageData::getSlice(int slice, int miplevel) const
|
||||||
{
|
{
|
||||||
checkSliceExists(slice, miplevel);
|
checkSliceExists(slice, miplevel);
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,13 @@
|
|||||||
#include "common/StringMap.h"
|
#include "common/StringMap.h"
|
||||||
#include "common/int.h"
|
#include "common/int.h"
|
||||||
#include "common/pixelformat.h"
|
#include "common/pixelformat.h"
|
||||||
#include "ImageDataBase.h"
|
#include "filesystem/FileData.h"
|
||||||
|
#include "CompressedSlice.h"
|
||||||
|
#include "CompressedFormatHandler.h"
|
||||||
|
|
||||||
// STL
|
// STL
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
@@ -44,53 +47,16 @@ class CompressedImageData : public Data
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class Memory : public Object
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
Memory(size_t size);
|
|
||||||
virtual ~Memory();
|
|
||||||
|
|
||||||
uint8 *data;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
}; // Memory
|
|
||||||
|
|
||||||
// Compressed image data can have multiple mipmap levels, each represented
|
|
||||||
// by a sub-image.
|
|
||||||
class Slice : public ImageDataBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
Slice(PixelFormat format, int width, int height, Memory *memory, size_t offset, size_t size);
|
|
||||||
Slice(const Slice &slice);
|
|
||||||
virtual ~Slice();
|
|
||||||
|
|
||||||
Slice *clone() const override;
|
|
||||||
void *getData() const override { return memory->data + offset; }
|
|
||||||
size_t getSize() const override { return dataSize; }
|
|
||||||
bool isSRGB() const override { return sRGB; }
|
|
||||||
size_t getOffset() const { return offset; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
StrongRef<Memory> memory;
|
|
||||||
|
|
||||||
size_t offset;
|
|
||||||
size_t dataSize;
|
|
||||||
bool sRGB;
|
|
||||||
|
|
||||||
}; // Slice
|
|
||||||
|
|
||||||
static love::Type type;
|
static love::Type type;
|
||||||
|
|
||||||
CompressedImageData();
|
CompressedImageData(const std::list<CompressedFormatHandler *> &formats, love::filesystem::FileData *filedata);
|
||||||
|
CompressedImageData(const CompressedImageData &c);
|
||||||
virtual ~CompressedImageData();
|
virtual ~CompressedImageData();
|
||||||
|
|
||||||
// Implements Data.
|
// Implements Data.
|
||||||
virtual CompressedImageData *clone() const = 0;
|
CompressedImageData *clone() const override;
|
||||||
virtual void *getData() const;
|
void *getData() const override;
|
||||||
virtual size_t getSize() const;
|
size_t getSize() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the number of mipmaps in this Compressed Image Data.
|
* Gets the number of mipmaps in this Compressed Image Data.
|
||||||
@@ -130,19 +96,18 @@ public:
|
|||||||
|
|
||||||
bool isSRGB() const;
|
bool isSRGB() const;
|
||||||
|
|
||||||
Slice *getSlice(int slice, int miplevel) const;
|
CompressedSlice *getSlice(int slice, int miplevel) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
PixelFormat format;
|
PixelFormat format;
|
||||||
|
|
||||||
bool sRGB;
|
bool sRGB;
|
||||||
|
|
||||||
// Single block of memory containing all of the sub-images.
|
// Single block of memory containing all of the sub-images.
|
||||||
StrongRef<Memory> memory;
|
StrongRef<CompressedMemory> memory;
|
||||||
|
|
||||||
// Texture info for each mipmap level.
|
// Texture info for each mipmap level.
|
||||||
std::vector<StrongRef<Slice>> dataImages;
|
std::vector<StrongRef<CompressedSlice>> dataImages;
|
||||||
|
|
||||||
void checkSliceExists(int slice, int miplevel) const;
|
void checkSliceExists(int slice, int miplevel) const;
|
||||||
|
|
||||||
|
|||||||
+45
-21
@@ -18,37 +18,61 @@
|
|||||||
* 3. This notice may not be removed or altered from any source distribution.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef LOVE_IMAGE_MAGPIE_COMPRESSED_IMAGE_DATA_H
|
#include "CompressedSlice.h"
|
||||||
#define LOVE_IMAGE_MAGPIE_COMPRESSED_IMAGE_DATA_H
|
#include "common/Exception.h"
|
||||||
|
|
||||||
// LOVE
|
|
||||||
#include "CompressedFormatHandler.h"
|
|
||||||
#include "filesystem/FileData.h"
|
|
||||||
#include "image/CompressedImageData.h"
|
|
||||||
|
|
||||||
// C++
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
namespace image
|
namespace image
|
||||||
{
|
{
|
||||||
namespace magpie
|
|
||||||
|
CompressedMemory::CompressedMemory(size_t size)
|
||||||
|
: data(nullptr)
|
||||||
|
, size(size)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
data = new uint8[size];
|
||||||
|
}
|
||||||
|
catch (std::exception &)
|
||||||
|
{
|
||||||
|
throw love::Exception("Out of memory.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CompressedImageData : public love::image::CompressedImageData
|
CompressedMemory::~CompressedMemory()
|
||||||
{
|
{
|
||||||
public:
|
delete[] data;
|
||||||
|
}
|
||||||
|
|
||||||
CompressedImageData(std::list<CompressedFormatHandler *> formats, love::filesystem::FileData *filedata);
|
CompressedSlice::CompressedSlice(PixelFormat format, int width, int height, CompressedMemory *memory, size_t offset, size_t size)
|
||||||
CompressedImageData(const CompressedImageData &c);
|
: memory(memory)
|
||||||
virtual ~CompressedImageData();
|
, offset(offset)
|
||||||
|
, dataSize(size)
|
||||||
|
{
|
||||||
|
this->format = format;
|
||||||
|
this->width = width;
|
||||||
|
this->height = height;
|
||||||
|
}
|
||||||
|
|
||||||
virtual CompressedImageData *clone() const;
|
CompressedSlice::CompressedSlice(const CompressedSlice &s)
|
||||||
}; // CompressedImageData
|
: memory(s.memory)
|
||||||
|
, offset(s.offset)
|
||||||
|
, dataSize(s.dataSize)
|
||||||
|
{
|
||||||
|
this->format = s.getFormat();
|
||||||
|
this->width = s.getWidth();
|
||||||
|
this->height = s.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
CompressedSlice::~CompressedSlice()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CompressedSlice *CompressedSlice::clone() const
|
||||||
|
{
|
||||||
|
return new CompressedSlice(*this);
|
||||||
|
}
|
||||||
|
|
||||||
} // magpie
|
|
||||||
} // image
|
} // image
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
#endif // LOVE_IMAGE_MAGPIE_COMPRESSED_IMAGE_DATA_H
|
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2017 LOVE Development Team
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// LOVE
|
||||||
|
#include "common/int.h"
|
||||||
|
#include "common/pixelformat.h"
|
||||||
|
#include "common/Object.h"
|
||||||
|
#include "ImageDataBase.h"
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace image
|
||||||
|
{
|
||||||
|
|
||||||
|
class CompressedMemory : public Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CompressedMemory(size_t size);
|
||||||
|
virtual ~CompressedMemory();
|
||||||
|
|
||||||
|
uint8 *data;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
}; // CompressedMemory
|
||||||
|
|
||||||
|
// Compressed image data can have multiple mipmap levels, each represented by a
|
||||||
|
// sub-image.
|
||||||
|
class CompressedSlice : public ImageDataBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CompressedSlice(PixelFormat format, int width, int height, CompressedMemory *memory, size_t offset, size_t size);
|
||||||
|
CompressedSlice(const CompressedSlice &slice);
|
||||||
|
virtual ~CompressedSlice();
|
||||||
|
|
||||||
|
CompressedSlice *clone() const override;
|
||||||
|
void *getData() const override { return memory->data + offset; }
|
||||||
|
size_t getSize() const override { return dataSize; }
|
||||||
|
bool isSRGB() const override { return sRGB; }
|
||||||
|
size_t getOffset() const { return offset; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
StrongRef<CompressedMemory> memory;
|
||||||
|
size_t offset;
|
||||||
|
size_t dataSize;
|
||||||
|
bool sRGB;
|
||||||
|
|
||||||
|
}; // CompressedSlice
|
||||||
|
|
||||||
|
} // image
|
||||||
|
} // love
|
||||||
@@ -26,8 +26,6 @@ namespace love
|
|||||||
{
|
{
|
||||||
namespace image
|
namespace image
|
||||||
{
|
{
|
||||||
namespace magpie
|
|
||||||
{
|
|
||||||
|
|
||||||
FormatHandler::FormatHandler()
|
FormatHandler::FormatHandler()
|
||||||
{
|
{
|
||||||
@@ -42,7 +40,7 @@ bool FormatHandler::canDecode(love::filesystem::FileData* /*data*/)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FormatHandler::canEncode(PixelFormat /*rawFormat*/, ImageData::EncodedFormat /*encodedFormat*/)
|
bool FormatHandler::canEncode(PixelFormat /*rawFormat*/, EncodedFormat /*encodedFormat*/)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -52,7 +50,7 @@ FormatHandler::DecodedImage FormatHandler::decode(love::filesystem::FileData* /*
|
|||||||
throw love::Exception("Image decoding is not implemented for this format backend.");
|
throw love::Exception("Image decoding is not implemented for this format backend.");
|
||||||
}
|
}
|
||||||
|
|
||||||
FormatHandler::EncodedImage FormatHandler::encode(const DecodedImage& /*img*/, ImageData::EncodedFormat /*format*/)
|
FormatHandler::EncodedImage FormatHandler::encode(const DecodedImage& /*img*/, EncodedFormat /*format*/)
|
||||||
{
|
{
|
||||||
throw love::Exception("Image encoding is not implemented for this format backend.");
|
throw love::Exception("Image encoding is not implemented for this format backend.");
|
||||||
}
|
}
|
||||||
@@ -62,6 +60,5 @@ void FormatHandler::free(unsigned char *mem)
|
|||||||
delete[] mem;
|
delete[] mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // magpie
|
|
||||||
} // image
|
} // image
|
||||||
} // love
|
} // love
|
||||||
@@ -18,20 +18,17 @@
|
|||||||
* 3. This notice may not be removed or altered from any source distribution.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef LOVE_IMAGE_MAGPIE_FORMAT_HANDLER_H
|
#pragma once
|
||||||
#define LOVE_IMAGE_MAGPIE_FORMAT_HANDLER_H
|
|
||||||
|
|
||||||
// LOVE
|
// LOVE
|
||||||
#include "image/ImageData.h"
|
|
||||||
#include "filesystem/FileData.h"
|
|
||||||
#include "common/Object.h"
|
#include "common/Object.h"
|
||||||
|
#include "common/pixelformat.h"
|
||||||
|
#include "filesystem/FileData.h"
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
namespace image
|
namespace image
|
||||||
{
|
{
|
||||||
namespace magpie
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all ImageData encoder/decoder library interfaces.
|
* Base class for all ImageData encoder/decoder library interfaces.
|
||||||
@@ -41,6 +38,13 @@ class FormatHandler : public love::Object
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum EncodedFormat
|
||||||
|
{
|
||||||
|
ENCODED_TGA,
|
||||||
|
ENCODED_PNG,
|
||||||
|
ENCODED_MAX_ENUM
|
||||||
|
};
|
||||||
|
|
||||||
// Raw RGBA pixel data.
|
// Raw RGBA pixel data.
|
||||||
struct DecodedImage
|
struct DecodedImage
|
||||||
{
|
{
|
||||||
@@ -76,7 +80,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Whether this format handler can encode to a particular format.
|
* Whether this format handler can encode to a particular format.
|
||||||
**/
|
**/
|
||||||
virtual bool canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat);
|
virtual bool canEncode(PixelFormat rawFormat, EncodedFormat encodedFormat);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes an image from its encoded form into raw pixel data.
|
* Decodes an image from its encoded form into raw pixel data.
|
||||||
@@ -91,7 +95,7 @@ public:
|
|||||||
* @param format The format to encode to.
|
* @param format The format to encode to.
|
||||||
* @return The encoded image data.
|
* @return The encoded image data.
|
||||||
**/
|
**/
|
||||||
virtual EncodedImage encode(const DecodedImage &img, ImageData::EncodedFormat format);
|
virtual EncodedImage encode(const DecodedImage &img, EncodedFormat format);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees memory allocated by the format handler.
|
* Frees memory allocated by the format handler.
|
||||||
@@ -100,8 +104,5 @@ public:
|
|||||||
|
|
||||||
}; // FormatHandler
|
}; // FormatHandler
|
||||||
|
|
||||||
} // magpie
|
|
||||||
} // image
|
} // image
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
#endif // LOVE_IMAGE_MAGPIE_FORMAT_HANDLER_H
|
|
||||||
@@ -20,6 +20,17 @@
|
|||||||
|
|
||||||
// LOVE
|
// LOVE
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
|
#include "common/config.h"
|
||||||
|
|
||||||
|
#include "magpie/PNGHandler.h"
|
||||||
|
#include "magpie/STBHandler.h"
|
||||||
|
#include "magpie/EXRHandler.h"
|
||||||
|
|
||||||
|
#include "magpie/ddsHandler.h"
|
||||||
|
#include "magpie/PVRHandler.h"
|
||||||
|
#include "magpie/KTXHandler.h"
|
||||||
|
#include "magpie/PKMHandler.h"
|
||||||
|
#include "magpie/ASTCHandler.h"
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
@@ -28,6 +39,79 @@ namespace image
|
|||||||
|
|
||||||
love::Type Image::type("image", &Module::type);
|
love::Type Image::type("image", &Module::type);
|
||||||
|
|
||||||
|
Image::Image()
|
||||||
|
{
|
||||||
|
using namespace magpie;
|
||||||
|
|
||||||
|
halfInit(); // Makes sure half-float conversions can be used.
|
||||||
|
|
||||||
|
formatHandlers = {
|
||||||
|
new PNGHandler,
|
||||||
|
new STBHandler,
|
||||||
|
new EXRHandler,
|
||||||
|
};
|
||||||
|
|
||||||
|
compressedFormatHandlers = {
|
||||||
|
new DDSHandler,
|
||||||
|
new PVRHandler,
|
||||||
|
new KTXHandler,
|
||||||
|
new PKMHandler,
|
||||||
|
new ASTCHandler,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Image::~Image()
|
||||||
|
{
|
||||||
|
// ImageData objects reference the FormatHandlers in our list, so we should
|
||||||
|
// release them instead of deleting them completely here.
|
||||||
|
for (FormatHandler *handler : formatHandlers)
|
||||||
|
handler->release();
|
||||||
|
|
||||||
|
for (CompressedFormatHandler *handler : compressedFormatHandlers)
|
||||||
|
handler->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Image::getName() const
|
||||||
|
{
|
||||||
|
return "love.image.magpie";
|
||||||
|
}
|
||||||
|
|
||||||
|
love::image::ImageData *Image::newImageData(love::filesystem::FileData *data)
|
||||||
|
{
|
||||||
|
return new ImageData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
love::image::ImageData *Image::newImageData(int width, int height, PixelFormat format)
|
||||||
|
{
|
||||||
|
return new ImageData(width, height, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
love::image::ImageData *Image::newImageData(int width, int height, PixelFormat format, void *data, bool own)
|
||||||
|
{
|
||||||
|
return new ImageData(width, height, format, data, own);
|
||||||
|
}
|
||||||
|
|
||||||
|
love::image::CompressedImageData *Image::newCompressedData(love::filesystem::FileData *data)
|
||||||
|
{
|
||||||
|
return new CompressedImageData(compressedFormatHandlers, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Image::isCompressed(love::filesystem::FileData *data)
|
||||||
|
{
|
||||||
|
for (CompressedFormatHandler *handler : compressedFormatHandlers)
|
||||||
|
{
|
||||||
|
if (handler->canParse(data))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::list<FormatHandler *> &Image::getFormatHandlers() const
|
||||||
|
{
|
||||||
|
return formatHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
ImageData *Image::newPastedImageData(ImageData *src, int sx, int sy, int w, int h)
|
ImageData *Image::newPastedImageData(ImageData *src, int sx, int sy, int w, int h)
|
||||||
{
|
{
|
||||||
ImageData *res = newImageData(w, h, src->getFormat());
|
ImageData *res = newImageData(w, h, src->getFormat());
|
||||||
|
|||||||
@@ -28,6 +28,9 @@
|
|||||||
#include "ImageData.h"
|
#include "ImageData.h"
|
||||||
#include "CompressedImageData.h"
|
#include "CompressedImageData.h"
|
||||||
|
|
||||||
|
// C++
|
||||||
|
#include <list>
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
namespace image
|
namespace image
|
||||||
@@ -46,17 +49,19 @@ public:
|
|||||||
|
|
||||||
static love::Type type;
|
static love::Type type;
|
||||||
|
|
||||||
virtual ~Image() {}
|
Image();
|
||||||
|
virtual ~Image();
|
||||||
|
|
||||||
// Implements Module.
|
// Implements Module.
|
||||||
virtual ModuleType getModuleType() const { return M_IMAGE; }
|
ModuleType getModuleType() const override { return M_IMAGE; }
|
||||||
|
const char *getName() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new ImageData from FileData.
|
* Creates new ImageData from FileData.
|
||||||
* @param data The FileData containing the encoded image data.
|
* @param data The FileData containing the encoded image data.
|
||||||
* @return The new ImageData.
|
* @return The new ImageData.
|
||||||
**/
|
**/
|
||||||
virtual ImageData *newImageData(love::filesystem::FileData *data) = 0;
|
ImageData *newImageData(love::filesystem::FileData *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates empty ImageData with the given size.
|
* Creates empty ImageData with the given size.
|
||||||
@@ -64,7 +69,7 @@ public:
|
|||||||
* @param height The height of the ImageData.
|
* @param height The height of the ImageData.
|
||||||
* @return The new ImageData.
|
* @return The new ImageData.
|
||||||
**/
|
**/
|
||||||
virtual ImageData *newImageData(int width, int height, PixelFormat format = PIXELFORMAT_RGBA8) = 0;
|
ImageData *newImageData(int width, int height, PixelFormat format = PIXELFORMAT_RGBA8);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates empty ImageData with the given size.
|
* Creates empty ImageData with the given size.
|
||||||
@@ -75,28 +80,36 @@ public:
|
|||||||
* copy it.
|
* copy it.
|
||||||
* @return The new ImageData.
|
* @return The new ImageData.
|
||||||
**/
|
**/
|
||||||
virtual ImageData *newImageData(int width, int height, PixelFormat format, void *data, bool own = false) = 0;
|
ImageData *newImageData(int width, int height, PixelFormat format, void *data, bool own = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new CompressedImageData from FileData.
|
* Creates new CompressedImageData from FileData.
|
||||||
* @param data The FileData containing the compressed image data.
|
* @param data The FileData containing the compressed image data.
|
||||||
* @return The new CompressedImageData.
|
* @return The new CompressedImageData.
|
||||||
**/
|
**/
|
||||||
virtual CompressedImageData *newCompressedData(love::filesystem::FileData *data) = 0;
|
CompressedImageData *newCompressedData(love::filesystem::FileData *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether a FileData is Compressed image data or not.
|
* Determines whether a FileData is Compressed image data or not.
|
||||||
* @param data The FileData to test.
|
* @param data The FileData to test.
|
||||||
**/
|
**/
|
||||||
virtual bool isCompressed(love::filesystem::FileData *data) = 0;
|
bool isCompressed(love::filesystem::FileData *data);
|
||||||
|
|
||||||
std::vector<StrongRef<ImageData>> newCubeFaces(ImageData *src);
|
std::vector<StrongRef<ImageData>> newCubeFaces(ImageData *src);
|
||||||
std::vector<StrongRef<ImageData>> newVolumeLayers(ImageData *src);
|
std::vector<StrongRef<ImageData>> newVolumeLayers(ImageData *src);
|
||||||
|
|
||||||
|
const std::list<FormatHandler *> &getFormatHandlers() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ImageData *newPastedImageData(ImageData *src, int sx, int sy, int w, int h);
|
ImageData *newPastedImageData(ImageData *src, int sx, int sy, int w, int h);
|
||||||
|
|
||||||
|
// Image format handlers we can use for decoding and encoding ImageData.
|
||||||
|
std::list<FormatHandler *> formatHandlers;
|
||||||
|
|
||||||
|
// Compressed image format handers we can use for parsing CompressedImageData.
|
||||||
|
std::list<CompressedFormatHandler *> compressedFormatHandlers;
|
||||||
|
|
||||||
}; // Image
|
}; // Image
|
||||||
|
|
||||||
} // image
|
} // image
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
#include "ImageData.h"
|
#include "ImageData.h"
|
||||||
|
#include "Image.h"
|
||||||
|
#include "filesystem/Filesystem.h"
|
||||||
|
|
||||||
using love::thread::Lock;
|
using love::thread::Lock;
|
||||||
|
|
||||||
@@ -29,13 +31,207 @@ namespace image
|
|||||||
|
|
||||||
love::Type ImageData::type("ImageData", &Data::type);
|
love::Type ImageData::type("ImageData", &Data::type);
|
||||||
|
|
||||||
ImageData::ImageData()
|
ImageData::ImageData(love::filesystem::FileData *data)
|
||||||
: data(nullptr)
|
|
||||||
{
|
{
|
||||||
|
decode(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageData::ImageData(int width, int height, PixelFormat format)
|
||||||
|
{
|
||||||
|
if (!validPixelFormat(format))
|
||||||
|
throw love::Exception("Unsupported pixel format for ImageData");
|
||||||
|
|
||||||
|
this->width = width;
|
||||||
|
this->height = height;
|
||||||
|
this->format = format;
|
||||||
|
|
||||||
|
create(width, height, format);
|
||||||
|
|
||||||
|
// Set to black/transparency.
|
||||||
|
memset(data, 0, getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageData::ImageData(int width, int height, PixelFormat format, void *data, bool own)
|
||||||
|
{
|
||||||
|
if (!validPixelFormat(format))
|
||||||
|
throw love::Exception("Unsupported pixel format for ImageData");
|
||||||
|
|
||||||
|
this->width = width;
|
||||||
|
this->height = height;
|
||||||
|
this->format = format;
|
||||||
|
|
||||||
|
if (own)
|
||||||
|
this->data = (unsigned char *) data;
|
||||||
|
else
|
||||||
|
create(width, height, format, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageData::ImageData(const ImageData &c)
|
||||||
|
{
|
||||||
|
width = c.width;
|
||||||
|
height = c.height;
|
||||||
|
format = c.format;
|
||||||
|
|
||||||
|
create(width, height, format, c.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageData::~ImageData()
|
ImageData::~ImageData()
|
||||||
{
|
{
|
||||||
|
if (decodeHandler.get())
|
||||||
|
decodeHandler->free(data);
|
||||||
|
else
|
||||||
|
delete[] data;
|
||||||
|
}
|
||||||
|
|
||||||
|
love::image::ImageData *ImageData::clone() const
|
||||||
|
{
|
||||||
|
return new ImageData(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageData::create(int width, int height, PixelFormat format, void *data)
|
||||||
|
{
|
||||||
|
size_t datasize = width * height * getPixelFormatSize(format);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this->data = new unsigned char[datasize];
|
||||||
|
}
|
||||||
|
catch(std::bad_alloc &)
|
||||||
|
{
|
||||||
|
throw love::Exception("Out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
memcpy(this->data, data, datasize);
|
||||||
|
|
||||||
|
decodeHandler = nullptr;
|
||||||
|
this->format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageData::decode(love::filesystem::FileData *data)
|
||||||
|
{
|
||||||
|
FormatHandler *decoder = nullptr;
|
||||||
|
FormatHandler::DecodedImage decodedimage;
|
||||||
|
|
||||||
|
auto module = Module::getInstance<Image>(Module::M_IMAGE);
|
||||||
|
|
||||||
|
if (module == nullptr)
|
||||||
|
throw love::Exception("love.image must be loaded in order to decode an ImageData.");
|
||||||
|
|
||||||
|
for (FormatHandler *handler : module->getFormatHandlers())
|
||||||
|
{
|
||||||
|
if (handler->canDecode(data))
|
||||||
|
{
|
||||||
|
decoder = handler;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decoder)
|
||||||
|
decodedimage = decoder->decode(data);
|
||||||
|
|
||||||
|
if (decodedimage.data == nullptr)
|
||||||
|
{
|
||||||
|
const std::string &name = data->getFilename();
|
||||||
|
throw love::Exception("Could not decode file '%s' to ImageData: unsupported file format", name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decodedimage.size != decodedimage.width * decodedimage.height * getPixelFormatSize(decodedimage.format))
|
||||||
|
{
|
||||||
|
decoder->free(decodedimage.data);
|
||||||
|
throw love::Exception("Could not convert image!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up any old data.
|
||||||
|
if (decodeHandler)
|
||||||
|
decodeHandler->free(this->data);
|
||||||
|
else
|
||||||
|
delete[] this->data;
|
||||||
|
|
||||||
|
this->width = decodedimage.width;
|
||||||
|
this->height = decodedimage.height;
|
||||||
|
this->data = decodedimage.data;
|
||||||
|
this->format = decodedimage.format;
|
||||||
|
|
||||||
|
decodeHandler = decoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
love::filesystem::FileData *ImageData::encode(FormatHandler::EncodedFormat encodedFormat, const char *filename, bool writefile) const
|
||||||
|
{
|
||||||
|
FormatHandler *encoder = nullptr;
|
||||||
|
FormatHandler::EncodedImage encodedimage;
|
||||||
|
FormatHandler::DecodedImage rawimage;
|
||||||
|
|
||||||
|
rawimage.width = width;
|
||||||
|
rawimage.height = height;
|
||||||
|
rawimage.size = getSize();
|
||||||
|
rawimage.data = data;
|
||||||
|
rawimage.format = format;
|
||||||
|
|
||||||
|
auto module = Module::getInstance<Image>(Module::M_IMAGE);
|
||||||
|
|
||||||
|
if (module == nullptr)
|
||||||
|
throw love::Exception("love.image must be loaded in order to encode an ImageData.");
|
||||||
|
|
||||||
|
for (FormatHandler *handler : module->getFormatHandlers())
|
||||||
|
{
|
||||||
|
if (handler->canEncode(format, encodedFormat))
|
||||||
|
{
|
||||||
|
encoder = handler;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoder != nullptr)
|
||||||
|
{
|
||||||
|
thread::Lock lock(mutex);
|
||||||
|
encodedimage = encoder->encode(rawimage, encodedFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoder == nullptr || encodedimage.data == nullptr)
|
||||||
|
{
|
||||||
|
const char *fname = "unknown";
|
||||||
|
love::getConstant(format, fname);
|
||||||
|
throw love::Exception("No suitable image encoder for %s format.", fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
love::filesystem::FileData *filedata = nullptr;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
filedata = new love::filesystem::FileData(encodedimage.size, filename);
|
||||||
|
}
|
||||||
|
catch (love::Exception &)
|
||||||
|
{
|
||||||
|
encoder->free(encodedimage.data);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(filedata->getData(), encodedimage.data, encodedimage.size);
|
||||||
|
encoder->free(encodedimage.data);
|
||||||
|
|
||||||
|
if (writefile)
|
||||||
|
{
|
||||||
|
auto fs = Module::getInstance<filesystem::Filesystem>(Module::M_FILESYSTEM);
|
||||||
|
|
||||||
|
if (fs == nullptr)
|
||||||
|
{
|
||||||
|
filedata->release();
|
||||||
|
throw love::Exception("love.filesystem must be loaded in order to write an encoded ImageData to a file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fs->write(filename, filedata->getData(), filedata->getSize());
|
||||||
|
}
|
||||||
|
catch (love::Exception &)
|
||||||
|
{
|
||||||
|
filedata->release();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filedata;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ImageData::getSize() const
|
size_t ImageData::getSize() const
|
||||||
@@ -289,23 +485,23 @@ bool ImageData::validPixelFormat(PixelFormat format)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageData::getConstant(const char *in, EncodedFormat &out)
|
bool ImageData::getConstant(const char *in, FormatHandler::EncodedFormat &out)
|
||||||
{
|
{
|
||||||
return encodedFormats.find(in, out);
|
return encodedFormats.find(in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageData::getConstant(EncodedFormat in, const char *&out)
|
bool ImageData::getConstant(FormatHandler::EncodedFormat in, const char *&out)
|
||||||
{
|
{
|
||||||
return encodedFormats.find(in, out);
|
return encodedFormats.find(in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringMap<ImageData::EncodedFormat, ImageData::ENCODED_MAX_ENUM>::Entry ImageData::encodedFormatEntries[] =
|
StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM>::Entry ImageData::encodedFormatEntries[] =
|
||||||
{
|
{
|
||||||
{"tga", ENCODED_TGA},
|
{"tga", FormatHandler::ENCODED_TGA},
|
||||||
{"png", ENCODED_PNG},
|
{"png", FormatHandler::ENCODED_PNG},
|
||||||
};
|
};
|
||||||
|
|
||||||
StringMap<ImageData::EncodedFormat, ImageData::ENCODED_MAX_ENUM> ImageData::encodedFormats(ImageData::encodedFormatEntries, sizeof(ImageData::encodedFormatEntries));
|
StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM> ImageData::encodedFormats(ImageData::encodedFormatEntries, sizeof(ImageData::encodedFormatEntries));
|
||||||
|
|
||||||
} // image
|
} // image
|
||||||
} // love
|
} // love
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "filesystem/FileData.h"
|
#include "filesystem/FileData.h"
|
||||||
#include "thread/threads.h"
|
#include "thread/threads.h"
|
||||||
#include "ImageDataBase.h"
|
#include "ImageDataBase.h"
|
||||||
|
#include "FormatHandler.h"
|
||||||
|
|
||||||
using love::thread::Mutex;
|
using love::thread::Mutex;
|
||||||
|
|
||||||
@@ -37,13 +38,6 @@ namespace love
|
|||||||
namespace image
|
namespace image
|
||||||
{
|
{
|
||||||
|
|
||||||
// Pixel format structure.
|
|
||||||
struct pixel
|
|
||||||
{
|
|
||||||
// Red, green, blue, alpha.
|
|
||||||
unsigned char r, g, b, a;
|
|
||||||
};
|
|
||||||
|
|
||||||
union Pixel
|
union Pixel
|
||||||
{
|
{
|
||||||
uint8 rgba8[4];
|
uint8 rgba8[4];
|
||||||
@@ -61,14 +55,10 @@ public:
|
|||||||
|
|
||||||
static love::Type type;
|
static love::Type type;
|
||||||
|
|
||||||
enum EncodedFormat
|
ImageData(love::filesystem::FileData *data);
|
||||||
{
|
ImageData(int width, int height, PixelFormat format = PIXELFORMAT_RGBA8);
|
||||||
ENCODED_TGA,
|
ImageData(int width, int height, PixelFormat format, void *data, bool own);
|
||||||
ENCODED_PNG,
|
ImageData(const ImageData &c);
|
||||||
ENCODED_MAX_ENUM
|
|
||||||
};
|
|
||||||
|
|
||||||
ImageData();
|
|
||||||
virtual ~ImageData();
|
virtual ~ImageData();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,12 +101,12 @@ public:
|
|||||||
* @param f The file to save the encoded image data to.
|
* @param f The file to save the encoded image data to.
|
||||||
* @param format The format of the encoded data.
|
* @param format The format of the encoded data.
|
||||||
**/
|
**/
|
||||||
virtual love::filesystem::FileData *encode(EncodedFormat format, const char *filename) = 0;
|
love::filesystem::FileData *encode(FormatHandler::EncodedFormat format, const char *filename, bool writefile) const;
|
||||||
|
|
||||||
love::thread::Mutex *getMutex() const;
|
love::thread::Mutex *getMutex() const;
|
||||||
|
|
||||||
// Implements ImageDataBase.
|
// Implements ImageDataBase.
|
||||||
virtual ImageData *clone() const override = 0;
|
ImageData *clone() const override;
|
||||||
void *getData() const override;
|
void *getData() const override;
|
||||||
size_t getSize() const override;
|
size_t getSize() const override;
|
||||||
bool isSRGB() const override;
|
bool isSRGB() const override;
|
||||||
@@ -125,18 +115,8 @@ public:
|
|||||||
|
|
||||||
static bool validPixelFormat(PixelFormat format);
|
static bool validPixelFormat(PixelFormat format);
|
||||||
|
|
||||||
static bool getConstant(const char *in, EncodedFormat &out);
|
static bool getConstant(const char *in, FormatHandler::EncodedFormat &out);
|
||||||
static bool getConstant(EncodedFormat in, const char *&out);
|
static bool getConstant(FormatHandler::EncodedFormat in, const char *&out);
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// The actual data.
|
|
||||||
unsigned char *data;
|
|
||||||
|
|
||||||
// We need to be thread-safe
|
|
||||||
// so we lock when we're accessing our
|
|
||||||
// data
|
|
||||||
love::thread::MutexRef mutex;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -148,6 +128,21 @@ private:
|
|||||||
float *f32;
|
float *f32;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Create imagedata. Initialize with data if not null.
|
||||||
|
void create(int width, int height, PixelFormat format, void *data = nullptr);
|
||||||
|
|
||||||
|
// Decode and load an encoded format.
|
||||||
|
void decode(love::filesystem::FileData *data);
|
||||||
|
|
||||||
|
// The actual data.
|
||||||
|
unsigned char *data = nullptr;
|
||||||
|
|
||||||
|
love::thread::MutexRef mutex;
|
||||||
|
|
||||||
|
// The format handler that was used to decode the ImageData. We need to know
|
||||||
|
// this so we can properly delete memory allocated by the decoder.
|
||||||
|
StrongRef<FormatHandler> decodeHandler;
|
||||||
|
|
||||||
static void pasteRGBA8toRGBA16(Row src, Row dst, int w);
|
static void pasteRGBA8toRGBA16(Row src, Row dst, int w);
|
||||||
static void pasteRGBA8toRGBA16F(Row src, Row dst, int w);
|
static void pasteRGBA8toRGBA16F(Row src, Row dst, int w);
|
||||||
static void pasteRGBA8toRGBA32F(Row src, Row dst, int w);
|
static void pasteRGBA8toRGBA32F(Row src, Row dst, int w);
|
||||||
@@ -164,8 +159,8 @@ private:
|
|||||||
static void pasteRGBA32FtoRGBA16(Row src, Row dst, int w);
|
static void pasteRGBA32FtoRGBA16(Row src, Row dst, int w);
|
||||||
static void pasteRGBA32FtoRGBA16F(Row src, Row dst, int w);
|
static void pasteRGBA32FtoRGBA16F(Row src, Row dst, int w);
|
||||||
|
|
||||||
static StringMap<EncodedFormat, ENCODED_MAX_ENUM>::Entry encodedFormatEntries[];
|
static StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM>::Entry encodedFormatEntries[];
|
||||||
static StringMap<EncodedFormat, ENCODED_MAX_ENUM> encodedFormats;
|
static StringMap<FormatHandler::EncodedFormat, FormatHandler::ENCODED_MAX_ENUM> encodedFormats;
|
||||||
|
|
||||||
}; // ImageData
|
}; // ImageData
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ bool ASTCHandler::canParse(const filesystem::FileData *data)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
StrongRef<CompressedImageData::Memory> ASTCHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedImageData::Slice>> &images, PixelFormat &format, bool &sRGB)
|
StrongRef<CompressedMemory> ASTCHandler::parse(filesystem::FileData *filedata, std::vector<StrongRef<CompressedSlice>> &images, PixelFormat &format, bool &sRGB)
|
||||||
{
|
{
|
||||||
if (!canParse(filedata))
|
if (!canParse(filedata))
|
||||||
throw love::Exception("Could not decode compressed data (not an .astc file?)");
|
throw love::Exception("Could not decode compressed data (not an .astc file?)");
|
||||||
@@ -129,12 +129,12 @@ StrongRef<CompressedImageData::Memory> ASTCHandler::parse(filesystem::FileData *
|
|||||||
if (totalsize + sizeof(header) > filedata->getSize())
|
if (totalsize + sizeof(header) > filedata->getSize())
|
||||||
throw love::Exception("Could not parse .astc file: file is too small.");
|
throw love::Exception("Could not parse .astc file: file is too small.");
|
||||||
|
|
||||||
StrongRef<CompressedImageData::Memory> memory(new CompressedImageData::Memory(totalsize), Acquire::NORETAIN);
|
StrongRef<CompressedMemory> memory(new CompressedMemory(totalsize), Acquire::NORETAIN);
|
||||||
|
|
||||||
// .astc files only store a single mipmap level.
|
// .astc files only store a single mipmap level.
|
||||||
memcpy(memory->data, (uint8 *) filedata->getData() + sizeof(ASTCHeader), totalsize);
|
memcpy(memory->data, (uint8 *) filedata->getData() + sizeof(ASTCHeader), totalsize);
|
||||||
|
|
||||||
images.emplace_back(new CompressedImageData::Slice(cformat, sizeX, sizeY, memory, 0, totalsize), Acquire::NORETAIN);
|
images.emplace_back(new CompressedSlice(cformat, sizeX, sizeY, memory, 0, totalsize), Acquire::NORETAIN);
|
||||||
|
|
||||||
format = cformat;
|
format = cformat;
|
||||||
sRGB = false;
|
sRGB = false;
|
||||||
|
|||||||
@@ -18,11 +18,10 @@
|
|||||||
* 3. This notice may not be removed or altered from any source distribution.
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef LOVE_IMAGE_MAGPIE_ASTC_HANDLER_H
|
#pragma once
|
||||||
#define LOVE_IMAGE_MAGPIE_ASTC_HANDLER_H
|
|
||||||
|
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
#include "CompressedFormatHandler.h"
|
#include "image/CompressedFormatHandler.h"
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
@@ -44,8 +43,8 @@ public:
|
|||||||
// Implements CompressedFormatHandler.
|
// Implements CompressedFormatHandler.
|
||||||
bool canParse(const filesystem::FileData *data) override;
|
bool canParse(const filesystem::FileData *data) override;
|
||||||
|
|
||||||
StrongRef<CompressedImageData::Memory> parse(filesystem::FileData *filedata,
|
StrongRef<CompressedMemory> parse(filesystem::FileData *filedata,
|
||||||
std::vector<StrongRef<CompressedImageData::Slice>> &images,
|
std::vector<StrongRef<CompressedSlice>> &images,
|
||||||
PixelFormat &format, bool &sRGB) override;
|
PixelFormat &format, bool &sRGB) override;
|
||||||
|
|
||||||
}; // ASTCHandler
|
}; // ASTCHandler
|
||||||
@@ -53,5 +52,3 @@ public:
|
|||||||
} // magpie
|
} // magpie
|
||||||
} // image
|
} // image
|
||||||
} // love
|
} // love
|
||||||
|
|
||||||
#endif // LOVE_IMAGE_MAGPIE_ASTC_HANDLER_H
|
|
||||||
|
|||||||
@@ -1,85 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2006-2017 LOVE Development Team
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
* claim that you wrote the original software. If you use this software
|
|
||||||
* in a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "CompressedImageData.h"
|
|
||||||
|
|
||||||
namespace love
|
|
||||||
{
|
|
||||||
namespace image
|
|
||||||
{
|
|
||||||
namespace magpie
|
|
||||||
{
|
|
||||||
|
|
||||||
CompressedImageData::CompressedImageData(std::list<CompressedFormatHandler *> formats, love::filesystem::FileData *filedata)
|
|
||||||
{
|
|
||||||
CompressedFormatHandler *parser = nullptr;
|
|
||||||
|
|
||||||
for (CompressedFormatHandler *handler : formats)
|
|
||||||
{
|
|
||||||
if (handler->canParse(filedata))
|
|
||||||
{
|
|
||||||
parser = handler;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parser == nullptr)
|
|
||||||
throw love::Exception("Could not parse compressed data: Unknown format.");
|
|
||||||
|
|
||||||
memory = parser->parse(filedata, dataImages, format, sRGB);
|
|
||||||
|
|
||||||
if (memory == nullptr)
|
|
||||||
throw love::Exception("Could not parse compressed data.");
|
|
||||||
|
|
||||||
if (format == PIXELFORMAT_UNKNOWN)
|
|
||||||
throw love::Exception("Could not parse compressed data: Unknown format.");
|
|
||||||
|
|
||||||
if (dataImages.size() == 0 || memory->size == 0)
|
|
||||||
throw love::Exception("Could not parse compressed data: No valid data?");
|
|
||||||
}
|
|
||||||
|
|
||||||
CompressedImageData::CompressedImageData(const CompressedImageData &c)
|
|
||||||
{
|
|
||||||
format = c.format;
|
|
||||||
sRGB = c.sRGB;
|
|
||||||
|
|
||||||
memory.set(new Memory(c.memory->size), Acquire::NORETAIN);
|
|
||||||
memcpy(memory->data, c.memory->data, memory->size);
|
|
||||||
|
|
||||||
for (const auto &i : c.dataImages)
|
|
||||||
{
|
|
||||||
Slice *slice = new Slice(i->getFormat(), i->getWidth(), i->getHeight(), memory, i->getOffset(), i->getSize());
|
|
||||||
dataImages.push_back(slice);
|
|
||||||
slice->release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CompressedImageData *CompressedImageData::clone() const
|
|
||||||
{
|
|
||||||
return new CompressedImageData(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
CompressedImageData::~CompressedImageData()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
} // magpie
|
|
||||||
} // image
|
|
||||||
} // love
|
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
// LOVE
|
// LOVE
|
||||||
#include "EXRHandler.h"
|
#include "EXRHandler.h"
|
||||||
|
#include "common/halffloat.h"
|
||||||
|
|
||||||
// tinyexr
|
// tinyexr
|
||||||
#define TINYEXR_IMPLEMENTATION
|
#define TINYEXR_IMPLEMENTATION
|
||||||
@@ -41,7 +42,7 @@ bool EXRHandler::canDecode(love::filesystem::FileData *data)
|
|||||||
return ParseEXRVersionFromMemory(&version, (const unsigned char *) data->getData(), data->getSize()) == TINYEXR_SUCCESS;
|
return ParseEXRVersionFromMemory(&version, (const unsigned char *) data->getData(), data->getSize()) == TINYEXR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EXRHandler::canEncode(PixelFormat /*rawFormat*/, ImageData::EncodedFormat /*encodedFormat*/)
|
bool EXRHandler::canEncode(PixelFormat /*rawFormat*/, EncodedFormat /*encodedFormat*/)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -186,7 +187,7 @@ FormatHandler::DecodedImage EXRHandler::decode(love::filesystem::FileData *data)
|
|||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
FormatHandler::EncodedImage EXRHandler::encode(const DecodedImage & /*img*/, ImageData::EncodedFormat /*encodedFormat*/)
|
FormatHandler::EncodedImage EXRHandler::encode(const DecodedImage & /*img*/, EncodedFormat /*encodedFormat*/)
|
||||||
{
|
{
|
||||||
throw love::Exception("Invalid format.");
|
throw love::Exception("Invalid format.");
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user