Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (553)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: 1 [2] 3 4 5
  ignore  |  Print  
  Crabs!  (Read 13373 times)
0 Members and 1 Guest are viewing this topic.
Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #30 - Posted 2011-10-07 13:29:06 »

Uh yeah, don't let it sleep, I haven't figured out the lifecycle management part yet... for one thing I can't figure out what to do about the fact that it seems that Android destroys the EGL context whever your app is pushed in the background. That can't be right, surely. Smithers! More work at the labs.

Cas Smiley

Offline zammbi

JGO Coder


Medals: 4



« Reply #31 - Posted 2011-10-07 13:37:59 »

Quote
I've managed to crash it twice, didn't get any message as to *why* it crashed,
You need to check the Android log file. I personally look it up in Eclipse. But you can get Android app to look at it or I believe there might be a hidden log file where it stores it.

Current project - Rename and Sort
Offline Cero
« Reply #32 - Posted 2011-10-07 13:39:52 »

hard to say where the limit is because creating them slows the game down, and also a periodically slow down (garbage collection?), but sometimes it goes back to 62 FPS but then slows down again

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #33 - Posted 2011-10-07 13:44:06 »

I think I've removed virtually all the GC in there - I think the only bit of garbage being created is actual Crabs (not very many!) and a couple of String.valueOfs() to show the crab count and fps, every frame. Not much can be done about that. I was hoping GC wouldn't be noticeable at all on 2.3 (which has an incremental GC), and especially not on 2.3 with dualcores.

Cas Smiley

Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #34 - Posted 2011-10-07 14:53:38 »

New version uploaded - this time with transparency, scaling and rotation. I just looked at it on a vanilla HTC Desire and strangely the framerate was only very slightly affected by all those transparent sprites. This leads me to believe that there is something else amiss with the circle rendering that's punting it into some sort of software emulation.

There are two suspicions:
firstly, I'm using GL_SRC_ALPHA, GL_ONE as the blend equation for the circles (your typical "glowy particle effect"), the sprites use GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, a relatively normal sprite blending mode.

secondly, I'm using slightly odd texture coordinates for the circles, emulating GL_TEXTURE_1D which isn't available in OpenGLES for some reason.

More experiments...

Cas Smiley

Offline Cero
« Reply #35 - Posted 2011-10-07 15:13:36 »

380 seems the limit now, the circles are way more slowing down than the crabs
even when idling with only 200, at 60 fps it drops to 52 every now and then

Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #36 - Posted 2011-10-07 15:19:01 »

Waaaaait a minute... n00b error alert! I put the fps counter in the logic thread not the screen update thread - doh. Now my Galaxy is only managing a more realistic 600 crabs at 60fps before it starts to permanently waver.

I've tweaked the circles.

New version uploaded!

Any difference for anyone?

Cas Smiley

Offline Cero
« Reply #37 - Posted 2011-10-07 15:26:46 »

yellow circles now ?

something seems wrong now, because the game is fluent as hell, but the fps counter says 20, and its 60 by the looks

Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #38 - Posted 2011-10-07 15:28:46 »

Well, that's the strange thing... the logic is running at 60fps but the drawing is occuring at the rate shown - that is, render() is only being called that many times per second. Yet on phones it still looks incredibly smooth, even down to about 20fps. Which I suppose is good news - I think I'm going to cap the game logic and update rate at 30fps in order to cope with Desires and the like which are still very common phones, and it'll still cope and feel smooth enough down to about 15fps by the looks of things.

Cas Smiley

Offline Cero
« Reply #39 - Posted 2011-10-07 15:30:30 »

but its much slower now
100 crabs result in idle 9 FPS

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #40 - Posted 2011-10-07 15:41:52 »

It's the same speed as before, just with the correct fps counter.

Cas Smiley

Offline endolf

JGO Coder


Medals: 7


Current project release date: sometime in 3003


« Reply #41 - Posted 2011-10-07 15:55:05 »

HTC Sensation goes down to 30fps with 600 crabs. At 300 it's down to about 50 fps, 400 it hovers around 40fps.

Endolf

Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #42 - Posted 2011-10-08 22:01:40 »

Hm, so some more extensive testing:

With 1 pixel opaque sprites - the bare minimum you'll agree, and not enough to be troubled by fillrate, I eventually drop down to 15fps with 2300 or so sprites. That's about 35 sprites per millisecond, which just strikes me as really poor Sad And this is purely the "rendering" part as well - this is just GL commands being issued, no sorting etc. going on here, apart from the tiny overhead to draw the FPS counter stuff. Targeting a phone that's not quite as powerful as the Galaxy S II - say, something around 800MHz versus its 1.2GHz, perhaps - we'd probably be looking at 2/3rds of that - maybe 22 sprites per millisecond.

And that's not even thinking about the fact that we're not actually counting the game logic or sprite engine overhead here  Sad On a single-core phone maybe we'd only get half the performance, like 11 sprites per millisecond! To get a half decent framerate (30fps being precisely half-decent) on a single core 800MHz phone means we'd be looking at using a paltry 350-odd sprites per frame! You might not think that's such a big deal but again, that's with no game logic at all to speak of. Even our simple little space invaders game Titan Attacks uses between 500-1000 sprites per frame and that doesn't include non-sprite rendering like special effects and score displays. Droid Assault uses between 1500-5000 sprites per frame!

I tried upping the size of the sprites to see what difference fill rate made to the Galaxy and remarkably even increasing the sprites to 32x32 pixels had absolutely no effect on framerate, leading me to think that the hardware rasteriser is proper fast.

So: I've uploaded a new .apk* with no crabs, just tiny pixels. At what point do you reach a pretty consistent 15fps?

Cas Smiley

* sorry about the size - in the middle of working around an Android asset problem

Offline Cero
« Reply #43 - Posted 2011-10-08 22:49:06 »

Quote
At what point do you reach a pretty consistent 15fps

370

phone has a 600 MHz single core cpu

Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #44 - Posted 2011-10-08 23:03:25 »

Quote
At what point do you reach a pretty consistent 15fps

370

phone has a 600 MHz single core cpu
Oh dear, that's lame Sad

Cas Smiley

Offline Cero
« Reply #45 - Posted 2011-10-08 23:26:23 »

I did buy this phone new together with a plan, this year.
So my guess is, it's safe to assume that many people have phones this slow

you don't even notice it normally - everything is fast, except for a few games from the market

try to make the best out of it =D

Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #46 - Posted 2011-10-08 23:34:12 »

Well, I am currently very suspicious anyway. According to the ARM website, the GPU inside the Galaxy should manage 30m triangles / second (in admittedly what is probably the most contrived test case possible of a single triangle fan with 30m triangles in it). If every single triangle was discrete we might reasonably assume that to end up being 10m triangles/second, or 30m vertices/second. The sprite engine draws each sprite as a pair of triangles with two shared vertices so we should be using up approximately 4 vertices per sprite, and so the theoretical simple throughput should be about 7.5m sprites per second, or 7500 sprites per millisecond. And yet I calculate I'm getting just 35 sprites per millisecond.

Clearly something is completely amiss, for the specs to tell me I should be managing 200x more sprites.

To clarify further: this is literally a single call to glDrawElements with one single batch of GL_TRIANGLES, where each triangle is a single pixel, drawn opaquely. Nothing else. And yet I'm 200x slower than I was expecting. Or have I got something seriously wrong with my maths?

Cas Smiley

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #47 - Posted 2011-10-08 23:47:56 »

Let me start by stating that I haven't run this benchmark, so I have no idea what I'm talking about.

Are you sure fillrate isn't your bottleneck?

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #48 - Posted 2011-10-08 23:56:43 »

Galaxy S II

30 FPS until 1500 crabs.

See my work:
OTC Software
Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #49 - Posted 2011-10-09 00:29:08 »

Let me start by stating that I haven't run this benchmark, so I have no idea what I'm talking about.

Are you sure fillrate isn't your bottleneck?
Definitely. These are 1 pixel sprites. When I increase each sprite to 32x32 the FPS is unchanged.

Cas Smiley

Offline bjgil2

Senior Newbie




That's it Mr. Giraffe, get all the marmalade


« Reply #50 - Posted 2011-10-09 03:34:09 »

At what point do you reach a pretty consistent 15fps?

Samsung Galaxy S
15 fps @ ~1200
Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #51 - Posted 2011-10-09 11:57:02 »

Aha! Bad news! For me, anyway. Just after I went to bed last night (bah, typical) I realised of course that the answer was staring me in the face. It couldn't possibly be the single call to glDrawElements that was slow. And indeed it wasn't, when I commented it out. In fact, the call to glDrawElements is so fast it doesn't even register. Unfortunately it's my sprite engine that's slowing things down. Now I'm going to get to grips with Android profiling and find out what bit's slowest. This is going to be no mean feat - I think I need a factor of 10 speedup :S

Cas Smiley

Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #52 - Posted 2011-10-09 12:13:16 »

My suspicions are confirmed. Turns out sorting takes almost no time at all. Remove the buffer write though, and I get 11,000 sprites before it drops to 15fps. If I remove the sprite transform/scale/rotate part I get 12,500 sprites, but there's not a lot I can really do about that code so it's not going to be optimisable any further. So: mere writing the vertex data is giving me a 5x slowdown, which is very troublesome and suspicious. That is, after all, only 300kb of data in a frame for 2,300 sprites.

Cas Smiley

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #53 - Posted 2011-10-09 12:13:50 »

Why not share it, so we can poke at it. Maybe turn it into a competition, for a small prize Smiley

That way you can work on your next game, instead of on silly performance problems.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #54 - Posted 2011-10-09 12:14:58 »

So: mere writing the vertex data is giving me a 5x slowdown,

My MappedObject library will probably help you out, as you can completely skip that step.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #55 - Posted 2011-10-09 12:35:38 »

I fear that I don't have access to Unsafe in Android. And I am resolute that I will not use native code either Smiley

Here's the offending method:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
      void add(Sprite s, Style newStyle) {
         SpriteImage image = s.image;
         GLBaseTexture newTexture0 = image.texture;
         if (currentRun == null || newStyle != currentStyle || newTexture0 != currentTexture) {
            // Changed state. Start new state.
           currentRun = stateRun[numRuns ++];
            currentRun.style = newStyle;
            currentRun.texture = newTexture0;
            currentRun.startIndex = indexCursor;
            currentRun.endIndex = indexCursor;
            currentStyle = newStyle;
            currentTexture = newTexture0;
         }

         final float tx0 = image.tx0;
         final float tx1 = image.tx1;
         final float ty0 = image.ty0;
         final float ty1 = image.ty1;
         final float xscale = s.xscale;
         final float yscale = s.yscale;
         final float x = s.x + s.ox;
         final float y = s.y + s.oy;
         final float alpha = s.alpha * ALPHA_DIV;

         // First scale then rotate coordinates
        float scaledx0 = -image.hotspotx * xscale;
         float scaledy0 = -image.hotspoty * yscale;
         float scaledx1 = (image.w - image.hotspotx) * xscale;
         float scaledy1 = (image.h - image.hotspoty) * yscale;

         float scaledx00, scaledx10, scaledx11, scaledx01, scaledy00, scaledy10, scaledy11, scaledy01;

         // Then rotate
        final double angle = s.angle;
         if (angle != 0) {
            double angle2 = toRadians(angle);
            double cos = cos(angle2);
            double sin = sin(angle2);

            scaledx00 = (float) (cos * scaledx0 - sin * scaledy0);
            scaledx10 = (float) (cos * scaledx1 - sin * scaledy0);
            scaledx11 = (float) (cos * scaledx1 - sin * scaledy1);
            scaledx01 = (float) (cos * scaledx0 - sin * scaledy1);
            scaledy00 = (float) (sin * scaledx0 + cos * scaledy0);
            scaledy10 = (float) (sin * scaledx1 + cos * scaledy0);
            scaledy11 = (float) (sin * scaledx1 + cos * scaledy1);
            scaledy01 = (float) (sin * scaledx0 + cos * scaledy1);
         } else {
            scaledx00 = scaledx0;
            scaledx10 = scaledx1;
            scaledx11 = scaledx1;
            scaledx01 = scaledx0;
            scaledy00 = scaledy0;
            scaledy10 = scaledy0;
            scaledy11 = scaledy1;
            scaledy01 = scaledy1;
         }

         // Then translate them
        final float x00 = scaledx00 + x;
         final float x01 = scaledx01 + x;
         final float x11 = scaledx11 + x;
         final float x10 = scaledx10 + x;
         final float y00 = scaledy00 + y;
         final float y01 = scaledy01 + y;
         final float y11 = scaledy11 + y;
         final float y10 = scaledy10 + y;
         final ReadableColor[] colors = s.color;

         FloatBuffer floats = vertices;
         IntBuffer ints = intColors;
         int vertex = vertexCursor * VERTEX_SIZE_IN_FLOATS;
         int ivertex = vertex;
         floats.position(vertex);
         ints.position(ivertex);
         floats.put(x00);
         floats.put(y00);
         floats.put(0.0f);
         floats.put(s.mirrored ? tx1 : tx0);
         floats.put(s.flipped ? ty0 : ty1);
         ReadableColor color = colors[0];
         ints.put((color.getRed() << 0) | (color.getGreen() << 8) | (color.getBlue() << 16)
               | (int) (color.getAlpha() * alpha) << 24);

         vertex += VERTEX_SIZE_IN_FLOATS;
         ivertex += VERTEX_SIZE_IN_FLOATS;
         floats.position(vertex);
         ints.position(ivertex);
         floats.put(x10);
         floats.put(y10);
         floats.put(0.0f);
         floats.put(s.mirrored ? tx0 : tx1);
         floats.put(s.flipped ? ty0 : ty1);
         color = colors[1];
         ints.put((color.getRed() << 0) | (color.getGreen() << 8) | (color.getBlue() << 16)
               | (int) (color.getAlpha() * alpha) << 24);

         vertex += VERTEX_SIZE_IN_FLOATS;
         ivertex += VERTEX_SIZE_IN_FLOATS;
         floats.position(vertex);
         ints.position(ivertex);
         floats.put(x11);
         floats.put(y11);
         floats.put(0.0f);
         floats.put(s.mirrored ? tx0 : tx1);
         floats.put(s.flipped ? ty1 : ty0);
         color = colors[2];
         ints.put((color.getRed() << 0) | (color.getGreen() << 8) | (color.getBlue() << 16)
               | (int) (color.getAlpha() * alpha) << 24);

         vertex += VERTEX_SIZE_IN_FLOATS;
         ivertex += VERTEX_SIZE_IN_FLOATS;
         floats.position(vertex);
         ints.position(ivertex);
         floats.put(x01);
         floats.put(y01);
         floats.put(0.0f);
         floats.put(s.mirrored ? tx1 : tx0);
         floats.put(s.flipped ? ty1 : ty0);
         color = colors[3];
         ints.put((color.getRed() << 0) | (color.getGreen() << 8) | (color.getBlue() << 16)
               | (int) (color.getAlpha() * alpha) << 24);


         // Write indices: need 6, for two triangles
        indices.position(indexCursor);
         indices.put((short) (vertexCursor + 0));
         indices.put((short) (vertexCursor + 1));
         indices.put((short) (vertexCursor + 2));
         indices.put((short) (vertexCursor + 0));
         indices.put((short) (vertexCursor + 2));
         indices.put((short) (vertexCursor + 3));


         indexCursor += 6;
         vertexCursor += 4;
         currentRun.endIndex += 6;
      }

(You've seen it before, and I know it's maybe not as efficient as it could be - just surprised at how inefficient it is. First plan: write everything to an int[] using FloatToIntBits then blat the entire int[] to the bytebuffer. Suspect that might be the best way for Android. Have to do int[] because of a colossal Android performance snafu when using FloatBuffer bulk puts.

Cas Smiley

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #56 - Posted 2011-10-09 12:45:06 »

1. See how my FastMath.sin/cos speeds up that rotation part, although you're probably not rotating right now. Remove the double. You can reduce the memory footprint of the lookuptable with the static SIN_BITS variable.


2. Only use indexed put/get on buffers. Threat a buffer like an array: do your own managing of indices.
1  
2  
3  
4  
    // Write indices: need 6, for two triangles
   indices.position(indexCursor);
    indices.put(...);
    indices.put(...);

1  
2  
3  
    // Write indices: need 6, for two triangles
   indices.put(indexCursor+0, ...);
    indices.put(indexCursor+1, ...);

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #57 - Posted 2011-10-09 14:44:57 »

Ok, by using an int[] array to build vertex data, and putting all the floats into it using Float.floatToRawIntBits(), then copying all the vertex data in one go to the direct buffer. I managed to double performance: got it up to 4600 sprites @ 15fps. With your FastMath.sinDeg/cosDeg methods, I managed to eke a further 10% out and got it up to 5200 sprites @ 15fps.

So that's about 2x faster basically. It would help now to get it about 5x faster. I'm just going to try absolute puts into a direct IntBuffer and avoid the int[] array copy and see how that improves things...

Cas Smiley

Offline Spasi
« Reply #58 - Posted 2011-10-09 15:14:39 »

I think that's too much bytecode for a single method. Your implementation must look much different now, but here's how I'd start optimizing:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
void add(Sprite s, Style newStyle) {
   SpriteImage image = s.image;
   GLBaseTexture newTexture0 = image.texture;
   checkState(newStyle, newTexture0);

   // First scale then rotate coordinates
  float scaledx0 = -image.hotspotx * s.xscale;
   float scaledx1 = (image.w - image.hotspotx) * s.xscale;
   float scaledy0 = -image.hotspoty * s.yscale;
   float scaledy1 = (image.h - image.hotspoty) * s.yscale;

   final float x = s.x + s.ox;
   final float y = s.y + s.oy;

   final float x00, x01, x11, x10;
   final float y00, y01, y11, y10;
   
   // Then rotate & translate
  final double angle = s.angle;
   if ( angle != 0 ) {
      double angle2 = toRadians(angle);
      float cos = (float)cos(angle2);
      float sin = (float)sin(angle2);

      x00 = cos * scaledx0 - sin * scaledy0 + x;
      x01 = cos * scaledx0 - sin * scaledy1 + x;
      x11 = cos * scaledx1 - sin * scaledy1 + x;
      x10 = cos * scaledx1 - sin * scaledy0 + x;

      y00 = sin * scaledx0 + cos * scaledy0 + y;
      y01 = sin * scaledx0 + cos * scaledy1 + y;
      y11 = sin * scaledx1 + cos * scaledy1 + y;
      y10 = sin * scaledx1 + cos * scaledy0 + y;
   } else {
      x00 = scaledx0 + x;
      x01 = scaledx0 + x;
      x11 = scaledx1 + x;
      x10 = scaledx1 + x;

      y00 = scaledy0 + y;
      y01 = scaledy1 + y;
      y11 = scaledy1 + y;
      y10 = scaledy0 + y;
   }

   FloatBuffer floats = vertices;
   IntBuffer ints = intColors;

   final float tx0 = s.mirrored ? image.tx1 : image.tx0;
   final float tx1 = s.mirrored ? image.tx0 : image.tx1;
   final float ty0 = s.flipped ? image.ty1 : image.ty0;
   final float ty1 = s.flipped ? image.ty0 : image.ty1;
   final float alpha = s.alpha * ALPHA_DIV;
   final ReadableColor[] colors = s.color;

   int vertex = vertexCursor * VERTEX_SIZE_IN_FLOATS;
   int ivertex = vertex;
   floats.position(vertex);
   ints.position(ivertex);
   putVertex(floats, ints, x00, y00, tx0, ty1, colors[0], alpha);

   vertex += VERTEX_SIZE_IN_FLOATS;
   ivertex += VERTEX_SIZE_IN_FLOATS;
   floats.position(vertex);
   ints.position(ivertex);
   putVertex(floats, ints, x10, y10, tx1, ty1, colors[1], alpha);

   vertex += VERTEX_SIZE_IN_FLOATS;
   ivertex += VERTEX_SIZE_IN_FLOATS;
   floats.position(vertex);
   ints.position(ivertex);
   putVertex(floats, ints, x11, y11, tx1, ty0, colors[2], alpha);

   vertex += VERTEX_SIZE_IN_FLOATS;
   ivertex += VERTEX_SIZE_IN_FLOATS;
   floats.position(vertex);
   ints.position(ivertex);
   putVertex(floats, ints, x01, y01, tx0, ty0, colors[3], alpha);

   putIndices(indices, indexCursor, vertexCursor);

   indexCursor += 6;
   vertexCursor += 4;
   currentRun.endIndex += 6;
}

private void checkState(Style newStyle, GLBaseTexture newTexture0) {
   if ( currentRun == null || newStyle != currentStyle || newTexture0 != currentTexture ) {
      // Changed state. Start new state.
     currentRun = stateRun[numRuns++];
      currentRun.style = newStyle;
      currentRun.texture = newTexture0;
      currentRun.startIndex = indexCursor;
      currentRun.endIndex = indexCursor;
      currentStyle = newStyle;
      currentTexture = newTexture0;
   }
}

private static void putVertex(FloatBuffer floats, IntBuffer ints, float x, float y, float tx, float ty, ReadableColor color, float alpha) {
   floats.put(x);
   floats.put(y);
   floats.put(0.0f);
   floats.put(tx);
   floats.put(ty);
   
   ints.put((color.getRed() << 0) | (color.getGreen() << 8) | (color.getBlue() << 16) | (int)(color.getAlpha() * alpha) << 24);
}

private static void putIndices(ShortBuffer indices, int indexCursor, int vertexCursor) {
   // Write indices: need 6, for two triangles

   indices.put(indexCursor + 0, (short)(vertexCursor + 0));
   indices.put(indexCursor + 1, (short)(vertexCursor + 1));
   indices.put(indexCursor + 2, (short)(vertexCursor + 2));
   indices.put(indexCursor + 3, (short)(vertexCursor + 0));
   indices.put(indexCursor + 4, (short)(vertexCursor + 2));
   indices.put(indexCursor + 5, (short)(vertexCursor + 3));
}


I've extracted a few methods and reorganized the code for better stack locality. Looks like vertex == ivertex always, so that could be cleaned-up further, but I wasn't sure.
Offline princec

JGO Kernel


Medals: 366
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #59 - Posted 2011-10-09 16:36:36 »

It is indeed a big method but unfortunately Dalvik doesn't do any useful inlining, so method calls are to be avoided.

Just tried directly writing to the IntBuffer using absolute put - much slower than writing to int[] array and copying it all at the end. So there we have it: got about 5000 sprites @ 15fps, or, 1250 or so at a glassy smooth 60fps on the Galaxy 2. I suppose that's livable with if I curb my expectations a little and make sure Chaz doesn't go overboard with the particle effects. I think in reality I really need another 2x speedup and as I say, probably not much chance of that happening without proper inlining, more buffer access "intrinsification", bounds check hoisting, peephole optimisation, etc. in Dalvik, for which I won't be holding my breath.

Anyway: latest version, once again with actual crabs, is here. One tap makes 100 crabs. Lifecycle still buggered, turned the music off though.

Cas Smiley

Pages: 1 [2] 3 4 5
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

TehJavaDev (16 views)
2014-08-28 18:26:30

CopyableCougar4 (25 views)
2014-08-22 19:31:30

atombrot (38 views)
2014-08-19 09:29:53

Tekkerue (34 views)
2014-08-16 06:45:27

Tekkerue (32 views)
2014-08-16 06:22:17

Tekkerue (20 views)
2014-08-16 06:20:21

Tekkerue (31 views)
2014-08-16 06:12:11

Rayexar (66 views)
2014-08-11 02:49:23

BurntPizza (44 views)
2014-08-09 21:09:32

BurntPizza (34 views)
2014-08-08 02:01:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!