These tutorials focus mainly on OpenGL, Win32 programming and the ODE physics engine. OpenGL has moved on to great heights and I don't cover the newest features but cover all of the basic concepts you will need with working example programs.


Working with the Win32 API is a great way to get to the heart of Windows and is just as relevant today as ever before. Whereas ODE has been marginalized as hardware accelerated physics becomes more common.


Games and graphics utilities can be made quickly and easily using game engines like Unity so this and Linux development in general will be the focus of my next tutorials.    



MATRIX GeomMatrix;

dWorldID World;

dSpaceID Space;

MyObject Object[2];         // two geom objects

dJointGroupID contactgroup;

dJointGroupID jointgroup;   // contact group for the new joint

dJointID Joint;             // the joint ID

void InitODE()

    World = dWorldCreate();

    Space = dHashSpaceCreate(0);

    contactgroup = dJointGroupCreate(0);

    // As well as the contact group for collisions we need to create a new joint group and

       // assign its ID to jointgroup

    jointgroup = dJointGroupCreate(0);

    dCreatePlane(Space, 0, 1, 0, 0);

    dWorldSetGravity(World, 0, -1.0, 0);

    dWorldSetCFM(World, 1e-5);

    dWorldSetERP(World, 0.2);

    dWorldSetContactMaxCorrectingVel(World, 0.9);

    dWorldSetContactSurfaceLayer(World, 0);

    dWorldSetAutoDisableFlag(World, 1);

    dReal sides[3];

    dMass m;

    dMatrix3 R;

    VECTOR tempVect(0.0, 0.0, 0.0);


    sides[0] = 2.0;

    sides[1] = 2.0;

    sides[2] = 2.0;

    // Here we instantiate the two bodies we will be using

    Object[0].Body = dBodyCreate(World);

    Object[1].Body = dBodyCreate(World);

    // Set up for body 1. Nothing much has changed here, we are now dealing with an array

       // instead of a single object and I have changed its initial position and rotated the

       // object 45 degrees around the Y axis using dRFromEulerAngles.

    dBodySetPosition(Object[0].Body, -1.4142, 1.0, -5.0);

    dBodySetLinearVel(Object[0].Body, tempVect.x, tempVect.y, tempVect.z);

    dBodySetData(Object[0].Body, (void*)i);

    dRFromEulerAngles(R, 0.0, pi / 4, 0.0);

    dBodySetRotation(Object[0].Body, R);

    dMassSetBox(&m, DENSITY, sides[0], sides[1], sides[2]);

    Object[0].Geom[0] = dCreateBox(Space, sides[0], sides[1], sides[2]);

    dGeomSetBody(Object[0].Geom[0], Object[0].Body);

    dBodySetMass(Object[0].Body, &m);

    // Set up for body 2. As above, except for its initial position. 

    dBodySetPosition(Object[1].Body, 1.4142, 3.0, -5.0);

    dBodySetLinearVel(Object[1].Body, tempVect.x, tempVect.y, tempVect.z);

    dBodySetData(Object[1].Body, (void*)i);

    dRFromEulerAngles(R, 0.0, pi / 4, 0.0);

    dBodySetRotation(Object[1].Body, R);

    dMassSetBox(&m, DENSITY, sides[0], sides[1], sides[2]);

    Object[1].Geom[0] = dCreateBox(Space, sides[0], sides[1], sides[2]);

    dGeomSetBody(Object[1].Geom[0], Object[1].Body);

    dBodySetMass(Object[1].Body, &m);


    // To join the two objects together we first need to create a new joint with a call to

       // dJointCreateBall and retain the ID returned in our Joint variable.

    Joint = dJointCreateBall(World, jointgroup);

    // We now instruct ODE that this new joint will be attached to our two object bodies.  

    dJointAttach(Joint, Object[0].Body, Object[1].Body);

    // And lastly we tell ODE where exactly the two objects are joined in world coordinates. 

    dJointSetBallAnchor(Joint, 0.0, 2.0, -5.0);


DrawGeom(Object[0].Geom[0], 0, 0, 0);

DrawGeom(Object[1].Geom[0], 0, 0, 0);

Joint = dJointCreateHinge(World, jointgroup);

dJointAttach(Joint, Object[0].Body, Object[1].Body);

dJointSetHingeAnchor(Joint, 0.0, 2.0, -5.0);

dJointSetHingeAxis(Joint, 0, 0, 1);

Joint = dJointCreateSlider(World, jointgroup);

dJointAttach(Joint, Object[0].Body, Object[1].Body);

dJointSetSliderAxis(Joint, 0, 1, 0);

dBodyAddForce(Object[1].Body, 0, 200, 0);   // Added a force to show the slider joint in action