运行效果就如上图,,
值得注意的是旋转是基于矩阵的旋转,要选择某个物体的时候千万要用
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(); } }