OSDN Git Service

[removed] Unnecessary synchronize blocks in touch handlers.
authornathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Tue, 16 Nov 2010 03:00:59 +0000 (03:00 +0000)
committernathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Tue, 16 Nov 2010 03:00:59 +0000 (03:00 +0000)
[changed] SpriteBatch handles to int, simplified the class, added javadocs.

backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/AndroidInput.java
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/AndroidMultiTouchHandler.java
gdx/src/com/badlogic/gdx/graphics/SpriteBatch.java
gdx/src/com/badlogic/gdx/graphics/SpriteCache.java
tests/gdx-tests-android/src/com/badlogic/gdx/tests/android/MicroBenchmarks.java
tests/gdx-tests/src/com/badlogic/gdx/tests/SpriteCacheTest.java

index 0d092e6..77134df 100644 (file)
@@ -83,8 +83,8 @@ public final class AndroidInput implements Input, OnKeyListener, OnTouchListener
                                }\r
                        }, 1000);\r
 \r
-       List<KeyEvent> keyEvents = new ArrayList<KeyEvent>();\r
-       List<TouchEvent> touchEvents = new ArrayList<TouchEvent>();\r
+       ArrayList<KeyEvent> keyEvents = new ArrayList<KeyEvent>();\r
+       ArrayList<TouchEvent> touchEvents = new ArrayList<TouchEvent>();\r
        int[] touchX = new int[10];\r
        int[] touchY = new int[10];\r
        boolean[] touched = new boolean[10];\r
@@ -290,11 +290,12 @@ public final class AndroidInput implements Input, OnKeyListener, OnTouchListener
                // synchronized in handler.postTouchEvent()\r
                touchHandler.onTouch(event, this);\r
                \r
-               if (sleepTime != 0)\r
+               if (sleepTime != 0) {\r
                        try {\r
                                Thread.sleep(sleepTime);\r
                        } catch (InterruptedException e) {\r
                        }\r
+               }\r
                return true;\r
        }\r
 \r
index f400916..12d4528 100644 (file)
@@ -71,14 +71,12 @@ public class AndroidMultiTouchHandler implements AndroidTouchHandler {
        }\r
 \r
        private void postTouchEvent (AndroidInput input, int type, int x, int y, int pointer) {\r
-               synchronized (input) {\r
-                       TouchEvent event = input.freeTouchEvents.newObject();\r
-                       event.pointer = pointer;\r
-                       event.x = x;\r
-                       event.y = y;\r
-                       event.type = type;                      \r
-                       input.touchEvents.add(event);                                   \r
-               }\r
+               TouchEvent event = input.freeTouchEvents.newObject();\r
+               event.pointer = pointer;\r
+               event.x = x;\r
+               event.y = y;\r
+               event.type = type;                      \r
+               input.touchEvents.add(event);                                   \r
        }\r
 \r
        public boolean supportsMultitouch (AndroidApplication activity) {\r
index f08bf99..7f51aee 100644 (file)
@@ -147,8 +147,8 @@ public class SpriteBatch {
 \r
                vertices = new float[size * Sprite.SPRITE_SIZE];\r
 \r
-               short[] indices = new short[size * 6];\r
                int len = size * 6;\r
+               short[] indices = new short[len];\r
                short j = 0;\r
                for (int i = 0; i < len; i += 6, j += 4) {\r
                        indices[i + 0] = (short) (j + 0);\r
index 5706545..985f55a 100644 (file)
@@ -1,41 +1,86 @@
 \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
 import com.badlogic.gdx.Gdx;\r
 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.MathUtils;\r
 \r
+/**\r
+ * Draws 2D images, optimized for geometry that does not change. Sprites and/or textures are cached and given an ID, which can\r
+ * later be used for drawing. The size, color, and texture region for each cached image cannot be modified. This information is\r
+ * stored in video memory and does not have to be sent to the GPU each time it is drawn.<br>\r
+ * <br>\r
+ * To cache {@link Sprite sprites} or {@link Texture textures}, first call {@link SpriteCache#beginCache()}, then call the\r
+ * appropriate add method to define the images. To complete the cache, call {@link SpriteCache#endCache()} and store the returned\r
+ * cache ID.<br>\r
+ * <br>\r
+ * To draw with SpriteCache, first call {@link #begin()}, then call {@link #draw(int)} with a cache ID. When SpriteCache drawing\r
+ * is complete, call {@link #end()}.<br>\r
+ * <br>\r
+ * By default, SpriteCache draws using screen coordinates and uses an x-axis pointing to the right, an y-axis pointing upwards and\r
+ * the origin is the bottom left corner of the screen. The default transformation and projection matrices can be changed. If the\r
+ * screen is {@link ApplicationListener#resize(int, int) resized}, the SpriteCache's matrices must be updated. For example:<br>\r
+ * <code>cache.getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());</code><br>\r
+ * <br>\r
+ * SpriteCache is managed. If the OpenGL context is lost and the restored, all OpenGL resources a SpriteCache uses internally are\r
+ * restored.<br>\r
+ * <br>\r
+ * SpriteCache is a reasonably heavyweight object. Typically only one instance should be used for an entire application.<br>\r
+ * <br>\r
+ * SpriteCache works with OpenGL ES 1.x and 2.0. For 2.0, it uses its own custom shader to draw.<br>\r
+ * <br>\r
+ * SpriteCache must be disposed once it is no longer needed.\r
+ */\r
 public class SpriteCache {\r
        static private final float[] tempVertices = new float[Sprite.SPRITE_SIZE];\r
 \r
-       final Mesh mesh;\r
-       boolean drawing = false;\r
+       private final Mesh mesh;\r
+       private boolean drawing;\r
        private final Matrix4 transformMatrix = new Matrix4();\r
        private final Matrix4 projectionMatrix = new Matrix4();\r
+       private ArrayList<Cache> caches = new ArrayList();\r
 \r
        private final Matrix4 combinedMatrix = new Matrix4();\r
-       ShaderProgram shader;\r
+       private ShaderProgram shader;\r
 \r
-       private CacheBuidler builder;\r
+       private boolean caching;\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
+        */\r
        public SpriteCache () {\r
                this(1000);\r
        }\r
 \r
+       /**\r
+        * Creates a cache with the specified size, using a default shader if OpenGL ES 2.0 is being used.\r
+        * @param size The maximum number of images this cache can hold. The memory required to hold the images is allocated up front.\r
+        */\r
        public SpriteCache (int size) {\r
+               this(size, createDefaultShader());\r
+       }\r
+\r
+       /**\r
+        * Creates a cache with the specified size and OpenGL ES 2.0 shader.\r
+        * @param size The maximum number of images this cache can hold. The memory required to hold the images is allocated up front.\r
+        */\r
+       public SpriteCache (int size, ShaderProgram shader) {\r
                mesh = new Mesh(true, size * 4, size * 6, new VertexAttribute(Usage.Position, 2, "a_position"), new VertexAttribute(\r
                        Usage.ColorPacked, 4, "a_color"), new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords"));\r
                mesh.setAutoBind(false);\r
 \r
-               short[] indices = new short[size * 6];\r
-               int len = size * 6;\r
+               int length = size * 6;\r
+               short[] indices = new short[length];\r
                short j = 0;\r
-               for (int i = 0; i < len; i += 6, j += 4) {\r
+               for (int i = 0; i < length; i += 6, j += 4) {\r
                        indices[i + 0] = (short)(j + 0);\r
                        indices[i + 1] = (short)(j + 1);\r
                        indices[i + 2] = (short)(j + 2);\r
@@ -46,56 +91,59 @@ public class SpriteCache {
                mesh.setIndices(indices);\r
 \r
                projectionMatrix.setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());\r
-\r
-               if (Gdx.graphics.isGL20Available()) createShader();\r
-       }\r
-\r
-       private void createShader () {\r
-               String vertexShader = "attribute vec4 a_position;\n" //\r
-                       + "attribute vec4 a_color;\n" //\r
-                       + "attribute vec2 a_texCoords;\n" //\r
-                       + "uniform mat4 u_projectionViewMatrix;\n" //\r
-                       + "varying vec4 v_color; \n" //\r
-                       + "varying vec2 v_texCoords;\n" //\r
-                       + "void main()\n" //\r
-                       + "{\n" //\r
-                       + "   v_color = a_color; \n" //\r
-                       + "   v_texCoords = a_texCoords; \n" //\r
-                       + "   gl_Position =  u_projectionViewMatrix * a_position;\n" //\r
-                       + "}";\r
-               String fragmentShader = "precision mediump float;\n" //\r
-                       + "varying vec4 v_color;\n" //\r
-                       + "varying vec2 v_texCoords;\n" //\r
-                       + "uniform sampler2D u_texture;\n" //\r
-                       + "void main()\n" //\r
-                       + "{\n" //\r
-                       + "  gl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n" //\r
-                       + "}";\r
-               shader = new ShaderProgram(vertexShader, fragmentShader);\r
-               if (shader.isCompiled() == false) throw new IllegalArgumentException("Error compiling shader: " + shader.getLog());\r
        }\r
 \r
+       /**\r
+        * Starts the definition of a new cache, allowing the add and {@link #endCache()} methods to be called.\r
+        */\r
        public void beginCache () {\r
-               if (builder != null) throw new IllegalStateException("endCache must be called before begin.");\r
-               builder = new CacheBuidler(mesh.getNumVertices() / 2 * 6);\r
+               if (caching) throw new IllegalStateException("endCache must be called before begin.");\r
+               caching = true;\r
+\r
+               offset = mesh.getNumVertices() / 2 * 6;\r
                mesh.getVerticesBuffer().compact();\r
        }\r
 \r
-       public Cache endCache () {\r
-               if (builder == null) throw new IllegalStateException("beginCache mustbe called before endCache.");\r
-               Cache cache = builder.finish();\r
-               builder = null;\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
-               return cache;\r
+\r
+               textures.clear();\r
+               counts.clear();\r
+\r
+               return caches.size() - 1;\r
        }\r
 \r
+       /**\r
+        * Adds the specified image to the cache.\r
+        */\r
        public void add (Texture texture, float[] vertices, int offset, int length) {\r
-               if (builder == null) throw new IllegalStateException("beginCache mustbe called before add.");\r
-               builder.add(texture, vertices.length / Sprite.SPRITE_SIZE);\r
+               if (!caching) 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
+               if (lastIndex < 0 || textures.get(lastIndex) != texture) {\r
+                       textures.add(texture);\r
+                       counts.add(count);\r
+               } else\r
+                       counts.set(lastIndex, counts.get(lastIndex) + count);\r
 \r
                mesh.getVerticesBuffer().put(vertices);\r
        }\r
 \r
+       /**\r
+        * Adds the specified image to the cache.\r
+        */\r
        public void add (Texture texture, float x, float y, int srcWidth, int srcHeight, float u, float v, float u2, float v2,\r
                float color) {\r
                final float fx2 = x + srcWidth;\r
@@ -128,6 +176,9 @@ public class SpriteCache {
                add(texture, tempVertices, 0, 20);\r
        }\r
 \r
+       /**\r
+        * Adds the specified image to the cache.\r
+        */\r
        public void add (Texture texture, float x, float y, int srcX, int srcY, int srcWidth, int srcHeight, Color tint) {\r
                float invTexWidth = 1.0f / texture.getWidth();\r
                float invTexHeight = 1.0f / texture.getHeight();\r
@@ -167,6 +218,9 @@ public class SpriteCache {
                add(texture, tempVertices, 0, 20);\r
        }\r
 \r
+       /**\r
+        * Adds the specified image to the cache.\r
+        */\r
        public void add (Texture texture, float x, float y, float width, float height, int srcX, int srcY, int srcWidth,\r
                int srcHeight, Color tint, boolean flipX, boolean flipY) {\r
 \r
@@ -219,6 +273,9 @@ public class SpriteCache {
                add(texture, tempVertices, 0, 20);\r
        }\r
 \r
+       /**\r
+        * Adds the specified image to the cache.\r
+        */\r
        public void add (Texture texture, float x, float y, float originX, float originY, float width, float height, float scaleX,\r
                float scaleY, float rotation, int srcX, int srcY, int srcWidth, int srcHeight, Color tint, boolean flipX, boolean flipY) {\r
 \r
@@ -344,10 +401,16 @@ public class SpriteCache {
                add(texture, tempVertices, 0, 20);\r
        }\r
 \r
+       /**\r
+        * Adds the specified sprite to the cache.\r
+        */\r
        public void add (Sprite sprite) {\r
                add(sprite.getTexture(), sprite.getVertices(), 0, 20);\r
        }\r
 \r
+       /**\r
+        * Prepares the OpenGL state for SpriteCache rendering.\r
+        */\r
        public void begin () {\r
                if (drawing) throw new IllegalStateException("end must be called before begin.");\r
 \r
@@ -358,9 +421,7 @@ public class SpriteCache {
                        gl.glDisable(GL10.GL_DEPTH_TEST);\r
                        gl.glDisable(GL10.GL_CULL_FACE);\r
                        gl.glDepthMask(false);\r
-\r
                        gl.glEnable(GL10.GL_TEXTURE_2D);\r
-                       // gl.glActiveTexture( GL10.GL_TEXTURE0 );\r
 \r
                        gl.glMatrixMode(GL10.GL_PROJECTION);\r
                        gl.glLoadMatrixf(projectionMatrix.val, 0);\r
@@ -376,9 +437,7 @@ public class SpriteCache {
                        gl.glDisable(GL20.GL_DEPTH_TEST);\r
                        gl.glDisable(GL20.GL_CULL_FACE);\r
                        gl.glDepthMask(false);\r
-\r
                        gl.glEnable(GL20.GL_TEXTURE_2D);\r
-                       // gl.glActiveTexture( GL20.GL_TEXTURE0 );\r
 \r
                        shader.begin();\r
                        shader.setUniformMatrix("u_projectionViewMatrix", combinedMatrix);\r
@@ -389,6 +448,9 @@ public class SpriteCache {
                drawing = true;\r
        }\r
 \r
+       /**\r
+        * Completes rendering for this SpriteCache.f\r
+        */\r
        public void end () {\r
                if (!drawing) throw new IllegalStateException("begin must be called before end.");\r
                drawing = false;\r
@@ -408,9 +470,13 @@ public class SpriteCache {
                mesh.unbind();\r
        }\r
 \r
-       public void draw (Cache cache) {\r
+       /**\r
+        * Draws all the images defined for the specified cache ID.\r
+        */\r
+       public void draw (int cacheID) {\r
                if (!drawing) throw new IllegalStateException("SpriteCache.begin must be called before draw.");\r
 \r
+               Cache cache = caches.get(cacheID);\r
                int offset = cache.offset;\r
                Texture[] textures = cache.textures;\r
                int[] counts = cache.counts;\r
@@ -431,6 +497,9 @@ public class SpriteCache {
                }\r
        }\r
 \r
+       /**\r
+        * Releases all resources held by this SpriteCache.\r
+        */\r
        public void dispose () {\r
                mesh.dispose();\r
                if (shader != null) shader.dispose();\r
@@ -454,34 +523,7 @@ public class SpriteCache {
                transformMatrix.set(transform);\r
        }\r
 \r
-       private class CacheBuidler {\r
-               private final ArrayList<Texture> textures = new ArrayList(8);\r
-               private final ArrayList<Integer> counts = new ArrayList(8);\r
-               private final int offset;\r
-\r
-               CacheBuidler (int offset) {\r
-                       this.offset = offset;\r
-               }\r
-\r
-               void add (Texture texture, int count) {\r
-                       count *= 6;\r
-                       int lastIndex = textures.size() - 1;\r
-                       if (lastIndex < 0 || textures.get(lastIndex) != texture) {\r
-                               textures.add(texture);\r
-                               counts.add(count);\r
-                       } else\r
-                               counts.set(lastIndex, counts.get(lastIndex) + count);\r
-               }\r
-\r
-               Cache finish () {\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
-                       return cache;\r
-               }\r
-       }\r
-\r
-       public class Cache {\r
+       static private class Cache {\r
                final int offset;\r
                final Texture[] textures;\r
                final int[] counts;\r
@@ -492,4 +534,31 @@ public class SpriteCache {
                        this.counts = counts;\r
                }\r
        }\r
+\r
+       static ShaderProgram createDefaultShader () {\r
+               if (!Gdx.graphics.isGL20Available()) return null;\r
+               String vertexShader = "attribute vec4 a_position;\n" //\r
+                       + "attribute vec4 a_color;\n" //\r
+                       + "attribute vec2 a_texCoords;\n" //\r
+                       + "uniform mat4 u_projectionViewMatrix;\n" //\r
+                       + "varying vec4 v_color; \n" //\r
+                       + "varying vec2 v_texCoords;\n" //\r
+                       + "void main()\n" //\r
+                       + "{\n" //\r
+                       + "   v_color = a_color; \n" //\r
+                       + "   v_texCoords = a_texCoords; \n" //\r
+                       + "   gl_Position =  u_projectionViewMatrix * a_position;\n" //\r
+                       + "}";\r
+               String fragmentShader = "precision mediump float;\n" //\r
+                       + "varying vec4 v_color;\n" //\r
+                       + "varying vec2 v_texCoords;\n" //\r
+                       + "uniform sampler2D u_texture;\n" //\r
+                       + "void main()\n" //\r
+                       + "{\n" //\r
+                       + "  gl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n" //\r
+                       + "}";\r
+               ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader);\r
+               if (shader.isCompiled() == false) throw new IllegalArgumentException("Error compiling shader: " + shader.getLog());\r
+               return shader;\r
+       }\r
 }\r
index a9742f5..b519d78 100644 (file)
@@ -88,11 +88,11 @@ public class MicroBenchmarks extends Activity {
                testThread.start();\r
        }\r
 \r
-       private void tic () {\r
+       void tic () {\r
                start = System.nanoTime();\r
        }\r
 \r
-       private void toc (final String info) {\r
+       void toc (final String info) {\r
                final float time = (System.nanoTime() - start) / 1000000000.0f;\r
 \r
                tv.post(new Runnable() {\r
index bdd86df..6675e6f 100644 (file)
@@ -36,7 +36,7 @@ public class SpriteCacheTest extends GdxTest implements InputProcessor {
        Texture texture;\r
        Texture texture2;\r
        SpriteCache spriteCache;\r
-       SpriteCache.Cache normalCache, spritesCache;\r
+       int normalCacheID, spriteCacheID;\r
        int renderMethod = 0;\r
 \r
        @Override public void render () {\r
@@ -59,7 +59,7 @@ public class SpriteCacheTest extends GdxTest implements InputProcessor {
                begin = (System.nanoTime() - start) / 1000000000.0f;\r
 \r
                start = System.nanoTime();\r
-               spriteCache.draw(normalCache);\r
+               spriteCache.draw(normalCacheID);\r
                draw1 = (System.nanoTime() - start) / 1000000000.0f;\r
 \r
                start = System.nanoTime();\r
@@ -91,7 +91,7 @@ public class SpriteCacheTest extends GdxTest implements InputProcessor {
                begin = (System.nanoTime() - start) / 1000000000.0f;\r
 \r
                start = System.nanoTime();\r
-               spriteCache.draw(spritesCache);\r
+               spriteCache.draw(spriteCacheID);\r
                draw1 = (System.nanoTime() - start) / 1000000000.0f;\r
 \r
                start = System.nanoTime();\r
@@ -164,7 +164,7 @@ public class SpriteCacheTest extends GdxTest implements InputProcessor {
                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
-               normalCache = spriteCache.endCache();\r
+               normalCacheID = spriteCache.endCache();\r
 \r
                angle = -15;\r
                \r
@@ -179,7 +179,7 @@ public class SpriteCacheTest extends GdxTest implements InputProcessor {
                        sprites3[i].setScale(scale);\r
                        spriteCache.add(sprites3[i]);\r
                }\r
-               spritesCache = spriteCache.endCache();\r
+               spriteCacheID = spriteCache.endCache();\r
                \r
                Gdx.input.setInputProcessor(this);\r
        }\r