运行效果就如上图,,
值得注意的是旋转是基于矩阵的旋转,要选择某个物体的时候千万要用
gl.glPushMatrix(); 保存模型矩阵
gl.glPopMatrix(); 释放矩阵
不然就很可能旋转的是整个投影矩阵
说点小插曲,鉴于某楼主在自己发布的源代码包里放美女图片,本人几乎也用同样的方法提高知名度了,呵呵,想把程序背景改为美女三点式泳衣图,,后来想到应该是后面章节的内容,,所以就没加了,,在此抗议一下那位楼主哦~呵呵
package com.jogl.learn.primitive; //要是想使用默认包,请去掉这行
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 PrimitiveExp extends JFrame {
GLRender listener=new GLRender();
static FPSAnimator animator=null;
public PrimitiveExp() throws HeadlessException {
super("JOGL立体图形");
setSize(600,480);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GLCapabilities glcaps=new GLCapabilities();
GLCanvas canvas=new GLCanvas(glcaps);
canvas.addGLEventListener(listener);
//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 PrimitiveExp app = new PrimitiveExp();
// 显示窗体
SwingUtilities.invokeLater(new Runnable() {
public void run() {
app.setVisible(true);
}
});
// 动画线程开始
SwingUtilities.invokeLater(new Runnable() {
public void run() {
animator.start();
}
});
}
}
package com.jogl.learn.primitive;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import com.sun.opengl.util.GLUT;
public class GLRender implements GLEventListener,KeyListener {
private float r;
Bsipic m_bsipic;
public void display(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL gl=drawable.getGL();
gl.glClearColor(0.0f, 0.0f, 0.6f, 1.0f); // 设置刷新背景色
gl.glClear(GL.GL_COLOR_BUFFER_BIT|GL.GL_DEPTH_BUFFER_BIT);// 刷新背景
gl.glLoadIdentity();
play(drawable);
gl.glFlush(); // 更新窗口
// 切换缓冲区
r+=1;if(r>360) r=0;// 重置当前的模型观察矩阵
}
private void play(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL gl=drawable.getGL();
GLUT glut=new GLUT();
gl.glPushMatrix();
gl.glPointSize(4); //点的大小
gl.glTranslatef (-5.0f, 4.0f,-13.0f);
gl.glRotatef(r,1.0f,1.0f,1.0f); //整体旋转
gl.glColor3f(1.0f, 0.0f, 0.0f);
m_bsipic.point(); //画点
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef ( 0.0f, 4.0f,-13.0f);
gl.glRotatef(r,1.0f,1.0f,1.0f); //整体旋转
gl.glColor3f(0.0f, 1.0f, 0.0f);
m_bsipic.line(); //画线
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef ( 5.0f, 4.0f,-13.0f);
gl.glRotatef(r,1.0f,1.0f,1.0f); //整体旋转
gl.glColor3f(0.0f, 0.0f, 1.0f);
m_bsipic.Triangle(); //画面
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef (-5.0f, 0.0f,-13.0f);
gl.glRotatef(r,1.0f,1.0f,1.0f); //整体旋转
gl.glColor3f(1.0f, 1.0f, 0.0f);
m_bsipic.square(); //画正方面
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef ( 0.0f, 0.0f,-13.0f);
gl.glRotatef(r,1.0f,1.0f,1.0f); //整体旋转
gl.glColor3f(0.0f, 1.0f, 1.0f);
m_bsipic.esquare(); //画正方体
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef ( 5.0f, 0.0f,-13.0f);
gl.glRotatef(r,1.0f,1.0f,1.0f); //整体旋转
gl.glColor3f(1.0f, 0.0f, 1.0f);
m_bsipic.park(); //画园
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef (-5.0f,-4.0f,-13.0f);
gl.glRotatef(r,1.0f,1.0f,1.0f); //整体旋转
gl.glColor3f(1.0f, 1.0f, 1.0f);
m_bsipic.pillar(); //园柱
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef ( 0.0f, -4.0f,-13.0f);
gl.glRotatef(r,1.0f,1.0f,1.0f); //整体旋转
gl.glColor3f(0.7f, 0.7f, 0.7f);
glut.glutSolidCone(1.5, 3, 3, 20);
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef ( 5.0f,-4.0f,-13.0f);
gl.glRotatef(r,1.0f,1.0f,1.0f); //整体旋转
gl.glColor3f(0.4f, 0.4f, 0.4f);
glut.glutWireTeapot(1);
gl.glPopMatrix();
}
public void displayChanged(GLAutoDrawable drawable, boolean arg1, boolean arg2) {
// TODO Auto-generated method stub
}
public void init(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL gl=drawable.getGL();
m_bsipic=new Bsipic(gl);
GLU glu=new GLU();
gl.glViewport(0,0,600,480); // 设置OpenGL视口大小。
gl.glMatrixMode(GL.GL_PROJECTION); // 设置当前矩阵为投影矩阵。
gl.glLoadIdentity(); // 重置当前指定的矩阵为单位矩阵
glu.gluPerspective // 设置透视图
( 54.0f, // 透视角设置为 45 度
(float)600/(float)480, // 窗口的宽与高比
0.1f, // 视野透视深度:近点1.0f
3000.0f // 视野透视深度:始点0.1f远点1000.0f
);
// 这和照象机很类似,第一个参数设置镜头广角度,第二个参数是长宽比,后面是远近剪切。
gl.glMatrixMode(GL.GL_MODELVIEW); // 设置当前矩阵为模型视图矩阵
gl.glLoadIdentity();
}
public void reshape(GLAutoDrawable drawable, int x, int y, int w,
int h) {
// TODO Auto-generated method stub
}
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
package com.jogl.learn.primitive;
import javax.media.opengl.GL;
//**主图形画图类*/
public class Bsipic {
GL gl;
public Bsipic(GL gl) {
this.gl = gl;
}
//**画点*/
public void point() {
gl.glBegin(GL.GL_POINTS);// 单个顶点
gl.glVertex3f(0.0f, 1.0f, -1.0f);// a点
gl.glVertex3f(-1.0f, -1.0f, 0.0f);// b点
gl.glVertex3f(1.0f, -1.0f, 0.0f);// c点
gl.glEnd();
}
public void line() {
gl.glBegin(GL.GL_LINE_LOOP); // 闭合折线
gl.glVertex3f(0.0f, 1.0f, -1.0f);// a点
gl.glVertex3f(-1.0f, -1.0f, 0.0f);// b点
gl.glVertex3f(1.0f, -1.0f, 0.0f);// c点
gl.glEnd();
}
public void Triangle() {
gl.glBegin(GL.GL_POLYGON);// 填充凸多边形
gl.glVertex3f(0.0f, 1.0f, -1.0f);// a点
gl.glVertex3f(-1.0f, -1.0f, 0.0f);// b点
gl.glVertex3f(1.0f, -1.0f, 0.0f);// c点
gl.glEnd();
}
public void square() {
gl.glBegin(GL.GL_POLYGON);// 填充凸多边形
gl.glVertex3f(0.0f, 0.0f, 0.0f);// a点
gl.glVertex3f(1.0f, 0.0f, 0.0f);// b点
gl.glVertex3f(1.0f, 0.0f, -1.0f);// c点
gl.glVertex3f(0.0f, 0.0f, -1.0f);// d点
gl.glEnd();
}
public void esquare() {
gl.glBegin(GL.GL_QUAD_STRIP);// 填充凸多边形
gl.glVertex3f(0.0f, 0.0f, 0.0f);// a0点
gl.glVertex3f(0.0f, 1.0f, 0.0f);// a1点
gl.glVertex3f(1.0f, 0.0f, 0.0f);// b0点
gl.glVertex3f(1.0f, 1.0f, 0.0f);// b1点
gl.glVertex3f(1.0f, 0.0f, -1.0f);// c0点
gl.glVertex3f(1.0f, 1.0f, -1.0f);// c1点
gl.glVertex3f(0.0f, 0.0f, -1.0f);// d0点
gl.glVertex3f(0.0f, 1.0f, -1.0f);// d1点
gl.glVertex3f(0.0f, 0.0f, 0.0f);// a0点
gl.glVertex3f(0.0f, 1.0f, 0.0f);// a1点
gl.glEnd();
// 现在这个正方体还缺上下两个面。应该补上。
gl.glBegin(GL.GL_POLYGON);// 填充凸多边形
gl.glVertex3f(0.0f, 0.0f, 0.0f);// a0点
gl.glVertex3f(1.0f, 0.0f, 0.0f);// b0点
gl.glVertex3f(1.0f, 0.0f, -1.0f);// c0点
gl.glVertex3f(0.0f, 0.0f, -1.0f);// d0点
gl.glVertex3f(0.0f, 1.0f, 0.0f);// a1点
gl.glVertex3f(1.0f, 1.0f, 0.0f);// b1点
gl.glVertex3f(1.0f, 1.0f, -1.0f);// c1点
gl.glVertex3f(0.0f, 1.0f, -1.0f);// d1点
gl.glEnd();
}
public void park() {
gl.glBegin(GL.GL_TRIANGLE_FAN);// 扇形连续填充三角形串
gl.glVertex3f(0, 0, 0.0f);
for (int i = 0; i <= 390; i += 30) {
float p = (float) (i * 3.14 / 180);
gl.glVertex3f((float) Math.sin(p), (float) Math.cos(p), 0.0f);// 园轨迹
}
gl.glEnd();
}
public void pillar() {
gl.glBegin(GL.GL_QUAD_STRIP);// 连续填充四边形串
for (int i = 0; i <= 390; i += 30) {
float p = (float) (i * 3.14 / 180);
gl.glVertex3f((float) Math.sin(p) / 2, (float) Math.cos(p) / 2, 1.0f);// 前园
gl.glVertex3f((float) Math.sin(p) / 2, (float) Math.cos(p) / 2, 0.0f);// 后园
}
gl.glEnd();
}
}