JOGL - 3D 立方体

在前面的章节中,我们已经了解了如何绘制 3d 三角形并旋转它。现在,在本章中,您可以学习如何绘制 3d 立方体、如何旋转它、如何在其上附加图像。同样,本章提供了绘制 3D 立方体、为其应用颜色和附加图像的示例。

下面给出了绘制 3d 立方体并为其应用颜色的程序。

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 );
        
        // 在 X、Y 和 Z 轴上旋转立方体
        gl.glRotatef(rquad, 1.0f, 1.0f, 1.0f);
        
        // 为不同面赋予不同颜色
        gl.glBegin(GL2.GL_QUADS); // 开始绘制立方体
        gl.glColor3f(1f,0f,0f); // 红色
        gl.glVertex3f(1.0f, 1.0f, -1.0f); // 四边形的右上方(顶部)
        gl.glVertex3f( -1.0f, 1.0f, -1.0f); // 四边形的左上方(顶部)
        gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // 四边形的左下方(顶部)
        gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // 四边形的右下方(顶部)
        
        gl.glColor3f( 0f,1f,0f ); //绿色
        gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 四边形的右上方
        gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 四边形的左上方
        gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 四边形的左下方
        gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 四边形的右下方
        
        gl.glColor3f( 0f,0f,1f ); //蓝色
        gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // 四边形的右上方(正面)
        gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // 四边形的左上方(正面)
        gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 四边形的左下方
        gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 四边形的右下方
        
        gl.glColor3f( 1f,1f,0f ); //黄色(红色 + 绿色)
        gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 四边形的左下角
        gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 四边形的右下角
        gl.glVertex3f( -1.0f, 1.0f, -1.0f ); // 四边形的右上角(背面)
        gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // 四边形的左上角(背面)
        
        gl.glColor3f( 1f,0f,1f ); //紫色(红色 + 绿色)
        gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // 四边形的右上方(左)
        gl.glVertex3f( -1.0f, 1.0f, -1.0f ); // 四边形的左上方(左)
        gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 四边形的左下方
        gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 四边形的右下方
        
        gl.glColor3f( 0f,1f, 1f ); //天蓝色(蓝色 + 绿色)
        gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // 四边形的右上方(右)
        gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // 四边形的左上角
        gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 四边形的左下角
        gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 四边形的右下角
        gl.glEnd(); // 四边形绘制完成
        gl.glFlush();
        
        rquad -= 0.15f;
   }
   
   @Override
   public void dispose( GLAutoDrawable drawable ) {
        // TODO 自动生成的方法存根
   }
   
   @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 自动生成的方法存根
      final GL2 gl = drawable.getGL().getGL2();
      if( height lt;= 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 );
      
      // 画布
      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();
   }
	
}

当您编译并执行上述程序时,将生成以下输出。它显示了一个彩色的 3D 立方体。

Multicolored Cube

将纹理应用于立方体

以下步骤用于将纹理应用于立方体 −

  • 您可以使用 Drawable 接口的 gl.glBindTexture(GL2.GL_TEXTURE_2D.texture) 方法将所需的纹理绑定到立方体。

  • 此方法需要纹理 (int) 参数以及 GL2.GL_TEXTURE_2D(int)

  • 在执行 Display() 之前,您需要创建纹理变量

  • init() 方法中或在起始glDisplay() 方法的行,使用 gl.glEnable(GL2.GL_TEXTURE_2D) 方法启用纹理。

  • 创建纹理对象,它需要一个文件对象作为参数,而文件对象又需要用作纹理的图像的路径。

File file = new File("c:\pictures\boy.jpg");
Texture t = TextureIO.newTexture(file, true);
Texture = t.getTextureObject(gl);
  • 处理"文件未找到"异常

下面给出的是将图像附加到立方体上的程序。

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) {
   
        // TODO 自动生成的方法存根
        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(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);
        
        // 正面
        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.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);
        
        // 顶面
        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);
        
        // 底面
        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);
        
        // 右面
        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);
        
        // 左面
        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();
        
        //在此处更改速度
        xrot += .1f;
        yrot += .1f;
        zrot += .1f;
   }
   
   @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);
      
        //
      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) {
   
      // TODO 自动生成的方法存根
      final GL2 gl = drawable.getGL().getGL2();
      if(height lt;= 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 自动生成的方法存根
        final GLProfile profile = GLProfile.get(GLProfile.GL2);
        GLCapabilities capabilities = new GLCapabilities(profile);
        
        // 画布
        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();
   }
	
}

当您编译并执行上述程序时,将生成以下输出。您可以看到一个应用了所需纹理的 3D 立方体。

Texture Cube