ãã®ãã¥ãŒããªã¢ã«ã§ã¯ãOpenGLã䜿çšããŠç»åãæç»ããæ¹æ³ãããã³libGDXãSpriteBatchã¯ã©ã¹ã䜿çšããŠãã®ããã»ã¹ãç°¡çŽ åããã³æé©åããæ¹æ³ã«ã€ããŠèª¬æããŸãã
ç»åã®æç»ã
å ã®åœ¢åŒïŒPNGãªã©ïŒããååŸãããGPUã«èªã¿èŸŒãŸããç»åã¯ããã¯ã¹ãã£ãšåŒã°ããŸãã ãã¯ã¹ãã£ã¯ãããã€ãã®ä»æ§ã«åŸã£ãŠæç»ãããŸããããã¯ã幟äœåŠç圢ç¶ã®èª¬æã§ããããã®åœ¢ç¶ã®é ç¹ã«ãã¯ã¹ãã£ãã©ã®ããã«éãããããã§ãã ããšãã°ã幟äœåŠç圢ç¶ã¯é·æ¹åœ¢ã«ããããšãã§ããé·æ¹åœ¢ã®åã³ãŒããŒã¯ãã¯ã¹ãã£ã®å¯Ÿå¿ããã³ãŒããŒãåç §ããŸãã
æç»ããã«ã¯ããã¯ã¹ãã£ãææ°ã®ç¶æ ïŒã¹ãããïŒã«ãããžãªã¡ããªãèšå®ããå¿ èŠããããŸãã ãã¯ã¹ãã£ã衚瀺ãããå Žæã®ãµã€ãºãšå Žæã¯ãOpenGLãã¥ãŒããŒãã®ãžãªã¡ããªãšèšå®ã«ãã£ãŠæ±ºãŸããŸãã å€ãã®2Dã²ãŒã ã¯ãç»é¢è§£å床ã«åãããŠãã¥ãŒããŒããã«ã¹ã¿ãã€ãºããŸãã ããã¯ããžãªã¡ããªããã¯ã»ã«ã§å®çŸ©ãããããšãæå³ããé©åãªãµã€ãºã®ãã¯ã¹ãã£ãç»é¢äžã®é©åãªå Žæã«ç°¡åã«æç»ã§ããŸãã
å€ãã®å Žåããã¯ã¹ãã£ãã€ã³ãã¯é·æ¹åœ¢ã®ãžãªã¡ããªã§è¡ãããŸãã ãŸããéåžžã«å€ãã®å Žåã1ã€ã®ãã¯ã¹ãã£ãŸãã¯ãã®ç°ãªãéšåãäœåºŠãæç»ãããŸãã GPUã§ã¬ã³ããªã³ã°ããããã«1ã€ã®é·æ¹åœ¢ãéä¿¡ããã®ã¯éå¹ççã§ãã 代ããã«ãåäžã®ãã¯ã¹ãã£ã®å€ãã®é·æ¹åœ¢ãèšè¿°ããŠãGPUã«ãŸãšããŠéä¿¡ã§ããŸãã ããã¯ãSpriteBatchã¯ã©ã¹ãè¡ãããšã§ãã
SpriteBatchã¯ããã®ãã¯ã¹ãã£ã衚瀺ãããåé·æ¹åœ¢ã®ãã¯ã¹ãã£ãšåº§æšãååŸããŸãã GPUã«éä¿¡ããã«ãã®æ å ±ãèç©ããŸãã æåŸã«èªã¿èŸŒãŸãããã¯ã¹ãã£ãšã¯ç°ãªããã¯ã¹ãã£ãåãåããšãæåŸã«èªã¿èŸŒãŸãããã¯ã¹ãã£ãã¢ã¯ãã£ãã«ããèç©ãããæç»æ å ±ãGPUã«éä¿¡ãã次ã®ãã¯ã¹ãã£ã®æç»ããŒã¿ã®èç©ãéå§ããŸãã
æç»ããããã€ãã®é·æ¹åœ¢ããšã«ãã¯ã¹ãã£ãå€æŽãããšãSpriteBatchãããªãã®æ°ã®é·æ¹åœ¢ãã°ã«ãŒãåã§ããªããªããŸãã ãŸãããã¯ã¹ãã£ãã€ã³ãã£ã³ã°ã¯éåžžã«é«äŸ¡ãªæäœã§ãã ãããã®çç±ãããå€ãã®å Žåãå€ãã®å°ããªç»åã1ã€ã®å€§ããªç»åã«ä¿åãã倧ããªç»åã®äžéšãæç»ããããšã§ãã¬ã³ããªã³ã°ã®ããã«èç©ãããé·æ¹åœ¢ã®æ°ãæ倧åãããã¯ã¹ãã£ã®å€æŽãåé¿ããŸãã 詳现ã«ã€ããŠã¯ã TexturePackerãåç §ããŠãã ããã
SpriteBatchïŒã¹ãã©ã€ãããã«ãŒïŒ
ã¢ããªã±ãŒã·ã§ã³ã§SpriteBatchã¯ã©ã¹ã䜿çšããæ¹æ³ã¯æ¬¡ã®ãšããã§ãã
public class Game implements ApplicationListener { private SpriteBatch batch; public void create () { batch = new SpriteBatch(); } public void render () { Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); // batch.begin(); // ! batch.end(); } public void resize (int width, int height) { } public void pause () { } public void resume () { } public void dispose () { } }
ã¬ã³ããªã³ã°ã®ããã®ãã¹ãŠã®SpriteBatchåŒã³åºãã¯ãbeginïŒïŒã¡ãœãããšendïŒïŒã¡ãœããã§å²ãå¿ èŠããããŸãã ïŒSpriteBatchã¯ã©ã¹ã§ã¯ãªãïŒä»ã®æ¹æ³ã§æç»ããããã®ã¡ãœããã®åŒã³åºãã¯ãbeginïŒïŒã¡ãœãããšendïŒïŒã¡ãœããã®éã§è¡ããªãã§ãã ããã
ãã¯ã¹ãã£ãŒ
Textureã¯ã©ã¹ã¯ããã¡ã€ã«ããç»åãåãåããGPUã«ããŒãããŸãã ïŒåç §ïŒãããžã§ã¯ãã®ã»ããã¢ããã§èª¬æãããŠããããã«ãã€ã¡ãŒãžãã¡ã€ã«ã¯ãassetsããã£ã¬ã¯ããªã«é 眮ããå¿ èŠããããŸãã ç»åãµã€ãºã¯2ã®ã¹ãä¹ïŒ16x16ã64x256ãªã©ïŒã§ããå¿ èŠããããŸãã
private Texture texture; ... texture = new Texture(Gdx.files.internal("image.png")); ... batch.begin(); batch.draw(texture, 10, 10); batch.end();
ããã«ããããã¯ã¹ãã£ãäœæãããã¬ã³ããªã³ã°ã®ããã«SpriteBatchã¯ã©ã¹ã«éä¿¡ãããŸãã ãã¯ã¹ãã£ã¯é·æ¹åœ¢ã§æç»ããããã®å·Šäžé ã¯ãã€ã³ãïŒ10ã10ïŒã«ãããå¹ ãšé«ãã¯ãã¯ã¹ãã£ã®ãµã€ãºã«çãããªããŸãã SpriteBatchã«ã¯ããã¯ã¹ãã£ãæç»ããããã®å€ãã®ã¡ãœããããããŸãã
draw(Texture texture, float x, float y)
ãã¯ã¹ãã£ã®å¯žæ³ã䜿çšããŠãxãyã«ãã¯ã¹ãã£ãæç»ããŸã
draw(Texture texture, float x, float y, int srcX, int srcY, int srcWidth, int srcHeight)
ãã¯ã¹ãã£ã®äžéšãæç»ããŸãã
draw(Texture texture, float x, float y, float width, float height, int srcX, int srcY, int srcWidth, int srcHeight, boolean flipX, boolean flipY)
å¹
*é«ããŸã§åŒã䌞ã°ãããå Žåã«ãã£ãŠã¯ãã©ãŒãªã³ã°ããããã¯ã¹ãã£ã®äžéšãæç»ããŸãã
draw(Texture texture, float x, float y, float originX, float originY, float width, float height, float scaleX, float scaleY, float rotation, int srcX, int srcY, int srcWidth, int srcHeight, boolean flipX, boolean flipY)
ãã®å·šå€§ãªæ¹æ³ã¯ãå§çž®ïŒã¹ãã¬ããïŒã®å¯èœæ§ãç¹ã®åšãã®å転ãããã³åå°ã®å¯èœæ§ãæã€ãã¯ã¹ãã£ã®äžéšãæç»ããŸãã
draw(Texture texture, float x, float y, float width, float height, float u, float v, float u2, float v2)
å¹
*é«ãã«åŒã䌞ã°ããããã¯ã¹ãã£ã®äžéšãæç»ããŸãã ããã¯ãããé«åºŠãªæ¹æ³ã§ãã 座æšã¯ãã¯ã»ã«ã§ã¯ãªãå®æ°ã§ç€ºãããŸãã
draw(Texture texture, float[] spriteVertices, int offset, int length)
spriteVerticlesã§æå®ããã圢ç¶ã«åŒã£åŒµãããšã«ããããã¯ã¹ãã£ã®äžéšãæç»ããŸã
TextureRegionïŒãã¯ã¹ãã£é åãŸãã¯ãã¯ã¹ãã£ã®äžéšïŒ
TextureRegionã¯ã©ã¹ã¯ããã¯ã¹ãã£å ã®é·æ¹åœ¢ãèšè¿°ãããã¯ã¹ãã£ã®äžéšã®ã¿ãæç»ããããã«äœ¿çšãããŸãã
private TextureRegion region; ... texture = new Texture(Gdx.files.internal("image.png")); region = new TextureRegion(texture, 20, 20, 50, 50); ... batch.begin(); batch.draw(region, 10, 10); batch.end();
ããã§ã20ã20ã50ã50ã¯ããã¯ã¹ãã£ã®äžéšãè¡šãããã€ã³ãïŒ10ã10ïŒã§æç»ãããŸãã ãã¯ã¹ãã£ãšè¿œå ã®ãã©ã¡ãŒã¿ãŒãSpriteBatchã¯ã©ã¹ã«æž¡ãããšã§åãã¢ã¯ã·ã§ã³ãå®è¡ã§ããŸãããTextureRegionã¯ã©ã¹ã䜿çšãããšãè¿œå ã®ãã©ã¡ãŒã¿ãŒãèŠãããããåå¥ã®ãªããžã§ã¯ããå®çŸ©ããŠæäœããæ¹ãç°¡åã«ãªãããããã䟿å©ã«ãªããŸãã
SpriteBatchã«ã¯ãTextureRegionãæç»ããããã®å€ãã®ã¡ãœããããããŸãã
draw(TextureRegion region, float x, float y)
-é åã®å¹
ãšé«ãã䜿çšããŠé åãæç»ããŸãã
draw(TextureRegion region, float x, float y, float width, float height)
-å¹
ãšé«ãã«å§çž®ãããïŒäŒžã³ãïŒé åãæç»ããŸãã
draw(TextureRegion region, float x, float y, float originX, float originY, float width, float height, float scaleX, float scaleY, float rotation)
-å¹
ãšé«ãã«åŒã䌞ã°ãããïŒå§çž®ãããïŒé åãæç»ããŸããåç¹originXãoriginYãåºæºã«ã¹ã±ãŒãªã³ã°ããã³å転ã§ããŸãã
ã¹ãã©ã€ãïŒã¹ãã©ã€ãïŒ
Spriteã¯ã©ã¹ã¯ããã¯ã¹ãã£ã®é åããã®é åãæç»ãããäœçœ®ãããã³é åã®è²ïŒè²ä»ãã®è²-è²ã®é°åœ±ä»ãïŒãèšè¿°ããŸãã
private Sprite sprite; ... texture = new Texture(Gdx.files.internal("image.png")); sprite = new Sprite(texture, 20, 20, 50, 50); sprite.setPosition(10, 10); sprite.setRotation(45); ... batch.begin(); sprite.draw(batch); batch.end();
ããã§ã20ã20ã50ã50ã¯ããã¯ã¹ãã£ã®é åãè¡šãã45床å転ãããã€ã³ãïŒ10ã10ïŒã§æç»ãããŸãã ãã¯ã¹ãã£ãŸãã¯ãã®äžéšãSpriteBatchã«è»¢éããä»ã®ãã©ã¡ãŒã¿ãŒãæž¡ãããšã§åãããšãã§ããŸããããã¹ãŠã®ãã©ã¡ãŒã¿ãŒã1ãæã«ä¿åãããããSpriteã¯ã©ã¹ã¯ããããã䟿å©ã«ããŸãã ãŸããSpriteã¯ã©ã¹ã¯ãžãªã¡ããªãå éšã«æ ŒçŽããå¿ èŠãªå Žåã«ã®ã¿åã«ãŠã³ãããããããã¬ãŒã éã§å€åããªãã¹ã±ãŒãªã³ã°ãå転ããŸãã¯ãã®ä»ã®ããããã£ã®æäœã®ããã©ãŒãã³ã¹ããããã«åäžããŸãã
Spriteã¯ã©ã¹ã¯ãã¢ãã«ã«é¢ããæ å ±ïŒå Žæãå転ã«é¢ããæ å ±ãªã©ïŒãšãã¥ãŒã«é¢ããæ å ±ïŒãã¯ã¹ãã£ã¯åãã¯ã©ã¹ã«ãã£ãŠæç»ãããïŒãæ··åããããšã«æ³šæããŠãã ããã ããã«ãããã¢ãã«ããã¥ãŒããå³å¯ã«åé¢ããã¢ãŒããã¯ãã£ã§Spriteã䜿çšããããšã¯äžé©åã«ãªããŸãã ãã®å ŽåãTextureã¯ã©ã¹ãŸãã¯TextureRegionã¯ã©ã¹ã䜿çšãããšããæå³ããããŸãã
çè²ïŒã·ã§ãŒãã£ã³ã°ïŒè²ïŒ
ãã¯ã¹ãã£ãæç»ãããšããç¹å®ã®è²ã§å¡ãã€ã¶ãããšãã§ããŸãã
private Texture texture; private TextureRegion region; private Sprite sprite; ... texture = new Texture(Gdx.files.internal("image.png")); region = new TextureRegion(texture, 20, 20, 50, 50); sprite = new Sprite(texture, 20, 20, 50, 50); sprite.setPosition(100, 10); sprite.setColor(0, 0, 1, 1); ... batch.begin(); batch.setColor(1, 0, 0, 1); batch.draw(texture, 10, 10); batch.setColor(0, 1, 0, 1); batch.draw(region, 50, 10); sprite.draw(batch); batch.end();
ãã®ã³ãŒãã¯ããã¯ã¹ãã£ããã®é åãããã³è²ä»ãã®ã¹ãã©ã€ããæç»ããæ¹æ³ã瀺ããŠããŸãã è²ã¯RGBAã¢ãã«ã§èšè¿°ãããåã³ã³ããŒãã³ãã®ç¯å²ã¯0ã1ã§ãããã¬ã³ããç¡å¹ã«ãªã£ãŠããå Žåãã¢ã«ãã¡ãã£ãã«ã¯ç¡èŠãããŸãã
ãã¬ã³ã
ããã·ã³ã°ã¯ããã©ã«ãã§æå¹ã«ãªã£ãŠããŸãã ããã¯ããã¯ã¹ãã£ãæç»ããããšãã«ããã®ãã¯ã¹ãã£ã®éæéšåãããã®å Žæã®ç»é¢ã«æ¢ã«æç»ãããŠãããã¯ã»ã«ããçµåã§ããããšãæå³ããŸãã
ããã·ã³ã°ããªãã«ãããšãç»é¢ã«ãã£ããã¹ãŠã®ãã®ãããã®å Žæã«æç»ããããã¯ã¹ãã£ã«ãã£ãŠæ¶å»ãããŸãã ããã¯ããå¹ççã§ãããããå¿ èŠãªãå Žåã¯ãã€ã§ãããã·ã³ã°ããªãã«ã§ããŸãã ããšãã°ããã«ã¹ã¯ãªãŒã³ã§å€§ããªèæ¯ç»åãæç»ããå Žåãäž»ã«ãã¬ã³ããç¡å¹ã«ããããšã§ããã©ãŒãã³ã¹ãæ¹åã§ããŸãã
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); // batch.begin(); batch.disableBlending(); backgroundSprite.draw(batch); batch.enableBlending(); // batch.end();
ã泚æ ç»é¢ããã¬ãŒã ããšã«ã¯ãªã¢ãããããšã確èªããŠãã ããã ããã§ãªãå Žåã¯ãã¢ã«ãã¡ãã£ãã«ããã®ãã¯ã¹ãã£ãäœåºŠãèªèº«ã®äžã«æç»ããããŸã£ããééã£ãå¹æãåŸãããŸãã ãŸããäžéšã®ãããªã¢ã¯ã»ã©ã¬ãŒã¿ã¢ãŒããã¯ãã£ã¯ãå šç»é¢ã§ç»åãæç»ããã®ã§ã¯ãªãããã¬ãŒã ããšã«ç»é¢ãã¯ãªã¢ããæ¹ãããŸãæ©èœããŸãã
ãã¥ãŒããŒã
SpriteBatchã«ã¯ãç¬èªã®æ圱ããã³å€æãããªãã¯ã¹ããããŸãã SpriteBatchãäœæããããšãçŸåšã®ã¢ããªã±ãŒã·ã§ã³ã®å¯žæ³ã䜿çšããŠãU軞ãäžã«åãã座æšç³»ã䜿çšããŠçŽäº€æ圱ã調æŽããŸãïŒã€ãŸãã0ã0ã¯ç»é¢ã®å·Šäžé -çŽTranslatorïŒã beginïŒïŒã¡ãœãããåŒã³åºããããšãSpriteBatchã¯ãã¥ãŒããŒããèšå®ããŸãã
ã泚æ 衚瀺é åã«é¢ãã詳现ãªããã¥ã¡ã³ãã衚瀺ãã次第ãããã«æçš¿ãããŸãã
ããã©ãŒãã³ã¹ã®æ¹åã
SpriteBatchã«ã¯ãGPUã«éä¿¡ããåã«èç©ãããã¹ãã©ã€ãã®æ倧æ°ãåãå ¥ããã³ã³ã¹ãã©ã¯ã¿ãŒããããŸãã ãã®æ°ãå°ãããããšãã¢ã¯ã»ã©ã¬ãŒã¿ãŒãžã®äœåãªåŒã³åºããå€ããªããŸãã æ°å€ã倧ããå ŽåãSpriteBatchã¯å€§éã®ã¡ã¢ãªã䜿çšããŸãã
SpriteBatchã«ã¯ãmaxSpritesInBatchãšãããããªãã¯ãã£ãŒã«ãããããŸãã SpriteBatchã©ã€ããµã€ã¯ã«äžã«äžåºŠã«ãããªã¢ã¯ã»ã©ã¬ãŒã¿ã«ã¬ã³ããªã³ã°ããããã«éä¿¡ã§ããã¹ãã©ã€ãã®æ倧æ°ã瀺ããŸãã ãã®æ°ãéåžžã«å€§ããèšå®ããŠç¢ºèªã§ããŸãã ããã¯ãSpriteBatchã«é©åãªãµã€ãºãèŠã€ããã®ã«åœ¹ç«ã¡ãŸãã SpriteBatchã®ãµã€ãºïŒã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ãæ°ïŒã¯ãmaxSpritesInBatchã®æ°ããããã«è¶ ããå¿ èŠããããŸãã maxSpritesInBatchã¯åžžã«ãŒãã«èšå®ã§ããŸããã€ãŸãããã®ã«ãŠã³ã¿ãŒããªã»ããããŸãã
SpriteBatchã«ã¯ããããªãã¯renderCallsãã£ãŒã«ãããããŸãã 次ã®ã¬ã³ããªã³ã°ãµã€ã¯ã«ã®åŸãéå§ïŒïŒããã³çµäºïŒïŒã®åŒã³åºãéã§SpriteBatchãç°ãªããžãªã¡ããªæ å ±ãéä¿¡ããåæ°ãä¿åããŸãã ããã¯ãç°ãªããã¯ã¹ãã£ãã¹ããããããå ŽåããŸãã¯SpriteBatchããã£ã±ãïŒãã£ãã·ã¥ãå°ããããïŒã®å Žåã«çºçããŸãã SpriteBatchã®ãµã€ãºãæ£ããéžæãããrenderCallsã倧ããããïŒçŽ15ã20ïŒå Žåãããã¯äœ¿çšããŠãããã¯ã¹ãã£ãå€ãããããšã瀺ããŠããŸãã ãã¯ã¹ãã£ã®äžéšã1ã€ã®å€§ããªãã¯ã¹ãã£ã«é 眮ããŠãã ããã
SpriteBatchã«ã¯ããããã¡ãŒã®æ°ãšãµã€ãºãåãå ¥ããè¿œå ã®ã³ã³ã¹ãã©ã¯ã¿ãŒããããŸãã ããã¯ãéåžžã®VAïŒé ç¹é åïŒã®ä»£ããã«VBOïŒé ç¹ãããã¡ãªããžã§ã¯ãïŒã§äœæ¥ããããã«æ瀺ããé«åºŠãªæ©èœã§ãã SpriteBatchã¯ãããã¡ã®ãªã¹ããä¿åããã¬ã³ããªã³ã°ãããã³ã«æ¬¡ã®ãããã¡ã䜿çšããŸãã maxSpritesInBatchãå°ãããrenderCallsã倧ããå Žåããã®æ©èœã«ããããã©ãŒãã³ã¹ããããã«åäžããŸãã