/** * Toy plaything for me to learn JOGL/OpenGL */ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.media.opengl.*; import com.sun.opengl.util.*; public class ToyFinal extends JFrame implements GLEventListener, KeyListener { ShapeManager shapeManager; Animator animator; trackball ball = new trackball(); int aWidth = 400; int aHeight = 400; JCheckBoxMenuItem wireframe; JCheckBoxMenuItem specular; JCheckBoxMenuItem smooth; JCheckBoxMenuItem backFaceCull; JCheckBoxMenuItem zBuffer; JCheckBoxMenuItem twoSided; JRadioButtonMenuItem[] levelItems; public static void main(String[] args){ ToyFinal t = new ToyFinal(); //exit if frame's close box is clicked t.addWindowListener( new WindowAdapter() { public void windowClosed(WindowEvent e){ System.exit(0); } public void windowClosing(WindowEvent e) { windowClosed(e); } } ); } int level; /* These functions are "callbacks" for events we are not interested in */ public void keyTyped(KeyEvent evt){ } public void keyReleased(KeyEvent evt){ } public ToyFinal(){ super("ToyFinal"); GLCanvas glc = new GLCanvas(); add("Center", glc); glc.setSize(aWidth,aHeight); JPopupMenu.setDefaultLightWeightPopupEnabled(false); //so menus appear above GLCanvas JMenuBar menubar = new JMenuBar(); setJMenuBar(menubar); shapeManager = new ShapeManager(); menubar.add(shapeManager.getMenu()); JMenu options = new JMenu("Options"); menubar.add(options); wireframe = new JCheckBoxMenuItem("Wireframe"); options.add(wireframe); specular = new JCheckBoxMenuItem("Specular Lighting"); options.add(specular); twoSided = new JCheckBoxMenuItem("Two-sided Lighting"); options.add(twoSided); backFaceCull = new JCheckBoxMenuItem("Back-face Cull"); options.add(backFaceCull); zBuffer = new JCheckBoxMenuItem("Use Z Buffer"); options.add(zBuffer); zBuffer.setSelected(true); smooth = new JCheckBoxMenuItem("Smooth Shading"); options.add(smooth); JMenu levels = new JMenu("Level"); ButtonGroup bg = new ButtonGroup(); levelItems = new JRadioButtonMenuItem[7]; for (int i = 0; i < levelItems.length; i++){ levelItems[i] = new JRadioButtonMenuItem(i+""); levels.add(levelItems[i]); bg.add(levelItems[i]); levelItems[i].addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { level = Integer.parseInt(e.getActionCommand()); } }); } level = 2; levelItems[level].setSelected(true); menubar.add(levels); ball.listen(glc); glc.addGLEventListener(this); glc.addKeyListener(this); addKeyListener(this); animator = new FPSAnimator(glc, 30); //animate at 30 fps animator.start(); pack(); //work out sizes of all Components setVisible(true); } public void init(GLAutoDrawable drawable){ GL gl = drawable.getGL(); gl.glClearColor(0.2f, 0.3f, 0.2f, 1.0f); } public void keyPressed(KeyEvent evt){ if(evt.getKeyChar() == 'q') { animator.stop(); System.exit(0); } if(evt.getKeyChar() == 's') specular.setSelected(!specular.isSelected()); //toggle if(evt.getKeyChar() == 'r') smooth.setSelected(!smooth.isSelected()); //toggle if(evt.getKeyChar() == 'l') twoSided.setSelected(!twoSided.isSelected()); //toggle if(evt.getKeyChar() == '+' && level < levelItems.length-1) levelItems[++level].setSelected(true); if(evt.getKeyChar() == '-' && level > 0) levelItems[--level].setSelected(true); } public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height){ GL gl = drawable.getGL(); gl.glViewport(x, y, width, height); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho(-2, 2, -2, 2, -5, 10); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glEnable(GL.GL_AUTO_NORMAL); aWidth = width; aHeight = height; } public void display(GLAutoDrawable drawable){ float[] teapotMat = {0.6f, 0.6f, 0.6f, 1.0f}; float[] teapotSpec = {0.8f, 0.8f, 0.8f, 1.0f}; float[] zero = {0.0f, 0.0f, 0.0f, 1.0f}; GL gl = drawable.getGL(); gl.glShadeModel(smooth.isSelected() ? GL.GL_SMOOTH : GL.GL_FLAT); gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, twoSided.isSelected() ? 1 : 0); if (zBuffer.isSelected()) { gl.glEnable(GL.GL_DEPTH_TEST); } else { gl.glDisable(GL.GL_DEPTH_TEST); } if (backFaceCull.isSelected()) { gl.glEnable(GL.GL_CULL_FACE); } else { gl.glDisable(GL.GL_CULL_FACE); } gl.glClear(GL.GL_DEPTH_BUFFER_BIT|GL.GL_COLOR_BUFFER_BIT); // gl.glColor3f(1.0f, 1.0f, 1.0f); float[] lightpos = {0.0f, 0.0f, 1.0f, 0.0f}; gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightpos, 0); gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_LIGHT0); gl.glEnable(GL.GL_NORMALIZE); //scale normals to have length 1 gl.glPushMatrix(); gl.glTranslatef(0.0f, 0.0f, -5.0f); gl.glMultMatrixf(ball.getRotMatrix(), 0); gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE, teapotMat, 0); if(specular.isSelected()){ gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, teapotSpec, 0); gl.glMateriali(GL.GL_FRONT, GL.GL_SHININESS, 80); } else { gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, zero, 0); gl.glMateriali(GL.GL_FRONT, GL.GL_SHININESS, 0); } if (wireframe.isSelected()) { gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); } else { gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); } shapeManager.display(gl,level,wireframe.isSelected()); gl.glPopMatrix(); } /** This method handles things if display depth changes */ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged){ } }