正投影和透视投影是OPENGL里最基本,而且最重要的内容.
下图分别是正投影和透视投影的运行效果图,运行的是两个大小,外貌完全相同的组合矩型框体.
但是视觉效果上却非常不一样,这正是正投影和透视投影的区别.
这由于正投影的逻辑宽度在前,后,顶,底,左,右都是相等的. 正投影往往适用与CAD, 文本,建筑绘图,2D游戏等用3D来描绘2D的处理,关键代码:
void glOrtho(double left, double right, double bottom, double top, double near_val, double far_val);
//这里注意是 GL 的函数, glOrtho更像是设置平面的坐标系统
//left是左坐标,right是右坐标,bottom是底坐标,top是顶坐标,near_val是近可视,far_val是远可视
透视投影则执行透视除法,对距离观察者较远的物体矩阵进行缩短和收缩.在投影到屏幕后,可视区域后端和前端的可视宽度不同.所以透视投影更适用于3D场景.例如3D游戏,关键代码:
void gluPerspective(double fovy, double aspect, double zNear, double zFar);
//这里注意是 GLU 的函数,gluPerspective像是设置摄像机,也像人的眼睛
//fovy为可视角度,aspect宽高比例,zNear近可视,zFar是远可视
一般来说透视投影会配合
glu.gluLookAt(0.0, 0.0, 0.0,
0.0, 0.0, 1.0,
0.0, 1.0, 0.0);
使用,原形为
public void gluLookAt(double eyeX, double eyeY, double eyeZ, //表示眼睛的坐标
double centerX, double centerY, double centerZ, //眼睛看向哪个点
double upX, double upY, double upZ) ; //角度宽度,一般为0,1,0
在不使用gluLookAt的情况下,系统默认眼睛(摄像机)在原点,也就是(0,0,0)点,向着负Z轴方向看,那么眼睛看向的反方向就是正Z轴方向
简单比喻就是gluPerspective设置眼睛的性能,gluLookAt设置眼睛的位置和视觉方向.
图一:
图二:
正投影代码:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.gl3dgame.ortho;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
/**
*
* @欢迎大家光临子瑜IT博客空间. */
public class GLRender implements GLEventListener {
float xRot = 0.0f;
float yRot = 0.0f;
GL gl;
public void init(GLAutoDrawable drawable) {
gl = drawable.getGL();
float whiteLight[] = {0.45f, 0.45f, 0.45f, 1.0f};
float sourceLight[] = {0.25f, 0.25f, 0.25f, 1.0f};
float lightPos[] = {-50.f, 25.0f, 250.0f, 0.0f};
gl.glEnable(GL.GL_DEPTH_TEST); //启用深度测试
gl.glFrontFace(GL.GL_CCW); //设置CCW方向为“正面”,CCW即CounterClockWise,逆时针
gl.glEnable(GL.GL_CULL_FACE); //用GL_CULL_FACE符号常量调用glEnable函数表示开启多边形表面剔除功能
// Enable lighting 启用灯光
gl.glEnable(GL.GL_LIGHTING);
// Setup and enable light 0 设置灯光
gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, whiteLight, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, sourceLight, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, sourceLight, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPos, 0);
gl.glEnable(GL.GL_LIGHT0);
// 启用材质
gl.glEnable(GL.GL_COLOR_MATERIAL);
// 决定对物体的正面还是反面,对环境光、镜面光还是漫射光进行颜色跟踪。
//第一个参数可以取GL_FRONT、GL_BACK、GL_FRONT_AND_BACK中的任意一种,
//第二个参数可以取GL_AMBIENT、GL_DIFFUSE、GL_AMBIENT_AND_DIFFUSE、GL_SPECULAR中的任意一种。
gl.glColorMaterial(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE);
// 黑色背景
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
public void display(GLAutoDrawable drawable) {
float fZ,bZ;
// 填充背景为背景颜色
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
fZ = 100.0f;
bZ = -100.0f;
// 保存矩阵状态和做旋转
gl.glPushMatrix();
gl.glRotatef(xRot, 1.0f, 0.0f, 0.0f);
gl.glRotatef(yRot, 0.0f, 1.0f, 0.0f);
// 设置绘画颜色为红
gl.glColor3f(1.0f, 0.0f, 0.0f);
// Front Face ///
gl.glBegin(GL.GL_QUADS);
//直截了当地指着Z轴,也就是指向前面的法线
gl.glNormal3f(0.0f, 0.0f, 1.0f);
// 正面左横
gl.glVertex3f(-50.0f, 50.0f, fZ);
gl.glVertex3f(-50.0f, -50.0f, fZ);
gl.glVertex3f(-35.0f, -50.0f, fZ);
gl.glVertex3f(-35.0f,50.0f,fZ);
// 正面右横
gl.glVertex3f(50.0f, 50.0f, fZ);
gl.glVertex3f(35.0f, 50.0f, fZ);
gl.glVertex3f(35.0f, -50.0f, fZ);
gl.glVertex3f(50.0f,-50.0f,fZ);
// 正面上横
gl.glVertex3f(-35.0f, 50.0f, fZ);
gl.glVertex3f(-35.0f, 35.0f, fZ);
gl.glVertex3f(35.0f, 35.0f, fZ);
gl.glVertex3f(35.0f, 50.0f,fZ);
// 正面下横
gl.glVertex3f(-35.0f, -35.0f, fZ);
gl.glVertex3f(-35.0f, -50.0f, fZ);
gl.glVertex3f(35.0f, -50.0f, fZ);
gl.glVertex3f(35.0f, -35.0f,fZ);
//顶外
// Normal points up Y axis
gl.glNormal3f(0.0f, 1.0f, 0.0f);
gl.glVertex3f(-50.0f, 50.0f, fZ);
gl.glVertex3f(50.0f, 50.0f, fZ);
gl.glVertex3f(50.0f, 50.0f, bZ);
gl.glVertex3f(-50.0f,50.0f,bZ);
//底外
gl.glNormal3f(0.0f, -1.0f, 0.0f);
gl.glVertex3f(-50.0f, -50.0f, fZ);
gl.glVertex3f(-50.0f, -50.0f, bZ);
gl.glVertex3f(50.0f, -50.0f, bZ);
gl.glVertex3f(50.0f, -50.0f, fZ);
//左外
gl.glNormal3f(1.0f, 0.0f, 0.0f);
gl.glVertex3f(50.0f, 50.0f, fZ);
gl.glVertex3f(50.0f, -50.0f, fZ);
gl.glVertex3f(50.0f, -50.0f, bZ);
gl.glVertex3f(50.0f, 50.0f, bZ);
//右外
gl.glNormal3f(-1.0f, 0.0f, 0.0f);
gl.glVertex3f(-50.0f, 50.0f, fZ);
gl.glVertex3f(-50.0f, 50.0f, bZ);
gl.glVertex3f(-50.0f, -50.0f, bZ);
gl.glVertex3f(-50.0f, -50.0f, fZ);
gl.glEnd();
gl.glFrontFace(GL.GL_CW); // 设置CW方向为“正面”,CW即ClockWise,顺时针
gl.glBegin(GL.GL_QUADS);
// Back section
// Pointing straight out Z
gl.glNormal3f(0.0f, 0.0f, -1.0f);
//后面左横
gl.glVertex3f(-50.0f, 50.0f, bZ);
gl.glVertex3f(-50.0f, -50.0f, bZ);
gl.glVertex3f(-35.0f, -50.0f, bZ);
gl.glVertex3f(-35.0f,50.0f,bZ);
//后面右横
gl.glVertex3f(50.0f, 50.0f, bZ);
gl.glVertex3f(35.0f, 50.0f, bZ);
gl.glVertex3f(35.0f, -50.0f, bZ);
gl.glVertex3f(50.0f,-50.0f,bZ);
//后面上横
gl.glVertex3f(-35.0f, 50.0f, bZ);
gl.glVertex3f(-35.0f, 35.0f, bZ);
gl.glVertex3f(35.0f, 35.0f, bZ);
gl.glVertex3f(35.0f, 50.0f,bZ);
// 后面下横
gl.glVertex3f(-35.0f, -35.0f, bZ);
gl.glVertex3f(-35.0f, -50.0f, bZ);
gl.glVertex3f(35.0f, -50.0f, bZ);
gl.glVertex3f(35.0f, -35.0f,bZ);
// Insides /
gl.glColor3f(0.75f, 0.75f, 0.75f);
// Normal points up Y axis
//内上
gl.glNormal3f(0.0f, 1.0f, 0.0f);
gl. glVertex3f(-35.0f, 35.0f, fZ);
gl.glVertex3f(35.0f, 35.0f, fZ);
gl.glVertex3f(35.0f, 35.0f, bZ);
gl.glVertex3f(-35.0f,35.0f,bZ);
//内下
gl.glNormal3f(0.0f, 1.0f, 0.0f);
gl.glVertex3f(-35.0f, -35.0f, fZ);
gl.glVertex3f(-35.0f, -35.0f, bZ);
gl.glVertex3f(35.0f, -35.0f, bZ);
gl.glVertex3f(35.0f, -35.0f, fZ);
//内左
gl.glNormal3f(1.0f, 0.0f, 0.0f);
gl.glVertex3f(-35.0f, 35.0f, fZ);
gl.glVertex3f(-35.0f, 35.0f, bZ);
gl.glVertex3f(-35.0f, -35.0f, bZ);
gl.glVertex3f(-35.0f, -35.0f, fZ);
//内右
gl.glNormal3f(-1.0f, 0.0f, 0.0f);
gl.glVertex3f(35.0f, 35.0f, fZ);
gl.glVertex3f(35.0f, -35.0f, fZ);
gl.glVertex3f(35.0f, -35.0f, bZ);
gl.glVertex3f(35.0f, 35.0f, bZ);
gl.glEnd();
gl.glFrontFace(GL.GL_CCW); //设置CCW方向为“正面”,CCW即CounterClockWise,逆时针
// Restore the matrix state 还原状态矩阵
gl.glPopMatrix();
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
float nRange = 100.0f;
float w=(float)width;
float h=(float)height;
// 防止为零
if (height == 0) {
height = 1;
}
//视口设置为窗口尺寸
gl.glViewport(0, 0, width, height);
// Reset projection matrix stack
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
//建立剪辑视图,正投影(左,右,底部,顶部,近,远)
if (w <= h) {
gl.glOrtho(-nRange, nRange, -nRange * h / w, nRange * h / w, -nRange-50, nRange);
} else {
gl.glOrtho(-nRange * w / h, nRange * w / h, -nRange, nRange, -nRange-50, nRange);
}
// 重置模型观察矩阵堆栈
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
}
}
/
package com.gl3dgame.ortho; //要是想使用默认包,请去掉这行
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.media.opengl.*;
import com.sun.opengl.util.Animator;
import com.sun.opengl.util.FPSAnimator;
public class OrthoMain extends JFrame {
GLRender listener = new GLRender();
static FPSAnimator animator = null;
public OrthoMain() throws HeadlessException {
super("正投影,上下左右调整角度");
setSize(600, 480);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GLCapabilities glcaps = new GLCapabilities();
GLCanvas canvas = new GLCanvas(glcaps);
canvas.addGLEventListener(listener);
this.addKeyListener(new keyEventListener());
//canvas.addMouseListener(listener);
getContentPane().add(canvas, BorderLayout.CENTER);
animator = new FPSAnimator(canvas, 60, true);
centerWindow(this);
}
private void centerWindow(Component frame) { // 居中窗体
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
frame.setLocation((screenSize.width - frameSize.width) >> 1,
(screenSize.height - frameSize.height) >> 1);
}
public static void main(String[] args) {
final OrthoMain app = new OrthoMain();
// 显示窗体
SwingUtilities.invokeLater(new Runnable() {
public void run() {
app.setVisible(true);
}
});
// 动画线程开始
SwingUtilities.invokeLater(new Runnable() {
public void run() {
animator.start();
}
});
}
class keyEventListener implements KeyListener {
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 38) {
listener.xRot -= 5.0f;
}
if (e.getKeyCode() == 40) {
listener.xRot += 5.0f;
}
if (e.getKeyCode() == 37) {
listener.yRot -= 5.0f;
}
if (e.getKeyCode() == 39) {
listener.yRot += 5.0f;
}
listener.xRot = (float) ((int) listener.xRot % 360);
listener.yRot = (float) ((int) listener.yRot % 360);
}
public void keyReleased(KeyEvent e) {
}
}
}
透视投影代码:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.gl3dgame.perspect;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
/**
*
* @欢迎大家光临子瑜IT博客空间.
*/
public class GLRender implements GLEventListener {
float xRot = 0.0f;
float yRot = 0.0f;
GL gl;
GLU glu;
public void init(GLAutoDrawable drawable) {
gl = drawable.getGL();
glu = new GLU();
float whiteLight[] = {0.45f, 0.45f, 0.45f, 1.0f};
float sourceLight[] = {0.25f, 0.25f, 0.25f, 1.0f};
float lightPos[] = {-50.f, 25.0f, 250.0f, 0.0f};
gl.glEnable(GL.GL_DEPTH_TEST); //启用深度测试 Hidden surface removal
gl.glFrontFace(GL.GL_CCW); //设置CCW方向为“正面”,CCW即CounterClockWise,逆时针
gl.glEnable(GL.GL_CULL_FACE); //用GL_CULL_FACE符号常量调用glEnable函数表示开启多边形表面剔除功能
// Enable lighting 启用灯光
gl.glEnable(GL.GL_LIGHTING);
// Setup and enable light 0 设置灯光
gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, whiteLight, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, sourceLight, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, sourceLight, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPos, 0);
gl.glEnable(GL.GL_LIGHT0);
// Enable color tracking 启用材质
gl.glEnable(GL.GL_COLOR_MATERIAL);
// 决定对物体的正面还是反面,对环境光、镜面光还是漫射光进行颜色跟踪。
//第一个参数可以取GL_FRONT、GL_BACK、GL_FRONT_AND_BACK中的任意一种,
//第二个参数可以取GL_AMBIENT、GL_DIFFUSE、GL_AMBIENT_AND_DIFFUSE、GL_SPECULAR中的任意一种。
gl.glColorMaterial(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE);
// 黑色背景
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
public void display(GLAutoDrawable drawable) {
float fZ,bZ;
// 填充背景为背景颜色
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
fZ = 100.0f;
bZ = -100.0f;
// 保存矩阵状态和做旋转
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f, -300.0f);
gl.glRotatef(xRot, 1.0f, 0.0f, 0.0f);
gl.glRotatef(yRot, 0.0f, 1.0f, 0.0f);
// 设置绘画颜色为红
gl.glColor3f(1.0f, 0.0f, 0.0f);
// Front Face ///
gl.glBegin(GL.GL_QUADS);
//直截了当地指着Z轴,也就是指向前面的法线
gl.glNormal3f(0.0f, 0.0f, 1.0f);
// 正面左横
gl.glVertex3f(-50.0f, 50.0f, fZ);
gl.glVertex3f(-50.0f, -50.0f, fZ);
gl.glVertex3f(-35.0f, -50.0f, fZ);
gl.glVertex3f(-35.0f,50.0f,fZ);
//正面右横
gl.glVertex3f(50.0f, 50.0f, fZ);
gl.glVertex3f(35.0f, 50.0f, fZ);
gl.glVertex3f(35.0f, -50.0f, fZ);
gl.glVertex3f(50.0f,-50.0f,fZ);
//正面上横
gl.glVertex3f(-35.0f, 50.0f, fZ);
gl.glVertex3f(-35.0f, 35.0f, fZ);
gl.glVertex3f(35.0f, 35.0f, fZ);
gl.glVertex3f(35.0f, 50.0f,fZ);
//正面下横
gl.glVertex3f(-35.0f, -35.0f, fZ);
gl.glVertex3f(-35.0f, -50.0f, fZ);
gl.glVertex3f(35.0f, -50.0f, fZ);
gl. glVertex3f(35.0f, -35.0f,fZ);
// 顶外
// Normal points up Y axis
gl.glNormal3f(0.0f, 1.0f, 0.0f);
gl.glVertex3f(-50.0f, 50.0f, fZ);
gl.glVertex3f(50.0f, 50.0f, fZ);
gl.glVertex3f(50.0f, 50.0f, bZ);
gl.glVertex3f(-50.0f,50.0f,bZ);
// 底外
gl.glNormal3f(0.0f, -1.0f, 0.0f);
gl.glVertex3f(-50.0f, -50.0f, fZ);
gl.glVertex3f(-50.0f, -50.0f, bZ);
gl.glVertex3f(50.0f, -50.0f, bZ);
gl.glVertex3f(50.0f, -50.0f, fZ);
// 左外
gl.glNormal3f(1.0f, 0.0f, 0.0f);
gl.glVertex3f(50.0f, 50.0f, fZ);
gl.glVertex3f(50.0f, -50.0f, fZ);
gl.glVertex3f(50.0f, -50.0f, bZ);
gl.glVertex3f(50.0f, 50.0f, bZ);
// 右外
gl.glNormal3f(-1.0f, 0.0f, 0.0f);
gl.glVertex3f(-50.0f, 50.0f, fZ);
gl.glVertex3f(-50.0f, 50.0f, bZ);
gl.glVertex3f(-50.0f, -50.0f, bZ);
gl.glVertex3f(-50.0f, -50.0f, fZ);
gl.glEnd();
gl.glFrontFace(GL.GL_CW); // 设置CW方向为“正面”,CW即ClockWise,顺时针
gl.glBegin(GL.GL_QUADS);
// Back section
// Pointing straight out Z
gl.glNormal3f(0.0f, 0.0f, -1.0f);
// 后面左横
gl.glVertex3f(-50.0f, 50.0f, bZ);
gl.glVertex3f(-50.0f, -50.0f, bZ);
gl.glVertex3f(-35.0f, -50.0f, bZ);
gl. glVertex3f(-35.0f,50.0f,bZ);
// 后面右横
gl.glVertex3f(50.0f, 50.0f, bZ);
gl.glVertex3f(35.0f, 50.0f, bZ);
gl.glVertex3f(35.0f, -50.0f, bZ);
gl. glVertex3f(50.0f,-50.0f,bZ);
// 后面上横
gl.glVertex3f(-35.0f, 50.0f, bZ);
gl.glVertex3f(-35.0f, 35.0f, bZ);
gl.glVertex3f(35.0f, 35.0f, bZ);
gl. glVertex3f(35.0f, 50.0f,bZ);
// 后面下横
gl. glVertex3f(-35.0f, -35.0f, bZ);
gl. glVertex3f(-35.0f, -50.0f, bZ);
gl. glVertex3f(35.0f, -50.0f, bZ);
gl. glVertex3f(35.0f, -35.0f,bZ);
// Insides /
//灰色
gl.glColor3f(0.75f, 0.75f, 0.75f);
// 内上
gl. glNormal3f(0.0f, 1.0f, 0.0f);
gl. glVertex3f(-35.0f, 35.0f, fZ);
gl. glVertex3f(35.0f, 35.0f, fZ);
gl. glVertex3f(35.0f, 35.0f, bZ);
gl. glVertex3f(-35.0f,35.0f,bZ);
// 内下
gl. glNormal3f(0.0f, 1.0f, 0.0f);
gl. glVertex3f(-35.0f, -35.0f, fZ);
gl. glVertex3f(-35.0f, -35.0f, bZ);
gl. glVertex3f(35.0f, -35.0f, bZ);
gl. glVertex3f(35.0f, -35.0f, fZ);
// 内左
gl. glNormal3f(1.0f, 0.0f, 0.0f);
gl. glVertex3f(-35.0f, 35.0f, fZ);
gl. glVertex3f(-35.0f, 35.0f, bZ);
gl. glVertex3f(-35.0f, -35.0f, bZ);
gl. glVertex3f(-35.0f, -35.0f, fZ);
// 内右
gl. glNormal3f(-1.0f, 0.0f, 0.0f);
gl. glVertex3f(35.0f, 35.0f, fZ);
gl.glVertex3f(35.0f, -35.0f, fZ);
gl. glVertex3f(35.0f, -35.0f, bZ);
gl. glVertex3f(35.0f, 35.0f, bZ);
gl.glEnd();
gl.glFrontFace(GL.GL_CCW); //设置CCW方向为“正面”,CCW即CounterClockWise,逆时针
// Restore the matrix state 还原状态矩阵
gl.glPopMatrix();
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
float fAspect;
// 防止为零
if (height == 0) {
height = 1;
}
//视口设置为窗口尺寸
gl.glViewport(0, 0, width, height);
fAspect =(float) width / height;
// Reset projection matrix stack
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
//透视投影 眼角度,比例,近可视,远可视
glu.gluPerspective(53.0f, fAspect, 1.0, 400.0);
// 重置模型观察矩阵堆栈
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
}
}
/
package com.gl3dgame.perspect; //要是想使用默认包,请去掉这行
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.media.opengl.*;
import com.sun.opengl.util.Animator;
import com.sun.opengl.util.FPSAnimator;
public class PerspectMain extends JFrame {
GLRender listener = new GLRender();
static FPSAnimator animator = null;
public PerspectMain() throws HeadlessException {
super("透视投影,上下左右调整角度");
setSize(600, 480);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GLCapabilities glcaps = new GLCapabilities();
GLCanvas canvas = new GLCanvas(glcaps);
canvas.addGLEventListener(listener);
this.addKeyListener(new keyEventListener());
//canvas.addMouseListener(listener);
getContentPane().add(canvas, BorderLayout.CENTER);
animator = new FPSAnimator(canvas, 60, true);
centerWindow(this);
}
private void centerWindow(Component frame) { // 居中窗体
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
frame.setLocation((screenSize.width - frameSize.width) >> 1,
(screenSize.height - frameSize.height) >> 1);
}
public static void main(String[] args) {
final PerspectMain app = new PerspectMain();
// 显示窗体
SwingUtilities.invokeLater(new Runnable() {
public void run() {
app.setVisible(true);
}
});
// 动画线程开始
SwingUtilities.invokeLater(new Runnable() {
public void run() {
animator.start();
}
});
}
class keyEventListener implements KeyListener {
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 38) {
listener.xRot -= 5.0f;
}
if (e.getKeyCode() == 40) {
listener.xRot += 5.0f;
}
if (e.getKeyCode() == 37) {
listener.yRot -= 5.0f;
}
if (e.getKeyCode() == 39) {
listener.yRot += 5.0f;
}
listener.xRot = (float) ((int) listener.xRot % 360);
listener.yRot = (float) ((int) listener.yRot % 360);
}
public void keyReleased(KeyEvent e) {
}
}
}
分享自己的技术论坛http://www.itneng.com/forum.php