Hi all
I couldn't find an 'intros/newbies' area here so figured I'd dive in here with my first post!
I'm a student of physics and recently got into the idea of putting basic (or complex) physics principles into my own simulators.
So to start I've just thrown together a little attempt at simulating particles in a box. It consists of a larger red (player) ball which you can move around to collide with other particles in the box. Manipulable settings include player mass, particle mass, gravity strength, number of particles, 'anti-gravity' player ball, 'freeze' the particles, and - my favourite - turn on electric fields around all the particles so they repel each other.
There's no 'gaming' element to it, but I'm pleased nonetheless as I've seen that it's possible to quite easily put physics into games. My next effort will probably be something relating to quantum mechanics or fluid dynamics. I'm in the process of learning geophysical fluid dynamics now too so in future I hope to do some basic planetary simulations (in 3D?), where the user can do things like set the rotation speed, gravity, density of atmosphere, generate clouds or ocean currents etc. Along the way I might have a go at making some games out of these things too.
Anyway, here's my first little project :) - https://github.com/Stuart88/Particles (https://github.com/Stuart88/Particles)
Full executable is available in the RAR archive on GitHub, or alternatively the source code is there along with the necessary font and sprite files
. Many of you will probably notice that I rather amateurishly dumped all the code in one huge source file. I know it should have been broken into separate files but visual studio didn't like the way I was trying to share variables across files. Instead of remedying the issue I decided to take the lazy route out of it. My goal here was simply to prove to myself that I can code a basic physics simulator. Later efforts will have neater code.
Also - for the physics folk - In the simulation, the momentum transfer on collision is accurate but for the electric fields it is not. The electric fields were just an extra thing I tacked onto the end, so instead of coding it with proper physics I just wrote an arbitrary velocity transfer using the inverse square law. For all intents and purposes it 'looks' correct, but for large numbers of particles the problem becomes obvious in that they never stop moving in the box (instead of reaching a stable equilibrium).
Another issue is that the particles sometimes 'jiggle' when at rest on the floor of the box
(http://i68.tinypic.com/25sannq.png)
It looks like instancing would require the use of direct OpenGL so a "compromise" would be to use vertex arrays (http://www.sfml-dev.org/tutorials/2.4/graphics-vertex-array.php) via SFML. That way you can draw everything with one draw call and still stick to using SFML stuff.
sf::VertexArray would be a much better way compared to rendering a sprite for every item.
From what I can find instanced rendering depends on glDrawElementsInstanced and GL_DRAW_INDIRECT_BUFFER, so it would require OpenGL 4.0+, which would be a problem for older computers.
SFML works very nicely with inserting custom OpenGL code, thankfully!
Instanced rendering isn't too much worse than a normal draw call. I haven't seen the internals of how VertexArray is rendered/how much faster it is than other primitives in SFML.
Just looked at it. Will be MUCH faster than rendering a separate primitive for each.
OP could do that by putting each particle on the same texture and just setting the texcoords for each array accordingly.
sf::RenderWindow window(sf::VideoMode(800, 800), "SFML works!");
window.setVerticalSyncEnabled(false);
sf::VertexArray Vertices = sf::VertexArray(sf::Quads, 16);
sf::Texture Bullets;
if (!Bullets.loadFromFile("bulletSprites.png")) {
return EXIT_FAILURE;
}
sf::IntRect Particle1{ 173, 112, 11, 11 };
sf::IntRect Particle2{ 188, 112, 11, 11 };
sf::IntRect Particle3{ 203, 112, 11, 11 };
Vertices[0].position = { 50, 50 }; Vertices[0].texCoords = { 173, 112 };
Vertices[1].position = { 70, 50 }; Vertices[1].texCoords = { 173 + 11, 112 };
Vertices[2].position = { 70, 70 }; Vertices[2].texCoords = { 173 + 11, 112 + 11 };
Vertices[3].position = { 50, 70 }; Vertices[3].texCoords = { 173, 112 + 11 };
Vertices[4].position = { 150, 150 }; Vertices[4].texCoords = { 188, 112 };
Vertices[5].position = { 170, 150 }; Vertices[5].texCoords = { 188 + 11, 112 };
Vertices[6].position = { 170, 170 }; Vertices[6].texCoords = { 188 + 11, 112 + 11 };
Vertices[7].position = { 150, 170 }; Vertices[7].texCoords = { 188, 112 + 11 };
Vertices[8].position = { 75, 250 }; Vertices[8].texCoords = { 203, 112 };
Vertices[9].position = { 100, 250 }; Vertices[9].texCoords = { 203 + 11, 112 };
Vertices[10].position = { 100, 275 }; Vertices[10].texCoords = { 203 + 11, 112 + 11 };
Vertices[11].position = { 75, 275 }; Vertices[11].texCoords = { 203, 112 + 11 };
Vertices[12].position = { 150, 350 }; Vertices[12].texCoords = { 173, 112 };
Vertices[13].position = { 170, 350 }; Vertices[13].texCoords = { 173 + 11, 112 };
Vertices[14].position = { 170, 370 }; Vertices[14].texCoords = { 173 + 11, 112 + 11 };
Vertices[15].position = { 150, 370 }; Vertices[15].texCoords = { 173, 112 + 11 };
sf::RenderStates State;
State.texture = &Bullets;
...
window.clear(sf::Color::Black);
window.draw(Vertices, State);
window.display();
Result:
(http://imgur.com/oGrbIuZ.png)