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 三角形的快照。由于此程序包含深度测试代码,因此三角形是实心的。

