JOGL - 3D 基础

在前面的章节中,我们已经了解了如何创建 2d 对象、对其应用效果以及变换对象。本章将教您如何绘制具有 3 维的线和一些形状。

让我们绘制一条带有 z 轴的简单线,并查看 2D 和 3D 线之间的区别。首先绘制一条简单线,然后将第二条线绘制到窗口 3 个单位处。

让我们通过程序绘制 3D 线 −

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 线
        gl.glBegin( GL2.GL_LINES );
        gl.glVertex3f( -0.75f,0f,3f );// 向窗口内移动 3 个单位
        gl.glVertex3f( 0f,-0.75f,3f );
        gl.glEnd();
   }
   
   @Override
   public void dispose( GLAutoDrawable arg0 ) {
        //方法主体
   }
   
   @Override
   public void init( GLAutoDrawable arg0 ) {
        // 方法主体
   }
   
   @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 ) {
	
        //获取 GL2 配置文件的功能对象
        final GLProfile profile = GLProfile.get( GLProfile.GL2 );
        GLCapabilities capabilities = new GLCapabilities(profile);
        
        // 画布
        final GLCanvas glcanvas = new GLCanvas( capabilities );
        Line3d line3d = new Line3d();
        glcanvas.addGLEventListener( line3d );
        glcanvas.setSize( 400, 400 );
        
        //创建框架
        final JFrame frame = new JFrame (" 3d line");
        
        //向其中添加画布
        frame.getContentPane().add( glcanvas );
        frame.setSize(frame.getContentPane().getPreferredSize() );
        frame.setVisible( true );
   }//end of main
	
}//end of class

编译并执行上述程序时,将生成以下输出 −

3D Line

可以通过为 glVertex3f() 方法的 z 象限赋予非零值来绘制 3D 形状,从而生成上述视图。现在连接剩余的线将产生 3D 边缘。

现在让我们以同样的方式开发具有第三维的边缘。

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 自动生成的方法存根
        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 线
        gl.glBegin(GL2.GL_LINES);
        
        //3 个单位进入窗口
        gl.glVertex3f(-0.75f,0f,3f);
        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();
        
         //底部
         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) {
        //方法主体
   }
	
   @Override
   public void init(GLAutoDrawable arg0) {
        // 方法主体
   }
   
   @Override
   public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
	
        // TODO 自动生成的方法 stubfinal
        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) {
   
        //获取 GL2 配置文件的功能对象
        final GLProfile profile = GLProfile.get(GLProfile.GL2);
        GLCapabilities capabilities = new GLCapabilities(profile);
        
        // 画布
        final GLCanvas glcanvas = new GLCanvas(capabilities);
        Edge1 b = new Edge1();
        glcanvas.addGLEventListener(b);
        glcanvas.setSize(400, 400);
        
        //创建框架
        final JFrame frame = new JFrame (" 3d edge");
        
        //向其中添加画布
        frame.getContentPane().add(glcanvas);
        frame.setSize(frame.getContentPane().getPreferredSize());
        frame.setVisible(true);
   }//end of main
	
}//end of class

编译并执行上述程序时,将生成以下输出 −

3D Edge

同样,通过将 3D 边发展到任何 2D 四边形的对应边并连接相邻顶点,您可以得到一个 3D 四边形。

下面给出了一个使用 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;

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);
        
        //绘制边缘 1.....
        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 个单位
        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();
        
        // 底部
        gl.glBegin(GL2.GL_LINES);
        gl.glVertex3f(0f,-0.75f, 0);
        gl.glVertex3f(0f,-0.75f,3f);
        gl.glEnd();
        
        // 边缘 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();
        
        //边 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();
        
        //最终边缘
        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) {
        //方法主体
   }
	
   @Override
   public void init(GLAutoDrawable arg0) {
        // 方法主体
   }
	
   @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(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) {
	
        //获取 GL2 配置文件的功能对象
        final GLProfile profile = GLProfile.get(GLProfile.GL2);
        GLCapabilities capabilities = new GLCapabilities(profile);
        
        // 画布
        final GLCanvas glcanvas = new GLCanvas(capabilities);
        Rhombus b = new Rhombus();
        glcanvas.addGLEventListener(b);
        glcanvas.setSize(400, 400);
        
        //创建框架
        final JFrame frame = new JFrame (" Rhombus 3d");
        
        //向其中添加画布
        frame.getContentPane().add(glcanvas);
        frame.setSize(frame.getContentPane().getPreferredSize());
        frame.setVisible(true);
   }//end of main
	
}//end of classimport javax.media.opengl.GL2;

编译并执行上述程序时,会生成以下输出。它显示了使用 3D 线条绘制的菱形。

Rhombus 3D

glBegin() 方法的预定义参数可用于绘制 3D 形状。