Skip to content

Instantly share code, notes, and snippets.

# DanielOaks/particles.cpp Last active Dec 18, 2015

OpenGL 2/3d particle test. First time doing anything in C/C++ for years, beware
 // First (proper) try at OpenGL programming, and first bit of C-like stuff // for years, besides a quick dabble in C# ; caveat emptor // // Daniel Oaks 2013, public domain etc // // g++ -Wall -L/usr/lib -lGL -lGLU -lglut --std=c++11 particles.cpp -o particles #include #include #include #include #include #include using namespace std; #define GRAVITY_STRENGTH (-0.2) #define NUMBER_OF_PARTICLES (30) #define PARTICLE_AGE (60) // Holds X, Y, and Z values, of either direction or forces // class Xyz { private: float x, y, z; public: float getX(); void setX(float value); void affectX(float value); float getY(); void setY(float value); void affectY(float value); float getZ(); void setZ(float value); void affectZ(float value); }; // X float Xyz::getX() { return x; } void Xyz::setX(float value) { x = value; } void Xyz::affectX(float value) { setX(getX() + value); } // Y float Xyz::getY() { return y; } void Xyz::setY(float value) { y = value; } void Xyz::affectY(float value) { setY(getY() + value); } // Z float Xyz::getZ() { return z; } void Xyz::setZ(float value) { z = value; } void Xyz::affectZ(float value) { setZ(getZ() + value); } // Holds a point, the forces affecting it, and allows simple affecting of it // class Point { private: Xyz forces; void initialize(float position_x, float position_y, float position_z); public: Xyz location; long age; Point(float position_x, float position_y, float position_z); void affect_by_forces(float force_on_x, float force_on_y, float force_on_z); void affect_by_gravity(); void tick(); void draw(); }; Point::Point(float position_x, float position_y, float position_z) { initialize(position_x, position_y, position_z); } void Point::initialize(float position_x, float position_y, float position_z) { location.setX(position_x); location.setY(position_y); location.setZ(position_z); forces.setX(0.0); forces.setY(0.0); forces.setZ(0.0); age = PARTICLE_AGE; } void Point::affect_by_forces(float force_on_x, float force_on_y, float force_on_z) { forces.affectX(force_on_x); forces.affectY(force_on_y); forces.affectZ(force_on_z); } void Point::affect_by_gravity() { forces.affectY(GRAVITY_STRENGTH); } void Point::tick() { age--; if (age < 0){ age = 0; } location.affectX(forces.getX()); location.affectY(forces.getY()); location.affectZ(forces.getZ()); } void Point::draw() { glBegin(GL_POINTS); glColor4f (1.0, (age / (float) PARTICLE_AGE), ((age / 2.3) / (float) PARTICLE_AGE), 1.0); glVertex3f(location.getX(), location.getY(), location.getZ()); glEnd(); } // Main program // // our particles list particle_list; // random! std::default_random_engine generator; std::uniform_real_distribution distribution(-7.0, 7.0); auto random_force = std::bind(distribution, generator); std::default_random_engine grav_generator; std::uniform_real_distribution grav_distribution(3.5, 10.0); auto random_grav_force = std::bind(grav_distribution, grav_generator); // this makes a gradient background, but that seems to slooooooooow // particles down a whole bunch void drawBackground() { glBegin(GL_QUADS); //red color glColor4f(0.05,0.0,0.2,1.0); glVertex3f(-1000.0, 1000.0,-1050.0); glVertex3f(-1000.0,-1000.0,-1050.0); //blue color glColor4f(0.05,0.0,0.1,1.0); glVertex3f(1000.0,-1000.0,-1050.0); glVertex3f(1000.0, 1000.0,-1050.0); glEnd(); } void changeSize(int w, int h) { // prevent divide-by-zero, when window height of zero if(h == 0) { h = 1; } float ratio = (1.0 * w) / h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0, 0, w, h); gluPerspective(45, ratio, 1, 1060); glMatrixMode(GL_MODELVIEW); } void renderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // draw current particles list::iterator i; for(i=particle_list.begin(); i != particle_list.end(); ++i) { i->affect_by_gravity(); i->tick(); i->draw(); } // add new particle for(int j = 0; j < NUMBER_OF_PARTICLES; j++) { particle_list.push_back(Point(0.0, -30.0, -1000.0)); particle_list.back().affect_by_forces((float) random_force(), (float) random_force() + (float) random_grav_force(), 0.0); } // remove front particle if possible while (particle_list.front().age == 0) { particle_list.pop_front(); } glutSwapBuffers(); } // ticks drawing function, keeps time in sync and all // so yeah, this doesn't do anything yet... shh, I'll fix it later long milliseconds = 0; void idleTick(void) { renderScene(); } // actually do all our stuff int main(int argc, char **argv) { // initialize glut glutInit(&argc, argv); glutInitWindowPosition(30, 30); glutInitWindowSize(500, 500); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow("So yeah..."); glClearColor(0.06, 0.0, 0.13, 1.0); // callbacks glutDisplayFunc(renderScene); glutReshapeFunc(changeSize); glutIdleFunc(idleTick); // loop glutMainLoop(); return 0; }
to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.