OSDN Git Service

[fixed] Using BitmapFont with Sprite.
authornathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Tue, 23 Nov 2010 08:45:39 +0000 (08:45 +0000)
committernathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Tue, 23 Nov 2010 08:45:39 +0000 (08:45 +0000)
[added] Ability to redefine a cache with SpriteCache.

gdx/src/com/badlogic/gdx/graphics/BitmapFont.java
gdx/src/com/badlogic/gdx/graphics/Sprite.java
gdx/src/com/badlogic/gdx/graphics/SpriteCache.java
gdx/src/com/badlogic/gdx/graphics/SpriteSheet.java
tests/gdx-tests/src/com/badlogic/gdx/tests/SpriteCacheTest.java

index 62a2c1e..3fc69d2 100644 (file)
@@ -90,8 +90,13 @@ public class BitmapFont {
                        Gdx.files.classpath("com/badlogic/gdx/utils/arial-15.png"), false);\r
     }\r
 \r
-    public BitmapFont(FileHandle fontFile, Sprite sprite) {\r
-        init(fontFile, sprite, false);\r
+       /**\r
+        * Creates a new BitmapFont with the glyphs relative to the specified sprite.\r
+        * @param sprite The sprite containing the glyphs. It must NOT be flipped.\r
+        * @param flip If true, the glyphs will be flipped for use with a perspective where 0,0 is the upper left corner.\r
+        */\r
+    public BitmapFont(FileHandle fontFile, Sprite sprite, boolean flip) {\r
+        init(fontFile, sprite, flip);\r
     }\r
 \r
     /**\r
@@ -114,8 +119,8 @@ public class BitmapFont {
 \r
     private void init(FileHandle fontFile, Sprite sprite, boolean flip) {\r
         this.sprite = sprite;\r
-        float invTexWidth = 1.0f / sprite.getWidth();\r
-        float invTexHeight = 1.0f / sprite.getHeight();\r
+        float invTexWidth = 1.0f / sprite.getTexture().getWidth();\r
+        float invTexHeight = 1.0f / sprite.getTexture().getHeight();\r
         float uSprite = sprite.getTextureRegionX();\r
         float vSprite = sprite.getTextureRegionY();\r
         float u2Sprite = uSprite + sprite.getTextureRegionWidth();\r
@@ -182,11 +187,11 @@ public class BitmapFont {
                 glyph.u = uSprite + srcX * invTexWidth;\r
                 glyph.u2 = uSprite + (srcX + glyph.width) * invTexWidth;\r
                 if (flip) {\r
-                    glyph.v =  srcY * invTexHeight;\r
-                    glyph.v2 = (srcY + glyph.height) * invTexHeight;\r
+                    glyph.v = vSprite + srcY * invTexHeight;\r
+                    glyph.v2 = vSprite + (srcY + glyph.height) * invTexHeight;\r
                 } else {\r
-                    glyph.v2 =  srcY * invTexHeight;\r
-                    glyph.v =  (srcY + glyph.height) * invTexHeight;\r
+                    glyph.v2 = vSprite + srcY * invTexHeight;\r
+                    glyph.v = vSprite + (srcY + glyph.height) * invTexHeight;\r
                 }\r
             }\r
 \r
index 0fb1e5d..10c5347 100644 (file)
@@ -494,6 +494,9 @@ public class Sprite {
                spriteBatch.draw(texture, getVertices(), 0, 20);\r
        }\r
 \r
+       /**\r
+        * Sets the sprite's texture. The texture region is unaffected.\r
+        */\r
        public void setTexture(Texture texture) {\r
                this.texture = texture;\r
        }\r
@@ -543,7 +546,7 @@ public class Sprite {
        }\r
        \r
        public float getTextureRegionY () {\r
-               return vertices[V1];\r
+               return vertices[V2];\r
        }\r
        \r
        public float getTextureRegionWidth () {\r
@@ -551,7 +554,7 @@ public class Sprite {
        }\r
        \r
        public float getTextureRegionHeight () {\r
-               return vertices[V1] - vertices[V2];\r
+               return vertices[V2] - vertices[V1];\r
        }\r
 \r
        /**\r
index f4d457e..77e5a34 100644 (file)
@@ -1,6 +1,7 @@
 \r
 package com.badlogic.gdx.graphics;\r
 \r
+import java.nio.FloatBuffer;\r
 import java.util.ArrayList;\r
 \r
 import com.badlogic.gdx.ApplicationListener;\r
@@ -8,6 +9,7 @@ import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.graphics.VertexAttributes.Usage;\r
 import com.badlogic.gdx.graphics.glutils.ShaderProgram;\r
 import com.badlogic.gdx.math.Matrix4;\r
+import com.badlogic.gdx.utils.GdxRuntimeException;\r
 import com.badlogic.gdx.utils.MathUtils;\r
 \r
 /**\r
@@ -48,10 +50,9 @@ public class SpriteCache {
        private final Matrix4 combinedMatrix = new Matrix4();\r
        private ShaderProgram shader;\r
 \r
-       private boolean caching;\r
+       private Cache currentCache;\r
        private final ArrayList<Texture> textures = new ArrayList(8);\r
        private final ArrayList<Integer> counts = new ArrayList(8);\r
-       private int offset;\r
 \r
        /**\r
         * Creates a cache that can contain up to 1000 images.\r
@@ -97,27 +98,60 @@ public class SpriteCache {
         * Starts the definition of a new cache, allowing the add and {@link #endCache()} methods to be called.\r
         */\r
        public void beginCache () {\r
-               if (caching) throw new IllegalStateException("endCache must be called before begin.");\r
-               caching = true;\r
-\r
-               offset = mesh.getNumVertices() / 2 * 6;\r
+               if (currentCache != null) throw new IllegalStateException("endCache must be called before begin.");\r
+               currentCache = new Cache(caches.size(), mesh.getNumVertices() / 2 * 6);\r
+               caches.add(currentCache);\r
                mesh.getVerticesBuffer().compact();\r
        }\r
 \r
        /**\r
+        * Starts the redefinition of an existing cache, allowing the add and {@link #endCache()} methods to be called. The cache\r
+        * cannot have more entries added to it than when it was first created.\r
+        */\r
+       public void beginCache (int cacheID) {\r
+               if (currentCache != null) throw new IllegalStateException("endCache must be called before begin.");\r
+               currentCache = caches.get(cacheID);\r
+               mesh.getVerticesBuffer().position(currentCache.offset);\r
+       }\r
+\r
+       /**\r
         * Ends the definition of a cache, returning the cache ID to be used with {@link #draw(int)}.\r
         */\r
        public int endCache () {\r
-               if (!caching) throw new IllegalStateException("beginCache must be called before endCache.");\r
-               caching = false;\r
-\r
-               Cache cache = new Cache(offset, textures.toArray(new Texture[textures.size()]), new int[counts.size()]);\r
-               for (int i = 0, n = counts.size(); i < n; i++)\r
-                       cache.counts[i] = counts.get(i);\r
-               caches.add(cache);\r
-\r
-               mesh.getVerticesBuffer().flip();\r
+               if (currentCache == null) throw new IllegalStateException("beginCache must be called before endCache.");\r
+\r
+               Cache cache = currentCache;\r
+               int cacheCount = mesh.getVerticesBuffer().position() - cache.offset;\r
+               if (cache.textures == null) {\r
+                       // New cache.\r
+                       cache.maxCount = cacheCount;\r
+                       cache.textures = textures.toArray(new Texture[textures.size()]);\r
+                       cache.counts = new int[counts.size()];\r
+                       for (int i = 0, n = counts.size(); i < n; i++)\r
+                               cache.counts[i] = counts.get(i);\r
+\r
+                       mesh.getVerticesBuffer().flip();\r
+               } else {\r
+                       // Redefine existing cache.\r
+                       if (cacheCount > cache.maxCount)\r
+                               throw new GdxRuntimeException("Cannot redefine a cache with more entries than when it was first created: "\r
+                                       + cacheCount + " (" + cache.maxCount + " max)");\r
+\r
+                       if (cache.textures.length < textures.size()) cache.textures = new Texture[textures.size()];\r
+                       for (int i = 0, n = textures.size(); i < n; i++)\r
+                               cache.textures[i] = textures.get(i);\r
+\r
+                       if (cache.counts.length < counts.size()) cache.counts = new int[counts.size()];\r
+                       for (int i = 0, n = counts.size(); i < n; i++)\r
+                               cache.counts[i] = counts.get(i);\r
+\r
+                       FloatBuffer vertices = mesh.getVerticesBuffer();\r
+                       vertices.position(0);\r
+                       Cache lastCache = caches.get(caches.size() - 1);\r
+                       vertices.limit(lastCache.offset + lastCache.maxCount);\r
+               }\r
 \r
+               currentCache = null;\r
                textures.clear();\r
                counts.clear();\r
 \r
@@ -128,7 +162,7 @@ public class SpriteCache {
         * Adds the specified image to the cache.\r
         */\r
        public void add (Texture texture, float[] vertices, int offset, int length) {\r
-               if (!caching) throw new IllegalStateException("beginCache must be called before add.");\r
+               if (currentCache == null) throw new IllegalStateException("beginCache must be called before add.");\r
 \r
                int count = vertices.length / Sprite.SPRITE_SIZE * 6;\r
                int lastIndex = textures.size() - 1;\r
@@ -522,14 +556,15 @@ public class SpriteCache {
        }\r
 \r
        static private class Cache {\r
+               final int id;\r
                final int offset;\r
-               final Texture[] textures;\r
-               final int[] counts;\r
+               int maxCount;\r
+               Texture[] textures;\r
+               int[] counts;\r
 \r
-               Cache (int offset, Texture[] textures, int[] counts) {\r
+               public Cache (int id, int offset) {\r
+                       this.id = id;\r
                        this.offset = offset;\r
-                       this.textures = textures;\r
-                       this.counts = counts;\r
                }\r
        }\r
 \r
index 562505b..a001da5 100644 (file)
@@ -230,7 +230,6 @@ public class SpriteSheet {
                        return super.getY() - offsetY;\r
                }\r
 \r
-               // BOZO - Test flip works.\r
                public void flip (boolean x, boolean y) {\r
                        super.flip(x, y);\r
                        if (x) {\r
@@ -263,23 +262,30 @@ public class SpriteSheet {
                        return index;\r
                }\r
 \r
+               /**\r
+                * The width of the image, before whitespace was removed for packing.\r
+                */\r
                public int getOriginalWidth () {\r
                        return originalWidth;\r
                }\r
 \r
+               /**\r
+                * The height of the image, before whitespace was removed for packing.\r
+                */\r
                public int getOriginalHeight () {\r
                        return originalHeight;\r
                }\r
 \r
                /**\r
-                * The offset from the left of the original image to the left of the packed image, after whitespace has been removed.\r
+                * The offset from the left of the original image to the left of the packed image, after whitespace was removed for packing.\r
                 */\r
                public int getOffsetX () {\r
                        return offsetX;\r
                }\r
 \r
                /**\r
-                * The offset from the bottom of the original image to the bottom of the packed image, after whitespace has been removed.\r
+                * The offset from the bottom of the original image to the bottom of the packed image, after whitespace was removed for\r
+                * packing.\r
                 */\r
                public int getOffsetY () {\r
                        return offsetY;\r
index 6675e6f..5d9ef71 100644 (file)
@@ -15,6 +15,7 @@ package com.badlogic.gdx.tests;
 \r
 import com.badlogic.gdx.Files.FileType;\r
 import com.badlogic.gdx.Gdx;\r
+import com.badlogic.gdx.Input;\r
 import com.badlogic.gdx.InputProcessor;\r
 import com.badlogic.gdx.graphics.Color;\r
 import com.badlogic.gdx.graphics.GL10;\r
@@ -26,6 +27,7 @@ import com.badlogic.gdx.graphics.Texture;
 import com.badlogic.gdx.graphics.Texture.TextureFilter;\r
 import com.badlogic.gdx.graphics.Texture.TextureWrap;\r
 import com.badlogic.gdx.tests.utils.GdxTest;\r
+import com.badlogic.gdx.utils.MathUtils;\r
 \r
 public class SpriteCacheTest extends GdxTest implements InputProcessor {\r
        int SPRITES = 400 / 2;\r
@@ -39,6 +41,10 @@ public class SpriteCacheTest extends GdxTest implements InputProcessor {
        int normalCacheID, spriteCacheID;\r
        int renderMethod = 0;\r
 \r
+       private float[] sprites;\r
+\r
+       private float[] sprites2;\r
+\r
        @Override public void render () {\r
                if (renderMethod == 0) renderNormal();\r
                ;\r
@@ -123,8 +129,8 @@ public class SpriteCacheTest extends GdxTest implements InputProcessor {
                        TextureWrap.ClampToEdge);\r
                pixmap.dispose();\r
 \r
-               float sprites[] = new float[SPRITES * 6];\r
-               float sprites2[] = new float[SPRITES * 6];\r
+               sprites = new float[SPRITES * 6];\r
+               sprites2 = new float[SPRITES * 6];\r
                Sprite[] sprites3 = new Sprite[SPRITES * 2];\r
 \r
                for (int i = 0; i < sprites.length; i += 6) {\r
@@ -185,6 +191,17 @@ public class SpriteCacheTest extends GdxTest implements InputProcessor {
        }\r
 \r
        @Override public boolean keyDown (int keycode) {\r
+               if (keycode != Input.Keys.KEYCODE_SPACE) return false;\r
+               float scale = MathUtils.random(0.75f, 1.25f);\r
+               float angle = MathUtils.random(1, 360);\r
+               spriteCache.beginCache(normalCacheID);\r
+               for (int i = 0; i < sprites2.length; i += 6)\r
+                       spriteCache.add(texture2, sprites2[i], sprites2[i + 1], 16, 16, 32, 32, scale, scale, angle, 0, 0, 32, 32, Color.WHITE,\r
+                               false, false);\r
+               for (int i = 0; i < sprites.length; i += 6)\r
+                       spriteCache.add(texture, sprites[i], sprites[i + 1], 16, 16, 32, 32, scale, scale, angle, 0, 0, 32, 32, Color.WHITE,\r
+                               false, false);\r
+               spriteCache.endCache();\r
                return false;\r
        }\r
 \r