Remembering the past to build the future

" Remembering the past to build the future "

Sunday, 9 June 2019

Verlet integration is a numerical method used to integrate Newton's equations of motion. It is frequently used to calculate trajectories of particles in molecular dynamics simulations and computer graphics. This is an OpenGL video demo that shows Verlet integration applied on particles:



Saturday, 4 May 2019

This is the final tutorial about a simple 3D level in OpenGL:




You can buy the code for only $5.


Buy the Visual C++ project on Fiverr

Saturday, 23 March 2019

OpenGL: The world from the camera perspective

When we’re talking about camera/view space we’re talking about all the vertex coordinates as seen from the camera’s perpective as the origin of the scene: the view matrix transforms all the world coordinates into view coordinates that are relative to the camera’s position and direction:



You can buy the code for only $5.


Buy the Visual C++ project on Fiverr

Sunday, 25 November 2018

OpenGL (Realize 3D Level series): Homogeneous Transformation Matrix

In this tutorial I want to treat the  theory behind a Homogeneous Transformation Matrix and an OpenGL program that puts into practice the concepts exposed:


If you don't wait you can buy the code for only $5.

Buy the Visual C++ project on Fiverr

Saturday, 25 August 2018

OpenGL (Realize 3D Level series): Rotation Matrix

In this tutorial I want to treat the  theory behind a Rotation Matrix and an OpenGL program that puts into practice the concepts exposed:



If you don't wait you can buy the code for only $5.

Buy the Visual C++ project on Fiverr

Saturday, 30 December 2017

OpenGL (Realize 3D Level series): The first triangle


The video tutorial completes the skeleton program started in the previous video and allows you to make your first triangle in OpenGL world.


If you don't wait you can buy the code for only $5.

Buy the Visual C++ project on Fiverr

Sunday, 22 October 2017

OpenGL Realize a 3D Level: Glut and Glew Configuration

In this video tutorial we will see how to configure Glut and Glew in Visual C++ for OpenGL applications:




If you don't wait you can buy the code for only $5.

Buy the Visual C++ project on Fiverr

Saturday, 14 October 2017

OpenGL: Realize a 3D Level Preview

This video is the preview of my Tutorial about making a 3D Level using OpenGL library and Microsoft Visual C++ 2015.



I will publish different videos to realize this application.

If you don't wait you can buy the code for only $5.
Buy the Visual C++ project on Fiverr

Monday, 26 December 2016

Unreal Engine Raycast and Volume Trigger

My Raycast and Volume demo in Unreal Engine using only C++. In this scene the default Pawn emits a ray that can intersect a physical object. An object is pulled up and than released by the default Pawn using key controls. If the Pawn overlap the circle on the floor the Trigger Volume is activated and this event open the door. Coming soon I will publish a tutorial.


Friday, 1 January 2016

Unreal Engine 4 : Actors and Transformations

In this post I want to share a little tutorial  about transformations using Unreal Engine. Unreal Engine is a big, great and professional engine that allows you to make amazing 3D and 2D games for every platform. The best way to start with this engine is to follow the first tutorial :


Fig 1. Level Designer Quick Start

After this tutorial you should have the basic concepts in your mind about levels, objects, materials, lighting and static transformations. The next step is making your own level and using C++ for funny dynamic behaviors like object rotations. My personal final result is:


Video 1. Rotation demo

As you can see the cube and the pyramid rotates about your Z axis. The pretty ambient is realized using free Unreal starter content as in the level designer quick start tutorial. The cube is located in X=0, Y=0 and Z=0 coordinates, while the pyramid is in a different other position. You can get the cube from the Modes panel inside the Basic tab:

Fig 2. Cube object
While you can find the pyramid in the Content Browser:


Fig 3. Pyramid



It's important to set, for cube and pyramid object, the mobility property to Movable value in the Details Panel. You can apply the material you like to this object. Now from the File menu, we have to choose New C++ class (Note you need a Visual Studio 2013 Express Edition installation, in this tutorial I have Unreal 4.8 as reference). You have to follow the quick wizard and choose AActor as base class. Unreal will launch Visual Studio with the initial C++ code. Now suppose the class name choosed during the wizard is RotatorActor, well we have to edit RotatorActor.h adding the RotationDemo method :


#pragma once



#include "GameFramework/Actor.h"

#include "RotatorActor.generated.h"



UCLASS()
class MYPROJECT3_API ARotatorActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ARotatorActor();

// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;

private:
// Rotation demo
virtual void RotationDemo(float DeltaSeconds);
};



and implement the method in the RotatorActor.cpp class:



#include "MyProject3.h"
#include "RotatorActor.h"


// Sets default values
ARotatorActor::ARotatorActor()
{
  // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void ARotatorActor::BeginPlay()
{
Super::BeginPlay();
}

// Called every frame
void ARotatorActor::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
RotationDemo(DeltaTime);
}

void ARotatorActor::RotationDemo(float DeltaTime){
AActor* pyramid = RootComponent->GetChildComponent(1)->GetOwner();

FRotator fRotator  = pyramid->GetActorRotation();
FVector  fLocation = pyramid->GetActorLocation();
FVector  fLocationOrigin(0, 0, 0);

fRotator.Yaw += 20 * DeltaTime;

pyramid->SetActorLocation(fLocationOrigin);
pyramid->SetActorRotation(fRotator);
pyramid->SetActorLocation(fLocation);

AActor* cube = RootComponent->GetChildComponent(0)->GetOwner();
cube->SetActorRotation(fRotator);
}


The implementation retrieves the cube and pyramid Actor reference and apply trasformations to this objects. In particular the cube is located in (0,0,0)  coordinate, so we can apply the rotation trasfomation around Z axis without any other trasfomation. The pyramid is not located to the origin, so to get a rotation about its own Z axis we need a trasfomation compositions (affine trasformation):

Traslation to the origin + Rotation around the Z axis + Traslation to the original position

The code is completed, now we need to realize the hierarchy for RotatorActor. We want that the cube and pyramid are children of RotatorActor. The first step is to add the RotatorActor class to the level, add the Scene component to RotatorActor and than moving the cube and pyramid on RotatorActor in the tab World Outliner :



If you like this post, or you want the project code you can write me. Thanks a lot for reading.

Wednesday, 16 July 2014

Physics : Cloth with particles

This demo shows how you can use the Verlet Integration to build a cloth with particles. For understand the theory behind the code, visit the site

Müller-Fischer et al.
Real-time physics

And thanks to the material from the site


The demo project has the following structure:

The main class : phys_sim.cpp. In this class you will find 2 methods, the first one

void BuildCloth(int nbParticlesX, int nbParticlesY);

makes a cloth, while the second one

void BuildRope(int nbParticles);

makes a rope. Use the method:

void initGL(int width, int height) 
{
glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse_0);
glLightfv (GL_LIGHT0, GL_POSITION, light_positio_0);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);

reshape(width, height);

glClearColor(0.126f, 0.126f, 0.128f, 1.0f);
glClearDepth(1.0f);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

glShadeModel(GL_FLAT);
glEnable(GL_NORMALIZE);
//BuildRope(20);
BuildCloth(4,4);
}

for drawing a cloth or  a rope. The physics engine is realized through the following C++ sources:

constraint.h
particle.h
particle_system.h


Here it is a video demo:


Monday, 14 July 2014

Picking : Click and move an object

In this demo we have a cube in the scene. If you click on the cube, the cube changes its color to yellow:
the cube is now selected. Starting from a cube selected, a click on the plane moves the cube in the position where we have clicked. This video shows some examples:


The demo uses the unProject method as in the  Picking post . You will find in the code some modification for drawing the cube in a different position on the plane.

Download the source here:

C Sources

Wednesday, 2 July 2014

Object Picking

In this post I want to share an easy implementation of picking through unProject method. The demo is realized in C, so we have only the main.cpp file and vector3.h file. In the demo we have a cube in the center of the scene, when we click on the cube, the cube changes its color.




If you open the main.cpp source file you can note the following lines of code:

GLdouble posX, posY, posZ;
GLdouble cubeX=0,cubeY=0.5,cubeZ=0;
GLdouble cubeSize=1.f;
bool cubePicked;


The variables posX,posY and posZ give us the  unproject mouse click coordinates.
The variables cubeX,cubeY and cubeZ save the cube position.
The variable cubSize set the size of the cube;
The boolean variable cubePick is true when the cube is clicked;

When we click in the scene, the unProject method is called:

void unProject(){

GLint viewport[4]; // Where The Viewport Values Will Be Stored
glGetIntegerv(GL_VIEWPORT, viewport); // Retrieves The Viewport Values (X, Y, Width, Height)

GLdouble modelview[16]; // Where The 16 Doubles Of The Modelview Matrix Are To Be Stored
glGetDoublev(GL_MODELVIEW_MATRIX, modelview); // Retrieve The Modelview Matrix

GLdouble projection[16];  // Where The 16 Doubles Of The Projection Matrix Are To Be Stored
glGetDoublev(GL_PROJECTION_MATRIX, projection); // Retrieve The Projection Matrix

GLfloat winX, winY, winZ;               // Holds Our X, Y and Z Coordinates

winX = (float)mouse2D.x;                  // Holds The Mouse X Coordinate
winY = (float)mouse2D.y;                  // Holds The Mouse Y Coordinate

glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

        //ROUND 2 DECIMAL
posX= ((int)(posX * 10 + .5) / 10.0);
posY= ((int)(posY * 10+ .5) / 10.0);
posZ= ((int)(posZ * 10 + .5) / 10.0);

}

the method saves posX,posY and posZ variables. After the pickingCheck method is called:

void pickingCheck(){

cubePicked=false;
if( posX>=cubeX-(cubeSize/2) && posX<=cubeX+(cubeSize/2)){
if( posY>=cubeY-(cubeSize/2) && posY<=cubeY+(cubeSize/2) ){
if( posZ>=cubeZ-(cubeSize/2) && posZ<=cubeZ+(cubeSize/2)){
cubePicked=true;
}
}
}

}

the method checks the posX,posY,posZ range values. If this values are inside the cube, the cube is picked.

Download the code from here:

Sources

Friday, 4 April 2014

Texture mapping on Torus

Hi, let's see a more complex texture mapping. In this demo I have written in the Geometry class a torus rendering method :

void torus(float out_radius, float int_radius, int textureId);

The method takes as input the tube radius ,the big radius from the center of the torus and a texture id. For a good quality rendering is important to set the normal on each vertex of the torus mesh, so for this reason we have the following private method used by torus:

Vector3 Geometry::getPointNormal(float out_angle,float int_angle, 
float out_radius,float int_radius){
 
 Vector3 tangentOut( -sin(out_angle), 
               cos(out_angle), 
      0);

 Vector3 tangentInt( cos(out_angle)*(-sin(int_angle)) ,
              sin(out_angle)*(-sin(int_angle)) ,
         cos(int_angle) );
 
 Vector3 normal = tangentOut^tangentInt;

 return normal.Normalize();

 }

getPointNormal() returns the normal vector (angles in radiants) for a vertex identified by polar coordinates. Another method used by the torus is:

Vector3 Geometry::getPoint(float out_angle,float int_angle, float out_radius,
float int_radius){

 return Vector3( ( out_radius+int_radius*cos(int_angle) )*cos(out_angle),
                 ( out_radius+int_radius*cos(int_angle) )*sin(out_angle),
                                         int_radius*sin(int_angle));
  
}

That returns cartesian coordinates from polar coordinates. For apply the texture we have the method:

void Geometry::glTorusTexCoord(float out_angle,float int_angle,int tx){

 glTexCoord2f( out_angle/PI , (int_angle)/PI );
 
}
The texture file must reside in your project directory. In my case I made a directory called texture and I put the file here.

Download the sources here


Here it is the video demo:



Thursday, 3 April 2014

OpenGL Texture Mapping

In this post I decided to get some Quake texture and making a simple but interesting 3D scene. As the other OpenGL post, we have a project with some C++ files and classes like Geometry,Scene,Main but in this demo I have used an external class for texture loading, TextureLoader inside the project. The first thing you have to control before to worry about compilation error is the following setting in your Visual C++ project:




Check Character Set = Not Set. Let's see the video demo before to start:




You can download the code here:

Texture Demo

For texture loader you can find all documentation here:

http://members.iinet.net.au/~cleathley/openGL/TextureLoader.htm

If you open the Scene class you can find the following fragment code on the top:

TextureLoader* Scene::pTextureLoader=new TextureLoader();
glTexture    Scene::floor;
glTexture    Scene::box;
glTexture    Scene::box2; 
TextureLoader is the class that loads the textures. We have three different textures, one for floor and two for boxes. The initGL() method inside the Scene class has now the code to initialize the textures:
 pTextureLoader->LoadTextureFromDisk("\\texture\\floor.jpg", &Scene::floor);
 pTextureLoader->LoadTextureFromDisk("\\texture\\box.jpg", &Scene::box); 
 pTextureLoader->LoadTextureFromDisk("\\texture\\box2.jpg", &Scene::box2); 
The texture files must reside in your project directory. In my case I made a directory called texture and I put all files here. With Geometry class in the draw() method of the Scene class, we find the code to draw all boxes using textures:
Geometry geo;

   glPushMatrix();
 glTranslatef(-3,0.75,5);
 geo.box(1.5f,1.5f,1.5f,Scene::box.TextureID);
   glPopMatrix();

   glPushMatrix();
 glTranslatef(-3,0.75,2);
 geo.box(1.5f,1.5f,1.5f,Scene::box.TextureID);
   glPopMatrix();
 
   glPushMatrix();
 glTranslatef(-3,0.75,-1);
 geo.box(1.5f,1.5f,1.5f,Scene::box.TextureID);
    glPopMatrix();

    glPushMatrix();
 glTranslatef(-3,0.75,-4);
 geo.box(1.5f,1.5f,1.5f,Scene::box.TextureID);
    glPopMatrix();

 
    glPushMatrix();
 glTranslatef(3,0.75,5);
 geo.box(1.5f,1.5f,1.5f,Scene::box2.TextureID);
    glPopMatrix();

    glPushMatrix();
 glTranslatef(3,0.75,2);
 geo.box(1.5f,1.5f,1.5f,Scene::box2.TextureID);
    glPopMatrix();
 
    glPushMatrix();
 glTranslatef(3,0.75,-1);
 geo.box(1.5f,1.5f,1.5f,Scene::box2.TextureID);
    glPopMatrix();

    glPushMatrix();
 glTranslatef(3,0.75,-4);
 geo.box(1.5f,1.5f,1.5f,Scene::box2.TextureID);
    glPopMatrix();

If you want to see how textures have been applied to boxes see the box method of the class Geometry:
void Geometry::box(GLdouble width, GLdouble height, GLdouble lenght,int textureId){
  
    glEnable(GL_TEXTURE_2D); 
    glShadeModel(GL_FLAT);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_MODULATE);

    glBindTexture(GL_TEXTURE_2D, textureId);

    // Front
   glBegin(GL_QUADS);
      glNormal3d(0, 0, lenght/2);
      glTexCoord2f(0, 0);
      glVertex3d(-width/2, height/2, lenght/2);
      glTexCoord2f(1, 0);
      glVertex3d(width/2, height/2, lenght/2);
      glTexCoord2f(1, 1);
      glVertex3d(width/2, -height/2, lenght/2); 
      glTexCoord2f(0, 1);
      glVertex3d(-width/2, -height/2, lenght/2);
   glEnd();

    // Right
   glBegin(GL_QUADS);
      glNormal3d(-width/2, 0, 0);
      glTexCoord2f(0, 0);
      glVertex3d(-width/2, +height/2, -lenght/2);
      glTexCoord2f(1, 0);
      glVertex3d(-width/2, +height/2, lenght/2);
      glTexCoord2f(1, 1);
      glVertex3d(-width/2, -height/2, lenght/2);
      glTexCoord2f(0, 1);
      glVertex3d(-width/2, -height/2, -lenght/2);
    glEnd();

    // Back
    glBegin(GL_QUADS);
       glNormal3d(0, 0, -lenght/2);
       glTexCoord2f(0, 0); 
       glVertex3d(width/2, height/2, -lenght/2);
       glTexCoord2f(1, 0);
       glVertex3d(-width/2, height/2, -lenght/2);
       glTexCoord2f(1, 1);
       glVertex3d(-width/2, -height/2, -lenght/2);
       glTexCoord2f(0, 1);
       glVertex3d(width/2, -height/2, -lenght/2);
    glEnd();

     // Left
    glBegin(GL_QUADS);
       glNormal3d(width/2, 0, 0);
       glTexCoord2f(0, 0);
       glVertex3d(width/2, height/2, lenght/2);
       glTexCoord2f(1, 0);
       glVertex3d(width/2, height/2, -lenght/2);
       glTexCoord2f(1, 1);
       glVertex3d(width/2, -height/2, -lenght/2);
       glTexCoord2f(0, 1);
       glVertex3d(width/2, -height/2, lenght/2);
     glEnd();

     // Top
     glBegin(GL_QUADS);
       glNormal3d(0, height/2, 0);
       glTexCoord2f(0, 0);
       glVertex3d(-width/2, height/2, -lenght/2);
       glTexCoord2f(1, 0);
       glVertex3d(width/2, height/2, -lenght/2);
       glTexCoord2f(1, 1);
       glVertex3d(width/2, height/2, lenght/2);
       glTexCoord2f(0, 1);
       glVertex3d(-width/2, height/2, lenght/2);
     glEnd();

     // Bottom
     glBegin(GL_QUADS);
        glNormal3d(0, -height/2, 0);
        glTexCoord2f(0, 0);
        glVertex3d(-width/2, -height/2, lenght/2);
        glTexCoord2f(1, 0);
        glVertex3d(width/2, -height/2, lenght/2);
        glTexCoord2f(1, 1);
        glVertex3d(width/2, -height/2, -lenght/2);
        glTexCoord2f(0, 1);
        glVertex3d(-width/2, -height/2, -lenght/2);
     glEnd();

     glDisable(GL_TEXTURE_2D);
}

Saturday, 29 March 2014

OpenGL Hierarchical Models

In many applications the parts of a model depend on one another: if we move one part, it causes other parts to move. We represent such models using trasformations. OpenGL trasformations are applied to the existing model-view matrix. Each trasformation represents a relative change from one scaling,position and orientation to another. In this post I show you a demo with a lamp. You can move some parts of the lamp using the keys 'a','s','d','f','g','h' from your keyboard. The lamp uses also a diffuse light with an emissive component. Here it is the video demo:




You can download the code here:
The demo uses the template code showed in the previous post plus other useful methods.
Inside the code you can find the drawLamp() methods with the following code:
 Geometry geo;
 int colors1[]={0,127,255, 102,255,0};
 int colors2[]={    255,153,51, 255,153,51, 255,153,51, 
        255,153,51, 255,153,51, 255,153,51};
 glPushMatrix();
 float   HEIGHT_CYL_A  = 0.5f;//BASE  HEIGHT
 float   HEIGHT_CYL_B  = 1.5f;//MIDDLE  HEIGHT
 float   HEIGHT_CYL_C  = 0.5f;//TOP  HEIGHT
 float   SPHERE_RADIUS = 0.5f;//SPHERE RADIUS
 /* Draw Base Start */
 glRotatef(arm1Angle,0,1,0);
 glTranslatef(0,HEIGHT_CYL_A/2,0);
 geo.box(2,HEIGHT_CYL_A,2,colors2);
 /* Draw Base End */
 /* Draw Sphere Joint Start*/
  glTranslatef(0,SPHERE_RADIUS/2+HEIGHT_CYL_A,0);
  geo.sphere(SPHERE_RADIUS,10,10,colors1);
 /* Draw Sphere Joint End*/
 /* Draw first middle Arm Start */
 glRotatef(-20,0,0,1);
 glTranslatef(0,SPHERE_RADIUS+HEIGHT_CYL_B/2,0);
 geo.box(1,HEIGHT_CYL_B,1,colors2);
 /* Draw first middle Arm End */
 /* Draw Sphere Joint Start*/
  glTranslatef(0,SPHERE_RADIUS+HEIGHT_CYL_B/2,0);
  geo.sphere(SPHERE_RADIUS,10,10,colors1);
 /* Draw Sphere Joint End*/
 /* Draw second middle Arm Start */
 glRotatef(arm2Angle,0,0,1);
 glTranslatef(0,SPHERE_RADIUS+HEIGHT_CYL_B/2,0);
 geo.box(1,HEIGHT_CYL_B,1,colors2);
  /* Draw second middle Arm End */
  /* Draw Sphere Joint Start*/
  glTranslatef(0,SPHERE_RADIUS+HEIGHT_CYL_B/2,0);
  geo.sphere(SPHERE_RADIUS,10,10,colors1);
 /* Draw Sphere Joint End*/
   /* Draw third Arm Start */
 glRotatef(arm3Angle,0,0,1);
 glTranslatef(0,SPHERE_RADIUS+HEIGHT_CYL_C/2,0);
 geo.box(2,HEIGHT_CYL_C,2,colors2);
  /* Draw third  Arm End */
 /*Sphere emission*/
 GLfloat mat_emission[] = {0.5, 0.8, 0.9, 0.0};
 glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
 /* Draw Sphere Final  Start*/
  glTranslatef(0,SPHERE_RADIUS+HEIGHT_CYL_C/2,0);
  geo.sphere(SPHERE_RADIUS,10,10,colors1);
  glEnable(GL_LIGHT1);
 /* Draw Sphere Final End*/
  
  /*Put light near the final sphere*/
  glEnable(GL_LIGHT1);
  GLfloat pos[]={ 0.0, 0.0, 0.0, 1.0};
  GLfloat color[]={ 1.0, 1.0, 1.0, 1.0};
  //glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 45.0);// set cutoff angle
  glLightfv(GL_LIGHT1, GL_POSITION, pos); 
  glLightfv(GL_LIGHT1, GL_DIFFUSE, color);
  //glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2);
  GLfloat mat_emission2[] = {0, 0, 0, 0.0};
  glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission2);
  glPopMatrix();
In this code you can see how every part of the lamp is realized starting from the previous part. And this is an alternative demo:



OpenGL Transformations

In this post I want to show 3D affine trasformations using OpenGL functions like glTranslate(), glRotate() ,glPushMatrix and glPopMatrix(). Here the final result:






You can download the c++ sources from the url: OpenGL Demo Use left mouse button to rotate the scene and middle plus right button for zoom. In the sources you will find some classes:
  • Geometry class allows you  boxes and spheres rendering with different colors
  • Scene class allows you to make a complete scene using Geometry
  • Main class starts the application
You can use Visual C++ Express Edition to build the demo but it's important to have OpenGL well configured in your environment, you can use this url to see how configure OpenGL: OpenGL configuration
Now open the sources and the Scene class. In this class we have several methods, for now we want to focus on draw() method. This method draws the scene and here we find the OpenGL code trasformations:

Geometry geo;

 int colors1[]={ 255,153,51, 0,127,255, 255,153,51, 
        0,127,255, 0,127,255, 0,127,255};
 
 int colors2[]={ 0,127,255, 102,255,0};
 int colors3[]={ 255,0,0, 255,0,0, 255,0,0, 
        255,0,0, 255,0,0, 255,0,0};
 
 int colors4[]={ 0,255,0, 0,255,0};
 int colors5[]={ 255,255,0, 255,255,0};
 
 /*Sphere in (0,1,0) 90 degree rotated around x axes
   Note:First trasformation is the rotation
        Second trasformation is the translation
        So you have to read the trasformations 
        from down to up in your code
  */
 glPushMatrix();
  glTranslatef(0,1,0);//Second
  glRotatef(90,1,0,0);//First
  geo.sphere(1,20,20,colors2);
 glPopMatrix();

 /*Box in (2,0.75,2)*/
 glPushMatrix();
  glTranslatef(2,0.75,2);
  geo.box(1.5,1.5,1.5,colors1);
 glPopMatrix();

 /*Box in (-2,0.75,-2)*/
 glPushMatrix();
  glTranslatef(-2,0.75,-2);
  geo.box(1.5,1.5,1.5,colors3);
 glPopMatrix();

 /*Sphere in (3,1,-3)  90 degree rotated around x axes*/
 glPushMatrix();
  glTranslatef(3,1,-3);
  glRotatef(90,1,0,0);
  geo.sphere(1,20,20,colors4);
 glPopMatrix();
 
 /*Sphere in (-4,1,4)  90 degree rotated around x axes*/
 glPushMatrix();
  glTranslatef(-4,1,4);
  glRotatef(90,1,0,0);
  geo.sphere(1,20,20,colors5);
 glPopMatrix();

 /* */
The glPushMatrix() save the current ModelView matrix, the glPopMatrix() restore the matrix saved. So we have used this methods to save current trasformation matrix before to apply our trasformations for a box or a sphere and then restore the initial trasformation matrix. If you note the code for a sphere, you can see a trasformation composition. The sphere is first rotated and then translated. Use this fragment code to play with trasformations and understand how OpenGL works with them.Well I have finished for now. I hope this post is useful.
Thanks for reading.

My Android Games, much are free