import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import java.net.URL; import javax.imageio.ImageIO; import com.jogamp.opengl.awt.GLJPanel; import javax.swing.*; import com.jogamp.opengl.*; import com.jogamp.opengl.util.awt.ImageUtil; import com.jogamp.opengl.util.gl2.GLUT; import com.jogamp.opengl.util.texture.Texture; import com.jogamp.opengl.util.texture.awt.AWTTextureIO; /** * A panel of type TextureDemo displays a textured object, * which the user can rotate by dragging the mouse. The main * routine in this class creates a window containing six * panels of type Texture Demo, with a variety of different * objects and textures. The main routine shows a windoe * that contains a TexttureDemo panel. */ public class TextureDemo extends GLJPanel implements GLEventListener, KeyListener { public static void main(String[] args){ JFrame window = new JFrame("USE ARROW KES TO CHANGE OBJECTS/TEXTURES"); GLJPanel content = new TextureDemo(); window.setContentPane(content); window.pack(); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setVisible(true); System.out.println("The left and right arrow keys will change the object."); System.out.println("The up and down arrow keys will change the texture."); System.out.println("The HOME key restores the original point of view."); System.out.println("The mouse can be used to rotate the view."); content.requestFocusInWindow(); } private Camera camera; // Contains the current view transform and projection. // The user can drag with the mouse to rotate the view. private int currentObject; // Code for the object displayed in the panel. private int currentTexture; // Code for the texture currently in use. private String[] textureFileNames = { "Earth-1024x512.jpg", "NightEarth-512x256.jpg", "brick001.jpg", "marble.jpg", "metal003.gif", "mandelbrot.jpeg" }; private Texture[] textures = new Texture[textureFileNames.length]; private final static int SPHERE = 0, CYLINDER = 1, CONE = 2, CUBE = 3, TORUS = 4, TEAPOT = 5, SQUARE = 6, CIRCLE = 7, RING = 8; private GLUT glut = new GLUT(); /** * Create a TextureDemo panel to show an object with a texture, and sets up * the camera and trackball so that the object can be rotated with the mouse. */ public TextureDemo() { setPreferredSize(new Dimension(600,600)); addGLEventListener(this); camera = new Camera(); camera.setScale(1); camera.installTrackball(this); addKeyListener(this); } /** * This method will be called when the GLJPanel is first * created. Here, in addition to the usual setup for 3D, * it sets a white material color, suitable for texturing. * It also loads, binds and enables the texture. (Since the * one texture will be used throughout the program, it * makes sense to do this once in the init method.) */ public void init(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); gl.glClearColor(0,0,0,1); gl.glEnable(GL2.GL_LIGHTING); gl.glEnable(GL2.GL_LIGHT0); gl.glEnable(GL2.GL_DEPTH_TEST); gl.glLightModeli(GL2.GL_LIGHT_MODEL_TWO_SIDE, 1); gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_AMBIENT_AND_DIFFUSE, new float[] { 1,1,1,1 }, 0); gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, new float[] { 0.3f, 0.3f, 0.3f, 1 }, 0); gl.glMateriali(GL2.GL_FRONT_AND_BACK, GL2.GL_SHININESS, 100); gl.glLightModeli(GL2.GL_LIGHT_MODEL_COLOR_CONTROL, GL2.GL_SEPARATE_SPECULAR_COLOR); // I am cheating by using separate specular color, which requires OpenGL 1.2, but // it gives nicer specular highlights on textured surfaces. for (int i = 0; i < textureFileNames.length; i++) { try { URL textureURL; textureURL = getClass().getClassLoader().getResource("textures/" + textureFileNames[i]); if (textureURL != null) { // textures[i] = TextureIO.newTexture(textureURL, true, null); // Alternative loader, gives upside down textures! BufferedImage img = ImageIO.read(textureURL); ImageUtil.flipImageVertically(img); textures[i] = AWTTextureIO.newTexture(GLProfile.getDefault(), img, true); textures[i].setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_S, GL2.GL_REPEAT); textures[i].setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_T, GL2.GL_REPEAT); } } catch (Exception e) { e.printStackTrace(); } } textures[0].enable(gl); } /** * Display method renders the current object, using the current texture. */ public void display(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); camera.apply(gl); if (currentObject <= CONE) gl.glRotated(90,-1,0,0); // rotate axis of object from z-axis to y-axis if (currentObject == CONE || currentObject == CYLINDER) gl.glTranslated(0,0,-0.5); // moves center of object to the origin textures[currentTexture].bind(gl); // Says which texture to use. switch (currentObject) { case SPHERE: TexturedShapes.uvSphere(gl); break; case CYLINDER: TexturedShapes.uvCylinder(gl); break; case CONE: TexturedShapes.uvCone(gl); break; case CUBE: TexturedShapes.cube(gl); break; case TORUS: TexturedShapes.uvTorus(gl); break; case TEAPOT: gl.glFrontFace(GL2.GL_CW); // Teapot has non-standard front faces // that don't work right with two-sided lighting. // This reverses the usual test for front face. glut.glutSolidTeapot(0.5); gl.glFrontFace(GL2.GL_CCW); break; case SQUARE: TexturedShapes.square(gl); break; case CIRCLE: TexturedShapes.circle(gl); break; case RING: TexturedShapes.ring(gl); break; } } // Extra, unused methods of the GLEventListener interface public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { } public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void dispose(GLAutoDrawable drawable) { } /** * Left/right arrow keys change the current object. * Up/down arrow keys change the current texture. * Home key restores the default camera viewpoint. */ public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if ( key == KeyEvent.VK_UP ) { currentTexture++; if (currentTexture >= textureFileNames.length) currentTexture = 0; } else if ( key == KeyEvent.VK_DOWN ) { currentTexture--; if (currentTexture < 0 ) currentTexture = textureFileNames.length - 1; } else if ( key == KeyEvent.VK_LEFT ) { currentObject--; if (currentObject < 0) currentObject = 8; } else if ( key == KeyEvent.VK_RIGHT ) { currentObject++; if (currentObject > 8) currentObject = 0; } else if ( key == KeyEvent.VK_HOME ) { camera.lookAt(0,0,30, 0,0,0, 0,1,0); } repaint(); } // Extra, unused methods of the KeyListener interface. public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } }