- JOGL - API for Basic Templates
- JOGL - Canvas with AWT
- JOGL - Canvas with Swing
- JOGL - GLJPanel Class
- JOGL Graphical Shapes
- JOGL - Drawing Basics
- JOGL - Drawing with GL_Lines
- JOGL - Pre-defined shapes
- JOGL Effects & Transformation
- JOGL - Transformation
- JOGL - Coloring
- JOGL - Scaling
- JOGL - Rotation
- JOGL - Lighting
- JOGL 3D Graphics
- JOGL - 3D Basics
- JOGL - 3D Triangle
- JOGL - 3D Cube
- JOGL - Appendix
- JOGL Useful Resources
- JOGL - Quick Guide
- JOGL - Useful Resources
- JOGL - Discussion
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 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:
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
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.
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.
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.
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.
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.