123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
function Spriter:draw( x, y )
local canvas = self:getCanvas()
--Only possible to use sprite batch if we used texture packer structure - default is series of disparate images
if self.usingTexturePacker then
self.spriteBatch:clear()
self.spriteBatch:bind()
end
local frameData = self:getFrameData()
--In my engine I had transformations active during rendering
--I had to re-set everything to origin to render at origin of canvas
--This should be safe
love.graphics.push()
love.graphics.origin()
--Draw onto off-screen canvas for flipping
--I'm sure there's an algorithmic solution to flipping the animation, but
--This was easier to me initially
--I'm not sure how to cleanly build a bounding rect to create a good canvas size, so I'm just doing screen w/h for now
--All graphics operations from this point forward render to canvas instead of screen
love.graphics.setCanvas(canvas)
--Duh
love.graphics.clear()
--I believe this is the default, but in case it's set elsewhere:w
love.graphics.setBlendMode('alpha')
--Loop through framedata and render images (bones are also in array)
for i = 1, # frameData do
local imageData = frameData[i]
if imageData.dataType == "image" then
local x, y = self:spriterToScreen( imageData.x, imageData.y )
love.graphics.setColor(255, 255, 255)
--Pivot data is stored as 0-1, but actually represents an offset of 0-width or 0-height for rotation purposes
local pivotX = imageData.pivotX or 0
local pivotY = imageData.pivotY or 1
if not self.usingTexturePacker then
--Rescape pivot data from 0,1 to 0,w/h
pivotX = rescale( pivotX, 0, 1, 0, imageData.image:getWidth() )
--Love2D has Y inverted from Spriter behavior -- pivotY is height - pivotY value
pivotY = imageData.image:getHeight() - rescale( pivotY, 0, 1, 0, imageData.image:getHeight() )
love.graphics.draw(imageData.image, x, y, -imageData.angle, imageData.scale_x, imageData.scale_y, pivotX, pivotY)
else
assert(imageData.tile, "No imageData.tile")
local w, h = imageData.tile.w, imageData.tile.h
assert(w and h, "Error getting dimensions of " .. tostring(imageData.tile.fileName))
pivotX = rescale( pivotX, 0, 1, 0, w )
--Love2D has Y inverted from Spriter behavior -- pivotY is height - pivotY value
pivotY = h - rescale( pivotY, 0, 1, 0, h )
--love.graphics.draw(self.textureAtlas.texture, imageData.tile.quad, x, y, -imageData.angle, imageData.scale_x, imageData.scale_y, pivotX, pivotY)
self.spriteBatch:add(imageData.tile.quad, x, y, -imageData.angle, imageData.scale_x, imageData.scale_y, pivotX, pivotY)
end
end
end
--Texturepacker rendering overhead
if self.usingTexturePacker then
self.spriteBatch:unbind()
love.graphics.draw(self.spriteBatch)
end
if self:getDebug() then
self:drawDebugInfo()
end
--Turn off canvas. Graphics operations now apply to screen
love.graphics.setCanvas()
-- The rectangle from the Canvas was already alpha blended.
-- Use the premultiplied blend mode when drawing the Canvas itself to prevent another blending.
love.graphics.setBlendMode("multiply", 'premultiplied')
--Return to transformations active prior to our draw
love.graphics.pop()
local scaleX, scaleY = self:getScale()
local xOffset, yOffset = self:getOffset()
local inversionOffset = self:getInversionOffset()
x = x + xOffset
y = y + yOffset
local canvasOffsetX, canvasOffsetY = self:getCanvasOffset()
--We offset things in the canvas purely to avoid clipping of the sprite. If we do so,
--We have to un-do the offset prior to rendering the canvas
x = x - (canvasOffsetX * scaleX)
y = y - (canvasOffsetY * scaleY)
local inverted = self:getInverted()
--I'm sure there's a more elegant way to handle this, but I'm being lazy.
--Handle flips by rendering with -1 x scaling
if not inverted then
love.graphics.draw(canvas, x, y, 0, scaleX, scaleY)
else
--Need to offset x position due to scaling
love.graphics.draw(canvas, x + inversionOffset, y, 0, -scaleX, scaleY)
end
--Turn default back on
love.graphics.setBlendMode('alpha')
end --draw