love2d教程12--画布和批量绘图
这次主要介绍两个批量绘图的结构canvas和spritebatch,到此love.graphics模块的数据类型就基本介绍完了.
canvas(0.8之前是framebuffer,现已不用)
画布用于离屏渲染,你可以认为它是一个不可见的屏幕,能在上面绘图,但是玩家看不见它,直到你把它绘制到
实际的屏幕上。它也被称为“渲染到纹理”。把不常动的物体(如背景)绘制到画布上,之后把整个画布绘制到屏幕上,可以提高效率.
spritebatch
批量精灵(我直译的),可以仅使用一次draw绘制单一图像的任意数量副本。把图像纹理集 (包含许多独立图像的单个图像)添加quad到批处理,
可以绘制纹理集中的的不同子图(就是前面文章中我说的图块)。
先看一下canvas的使用
1创建
canvas = love.graphics.newCanvas( width, height ) --若不带参数则是窗口大小
2在画布上绘图
一种是
canvas:renderTo( func ) --func是函数
另一种
love.graphics.setCanvas( canvas )
func()
love.graphics.setCanvas()
3显示,在love.draw()回调函数里
love.graphics.draw(canvas,0,0)
注意不要在love.draw()和love.update(dt)函数里在canvas上画图,否则速度比不用canvas还慢.
canvas里还有一个比较重要的函数setWrap(),它用来设置如何处理变换后的canvas.有两种模式
"clamp"变换后超出canvas边界的部分将消失,"repeat"变换后超出的部分会在另一边绘制.
再看spritebatch的使用
1创建
mybatch=love.graphics.newSpriteBatch(img,number) --number最大为1000
2向batch里添加要绘制的图像
--添加普通图片
id = mybatch:add( x, y, r, sx, sy, ox, oy, kx, ky) --与love.graphics.draw()参数意义相同
--或添加quad
id=mybatch:addq( quad,x, y, r, sx, sy, ox, oy, kx, ky)
注意这里的quad是创建spritebatch的参数img中的,id为数字,编号从0开始,添加一次增一.
(lua都是以1为起始,而且love里其它地方也是,可这里竟然从0开始,真是让我意外)
3显示,在love.draw()回调函数里
love.graphics.draw(mybatch,0,0)
spritebatch其它函数还有bind(),即把spirebatch绑定到内存.当更新spirtebatch里内容时,使用bind()
可以提高效率,用法看wiki;setq()更换编号为id的quad.
例子如下,按"c"切换canvas和spritebatch,按"空格"打开测试,可以看到使用canvas比直接绘图几乎快了一倍.不过
spritebatch的使用bind和不用bind没有变化,可能bind只有当更新内容时有效果,或者我用错地方了,希望读者指正.
main.lua (canvas测试修改自love官方论坛里TechnoCat的framebuffer)
lg=love.graphics function testCanvas() img= lg.newImage("tuzi.png") translate = {x=0, y=0} scene = {} scene.width = 2048 scene.height = 2048 --初始化Canvas myCanvas = lg.newCanvas(scene.width, scene.height) --创建随机物体 imageSet = {} --为图片坐标集合 for i = 1, 10000 do local entry = {} entry.x = math.random(scene.width-128) entry.y = math.random(scene.height-128) imageSet[i] = entry end --设置绘图操作 lg.setCanvas(myCanvas) for _,v in ipairs(imageSet) do lg.draw(img, v.x, v.y) end lg.setCanvas() --另一种方法 --[[ myCanvas:renderTo( function() for _,v in ipairs(imageSet) do lg.draw(image, v.x, v.y) end end ) --]] end function drawCanvas() lg.push() lg.translate(translate.x, translate.y) if testOn then lg.draw(myCanvas, 0, 0) else for _,v in ipairs(imageSet) do lg.draw(img, v.x, v.y) end end lg.pop() local fps = love.timer.getFPS() if testOn then lg.setCaption("开启canvas时FPS:" ..fps,0,0) else lg.setCaption("关闭canvas时FPS:" ..fps,0,0) end end function testBatch() tex=lg.newImage("run.png") quad={} local w,h=84,108 local texW,texH=tex:getWidth(),tex:getHeight() local col,row=texW/w,texH/h for i=1,row do for j=1,col do table.insert (quad,lg.newQuad((j-1)*w,(i-1)*h,w,h,texW,texH)) end end --创建512个需要绘制的图片 mySprite = lg.newSpriteBatch( tex,512) end function drawBatch() if testOn then mySprite:bind() for i=1,8 do for j=1,64 do --84,108为图块的宽和高,864为图片的高 mySprite:setColor(math.random(0,255),math.random(0,255),math.random(0,255)) mySprite:addq(quad[j],(j-1)*84,(j-1)*104+(i-1)*864,0,1,1,0,0,0,0) end end mySprite:unbind() else for i=1,8 do for j=1,64 do --84,108为图块的宽和高,864为图片的高 mySprite:setColor(math.random(0,255),math.random(0,255),math.random(0,255)) mySprite:addq(quad[j],math.ceil(j%8-1)*84,math.ceil(j/8-1)*104+(i-1)*864,0,1,1,0,0,0,0) end end end lg.draw(mySprite,0,0) local fps = love.timer.getFPS() if testOn then lg.setCaption("使用bind时fps:" .. fps ) else lg.setCaption("关闭bind时fps:" .. fps) end end function love.load() testOn=false --testOn为false时关闭canvas/spritebatch的bind,为true时开启 mode=false --mode为false测试spritebatch,为true测试canvas testCanvas() testBatch() end function love.update(dt) if love.keyboard.isDown("left") then translate.x = translate.x + 1000*dt elseif love.keyboard.isDown("right") then translate.x = translate.x - 1000*dt end if love.keyboard.isDown("up") then translate.y = translate.y + 1000*dt elseif love.keyboard.isDown("down") then translate.y = translate.y - 1000*dt end end function love.draw() lg.print("press <c> change mode, press <space> open stest",10,10) if mode then drawCanvas() else drawBatch() end lg.setCaption("FPS:" .. love.timer.getFPS() ) end function love.keypressed(k) if k=="c" then mode = not mode end if k==" " then testOn= not testOn end end
代码下载,已clone的直接git pull
git clone git://gitcafe.com/dwdcth/love2d-tutor.git
或git clone https://github.com/dwdcth/mylove2d-tutor-in-chinese.git
作者:半山
出处:http://www.cnblogs.com/xdao/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。