JOGL 3D Graphics



In this chapter, let us see how to deal with 3D graphics.

Drawing a 3D line

Let us draw a simple line with z axis and see the difference between 2D and 3D lines. Draw a simple line first, then draw the second line 3 units into the window.

Let us go through the program to draw a 3D line:

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.media.opengl.glu.GLU;
import javax.swing.JFrame;

public class Line3d implements GLEventListener{
   private GLU glu = new GLU();
   @Override
   public void display( GLAutoDrawable drawable ) {   
      final GL2 gl = drawable.getGL().getGL2();
      gl.glTranslatef( 0f, 0f, -2.5f );
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( -0.75f,0f,0 );
      gl.glVertex3f( 0f,-0.75f, 0 );
      gl.glEnd();
      //3d line
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( -0.75f,0f,3f );// 3 units into the window
      gl.glVertex3f( 0f,-0.75f,3f );
      gl.glEnd();
   }
   @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 ) {
      GL2 gl = drawable.getGL().getGL2();
      if( height <=0 )
         height =1;
      final float h = ( float ) width / ( float ) height;
      gl.glViewport( 0, 0, width, height );
      gl.glMatrixMode( GL2.GL_PROJECTION );
      gl.glLoadIdentity();
      glu.gluPerspective( 45.0f, h, 1.0, 20.0 );
      gl.glMatrixMode( GL2.GL_MODELVIEW );
      gl.glLoadIdentity();
   }
   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 );
      Line3d line3d = new Line3d();
      glcanvas.addGLEventListener( line3d );
      glcanvas.setSize( 400, 400 );
      //creating frame
      final JFrame frame = new JFrame (" 3d line");
      //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, the following output is generated:

3D Line

3D shapes can be drawn by giving non-zero values to z quadrant of the glVertex3f() method, which generates the above view. Now joining the remaining lines will lead to a 3D edge.

Program to develop a 3D edge:

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.media.opengl.glu.GLU;
import javax.swing.JFrame;

public class Edge1 implements GLEventListener{
   private GLU glu = new GLU();
   @Override
   public void display(GLAutoDrawable drawable) {   
      // TODO Auto-generated method stub
      final GL2 gl = drawable.getGL().getGL2();
      gl.glTranslatef(0f, 0f, -2.5f);
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glEnd();
      //3d line
      gl.glBegin(GL2.GL_LINES);
      //3 units in to the window
      gl.glVertex3f(-0.75f,0f,3f);
      gl.glVertex3f(0f,-0.75f,3f);
      gl.glEnd();
      //top
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glVertex3f(-0.75f,0f,3f);
      gl.glEnd();
      //bottom
      gl.glBegin(GL2.GL_LINES); 
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glVertex3f(0f,-0.75f,3f);
      gl.glEnd();
   }
   @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) {
      GL2 gl = drawable.getGL().getGL2();
      if(height <=0)
         height =1;
      final float h = (float) width / (float) height;
      gl.glViewport(0, 0, width, height);
      gl.glMatrixMode(GL2.GL_PROJECTION);
      gl.glLoadIdentity();
      glu.gluPerspective(45.0f, h, 1.0, 20.0);
      gl.glMatrixMode(GL2.GL_MODELVIEW);
      gl.glLoadIdentity();
   }
   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);
      Edge1 b = new Edge1();
      glcanvas.addGLEventListener(b);
      glcanvas.setSize(400, 400);
      //creating frame
      final JFrame frame = new JFrame (" 3d edge");
      //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, the following output is generated:

3D Edge

In the same way, by developing 3D edges to corresponding sides of any 2D quadrilateral and joining the adjacent vertices, you can get a 3D quadrilateral.

Let us go through the program to draw a rhombus:

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.media.opengl.glu.GLU;
import javax.swing.JFrame;

public class Rhombus implements GLEventListener{
   private GLU glu = new GLU();
   @Override
   public void display(GLAutoDrawable drawable) { 
      final GL2 gl = drawable.getGL().getGL2();
      gl.glTranslatef(0f, 0f, -2.5f);
      //drawing edge1.....
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glEnd();
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,3f);// 3 units into the window
      gl.glVertex3f(0f,-0.75f,3f);
      gl.glEnd();
      //top
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glVertex3f(-0.75f,0f,3f);
      gl.glEnd();
      //bottom
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glVertex3f(0f,-0.75f,3f);
      gl.glEnd();
      //edge 2....
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glVertex3f(0.75f,0f, 0);
      gl.glEnd();
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0f,-0.75f, 3f);
      gl.glVertex3f(0.75f,0f, 3f);
      gl.glEnd();
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0f,-0.75f, 0);
      gl.glVertex3f(0f,-0.75f, 3f);
      gl.glEnd();
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0.75f,0f, 0);
      gl.glVertex3f(0.75f,0f, 3f);
      gl.glEnd();
      //Edge 3.............
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f( 0.0f,0.75f,0);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glEnd();
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f( 0.0f,0.75f,3f);
      gl.glVertex3f(-0.75f,0f,3f);
      gl.glEnd();
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f( 0.0f,0.75f,0);
      gl.glVertex3f( 0.0f,0.75f,3f);
      gl.glEnd();
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(-0.75f,0f,0);
      gl.glVertex3f(-0.75f,0f,3f);
      gl.glEnd();
      //final edge
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0.75f,0f, 0);
      gl.glVertex3f( 0.0f,0.75f,0);
      gl.glEnd();
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0.75f,0f,3f);
      gl.glVertex3f( 0.0f,0.75f,3f);
      gl.glEnd();
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f(0.75f,0f, 0);
      gl.glVertex3f(0.75f,0f,3f);
      gl.glEnd();
      gl.glBegin(GL2.GL_LINES);
      gl.glVertex3f( 0.0f,0.75f,0);
      gl.glVertex3f( 0.0f,0.75f,3f);
      gl.glEnd();
    }      
   @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) {
      // TODO Auto-generated method stub final 
      GL2 gl = drawable.getGL().getGL2();
      if(height <=0)
      height =1;
      final float h = (float) width / (float) height;
      gl.glViewport(3, 6, width, height);
      gl.glMatrixMode(GL2.GL_PROJECTION);
      gl.glLoadIdentity();
      glu.gluPerspective(45.0f, h, 1.0, 20.0);
      gl.glMatrixMode(GL2.GL_MODELVIEW);
      gl.glLoadIdentity();
   }
   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);
      Rhombus b = new Rhombus();
      glcanvas.addGLEventListener(b);
      glcanvas.setSize(400, 400);
      //creating frame
      final JFrame frame = new JFrame (" Rhombus 3d");
      //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;

When you compile and execute the above program, the following output is generated. It shows a rhombus drawn using 3D lines

Rhombus 3d

The predefined parameters of glBegin() method can be used for drawing 3D shapes.

Let us go through the program for drawing a 3D triangle (without depth test):

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.media.opengl.glu.GLU;
import javax.swing.JFrame;
import com.jogamp.opengl.util.FPSAnimator;

public class Triangle3d implements GLEventListener{
   private GLU glu = new GLU();
   private float rtri =0.0f;
   @Override
   public void display(GLAutoDrawable drawable) {
      final GL2 gl = drawable.getGL().getGL2();
      // 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.glTranslatef( -0.5f, 0.0f, -6.0f );         // Move the triangle 
      gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f );
      gl.glBegin(  GL2.GL_TRIANGLES );         
      //drawing triangle in all dimensions
      // Front
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); // Red
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top Of Triangle (Front)
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Green
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Left Of Triangle (Front)
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); // Blue
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Right Of Triangle (Front)
      // Right
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); // Red
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top Of Triangle (Right)
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); // Blue
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Left Of Triangle (Right)
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Green
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Right Of Triangle (Right)
      // Left
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); // Red
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top Of Triangle (Back)
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Green
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Left Of Triangle (Back)
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); // Blue
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Right Of Triangle (Back)
      //left
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Red
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top Of Triangle (Left)
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); // Blue
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Left Of Triangle (Left)
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Green
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Right Of Triangle (Left)
      gl.glEnd(); // Done Drawing 3d  triangle (Pyramid)
      gl.glFlush();
      rtri +=0.2f;   
   }
   @Override
   public void dispose( GLAutoDrawable drawable ) {
      //method body
   }
   @Override
   public void init( GLAutoDrawable drawable ) {
      //method body
   }
   @Override
   public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) {
      final GL2 gl = drawable.getGL().getGL2();
      if(height <=;)
         height =1;
      final float h = ( float ) width / ( float ) height;
      gl.glViewport( 0, 0, width, height );
      gl.glMatrixMode( GL2.GL_PROJECTION );
      gl.glLoadIdentity();
      glu.gluPerspective( 45.0f, h, 1.0, 20.0 );
      gl.glMatrixMode( GL2.GL_MODELVIEW );
      gl.glLoadIdentity();
   }
   public static void main( String[] args ) {
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities( profile );
      // The canvas 
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      Triangle3d triangle = new Triangle3d();
      glcanvas.addGLEventListener( triangle );
      glcanvas.setSize( 400, 400 );
      final JFrame frame = new JFrame ( "3d  Triangle (shallow)" );
      frame.getContentPane().add( glcanvas );
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
      final FPSAnimator animator = new FPSAnimator( glcanvas, 300,true );
      animator.start();
   }
}

When you compile and execute the above program, the following output is generated. Here, you have the snapshots of rotating 3D triangle. Since this program does not includes depth test, the triangle is generated hollow.

Triangle 3D

To make the triangle solid, you need to enable depth test by using glEnable(GL_DEPTH_TEST). Enabling the depth buffer gives you blank screen. This can be cleared while clearing the color using glClear(GL_COLOR_BUFFERBIT | GL_DEPTH_BUFFER_BIT) method. To enable depth test in the init() method or in the glDisplay() method, write the following code:

public void init(GLAutoDrawable drawable) {
   final GL2 gl = drawable.getGL().getGL2(); 
   gl.glShadeModel(GL2.GL_SMOOTH); 
   gl.glClearColor(0f, 0f, 0f, 0f); 
   gl.glClearDepth(1.0f); 
   gl.glEnable(GL2.GL_DEPTH_TEST);
   gl.glDepthFunc(GL2.GL_LEQUAL);
   gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
}

Let us go through the program for drawing a 3D triangle (with depth test):

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.media.opengl.glu.GLU;
import javax.swing.JFrame;
import com.jogamp.opengl.util.FPSAnimator;

public class Triangledepthtest implements GLEventListener{
   private GLU glu = new GLU();
   private float rtri =0.0f;
   @Override
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glShadeModel( GL2.GL_SMOOTH );
      gl.glClearColor( 0f, 0f, 0f, 0f );
      gl.glClearDepth( 1.0f );
      gl.glEnable( GL2.GL_DEPTH_TEST );
      gl.glDepthFunc( GL2.GL_LEQUAL );
      gl.glHint( GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST );
      // 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.glTranslatef( -0.5f,0.0f,-6.0f );  // Move the triangle 
      gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f );
      gl.glBegin( GL2.GL_TRIANGLES );                
      //drawing triangle in all dimentions
      //front
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); // Red
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); // Green
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Left
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); // Blue
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Right)
      //right
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); 
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top 
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); 
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Left 
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); 
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Right
      //left
      gl.glColor3f( 1.0f, 0.0f, 0.0f ); 
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top 
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); 
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Left 
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); 
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Right 
      //top
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); 
      gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // Top 
      gl.glColor3f( 0.0f, 0.0f, 1.0f ); 
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Left 
      gl.glColor3f( 0.0f, 1.0f, 0.0f ); 
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Right 
      gl.glEnd(); // Done Drawing 3d  triangle (Pyramid)            
      gl.glFlush();
      rtri +=0.2f;
   }
   @Override
   public void dispose( GLAutoDrawable drawable ) {
      //method body
   }
   @Override
   public void init( GLAutoDrawable drawable  ) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glShadeModel( GL2.GL_SMOOTH );
      gl.glClearColor( 0f, 0f, 0f, 0f );
      gl.glClearDepth( 1.0f );
      gl.glEnable( GL2.GL_DEPTH_TEST );
      gl.glDepthFunc( GL2.GL_LEQUAL );
      gl.glHint( GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST );
   }
   @Override
   public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) {
      final GL2 gl = drawable.getGL().getGL2();
      if( height <=0 )
         height =1;
      final float h = ( float ) width / ( float ) height;
      gl.glViewport( 0, 0, width, height );
      gl.glMatrixMode( GL2.GL_PROJECTION );
      gl.glLoadIdentity();
      glu.gluPerspective( 45.0f, h, 1.0, 20.0 );
      gl.glMatrixMode( GL2.GL_MODELVIEW );
      gl.glLoadIdentity();
   }
   public static void main( String[] args ) {
      // TODO Auto-generated method stub
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities( profile );
      // The canvas 
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      Triangledepthtest triangledepthtest = new Triangledepthtest();
      glcanvas.addGLEventListener( triangledepthtest );
      glcanvas.setSize( 400, 400 );
      final JFrame frame = new JFrame ( "3d  Triangle (solid)" );
      frame.getContentPane().add(glcanvas);
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
      final FPSAnimator animator = new FPSAnimator( glcanvas, 300,true );
      animator.start();
   }
}

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

Here, you can see the snapshots of rotating 3D triangle. Since this program includes code for depth test, the triangle is generated solid.

Triangle Depth Test

Drawing a 3D cube

In the same way, let us draw a 3D cube and apply colors to it. Let us go through the program to create a 3D cube:

import java.awt.DisplayMode;
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.media.opengl.glu.GLU;
import javax.swing.JFrame;
import com.jogamp.opengl.util.FPSAnimator;

public class Cube implements GLEventListener{

   public static DisplayMode dm, dm_old;
   private GLU glu = new GLU();
   private float rquad=0.0f;
   @Override
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glClear( GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );     
      gl.glLoadIdentity();
      gl.glTranslatef( 0f, 0f, -5.0f ); 
      gl.glRotatef( rquad, 1.0f, 1.0f, 1.0f ); // Rotate The Cube On X, Y & Z
      //giving different colors to different sides
      gl.glBegin( GL2.GL_QUADS ); // Start Drawing The Cube
      gl.glColor3f( 1f,0f,0f );   //red color
      gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // Top Right Of The Quad (Top)
      gl.glVertex3f( -1.0f, 1.0f, -1.0f); // Top Left Of The Quad (Top)
      gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // Bottom Left Of The Quad (Top)
      gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // Bottom Right Of The Quad (Top)
      gl.glColor3f( 0f,1f,0f ); //green color
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Top Right Of The Quad 
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Top Left Of The Quad 
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Bottom Left Of The Quad 
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Bottom Right Of The Quad 
      gl.glColor3f( 0f,0f,1f ); //blue color
      gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // Top Right Of The Quad (Front)
      gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // Top Left Of The Quad (Front)
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Bottom Left Of The Quad 
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Bottom Right Of The Quad 
      gl.glColor3f( 1f,1f,0f ); //yellow (red + green)
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Bottom Left Of The Quad 
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Bottom Right Of The Quad
      gl.glVertex3f( -1.0f, 1.0f, -1.0f ); // Top Right Of The Quad (Back)
      gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // Top Left Of The Quad (Back)
      gl.glColor3f( 1f,0f,1f ); //purple (red + green)
      gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // Top Right Of The Quad (Left)
      gl.glVertex3f( -1.0f, 1.0f, -1.0f ); // Top Left Of The Quad (Left)
      gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // Bottom Left Of The Quad 
      gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // Bottom Right Of The Quad 
      gl.glColor3f( 0f,1f, 1f ); //sky blue (blue +green)
      gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // Top Right Of The Quad (Right)
      gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // Top Left Of The Quad 
      gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // Bottom Left Of The Quad 
      gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // Bottom Right Of The Quad 
      gl.glEnd(); // Done Drawing The Quad
      gl.glFlush();
      rquad -=0.15f;
   }
   @Override
   public void dispose( GLAutoDrawable drawable ) {
   // TODO Auto-generated method stub
   }
   @Override
   public void init( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glShadeModel( GL2.GL_SMOOTH );
      gl.glClearColor( 0f, 0f, 0f, 0f );
      gl.glClearDepth( 1.0f );
      gl.glEnable( GL2.GL_DEPTH_TEST );
      gl.glDepthFunc( GL2.GL_LEQUAL );
      gl.glHint( GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST );
   }
   @Override
   public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) {
      final GL2 gl = drawable.getGL().getGL2();
      if( height <=0 )
         height =1;
      final float h = ( float ) width / ( float ) height;
      gl.glViewport( 0, 0, width, height );
      gl.glMatrixMode( GL2.GL_PROJECTION );
      gl.glLoadIdentity();
      glu.gluPerspective( 45.0f, h, 1.0, 20.0 );
      gl.glMatrixMode( GL2.GL_MODELVIEW );
      gl.glLoadIdentity();
   }
   public static void main( String[] args ) {
      final GLProfile profile = GLProfile.get( GLProfile.GL2 );
      GLCapabilities capabilities = new GLCapabilities( profile );
      // The canvas 
      final GLCanvas glcanvas = new GLCanvas( capabilities );
      Cube cube = new Cube();
      glcanvas.addGLEventListener( cube );
      glcanvas.setSize( 400, 400 );
      final JFrame frame = new JFrame ( " Multicolored cube" );
      frame.getContentPane().add( glcanvas );
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
      final FPSAnimator animator = new FPSAnimator( glcanvas, 300,true );
      animator.start();
   }
}

When you compile and execute the above program, the following output is generated. This shows a colored 3D cube.

Multicolored Cube

Applying texture to the cube

The following steps are given to apply texture to a cube:

  • You can bind required texture to the cube using gl.glBindTexture(GL2.GL_TEXTURE_2D. texture) method of Drawable interface.

  • This method requires texture (int) argument along with GL2.GL_TEXTURE_2D(int)

  • Before you execute Display(), you need to create texture variable.

  • In the init() method or in the starting lines of glDisplay() method, enable the texture using gl.glEnable(GL2.GL_TEXTURE_2D) method.

  • Create the texture object, which needs a file object as a parameter, which in turn needs path of the image used as texture to the object.

File file=new File(c:\\pictures\\boy.jpg);
Texture t=textureIO.newTexture(file, true);
texture=t.getTextureObject(gl);
  • Handle the file not found exception.

    Let us go through the program to apply texture to a cube:

  • import java.awt.DisplayMode;
    import java.io.File;
    import java.io.IOException;
    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.media.opengl.glu.GLU;
    import javax.swing.JFrame;
    import com.jogamp.opengl.util.FPSAnimator;
    import com.jogamp.opengl.util.texture.Texture;
    import com.jogamp.opengl.util.texture.TextureIO;
    
    public class CubeTexture implements GLEventListener {
       public static DisplayMode dm, dm_old;
       private GLU glu = new GLU();
       private float xrot,yrot,zrot;
       private int texture;
       @Override
       public void display(GLAutoDrawable drawable) {
          final GL2 gl = drawable.getGL().getGL2();
          gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);   
          gl.glLoadIdentity();                       // Reset The View
          gl.glTranslatef(0f, 0f, -5.0f);
          gl.glRotatef(xrot, 1.0f, 1.0f, 1.0f); 
          gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
          gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);
          gl.glBindTexture(GL2.GL_TEXTURE_2D, texture);
          gl.glBegin(GL2.GL_QUADS);
          // Front Face
          gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f,  1.0f);
          gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f,  1.0f);
          gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f,  1.0f,  1.0f);
          gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f,  1.0f,  1.0f);
          // Back Face
          gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);
          gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f,  1.0f, -1.0f);
          gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f,  1.0f, -1.0f);
          gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);
          // Top Face
          gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f,  1.0f, -1.0f);
          gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f,  1.0f,  1.0f);
          gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f,  1.0f,  1.0f);
          gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f,  1.0f, -1.0f);
          // Bottom Face
          gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);
          gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);
          gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f,  1.0f);
          gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f,  1.0f);
          // Right face
          gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f);
          gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f,  1.0f, -1.0f);
          gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f,  1.0f,  1.0f);
          gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f,  1.0f);
          // Left Face
          gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f);
          gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f,  1.0f);
          gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f,  1.0f,  1.0f);
          gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f,  1.0f, -1.0f);
          gl.glEnd();
          gl.glFlush();
          //change the speeds here  
          xrot+=.1f;
          yrot+=.1f;
          zrot+=.1f;
       }
       @Override
       public void dispose(GLAutoDrawable drawable) {
          // method body
       }
       @Override
       public void init(GLAutoDrawable drawable) {
          final GL2 gl = drawable.getGL().getGL2();
          gl.glShadeModel(GL2.GL_SMOOTH);
          gl.glClearColor(0f, 0f, 0f, 0f);
          gl.glClearDepth(1.0f);
          gl.glEnable(GL2.GL_DEPTH_TEST);
          gl.glDepthFunc(GL2.GL_LEQUAL);
          gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
          gl.glEnable(GL2.GL_TEXTURE_2D);
          try
          {
             File im = new File("E:\\office\\boy.jpg ");
             Texture t = TextureIO.newTexture(im, true);
             texture= t.getTextureObject(gl);
          }
          catch(IOException e)
          {
             e.printStackTrace();
          }
       }
       @Override
       public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
          final GL2 gl = drawable.getGL().getGL2();
          if(height <=0)
             height =1;
          final float h = (float) width / (float) height;
          gl.glViewport(0, 0, width, height);
          gl.glMatrixMode(GL2.GL_PROJECTION);
          gl.glLoadIdentity();
          glu.gluPerspective(45.0f, h, 1.0, 20.0);
          gl.glMatrixMode(GL2.GL_MODELVIEW);
          gl.glLoadIdentity();
       }
       public static void main(String[] args) {
          final GLProfile profile = GLProfile.get(GLProfile.GL2);
          GLCapabilities capabilities = new GLCapabilities(profile);
          // The canvas 
          final GLCanvas glcanvas = new GLCanvas(capabilities);
          CubeTexture r = new CubeTexture();
          glcanvas.addGLEventListener(r);
          glcanvas.setSize(400, 400);
          final JFrame frame = new JFrame (" Textured Cube");
          frame.getContentPane().add(glcanvas);
          frame.setSize(frame.getContentPane().getPreferredSize());
          frame.setVisible(true);
          final FPSAnimator animator = new FPSAnimator(glcanvas, 300,true );
          animator.start();
       }
    }
    

    When you compile and execute the above program, the following output is generated. You can see a 3D cube with desired texture applied on it.

    Textured Cube

    Appendix

    GPU - Graphical processing unit, it is a special electronic device that accelerates the rendering of images.

    JNI - Java Native Interface. Using which, java access native methods.

    Model They are the objects constructed from basic graphics primitives such as points, lines and polygons.

    Pixel Smallest unit of display seen on the screen.

    Projection - The method of mapping the coordinates of an object to a two-dimensional plane is called projection.

    Projection matrix - It is a linear transformation of an object on the 2D surface.

    Rendering A process by which computer creates images from models.

    Viewport - A viewport is a viewing region on the screen in computer graphics.

    Advertisements