JOGL轉化物件


OpenGL提供了更多的功能,比如色彩應用到一個物件,比例,燈光,旋轉的物體等。本章介紹了一些變換使用JOGL的物件。

移動物件的視窗

在前面的章節中,我們討論的方案畫線,用簡單的線條繪製各種形狀。以這種方式建立的形狀可被顯示在該視窗內的任何位置。它是通過使用glTranslatef (float x, float y, float z) 方法完成。

這種方法屬於GLMatrixFunc介面,它在javax.media.opengl.fixedfunc包。

GLMatrixFunc 介面

interface: GLMatrixFunc

package: javax.media.opengl.fixedfunc

讓我們來看看這個介面的一些重要方法:

Sr. No. 方法和說明
1

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

這個方法旋轉當前矩陣。

2

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

此方法用於縮放當前矩陣。

3

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

此方法用於轉換的當前矩陣。

4

void glLoadIdentity()

此方法載入當前矩陣與單位矩陣。

glTranslate()方法的移動坐標系的原點,以通過所述引數(x,y,z),傳遞給glTranslate()方法作為引數指定的點。儲存和恢復的未翻譯的坐標系,glPushMatrix()和glPopMatrix()方法被使用。

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

只要 glTranslate()方法被使用時,它改變了元件的螢幕上的位置。因此,GLEventListener 介面的 reshape()方法應該重寫和OpenGL視口和投影矩陣應該初始化。

下面的程式碼顯示初始化視口和投影矩陣模板:

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

運用顏色的物件

要應用顏色的物體,使用GL2類的glColor()方法。

語法

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

例子

如果通過顏色值(1,0,0),那麼得到的紅色和(1,1,0)的值給定為黃色。

  • x表示使用的顏色數, 3 (red, blue, green) or 4(red, blue, green, alpha)。為了得到不同的顏色組合,這些顏色值作為引數傳遞。顏色引數的序列必須是維護的順序。

  • y表示它接受的引數,如位元組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

如果三角形,可以為每個頂點應用不同的顏色。

讓我們通過程式的顏色應用到一個三角形:

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

當編譯並執行以上程式,會得到如下彩色三角形:

Triangle Color

應用顏色為多邊形

讓我們通過程式的顏色應用到多邊形:

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

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

Colored Polygon

縮放

縮放物件是通過使用GLMatrixFunc介面的void glScalef(float x, float y, float z) 方法進行。該方法接受三個浮點引數,使用我們指定軸沿x,y和z比例因子。

例如,在下面的程式中,一個三角形是減弱至50%。在這裡,50傳遞的是沿所有軸的引數。

讓我們通過程式來擴充套件一個三角形:

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;

編譯和執行上面的程式,我們得到以下輸出。在這裡,可以看到一個三角形的減弱相比,由TriangleColor.java生產的原三角形:

Scaling

旋轉

物件旋轉可以沿任意3軸來完成,使用GLMatrixFunc介面的void glRotatef(float angle, float x, float y, float z) 方法。需要傳遞的旋轉以及x,y,z軸的角度作為引數傳遞給該方法。

下面的步驟指導成功地旋轉物件:

  • 清除顏色快取和深度快取最初使用gl.glClear(GL2.GL_COLOR_BUFFER_BIT| GL2.GL_DEPTH_BUFFER_BIT)方法。此方法擦除物件的先前狀態,使檢視清晰。

  • 復位用glLoadIdentity()方法的投影矩陣。

範例化的動畫類和使用start()方法啟動動畫。

FPSAnimator 類

Class:

FPSAnimator

Package: javax.media.opengl.util

構造方法

FPSAnimator(GLAutoDrawable drawable, int fps)

建立給定的目標影格每秒的值和初始繪製的動畫一個FPSAnimator。

FPSAnimator(GLAutoDrawable drawable, int fps, boolean cheduleAtFixedRate)

建立一個具有給定的目標影格每秒的值,初始繪製動畫,和一個標誌,指示是否使用固定利率排程FPSAnimator。

FPSAnimator(int fps)

建立由給定的目標影格每秒值的FPSAnimator。

FPSAnimator(int fps, boolean scheduleAtFixedRate)

建立由給定的目標影格每秒的值和一個標誌,指示是否使用固定速率的排程FPSAnimator。

start() 和stop()在這個類中的兩個重要的方法。

讓我們通過程式來旋轉一個三角形:

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

如果編譯並執行上述程式,它會生成以下輸出。在這裡,可以看到周圍x軸旋轉彩色三角形的各個快照。

Triangle Rotation

燈光

要設定燈光,使用過glEnable()方法初步啟用的照明。然後應用照明的物件,使用GLLightingFunc介面的 glLightfv(int light, int pname, float[] params, int params_offset) 方法。這個方法有四個引數。

下表描述了gllightfv()方法的引數。

Sr. No. 引數名稱和描述
1

Light

指定的光。燈的數量依賴於實現,但至少八個燈支援。它接受10個值,這些引數是在一個名為下面給出的光源引數表中單獨討論。

2

Pname

指定一個單值的光源引數。光源有10個引數,如下所述。

3

Params

指定的指標被設定到的光源的引數pname的一個或多個值。

4

Light source parameter

可以使用以下任何給定的光源引數。

光源引數:

Sr. No. 引數及描述
1

GL_AMBIENT

它包含指定的光的環境亮度的引數。

2

GL_DIFFUSE

它包含指定的光的漫反射的強度的引數。

3

GL_SPECULAR

它包含指定的光的鏡面反射強度的引數。

4

GL_POSITION

它包含指定的均質物體坐標的光的位置的4個整數或浮點值。

5

GL_SPOT_DIRECTION

它包含在均質物體坐標指定的光的方向的引數。

6

GL_SPOT_EXPONENT

此引數指定的光的強度分布。

7

GL_SPOT_CUTOFF

這種單引數指定的光的最大發散角。

8

GL_CONSTANT_ATTENUATION or GL_LINEAR_ATTENUATION or GL_QUADRATIC_ATTENUATION

可以使用任意的衰減係數,它是由一個單一的值來表示。

照明被啟用並使用過glEnable()方法和glDisable()函式以及引數GL_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);

施加光到一個旋轉多角

遵循用於將光以一個旋轉多角給定的步驟。

使用旋轉glRotate()方法的多邊形:

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

讓我們通過程式將光應用到旋轉面:

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

如果編譯並執行上述程式,它會生成以下輸出。在這裡,可以觀察到一個旋轉的多邊形燈光的各種快照。

Polygon Lighting