I'm trying to simulate Newton's law of universal gravitation. I already created the particles, and I added the drawing functions. I can't find why I only see a white window.
#include <GLUT/GLUT.h>
#include <OpenGL/gl.h>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <vector>
#include <stdio.h>
#include <iostream>
#include <math.h>
using namespace std;
GLfloat xRotated, yRotated, zRotated;
#define WIDTH 800
#define HEIGHT 1200
#define RAD 2000
// 6.67259(30)*10^-11 N(m/kg)^2
// mi escala sera la proporcion de 1 a 1 millón de toneladas.
#define GE 6.67259
void init(void)
{
glClearColor(0,1,0,0);
}
typedef struct particulas{
float x,y,z; // se va a comenza
float factor;
void Drawparticulas();
particulas(float px,float py,float pz,float pfactor){
x=px;
y=py;
z=pz;
factor=pfactor;
}
};
void particulas::Drawparticulas()
{
// clear the drawing buffer.
glPushMatrix();
//glLoadIdentity();
glTranslatef(x,y,z);
//escala al tamaño pedido
glScalef(factor,factor,factor);
glBegin(GL_QUADS); // Draw The Cube Using quads
glColor3f(0.0f,1.0f,0.0f); // Color Blue
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
glColor3f(1.0f,0.5f,0.0f); // Color Orange
glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
glColor3f(1.0f,0.0f,0.0f); // Color Red
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)
glColor3f(1.0f,1.0f,0.0f); // Color Yellow
glVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back)
glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back)
glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back)
glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back)
glColor3f(0.0f,0.0f,1.0f); // Color Blue
glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)
glColor3f(1.0f,0.0f,1.0f); // Color Violet
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
glEnd(); // End Drawing The Cube
glPopMatrix();
}
vector<particulas*> mundo;
void Muevelos()
{
//Dibujo las lineas del inicio
glBegin(GL_LINES);
glVertex3f(-RAD, -RAD, 0.0f);
glVertex3f(RAD, -RAD, 0.0f);
glVertex3f(RAD, -RAD, 0.0f);
glVertex3f(RAD, RAD, 0.0f);
glVertex3f(RAD, RAD, 0.0f);
glVertex3f(-RAD, RAD, 0.0f);
glVertex3f(-RAD, RAD, 0.0f);
glVertex3f(-RAD, -RAD, 0.0f);
glEnd();
for(int i=0;i<mundo.size();i++){
mundo[i]->Drawparticulas();
}
}
// Not using this yet
void animation(void)
{
for(int i=1;i<mundo.size();i++){
float xd = mundo[0]->x-mundo[i]->x;
float yd = mundo[0]->y-mundo[i]->y;
float zd = mundo[0]->x-mundo[i]->x;
float Distance = sqrt(xd*xd + yd*yd + zd*zd);
// Ill apply the newtons law.
//(mi*m2/D)g
float F=(mundo[0]->factor*mundo[0]->factor/Distance)*GE;
//Normalized Vector
float nx,ny,nz;
nx=mundo[i]->x/Distance;
ny=mundo[i]->y/Distance;
nz=mundo[i]->z/Distance;
mundo[i]->x+=F*nx;
mundo[i]->y+=F*ny;
mundo[i]->z+=F*nz;
}
}
void reshape(int x, int y)
{
if (y == 0 || x == 0) return; //Nothing is visible then, so return
//Set a new projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//Angle of view:40 degrees
//Near clipping plane distance: 0.5
//Far clipping plane distance: 20.0
gluPerspective(100.0,(GLdouble)x/(GLdouble)y,0,1000);
glMatrixMode(GL_MODELVIEW);
gluLookAt(-600,-600 , -600,
0, 0, 0,
0, 1, 0
);
glViewport(0,0,x,y); //Use the whole window for rendering
}
int main(int argc, char** argv){
mundo.resize(20);
mundo[0]=new particulas(0,0,0,2); // centro
for(int i=1;i<mundo.size();i++){
float x=-RAD/2.0 + rand()%RAD;
float y=-RAD/2.0 + rand()%RAD;
float z=-RAD/2.0 + rand()%RAD;
float r= 1+rand()%3;
// printf("%lf %lf %lf %lf\n",x,y,z,r);
mundo[i]=new particulas(x,y,z,r);
}
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(1920/2-WIDTH/2,1080/2-HEIGHT/2);
glutInitWindowSize(WIDTH,HEIGHT);
glutCreateWindow("Giu");
// glutInitWindowPosition(100, 100);
glEnable(GL_DEPTH_TEST);
//init();
gluLookAt(-600,-600 , -600,
0, 0, 0,
0, 1, 0
);
glutDisplayFunc(Muevelos);
glutReshapeFunc(reshape);
//Set the function for the animation.
//glutIdleFunc(animation);
glutMainLoop();
return 0;
}
zNear
parameter to gluPerspective()
must be greater than zero.glLoadIdentity()
after gluLookAt()
or else your modelview matrix will turn to gibberish after the second window resize.glutSwapBuffers()
at the end of your display callback so that your back buffer can actually make it to the frontbuffer someday.A working example:
#include <GL/glut.h>
#include <vector>
using namespace std;
#include <glm/glm.hpp>
#include <glm/gtx/norm.hpp>
using namespace glm;
struct Particle
{
dvec3 pos;
dvec3 vel;
double mass;
dvec3 force;
void Integrate( double dt )
{
const dvec3 accel = force / mass;
// semi-implicit euler
vel = vel + accel * dt;
pos = pos + vel * dt;
}
};
void Integrate( vector< Particle >& particles, double dt )
{
// zero out force vectors for this tick
for( size_t i = 0; i < particles.size(); ++i )
{
particles[i].force = dvec3( 0 );
}
// accumulate force vectors for each particle
for( size_t i = 0; i < particles.size(); ++i )
{
for( size_t j = i+1; j < particles.size(); ++j )
{
Particle& p1 = particles[i];
Particle& p2 = particles[j];
// http://en.wikipedia.org/wiki/Newton%27s_law_of_universal_gravitation#Vector_form
const double BigGee = 1.0;
const dvec3 diff = ( p2.pos - p1.pos );
const dvec3 rHat = glm::normalize( diff );
const double r2 = glm::length2( diff );
const dvec3 force = BigGee * ( ( p1.mass * p2.mass ) / r2 ) * rHat;
p1.force += force;
p2.force -= force;
}
}
// update positions/velocities
for( size_t i = 0; i < particles.size(); ++i )
{
particles[i].Integrate( dt );
}
}
vector< Particle > particles;
void display()
{
// use last frame time to calculate delta-t
static int last = glutGet( GLUT_ELAPSED_TIME );
int cur = glutGet( GLUT_ELAPSED_TIME );
double dt = ( cur - last ) / 1000.0;
last = cur;
Integrate( particles, dt );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
double ar = w / h;
glOrtho( -100 * ar, 100 * ar, -100, 100, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// draw particles
glPointSize( 5 );
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_DOUBLE, sizeof( Particle ), &particles[0].pos[0] );
glDrawArrays( GL_POINTS, 0, particles.size() );
glDisableClientState( GL_VERTEX_ARRAY );
glutSwapBuffers();
}
void timer( int value )
{
glutPostRedisplay();
glutTimerFunc( 16, timer, 0 );
}
int main(int argc, char **argv)
{
particles.resize( 2 );
// "sun"
particles[0].pos = dvec3( 0, 0, 0 );
particles[0].vel = dvec3( 0, 0, 0 );
particles[0].mass = 100000;
// "planet"
particles[1].pos = dvec3( 50, 0, 0 );
particles[1].vel = dvec3( 0, -20, 0 );
particles[1].mass = 1;
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return 0;
}