JOGL圖形形狀


本教學介紹了繪製直線,用直線的各種形狀。 OpenGL的API提供了原始的方法,用這些方法,可以開發形狀,如三角形,多邊形和圓形繪製基本圖形元素如點,頂點,線等。或者二維和三維。

圖形物件

要存取程式特定於硬體和作業系統平台,以及其他語言編寫,比如C和C++(原生應用)庫,Java使用一種稱為Java本地介面(JNI)程式設計框架的工作。 JOGL內部使用此介面,如圖中下面的圖表來存取OpenGL函式。

JNI

GLEventListener介面的所有四種方法讓程式碼(Java JOGL方法),它內部呼叫OpenGL函式,這些JOGL方法的命名也類似於 OpenGL 命名約定。如果在OpenGL中的函式名是在glBegin(),它被用作gl.glBegin()。

只要gl.glBegin()的Java JOGL的方法被呼叫時,它在內部呼叫OpenGL的glBegin()方法。這是在安裝JOGL的時間對使用者的系統上安裝本地庫檔案的原因。

Display() 方法

這是其中包含用於開發圖形的程式碼的一個重要方法。這就要求GLAutoDrawable介面物件作為引數。

Display()方法中,首先得到使用GL介面的物件的OpenGL上下文(GL繼承GLBase介面,該介面包含的方法來生成所有的OpenGL上下文物件)。由於本教學是關於JOGL2讓我們產生GL2物件。

讓我們通過程式碼片段獲取GL2物件:

//Generating GL object
GL gl=drawable.getGL();
GL gl=drawable.getGL(); 
//Using this Getting the Gl2 Object            
//this can be written in a single line like        
final GL2 gl = drawable.getGL().getGL2();

使用GL2介面的物件,就可以存取GL2介面的成員,而這又提供了存取 OpenGL[1.0 ...3.0]功能。

繪製一條線

GL2介面包含的方法和列表,但這裡的三個主要方法的重要論述,即函式是glBegin()glVertex()和glEnd()。

Sr. No. 方法及描述
1

glBegin()

此方法開始畫線過程。它採用預定義的字串整數“GL_LINES”作為一個引數,它是由GL介面繼承。

2

glVertex3f()/glVertex2f()

此方法建立的頂點,我們必須通過坐標引數3f 和 2f,,這表示3維的浮點坐標和2維浮點分別坐標。

3

glEnd()

行結尾

讓我們通過程式來繪製一條直線:

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 Line implements GLEventListener{
   @Override
   public void display(GLAutoDrawable drawable) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glBegin (GL2.GL_LINES);//static field
      gl.glVertex3f(0.50f,-0.50f,0);
      gl.glVertex3f(-0.50f,0.50f,0);
      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);
      Line l = new Line();
      glcanvas.addGLEventListener(l);
      glcanvas.setSize(400, 400);
      //creating frame
      final JFrame frame = new JFrame ("straight Line");
      //adding canvas to frame
      frame.getContentPane().add(glcanvas);
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
   }//end of main
}//end of classimport javax.media.opengl.GL2;
Line

使用GL_LINES繪製形狀

讓我們通過一個程式使用GL_LINES繪製一個三角形:

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 Triangle implements GLEventListener{
   @Override
   public void display(GLAutoDrawable drawable) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glBegin (GL2.GL_LINES);
      //drawing the base
      gl.glBegin (GL2.GL_LINES);
      gl.glVertex3f(-0.50f, -0.50f, 0);
      gl.glVertex3f(0.50f, -0.50f, 0);
      gl.glEnd();
      //drawing the right edge
      gl.glBegin (GL2.GL_LINES);
      gl.glVertex3f(0f, 0.50f, 0);
      gl.glVertex3f(-0.50f, -0.50f, 0);
      gl.glEnd();
      //drawing the lft edge
      gl.glBegin (GL2.GL_LINES);
      gl.glVertex3f(0f, 0.50f, 0);
      gl.glVertex3f(0.50f, -0.50f, 0);
      gl.glEnd();
      gl.glFlush();
   }
   @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);
      Triangle l = new Triangle();
      glcanvas.addGLEventListener(l);
      glcanvas.setSize(400, 400);
      //creating frame
      final JFrame frame = new JFrame ("Triangle");
      //adding canvas to frame
      frame.getContentPane().add(glcanvas);
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
   }//end of main
}//end of classimport javax.media.opengl.GL2;

如果編譯並執行上述程式,將生成以下輸出。它示出了使用glBegin()方法的GL_LINES畫出一個三角形。

Triangle

讓我們通過一個程式中使用GL_LINES畫一個菱形:

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 Rhombus implements GLEventListener{
   @Override
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      //edge1
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0.0f,0.75f,0 );
      gl.glVertex3f( -0.75f,0f,0 );
      gl.glEnd();
      //edge2
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( -0.75f,0f,0 );
      gl.glVertex3f( 0f,-0.75f, 0 );
      gl.glEnd();
      //edge3
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0f,-0.75f, 0 );
      gl.glVertex3f( 0.75f,0f, 0 );
      gl.glEnd();
      //edge4 
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0.75f,0f, 0 );
      gl.glVertex3f( 0.0f,0.75f,0 );
      gl.glEnd();
      gl.glFlush();
   }
   @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 );
      Rhombus rhombus = new Rhombus();
      glcanvas.addGLEventListener( rhombus );
      glcanvas.setSize( 400, 400 );
      //creating frame
      final JFrame frame = new JFrame ( "Rhombus" );
      //adding canvas to frame
      frame.getContentPane().add( glcanvas );
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
   }//end of main
}//end of class

如果編譯並執行以上程式,會得到下面的輸出。它示出了使用在glBegin()方法的GL_LINES產生一個菱形。

Rhombus

讓我們通過一個程式使用GL_LINES畫一所房子:

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 House implements GLEventListener{
   @Override
   public void display( GLAutoDrawable drawable ) {
      final GL2 gl = drawable.getGL().getGL2();
      //drawing top
      gl.glBegin ( GL2.GL_LINES );
      gl.glVertex3f( -0.3f, 0.3f, 0 );
      gl.glVertex3f( 0.3f,0.3f, 0 );
      gl.glEnd();
      //drawing bottom
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( -0.3f,-0.3f, 0 );
      gl.glVertex3f( 0.3f,-0.3f, 0 );
      gl.glEnd();
      //drawing the right edge
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( -0.3f,0.3f, 0 );
      gl.glVertex3f( -0.3f,-0.3f, 0 );
      gl.glEnd();
      //drawing the left edge
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0.3f,0.3f,0 );
      gl.glVertex3f( 0.3f,-0.3f,0 );
      gl.glEnd();
      //building roof
      //building lft dia 
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0f,0.6f, 0 );
      gl.glVertex3f( -0.3f,0.3f, 0 );
      gl.glEnd();
      //building rt  dia 
      gl.glBegin( GL2.GL_LINES );
      gl.glVertex3f( 0f,0.6f, 0 );
      gl.glVertex3f( 0.3f,0.3f, 0 );
      gl.glEnd();
      //building door
      //drawing top
      gl.glBegin ( GL2.GL_LINES );
      gl.glVertex3f( -0.05f, 0.05f, 0 );
      gl.glVertex3f( 0.05f, 0.05f, 0 );
      gl.glEnd();
      //drawing the left edge
      gl.glBegin ( GL2.GL_LINES );
      gl.glVertex3f( -0.05f, 0.05f, 0 );
      gl.glVertex3f( -0.05f, -0.3f, 0 );
      gl.glEnd();
      //drawing the right edge
      gl.glBegin ( GL2.GL_LINES );
      gl.glVertex3f( 0.05f, 0.05f, 0 );
      gl.glVertex3f( 0.05f, -0.3f, 0 );
      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 );
      House house = new House();
      glcanvas.addGLEventListener( house );
      glcanvas.setSize(400, 400);
      //creating frame
      final JFrame frame = new JFrame( "House" );
      //adding canvas to frame
      frame.getContentPane().add( glcanvas );
      frame.setSize( frame.getContentPane().getPreferredSize() );
      frame.setVisible( true );
   }//end of main
}//end of class

如果編譯並執行以上程式,會得到下面的輸出。它示出了使用GL_LINES()方法生成一所房子的圖。

House

使用glBegin()更多的引數繪畫出更多的形狀

除了GL_LINES預定義的字串引數,glBegin()方法接受八個引數。可以用它來繪製不同的形狀。這些用於相同GL_LINES。

下表顯示了glBegin()方法的引數和描述:

Sr. No. 引數和描述
1

GL_LINES

建立每對頂點作為一個獨立的線段。

2

GL_LINE_STRIP

繪製線段的連線組從第一頂點到最後。

3

GL_LINE_LOOP

繪製線段的從第一頂點到最後一個連線組再次回到第一個點。

4

GL_TRIANGLES

把頂點的每一三元組作為一個獨立的三角形。

5

GL_TRIANGLE_STRIP

繪製三角形的連線組。一個三角形被定義為所述第一兩個頂點後呈現的每個頂點。

6

GL_TRIANGLE_FAN

繪製三角形的連線組。一個三角形被定義為所述第一兩個頂點後呈現的每個頂點。

7

GL_QUADS

將每個組的四個頂點作為一個獨立的四邊形。

8

GL_QUAD_STRIP

繪製四邊形的連線組。一個四邊形被定義為每對所述第一對後呈現的頂點。

9

GL_POLYGON

繪製一個單一的,凸多邊形。頂點1,...,N定義這個多邊形。

讓我們來看看使用glBegin()引數的一些例子。

程式畫線帶鋼:

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 LineStrip implements GLEventListener{
   @Override
   public void display(GLAutoDrawable drawable) {
      final GL2 gl = drawable.getGL().getGL2();
      gl.glBegin (GL2.GL_LINE_STRIP);
      gl.glVertex3f(-0.50f,-0.75f, 0);
      gl.glVertex3f(0.7f,0.5f, 0);
      gl.glVertex3f(0.70f,-0.70f, 0);
      gl.glVertex3f(0f,0.5f, 0);
      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);
      LineStrip r = new LineStrip();
      glcanvas.addGLEventListener(r);
      glcanvas.setSize(400, 400);
      //creating frame
      final JFrame frame = new JFrame ("LineStrip");
      //adding canvas to frame
      frame.getContentPane().add(glcanvas);
      frame.setSize(frame.getContentPane().getPreferredSize());
      frame.setVisible(true);
   }//end of main
}//end of classimport javax.media.opengl.GL2;

如果編譯並執行上面的程式碼,生成以下輸出:

LineStrip

程式碼片段display()方法來繪製線路回路:

public void display(GLAutoDrawable drawable) {
   final GL2 gl = drawable.getGL().getGL2();
   gl.glBegin (GL2.GL_LINE_LOOP);
   gl.glVertex3f( -0.50f, -0.75f, 0);
   gl.glVertex3f(0.7f, .5f, 0);
   gl.glVertex3f(0.70f,  -0.70f, 0);
   gl.glVertex3f(0f, 0.5f, 0);
   gl.glEnd();
}

如果用上面的程式碼替換任何基本的模板方案的display()方法,編譯並執行它,下面的輸出生成:

Line Loop

程式碼片段display()方法使用GL_TRIANGLES畫三角形

public void display(GLAutoDrawable drawable) {
   final GL2 gl = drawable.getGL().getGL2();
   gl.glBegin(GL2.GL_TRIANGLES);        // Drawing Using Triangles
   gl.glVertex3f(0.5f,0.7f,0.0f);      // Top
   gl.glVertex3f(-0.2f,-0.50f,0.0f);  // Bottom Left
   gl.glVertex3f(0.5f,-0.5f,0.0f);   //Bottom Right
   gl.glEnd();   
}

如果用上面的程式碼替換顯示任何基本的模板程式的方法,編譯並執行它,下面的輸出生成:

Triangles

程式碼片段display()方法來繪製三角形:

public void display(GLAutoDrawable drawable) {
   final GL2 gl = drawable.getGL().getGL2();
   gl.glBegin (GL2.GL_TRIANGLE_STRIP);
   gl.glVertex3f(0f,0.5f,0);
   gl.glVertex3f(-0.50f,-0.75f,0);
   gl.glVertex3f(0.28f,0.06f,0);
   gl.glVertex3f(0.7f,0.5f,0);
   gl.glVertex3f(0.7f,-0.7f,0);
   gl.glEnd();   
}

如果要更換顯示器的任何與上面的程式碼的基本模板方案的方法,編譯並執行它,下面的輸出生成:

Triangle Strip

程式碼片段display()方法來繪製四邊形:

public void display(GLAutoDrawable drawable) {
   final GL2 gl = drawable.getGL().getGL2();
   gl.glBegin(GL2.GL_QUADS);
   gl.glVertex3f( 0.0f,0.75f,0);
   gl.glVertex3f(-0.75f,0f,0);
   gl.glVertex3f(0f,-0.75f,0);
   gl.glVertex3f(0.75f,0f,0);
   gl.glEnd();   
}

如果用上面的程式碼替換顯示任何基本的模板程式的方法,編譯並執行它,下面的輸出生成:

Quads

程式碼片段display()方法來繪製多邊形:

public void display(GLAutoDrawable drawable) {
   final GL2 gl = drawable.getGL().getGL2();
   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();
}

如果用上面的程式碼替換任何基本的模板方案的display()方法,編譯並執行它,會生成以下輸出

Polygon