/** * Lesson18.java * * by Lapo Luchini * Based on Lesson 7 by Darren Hodges * Date: 23/08/2000 * * Port of the NeHe OpenGL Tutorial (Lesson 18: "Quadratics") * to Java using the GL4Java interface to OpenGL. * * Note: The MipMapping code is only available in GL4Java 2.1.2.1 and later! * */ import java.applet.*; import java.awt.*; import java.awt.event.*; //GL4Java classes import gl4java.GLContext; import gl4java.awt.GLAnimCanvas; import gl4java.utils.textures.*; public class Lesson18 extends Applet { //Our rendering canvas //We are using GLAnimCanvas because we want the canvas //to be constantly redrawn renderCanvas canvas=null; /** * void init() * * Initialise the applet. */ public void init() { //We will use BorderLayout to layout the applet components setLayout(new BorderLayout()); //Create our canvas and add it to the center of the applet canvas=new renderCanvas(getSize().width, getSize().height); canvas.requestFocus(); add("Center", canvas); } /** * void start() * * Start the applet. */ public void start() { //Start animating the canvas canvas.start(); } /** * void stop() * * Stop the applet. */ public void stop() { //Stop animating the canvas canvas.stop(); } /** * void destroy() * * Destroy the applet. */ public void destroy() { //Stop animating the canvas canvas.stop(); //Destroy the canvas canvas.destroy(); } private class renderCanvas extends GLAnimCanvas implements KeyListener, MouseListener { boolean light = true; //Lighting ON/OFF boolean lp = false; //L Pressed? boolean fp = false; //F Pressed? boolean sp = false; //Spacebar Pressed? float xrot = 0.0f; //X Rotation float yrot = 0.0f; //Y Rotation float xspeed = 0.0f; //X Rotation Speed float yspeed = 0.0f; //Y Rotation Speed float z = -5.0f; //Depth Into The Screen //Ambient light float[] LightAmbient = { 0.5f, 0.5f, 0.5f, 1.0f }; //Diffuse light float[] LightDiffuse = { 1.0f, 1.0f, 1.0f, 1.0f }; //Light position float[] LightPosition = { 0.0f, 0.0f, 2.0f, 1.0f }; int filter = 0; //Which Filter To Use int[] texture = new int[3]; //Storage for 3 textures int part1; // Start Of Disc int part2; // End Of Disc int p1=0; // Increase 1 int p2=1; // Increase 2 long quadratic; // Storage For Our Quadratic Objects int object=0; // Which Object To Draw public renderCanvas(int w, int h) { super(w, h); //Registers this canvas to process keyboard events addKeyListener(this); addMouseListener(this); } public void preInit() { //We want double buffering doubleBuffer = true; //But we dont want stereo view stereoView = false; } public void LoadTextures() { PngTextureLoader texLoader=new PngTextureLoader(gl, glu); // catch exception if executed by command-line try { texLoader.readTexture(getCodeBase(), "data/crate.png"); } catch(NullPointerException e) { texLoader.readTexture("data/crate.png"); } if(texLoader.isOk()) { gl.glGenTextures(3, texture); gl.glBindTexture(GL_TEXTURE_2D, texture[0]); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl.glTexImage2D(GL_TEXTURE_2D, 0, 3, texLoader.getImageWidth(), texLoader.getImageHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, texLoader.getTexture()); //Create Linear Filtered Texture gl.glBindTexture(GL_TEXTURE_2D, texture[1]); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl.glTexImage2D(GL_TEXTURE_2D, 0, 3, texLoader.getImageWidth(), texLoader.getImageHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, texLoader.getTexture()); //Create MipMapped Texture (Only with GL4Java 2.1.2.1 and later!) gl.glBindTexture(GL_TEXTURE_2D, texture[2]); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glu.gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texLoader.getImageWidth(), texLoader.getImageHeight(), GL_RGB, GL_UNSIGNED_BYTE, texLoader.getTexture()); } } public void init() { LoadTextures(); gl.glEnable(GL_TEXTURE_2D); //This Will Clear The Background Color To Black gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Enables Clearing Of The Depth Buffer gl.glClearDepth(1.0); //The Type Of Depth Lesson18 To Do gl.glDepthFunc(GL_LESS); //Enables Depth Lesson18ing gl.glEnable(GL_DEPTH_TEST); //Enables Smooth Color Shading gl.glShadeModel(GL_SMOOTH); //Select The Projection Matrix gl.glMatrixMode(GL_PROJECTION); //Reset The Projection Matrix gl.glLoadIdentity(); //Calculate The Aspect Ratio Of The Window glu.gluPerspective(45.0, (float)getSize().width / (float)getSize().height, 0.1, 100.0); //Select The Modelview Matrix gl.glMatrixMode(GL_MODELVIEW); //Lights gl.glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); gl.glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); gl.glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); //Enable light gl.glEnable(GL_LIGHT1); gl.glEnable(GL_LIGHTING); quadratic=glu.gluNewQuadric(); // Create A Pointer To The Quadric Object ( NEW ) glu.gluQuadricNormals(quadratic, GLU_SMOOTH); // Create Smooth Normals ( NEW ) glu.gluQuadricTexture(quadratic, GL_TRUE); // Create Texture Coords ( NEW ) } public void destroy() { //Destroy the GLContext cvsDispose(); } public void reshape(int width, int height) { //Reset The Current Viewport And Perspective Transformation gl.glViewport(0, 0, width, height); //Select The Projection Matrix gl.glMatrixMode(GL_PROJECTION); //Reset The Projection Matrix gl.glLoadIdentity(); //Calculate The Aspect Ratio Of The Window glu.gluPerspective(45.0, getSize().width/(float)getSize().height, 0.1, 100.0); //Select The Modelview Matrix gl.glMatrixMode(GL_MODELVIEW); } private void DrawCube() { gl.glBegin(GL_QUADS); //Front Face gl.glNormal3f(0.0f, 0.0f, 1.0f); gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f); //Bottom Left Of The Texture and Quad gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, 1.0f); //Bottom Right Of The Texture and Quad gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, 1.0f); //Top Right Of The Texture and Quad gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, 1.0f); //Top Left Of The Texture and Quad //Back Face gl.glNormal3f(0.0f, 0.0f, -1.0f); gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f); //Bottom Right Of The Texture and Quad gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -1.0f); //Top Right Of The Texture and Quad gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -1.0f); //Top Left Of The Texture and Quad gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f); //Bottom Left Of The Texture and Quad //Top Face gl.glNormal3f(0.0f, 1.0f, 0.0f); gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -1.0f); //Top Left Of The Texture and Quad gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, 1.0f, 1.0f); //Bottom Left Of The Texture and Quad gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, 1.0f, 1.0f); //Bottom Right Of The Texture and Quad gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -1.0f); //Top Right Of The Texture and Quad //Bottom Face gl.glNormal3f(0.0f, -1.0f, 0.0f); gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f); //Top Right Of The Texture and Quad gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f); //Top Left Of The Texture and Quad gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, 1.0f); //Bottom Left Of The Texture and Quad gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f); //Bottom Right Of The Texture and Quad //Right face gl.glNormal3f(1.0f, 0.0f, 0.0f); gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, -1.0f); //Bottom Right Of The Texture and Quad gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, -1.0f); //Top Right Of The Texture and Quad gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f( 1.0f, 1.0f, 1.0f); //Top Left Of The Texture and Quad gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f( 1.0f, -1.0f, 1.0f); //Bottom Left Of The Texture and Quad //Left Face gl.glNormal3f(-1.0f, 0.0f, 0.0f); gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, -1.0f); //Bottom Left Of The Texture and Quad gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f); //Bottom Right Of The Texture and Quad gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, 1.0f); //Top Right Of The Texture and Quad gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(-1.0f, 1.0f, -1.0f); //Top Left Of The Texture and Quad gl.glEnd(); } public void display() { //Ensure GL is initialised correctly if (glj.gljMakeCurrent(true) == false) return; //Clear The Screen And The Depth Buffer gl.glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //Reset The View gl.glLoadIdentity(); //Move into the screen gl.glTranslatef(0.0f, 0.0f, z); //Rotate On The X Axis gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f); //Rotate On The Y Axis gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f); gl.glBindTexture(GL_TEXTURE_2D, texture[filter]); // Select A Filtered Texture switch(object) { // Check object To Find Out What To Draw case 0: // Drawing Object 1 DrawCube(); // Draw Our Cube break; // Done case 1: // Drawing Object 2 gl.glTranslatef(0.0f,0.0f,-1.5f); // Center The Cylinder glu.gluCylinder(quadratic,1.0f,1.0f,3.0f,32,32); // Draw Our Cylinder break; // Done case 2: // Drawing Object 3 glu.gluDisk(quadratic,0.5f,1.5f,32,32); // Draw A Disc (CD Shape) break; // Done case 3: // Drawing Object 4 glu.gluSphere(quadratic,1.3f,32,32); // Draw A Sphere break; // Done case 4: // Drawing Object 5 gl.glTranslatef(0.0f,0.0f,-1.5f); // Center The Cone glu.gluCylinder(quadratic,1.0f,0.0f,3.0f,32,32); // A Cone With A Bottom Radius Of .5 And A Height Of 2 break; // Done case 5: // Drawing Object 6 part1+=p1; // Increase Start Angle part2+=p2; // Increase Sweep Angle if(part1>359) { // 360 Degrees p1=0; // Stop Increasing Start Angle part1=0; // Set Start Angle To Zero p2=1; // Start Increasing Sweep Angle part2=0; // Start Sweep Angle At Zero } if(part2>359) { // 360 Degrees p1=1; // Start Increasing Start Angle p2=0; // Stop Increasing Sweep Angle } glu.gluPartialDisk(quadratic,0.5f,1.5f,32,32,part1,part2-part1); // A Disk Like The One Before break; // Done }; xrot+=xspeed; // Increase Rotation On X Axis yrot+=yspeed; // Increase Rotation On Y Axis //Swap buffers glj.gljSwap(); glj.gljFree(); } public void keyTyped(KeyEvent e) { //We are not handling any keyboard events yet } public void keyPressed(KeyEvent e) { //Ensure GL is initialised correctly if (glj.gljMakeCurrent(true) == false) return; switch(e.getKeyCode()) { //Switch ON/OFF light when L is pressed case KeyEvent.VK_L: if(!lp) { lp = true; //Toggle light light = !light; if(!light) gl.glDisable(GL_LIGHTING); else gl.glEnable(GL_LIGHTING); } break; //Switch filter when F is pressed case KeyEvent.VK_F: if(!fp) { fp = true; //Change filter filter += 1; if(filter > 2) filter = 0; } break; //Move cube back when user presses PG_UP case KeyEvent.VK_PAGE_UP: z -= 0.2f; break; //Move cube forwards when user presses PG_DOWN case KeyEvent.VK_PAGE_DOWN: z += 0.2f; break; //Increase X rotation speed when user presses UP case KeyEvent.VK_UP: xspeed += 0.2f; break; //Decrease X rotation speed when user presses DOWN case KeyEvent.VK_DOWN: xspeed -= 0.2f; break; //Increase Y rotation speed when user presses RIGHT case KeyEvent.VK_RIGHT: yspeed += 0.2f; break; //Decrease Y rotation speed when user presses LEFT case KeyEvent.VK_LEFT: yspeed -= 0.2f; break; //Switch filter when F is pressed case KeyEvent.VK_SPACE: if(!sp) { sp = true; //Change filter object += 1; if(object > 5) object = 0; } break; } glj.gljFree(); } public void keyReleased(KeyEvent e) { switch(e.getKeyCode()) { //Key has been released case KeyEvent.VK_L: lp = false; break; //Key has been released case KeyEvent.VK_F: fp = false; break; case KeyEvent.VK_SPACE: sp = false; break; } } // Methods required for the implementation of MouseListener public void mouseEntered( MouseEvent evt ) { Component comp = evt.getComponent(); if( comp.equals(this ) ) { requestFocus(); } } public void mouseExited( MouseEvent evt ) { } public void mousePressed( MouseEvent evt ) { } public void mouseReleased( MouseEvent evt ) { } public void mouseClicked( MouseEvent evt ) { Component comp = evt.getComponent(); if( comp.equals(this ) ) { requestFocus(); } } } static class MyAdapter extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } public static void main(String as[]) { GLContext.gljNativeDebug = true; GLContext.gljThreadDebug = false; GLContext.gljClassDebug = true; Frame f=new Frame("Lesson18"); Lesson18 a=new Lesson18(); a.init(); a.start(); f.add("Center", a); f.setSize(400, 400); f.show(); f.addWindowListener(new MyAdapter()); } }