JOGL - 3D 三角形
在上一章中,我们已经了解了如何绘制 3D 形状,本章将教您如何绘制 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; 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(); // 清除屏幕和深度缓冲区 gl.glClear( GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT ); gl.glLoadIdentity(); // 重置视图 gl.glTranslatef( -0.5f, 0.0f, -6.0f ); // 移动三角形 gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f ); gl.glBegin( GL2.GL_TRIANGLES ); // 在所有维度上绘制三角形 // 正面 gl.glColor3f( 1.0f, 0.0f, 0.0f ); // 红色 gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 三角形顶部(正面) gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 绿色 gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 三角形左侧(正面) gl.glColor3f( 0.0f, 0.0f, 1.0f ); // 蓝色 gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 三角形右侧(正面) // 右侧 gl.glColor3f( 1.0f, 0.0f, 0.0f ); // 红色 gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 三角形顶部(右) gl.glColor3f( 0.0f, 0.0f, 1.0f ); // 蓝色 gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 三角形左侧(右) gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 绿色 gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 三角形右侧(右) // 左 gl.glColor3f( 1.0f, 0.0f, 0.0f ); // 红色 gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 三角形顶部(后面) gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 绿色 gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 三角形左侧(后面) gl.glColor3f( 0.0f, 0.0f, 1.0f ); // 蓝色 gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 三角形右侧(后面) //左侧 gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 红色 gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 三角形顶部(左侧) gl.glColor3f( 0.0f, 0.0f, 1.0f ); // 蓝色 gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 三角形左侧(左) gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 绿色 gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 三角形右侧(左) gl.glEnd(); // 完成绘制 3d 三角形(金字塔) gl.glFlush(); rtri += 0.2f; } @Override public void dispose( GLAutoDrawable drawable ) { //方法主体 } @Override public void init( GLAutoDrawable drawable ) { //方法主体 } @Override public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) { // TODO 自动生成的方法存根 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 自动生成的方法存根 final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities( profile ); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities ); Triangle3d triple = new Triangle3d(); glcanvas.addGLEventListener( triple ); 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(); } }
编译并执行上述程序时,会生成以下输出。这里,您有旋转 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); }
下面给出的是使用深度测试绘制 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; 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); // 清除屏幕和深度缓冲区 gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); // 重置视图 gl.glTranslatef( -0.5f,0.0f,-6.0f ); // 移动三角形 gl.glRotatef( rtri, 0.0f, 1.0f, 0.0f ); gl.glBegin( GL2.GL_TRIANGLES ); //在所有维度上绘制三角形 //正面 gl.glColor3f( 1.0f, 0.0f, 0.0f ); // 红色 gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 顶部 gl.glColor3f( 0.0f, 1.0f, 0.0f ); // 绿色 gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 左 gl.glColor3f( 0.0f, 0.0f, 1.0f ); // 蓝色 gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 右) //右 gl.glColor3f( 1.0f, 0.0f, 0.0f ); gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 上 gl.glColor3f( 0.0f, 0.0f, 1.0f ); gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // 左 gl.glColor3f( 0.0f, 1.0f, 0.0f ); gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 右 //左 gl.glColor3f( 1.0f, 0.0f, 0.0f ); gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 上 gl.glColor3f( 0.0f, 1.0f, 0.0f ); gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // 左 gl.glColor3f( 0.0f, 0.0f, 1.0f ); gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 右 //上 gl.glColor3f( 0.0f, 1.0f, 0.0f ); gl.glVertex3f( 1.0f, 2.0f, 0.0f ); // 顶部 gl.glColor3f( 0.0f, 0.0f, 1.0f ); gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // 左侧 gl.glColor3f( 0.0f, 1.0f, 0.0f ); gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // 右侧 gl.glEnd(); // 完成绘制 3d 三角形(金字塔) 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 自动生成的方法存根 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 自动生成的方法存根 final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities( profile ); // 画布 final GLCanvas glcanvas = new GLCanvas( capabilities ); Triangledepthtest tripledepthtest = new Triangledepthtest(); glcanvas.addGLEventListener( tripledepthtest ); 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(); } }
编译并执行上述程序时,将生成以下输出。
在这里,您可以看到旋转的 3D 三角形的快照。由于此程序包含深度测试代码,因此三角形是实心的。
