JOGL - 三維三角形



在上一個章節中我們已經瞭解瞭如何繪製三維形狀,本章將教您如何繪製三維三角形並對其進行旋轉。

下面給出了繪製一個三維三角形並對其進行旋轉的程式。

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 ) {
	
      // TODO Auto-generated method stub
      final GL2 gl = drawable.getGL().getGL2();
      if(height lt;=;)
         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 );
      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();
   }
	
}

當您編譯並執行上述程式時,將生成以下輸出。此處,您獲得旋轉三維三角形的快照。由於該程式不包含深度測試,因此生成的三角形是空心的。

Triangle 3D

要使三角形變為實心的,您需要使用 glEnable(GL_DEPTH_TEST) 啟用深度測試。啟用深度緩衝區會為您提供一個空白的螢幕。可以使用 glClear(GL_COLOR_BUFFERBIT | GL_DEPTH_BUFFER_BIT) 方法透過清除顏色來清除此空白螢幕。要在 init() 方法或 glDisplay() 方法中啟用深度測試,請編寫以下程式碼:

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);
 }

下面給出了繪製帶深度測試的三維三角形的程式。

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 dimensions
      //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 ) {
   }
   
   @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 ) {
	
      // 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( 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();
   }
	
}

當您編譯並執行上述程式時,將生成以下輸出。

此處,您可以看到旋轉三維三角形的快照。由於該程式包含深度測試程式碼,因此生成的三角形是實心的。

Triangle Depth Test
廣告
© . All rights reserved.