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 立方体。
将纹理应用于立方体
以下步骤用于将纹理应用于立方体 −
您可以使用 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 立方体。

