I got threading working using your lib for the updating and all but got no fps boost (other then not droping when mouse click) as it spends almost all of its time filling arrays. This means that anything you do on the cpu takes time away from filling arrays but at this point you get so fillrate limited that going through the ugliness may not be worth it. I will probably be fill rate limited at 50k sprites if they are 64*64 pixels. I don't drop fps on my shitty old pc till 100k+ now with the geobatcher.

I know about hyperthreading and all that jazz and I know about pooling (even though I have yet to implement it). I also, use the arraylist trick right now and have avoided link lists like the plague ever since CS 2.....

I need to add in different tex coords as it needs to work with calls that you would use with the old batcher and is still setup for atlases and texture regions. I also need to add rotation on the gpu....not sure how I want to do that. I like the if to check to see if you need to even do rotation and I know that you stay the hell away from ifs in shaders. But I also know that you don't want to use too much trig in shaders.

Question on pooling in java. If you have an object and you take the referance of the object and use new to create a new object of that type. Does the old referance get GC? I think it does. I just don't know if I should have massive methods for resetting or many methods for setting one thing.

Question on pooling in java. If you have an object and you take the referance of the object and use new to create a new object of that type. Does the old referance get GC? I think it does. I just don't know if I should have massive methods for resetting or many methods for setting one thing.

Objecto = null; // Allocates 32/64 bits.o = newObject(); // Allocates the memory needed for the attributes of the "Object" class.o = newObject(); // Allocates a bunch of memory again...// The problem with the above statement is, that// the first "Object" which was created, won't be simply thrown away instantanious, // it needs to be gc'ed (you could have given another object a reference, // the purpose of the gc is to collect objects, which aren't needed anymore...// (I'm just explaining, why the second time "Object" is created, the old// Object doesn't get thrown away...) )// Take this as an example:Objecto = null;o = newObject();anotherObject.setObject(o);o = null;// (In case we wouldn't do it garbage-collected:) the "new Object()" is getting// thrown away, since we re-assign "null" to "o".

How one usually does pooling:

1 2 3 4 5 6 7

// For example with a vector. Can simply be changed to be a particle:// Init-Function or constructor of whatever (your game):Vec2vec = newVec2();// Getting a vector to be used:publicVec2get(floatx, floaty) {returnvec.set(x, y); // Vec2.set(float, float) returns itself.}

The thing about pooling is to avoid "new" statements, because that would allocate new memory, and propably throw away the old object.

So why don't we always use pooling and only have one instance of every class?

Let's dig up the old example, but with vectors, again:

1 2 3 4 5 6 7

Vec2vec = newVec2(10f, 10f);// You expect the enemy to be placed at (10|10), which is right...enemy.setPosition(vec);// ... until now. We change the values for vec, and since we // change the values in the same object, which also got passed// to the enemy, the enemy will now be at (100|100)...vec.set(100f, 100f);

So beware of that when pooling objects.

EDIT:One more thing...There are languages out there, where EVERY object is immutable, which means nothing can be changed. No values. Nothing. (Haskell)It's called "side-effect" (it's just the above example with the enemy, why side-effects are bad). Many functional languages (I'd say) prefer being somehow immutable. Some allow side-effects, but it's not recommended to use them (like scheme / lisp) and some don't allow them (as said: Haskell).

Yeah thats what I kinda though about pooling. So basically you will have to have methods with mass args for all attributes or set them with different method calls as the chance the dead particle being of the type you want is slim.

I was going to do exactly that for rotation. Use vec3 for loc and have z be the rotation. How do I rotate in shader with out dropping performance?

Yeah thats what I kinda though about pooling. So basically you will have to have methods with mass args for all attributes or set them with different method calls as the chance the dead particle being of the type you want is slim.

I was going to do exactly that for rotation. Use vec3 for loc and have z be the rotation. How do I rotate in shader with out dropping performance?

My idea of pooling:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

publicclassPool{

privateArrayList<Particle> pool;

publicPool(){pool = newArrayList<>(); }

publicParticleget(){if(!pool.isEmpty()){returnpool.remove(pool.size() - 1); }//Tell the particle which pool it belongs to//so it can recycle itself when it dies. returnnewParticle(pool);//(Note: the caller of get() is responsible for initializing the particle) }

publicvoidrecycle(Particlep){pool.add(p); }}

Rotation can be done in multiple ways but the best way to do it in a shader is with a 2D rotation matrix. You simply generate a rotation matrix from an angle (the rotation variable) you pass to the shader per particle and rotate the generated coordinates with this matrix. It doesn't affect fill rate at all, so it won't cost anything in a real game. However, it does cost some memory bandwidth for the extra rotation variable per particle plus some geometry shader performance, but this is completely irrelevant in this case since fill rate will outweigh it by far.

You can generate the rotation matrix in your geometry shader like this:

Then rotate the local coordinates by multiply them with this matrix. See the full shader source below.

There's no reason to pack the rotation into a vec3. Just add another float variable to the shader and treat it as a completely different attribute, since that's what it is. Packing is soooo fixed function pipeline.

Java source code(The only relevant stuff is the attribute setup at start and before/after rendering, but I don't have time to pick out the relevant parts... >_<)

Performance had a slight impact since my particles/sprites/whatever are so small and many (= not fill-rate limited): I now only get around 1.0 million particles at 60 FPS, down from 1.1 million. I strongly suspect it's because of the additional memory footprint of the particles. 20 bytes --> 24 bytes = a 20% increase in memory usage. The additional GPU load shouldn't be significant.

EDIT: Did some more benchmarking. Turns out the GPU impact was higher than I thought and that seems to be the main reason for the performance loss. However, doing that math on the CPU instead and uploading all 4 coordinates is of course a lot more expensive, so it's obviously worth it.

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