For past two days I made my first OpenGL project, I know, It's fixed pipeline, but my focus was on gravity algorithm, so, tell what do you think, and how can I make it faster?
main.cpp
#pragma comment(lib, "glew32.lib")
#include <stdlib.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include "GL/glew.h"
#define GLEW_STATIC
#include <glut.h>
#define WIDTH 800
#define HEIGHT 640
#define AU (149.6e6 * 1000)
#define SCALE (250 / AU)
#define G 6.67428e-11
int scale = 10;
struct Vec2 {
double x;
double y;
};
using namespace std;
struct Object {
int id;
Vec2 pos;
Vec2 vel;
double mass;
double r;
};
Object b = Object{ 0, Vec2{ 2 * AU, 1 * AU, }, Vec2{ 0, 20 * 1000 }, 1.98892 * pow(10, 30), 40 };
Object b2 = Object{ 1, Vec2{ 1 * AU, 1 * AU }, Vec2{ 0, -20 * 1000 }, 1.98892 * pow(10, 30), 40 };
vector<Object> bodies;
int bodyIndex = 0;
void init() {
glClearColor(0, 0, 0, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, WIDTH, 0, HEIGHT);
glewInit();
glPointSize(10);
bodies.push_back(b);
bodies.push_back(b2);
bodyIndex = bodies.size();
}
Vec2 attraction(Object body, Object other) {
// Compute the distance of the other body
double dx = other.pos.x - body.pos.x;
double dy = other.pos.y - body.pos.y;
double d = sqrt(pow(other.pos.x - body.pos.x, 2) + pow(other.pos.y - body.pos.y, 2));
// Report an error if the distance is zero; otherwise we'll
// get a ZeroDivisionError exception further down
if (d == 0) std::cout << "[ ! ] Collision between objects is not possible;" << std::endl;
// Compute the force of attraction
double f = G * body.mass * other.mass / pow(d, 2);
//Compute the direction of the force
double theta = atan2(dy, dx);
return Vec2{ cos(theta) * f, sin(theta) * f };
}
void render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
int timestep = 24 * 3600;
glBegin(GL_POINTS);
for (auto b : bodies) {
Vec2 totalForce{ 0, 0 };
for (auto other : bodies) {
if (bodies.at(b.id).id != bodies.at(other.id).id) {
Vec2 force = attraction(bodies.at(b.id), bodies.at(other.id));
totalForce.x += force.x;
totalForce.y += force.y;
}
}
bodies.at(b.id).vel.x += totalForce.x / bodies.at(b.id).mass * timestep;
bodies.at(b.id).vel.y += totalForce.y / bodies.at(b.id).mass * timestep;
bodies.at(b.id).pos.x += bodies.at(b.id).vel.x * timestep;
bodies.at(b.id).pos.y += bodies.at(b.id).vel.y * timestep;
for (int x = 0; x < WIDTH; x += scale) {
for (int y = 0; y < HEIGHT; y += scale) {
float sum = 0;
for (auto b : bodies) {
sum += (b.r / (sqrt(pow(b.pos.x*SCALE - x, 2) + pow(b.pos.y*SCALE - y, 2))*0.001))*0.0001;
glColor3f(sum, sum, sum);
glVertex2i(x, y);
}
}
}
}
glEnd();
glutSwapBuffers();
}
void OnMouseClick(int button, int state, int x, int y){
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
Object X = Object{ bodyIndex, Vec2{ x / SCALE, (HEIGHT - y) / SCALE, }, Vec2{ 0, 0 }, 3.302 * pow(10, 13), 40 };
bodies.push_back(X);
bodyIndex++;
}
}
void timer(int) {
glutPostRedisplay();
glutTimerFunc(1000 / 60, timer, 0);
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitWindowSize(WIDTH-2, HEIGHT);
glutInitWindowPosition(500, 200);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("Gravity");
init();
glutDisplayFunc(render);
glutMouseFunc(OnMouseClick);
glutTimerFunc(50, timer, 50);
glutMainLoop();
return 0;
}