JOGL Transformation of Objects



OpenGL provides more features such as applying colors to an object, scaling, lighting, rotating an object etc. This chapter describes some of the transformations on objects using JOGL.

Moving an object on the window

In previous chapters we discussed the programs for drawing a line and drawing various shapes using simple lines. The shapes created in this way can be displayed on any location within the window. It is done by using glTranslatef (float x, float y, float z) method.

This method belongs to GLMatrixFunc interface, which is in javax.media.opengl.fixedfunc package.

GLMatrixFunc interface

interface: GLMatrixFunc

package: javax.media.opengl.fixedfunc

Let us see some important methods of this interface:

Sr. No. Methods and Description
1

void glRotatef(float angle, float x, float y, float z)

This method rotates the current matrix.

2

void glScalef(float x, float y, float z)

This method is used to scale the current matrix.

3

void glTranslatef(float x, float y,float z)

This method is used to translate the current matrix.

4

void glLoadIdentity()

This method loads the current matrix with identity matrix.

glTranslate() method moves origin of the coordinate system to the point specified by the parameters (x,y,z), passed to glTranslate() method as argument. To save and restore the untranslated coordinate system, glPushMatrix() and glPopMatrix() methods are used.

 gl.glTranslatef(0f, 0f, -2.5f);

Whenever glTranslate() method is used, it changes the position of the component on the screen. Hence, reshape() method of GLEventListener interface should be overridden and OpenGL viewport and projection matrix should be initialized.

The following code shows the template to initialize view port and projection matrix:

public void reshape(GLAutoDrawable drawable, int x,  int y, int width, int height){
   final GL2 gl = drawable.getGL().getGL2(); 
   // get the OpenGL 2 graphics object  
   if(height <=0)
      height =1;
   //preventing devided by 0 exception height =1;
   final float h = (float) width / (float) height;
   // display area to cover the entire window
   gl.glViewport(0, 0, width, height);
   //transforming projection matrix
   gl.glMatrixMode(GL2.GL_PROJECTION);
   gl.glLoadIdentity();
   glu.gluPerspective(45.0f, h, 1.0, 20.0);
   //transforming model view gl.glLoadIdentity();
   gl.glMatrixMode(GL2.GL_MODELVIEW);
   gl.glLoadIdentity();
}

Applying color to an object

To apply color to an object, use method glColor() of GL2 class.

Syntax

 gl.glColorXY(1f,0f,0f);

where,

  • x denotes the number of colors used, 3 (red, blue, green) or 4(red, blue, green, alpha). To get various color combinations, values for these colors are passed as parameters. The sequence of the color parameters must be main-tained in that order.

  • Example

    If you pass color values as (1, 0, 0) then you get red color and (1, 1, 0) values give you yellow color.

  • y denotes the datatype which accepts parameters such as byte(b), double(d), float(f), int(i), short(s), ubyte(ub), uint(ui), ushort(us).

 gl.glColor3f(1f,0f,0f);   //gives us red         
 gl.glColor3f(0f,1f,0f);   //gives us blue         
 gl.glColor3f(0f,0f,1f);   //gives us green

In case of triangle you can apply different colors for each vertex.

Let us go through the program to apply colors to a triangle:

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;

public class TriangleColor implements GLEventListener{
   @Override
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glBegin( GL2.GL_TRIANGLES );         // Drawing Using Triangles
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); //Red
      gl.glVertex3f( 0.5f,0.7f,0.0f ); // Top
      gl.glColor3f( 0.0f,1.0f,0.0f ); //blue
      gl.glVertex3f( -0.2f,-0.50f,0.0f );              // Bottom Left
      gl.glColor3f( 0.0f,0.0f,1.0f ); //green
      gl.glVertex3f( 0.5f,-0.5f,0.0f );              //Bottom Right
      gl.glEnd();   
   }
   @Override
   public void dispose( GLAutoDrawable arg0 ) {
      //method body
   }
   @Override
   public void init( GLAutoDrawable arg0 ) {
      // method body
   }
   @Override
   public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) {
      // method body
   }
   public static void main( String[] args ) {
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities( profile );
      // The canvas 
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      TriangleColor triangle = new TriangleColor();
      glcanvas.addGLEventListener( triangle );
      glcanvas.setSize( 400, 400 );
      //creating frame
      final JFrame frame = new JFrame (" Colored Triangle");      
      //adding canvas to it
      frame.getContentPane().add( glcanvas );
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
   }//end of main
}//end of class

When you compile and execute the above program, you get the following colored triangle:

Triangle Color

Applying color to a polygon

Let us go through the program to apply colors to a polygon:

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;

public class PolygonColor implements GLEventListener{
   @Override
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glColor3f( 1f,0f,0f ); //applying red   
      gl.glBegin( GL2.GL_POLYGON );
      gl.glVertex3f( 0f,0.5f,0f  );
      gl.glVertex3f( -0.5f,0.2f,0f );
      gl.glVertex3f( -0.5f,-0.2f,0f );
      gl.glVertex3f( 0f,-0.5f,0f );
      gl.glVertex3f( 0f,0.5f,0f );
      gl.glVertex3f( 0.5f,0.2f,0f );
      gl.glVertex3f( 0.5f,-0.2f,0f );
      gl.glVertex3f( 0f,-0.5f,0f );
      gl.glEnd();
   }
   @Override
   public void dispose( GLAutoDrawable arg0 ) {
      //method body
   }
   @Override
   public void init( GLAutoDrawable arg0 ) {
      // method body
   }
   @Override
   public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) {
      // method body
   }
   public static void main( String[] args ) {
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities( profile );
      // The canvas 
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      PolygonColor polygon = new PolygonColor();
      glcanvas.addGLEventListener( polygon );
      glcanvas.setSize( 400, 400 );
      //creating frame
      final JFrame frame = new JFrame ( "Colored Polygon" );
      //adding canvas to frame
      frame.getContentPane().add( glcanvas );
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
   }//end of main
}//end of class

When you compile and execute the above program, the following output is generated:

Colored Polygon

Scaling

Scaling an object is done by using void glScalef(float x, float y, float z) method of GLMatrixFunc interface. This method accepts three floatingpoint parameters, using which we specify the scale factors along the x, y, and z axes respectively.

For example, in the following program, a triangle is diminished to 50%. Here, value 50 is passed as parameter along all the axes.

Let us go through the program to scale a triangle:

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;

public class Scaling implements GLEventListener{
   @Override
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glScalef( 0.50f,0.25f,0.50f );
      gl.glBegin( GL2.GL_TRIANGLES );       // Drawing Using Triangles
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); //Red
      gl.glVertex3f( 0.5f,0.7f,0.0f ); // Top
      gl.glColor3f( 0.0f,1.0f,0.0f ); //blue
      gl.glVertex3f( -0.2f,-0.50f,0.0f );          // Bottom Left
      gl.glColor3f( 0.0f,0.0f,1.0f ); //green
      gl.glVertex3f( 0.5f,-0.5f,0.0f );           //Bottom Right
      gl.glEnd();
   }
   @Override
   public void dispose( GLAutoDrawable arg0 ) {
      //method body
   }
   @Override
   public void init( GLAutoDrawable arg0 ) {
      // method body
   }
   @Override
   public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) {
      // method body
   }
   public static void main( String[] args ) {
      //getting the capabilities object of GL2 profile
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities( profile );
      // The canvas 
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      Scaling scaling = new Scaling();
      glcanvas.addGLEventListener( scaling );
      glcanvas.setSize( 400, 400 );
      //creating frame
      final JFrame frame = new JFrame (" Dimnished Triangle (Scaling )");
      //adding canvas to it
      frame.getContentPane().add(glcanvas);
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
   }//end of main
}//end of classimport javax.media.opengl.GL2;

On compiling and executing the above program, we get the following output. Here, you can observe a diminished triangle as compared to the original triangle produced by TriangleColor.java:

Scaling

Rotation

Rotation of objects can be done along any of the 3 axes, using void glRotatef(float angle, float x, float y, float z) method of GLMatrixFunc interface. You need to pass angle of rotation and x, y, z axes as parameters to this method.

The following steps guide you to rotate an object successfully:

  • Clear the color buffer and depth buffer initially using gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT) method. This method erases the previous state of the object and makes the view clear.

  • Reset the projection matrix using glLoadIdentity() method.

Instantiate the animator class and start the animator using start() method.

FPSAnimator class

Class:

FPSAnim

ator

Package: javax.media.opengl.util

Constructor

FPSAnimator(GLAutoDrawable drawable, int fps)

Creates an FPSAnimator with a given target frames-per-second value and an initial drawable to animate.

FPSAnimator(GLAutoDrawable drawable, int fps, boolean cheduleAtFixedRate)

Creates an FPSAnimator with a given target frames-per-second value, an initial drawable to animate, and a flag indicating whether to use fixed-rate scheduling.

FPSAnimator(int fps)

Creates an FPSAnimator with a given target frames-per-second value.

FPSAnimator(int fps, boolean scheduleAtFixedRate)

Creates an FPSAnimator with a given target frames-per-second value and a flag indicating whether to use fixed rate scheduling.

start() and stop() are two important methods in this class.

Let us go through the program to rotate a triangle:

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;
import com.jogamp.opengl.util.FPSAnimator;
public class TriangleRotation implements GLEventListener{
   private float rtri;  //for angle of rotation
   @Override
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glClear (GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );     
      // Clear The Screen And The Depth Buffer
      gl.glLoadIdentity();                  // Reset The View
      gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f );//triangle rotation
      gl.glBegin( GL2.GL_TRIANGLES );         // Drawing Using Triangles
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); //Red
      gl.glVertex3f( 0.5f,0.7f,0.0f ); // Top
      gl.glColor3f( 0.0f,1.0f,0.0f ); //blue
      gl.glVertex3f( -0.2f,-0.50f,0.0f );              // Bottom Left
      gl.glColor3f( 0.0f,0.0f,1.0f ); //green
      gl.glVertex3f( 0.5f,-0.5f,0.0f );              // Bottom Right
      gl.glEnd();   
      gl.glFlush();
      rtri +=0.2f;  //assigning the angle
   }
   @Override
   public void dispose( GLAutoDrawable arg0 ) {
      //method body
   }
   @Override
   public void init( GLAutoDrawable arg0 ) {
      // method body
   }
   @Override
   public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) {
      // method body
   }
   public static void main( String[] args ) {
      //getting the capabilities object of GL2 profile 
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities( profile );
      // The canvas 
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      TriangleRotation triangle = new TriangleRotation();
      glcanvas.addGLEventListener( triangle );
      glcanvas.setSize( 400, 400 );
      //creating frame
      final JFrame frame = new JFrame ( "Rotating Triangle" );
      //adding canvas to it
      frame.getContentPane().add( glcanvas );
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
      //Instantiating and Initiating Animator
      final FPSAnimator animator = new FPSAnimator( glcanvas, 300,true );
      animator.start();
   }//end of main
}//end of class

If you compile and execute the above program, it generates the following output. Here, you can observe various snapshots of a rotating colored triangle around x axis.

Triangle Rotation

Lighting

To set lighting, initially enabled lighting using glEnable() method. Then apply lighting for the objects, using glLightfv(int light, int pname, float[] params, int params_offset) method of GLLightingFunc interface. This method takes four parameters.

The following table describes parameters of gllightfv() method.

Sr. No. Parameter Name and Description
1

Light

Specifies a light. The number of lights depends on the implementation, but at least eight lights are supported. It accepts ten values, those parameters are discussed in a separate table named Light Source Parameters given below.

2

Pname

Specifies a single valued light source parameter. For light source, there are ten parameters as discussed below.

3

Params

Specifies a pointer to the value or values that is set to the parameter pname of light source light.

4

Light source parameter

You can use any of the light source parameters given below.

Light source parameters:

Sr. No. Parameter and Description
1

GL_AMBIENT

It contains the parameters that specify the ambient intensity of the light.

2

GL_DIFFUSE

It contains the parameters that specify the diffuse intensity of the light.

3

GL_SPECULAR

It contains the parameters that specify the specular intensity of the light.

4

GL_POSITION

It contains four integer or floating-point values that specify the position of the light in homogeneous object coordinates.

5

GL_SPOT_DIRECTION

It contains parameters that specify the direction of light in homogeneous object coordinates.

6

GL_SPOT_EXPONENT

Parameters of this specify the intensity distribution of light.

7

GL_SPOT_CUTOFF

The single parameter of this specifies the maximum spread angle of the light.

8

GL_CONSTANT_ATTENUATION or GL_LINEAR_ATTENUATION or GL_QUADRATIC_ATTENUATION

You can use any of these attenuation factors, which is represented by a single value.

Lighting is enabled and disabled using glEnable() and glDisable () methods with argument GL_LIGHTING.

The following template is given for lighting:

gl.glEnable(GL2.GL_LIGHTING);
gl.glEnable(GL2.GL_LIGHT0); gl.glEnable(GL2.GL_NORMALIZE);
float[] ambientLight = { 0.1f, 0.f, 0.f,0f }; // weak RED ambient
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambientLight, 0);
float[] diffuseLight = { 1f,2f,1f,0f }; //multi-color diffuse
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, diffuseLight, 0);

Applying light to a rotating polygon

Follow the given steps for applying light to a rotating polygon.

Rotate the polygon using glRotate() method:

gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);  
// Clear The Screen And The Depth Buffer 
gl.glLoadIdentity();                  
// Reset The View 
gl.glRotatef(rpoly, 0.0f, 1.0f, 0.0f);

Let us go through the program to apply light to a rotating polygon:

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;
import com.jogamp.opengl.util.FPSAnimator;

public class PolygonLighting implements GLEventListener{
   private float rpoly;
   @Override
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glColor3f(1f,0f,0f); //applying red   
      // Clear The Screen And The Depth Buffer
      gl.glClear( GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );  
      gl.glLoadIdentity();                  // Reset The View
      gl.glRotatef( rpoly, 0.0f, 1.0f, 0.0f );
      gl.glBegin( GL2.GL_POLYGON );
      gl.glVertex3f( 0f,0.5f,0f );
      gl.glVertex3f( -0.5f,0.2f,0f );
      gl.glVertex3f( -0.5f,-0.2f,0f );
      gl.glVertex3f( 0f,-0.5f,0f );
      gl.glVertex3f( 0f,0.5f,0f );
      gl.glVertex3f( 0.5f,0.2f,0f );
      gl.glVertex3f( 0.5f,-0.2f,0f );
      gl.glVertex3f( 0f,-0.5f,0f );
      gl.glEnd();
      gl.glFlush();
      rpoly +=0.2f;  //assigning the angle
      gl.glEnable( GL2.GL_LIGHTING ); 
      gl.glEnable( GL2.GL_LIGHT0 ); 
      gl.glEnable( GL2.GL_NORMALIZE );
      float[] ambientLight =  0.1f, 0.f, 0.f,0f }; // weak RED ambient 
      gl.glLightfv( GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambient-Light, 0 ); 
      float[] diffuseLight = { 1f,2f,1f,0f }; //multi color diffuse 
      gl.glLightfv( GL2.GL_LIGHT0, GL2.GL_DIFFUSE, diffuse-Light, 0 );
   }
   @Override
   public void dispose( GLAutoDrawable arg0 ) {
      //method body
   }
   @Override
   public void init( GLAutoDrawable arg0 ) {
      // method body
   }
   @Override
   public void reshape( GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4 ) {
      // method body
   }
   public static void main( String[] args ) {
      //getting the capabilities object of GL2 profile 
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities( profile );
      // The canvas 
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      PolygonLighting polygonlighting = new PolygonLighting();
      glcanvas.addGLEventListener( polygonlighting );
      glcanvas.setSize( 400, 400 );
      //creating frame
      final JFrame frame = new JFrame ( " Polygon lighting " );
      //adding canvas to it
      frame.getContentPane().add( glcanvas );
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
      //Instantiating and Initiating Animator
      final FPSAnimator animator = new FPSAnimator(glcanvas, 300,true );
      animator.start();
   }//end of main
}//end of class

If you compile and execute the above program, it generates the following output. Here, you

can observe various snapshots of a rotating polygon with lighting.

Polygon Lighting
Advertisements