java left logo
java middle logo
java right logo
 

Home arrow Other API Tips
 
 
Main Menu
Home
Java Tutorials
Book Reviews
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Java Network
Java Forums
Java Blog




Most Visited Tips
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Book Reviews
Top Rated Tips
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Book Reviews


Statistics
Registered Users: 4092
Java SE Tips: 614
Java ME Tips: 202
Java EE Tips: 183
Other API Tips: 779
Java Applications: 298
Java Libraries: 209
Java Games: 16
Book Reviews:
 
 
 
Morphing and loading objects from a file - NeHe Tutorial JOGL Port E-mail
User Rating: / 3
PoorBest 

This example shows how to load simple objects from a text file, and morph smoothly from one object into another.

This is the Java port of the one of the NeHe OpenGL tutorials.

You can get complete IntelliJ IDEA project structure (all source, resources, build script, ) by downloading the source distribution from here.

The original post of the programmer who ported the examples can be found here.


Image

package demos.nehe.lesson25;

import demos.common.GLDisplay;

public class Lesson25 {
    public static void main(String[] args) {
        GLDisplay neheGLDisplay = GLDisplay.createGLDisplay("Lesson 25: Morphing points");
        Renderer renderer = new Renderer();
        InputHandler inputHandler = new InputHandler(renderer, neheGLDisplay);
        neheGLDisplay.addGLEventListener(renderer);
        neheGLDisplay.addKeyListener(inputHandler);
        neheGLDisplay.start();
    }
}


package demos.nehe.lesson25;

import demos.common.GLDisplay;

import javax.swing.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

class InputHandler extends KeyAdapter {
    private Renderer renderer;

    public InputHandler(Renderer renderer, GLDisplay display) {
        this.renderer = renderer;
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_1, 0)"Morph to object 1");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_2, 0)"Morph to object 2");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_3, 0)"Morph to object 3");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_4, 0)"Morph to object 4");

        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)"Increase X speed");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)"Decrease X speed");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)"Increase Y speed");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0)"Decrease Y speed");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0)"Increase Z speed");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0)"Decrease Z speed");

        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0)"Object farther");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_Z, 0)"Object closer");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_W, 0)"Object up");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_S, 0)"Object down");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_A, 0)"Object left");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_D, 0)"Object right");
    }

    public void keyPressed(KeyEvent e) {
        processKeyEvent(e, true);
    }

    public void keyReleased(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_1:  // Is 1 Pressed, key Not Equal To 1 And Morph False?
                renderer.morphTo(1)// Sets key To 1 (To Prevent Pressing 1 2x In A Row)
                break;
            case KeyEvent.VK_2:  // Is 2 Pressed, key Not Equal To 2 And Morph False?
                renderer.morphTo(2)// Sets key To 2 (To Prevent Pressing 2 2x In A Row)
                break;
            case KeyEvent.VK_3:  // Is 3 Pressed, key Not Equal To 3 And Morph False?
                renderer.morphTo(3)// Sets key To 3 (To Prevent Pressing 3 2x In A Row)
                break;
            case KeyEvent.VK_4:  // Is 4 Pressed, key Not Equal To 4 And Morph False?
                renderer.morphTo(4)// Sets key To 4 (To Prevent Pressing 4 2x In A Row)
                break;
            default:
                processKeyEvent(e, false);
        }
    }

    private void processKeyEvent(KeyEvent e, boolean pressed) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_PAGE_UP: // Is Page Up Being Pressed?
                renderer.increaseZspeed(pressed)// Increase zspeed
                break;
            case KeyEvent.VK_PAGE_DOWN:  // Is Page Down Being Pressed?
                renderer.decreaseZspeed(pressed)// Decrease zspeed
                break;
            case KeyEvent.VK_DOWN: // Is Page Up Being Pressed?
                renderer.increaseXspeed(pressed)// Increase xspeed
                break;
            case KeyEvent.VK_UP: // Is Page Up Being Pressed?
                renderer.decreaseXspeed(pressed)// Decrease xspeed
                break;
            case KeyEvent.VK_RIGHT: // Is Page Up Being Pressed?
                renderer.increaseYspeed(pressed)// Increase yspeed
                break;
            case KeyEvent.VK_LEFT: // Is Page Up Being Pressed?
                renderer.decreaseYspeed(pressed)// Decrease yspeed
                break;
            case KeyEvent.VK_Q:  // Is Q Key Being Pressed?
                renderer.moveObjectFarther(pressed)// Move Object Away From Viewer
                break;
            case KeyEvent.VK_Z:  // Is Z Key Being Pressed?
                renderer.moveObjectCloser(pressed)// Move Object Towards Viewer
                break;
            case KeyEvent.VK_W:  // Is W Key Being Pressed?
                renderer.moveObjectUp(pressed);  // Move Object Up
                break;
            case KeyEvent.VK_S:  // Is S Key Being Pressed?
                renderer.moveObjectDown(pressed)// Move Object Down
                break;
            case KeyEvent.VK_D:  // Is D Key Being Pressed?
                renderer.moveObjectRight(pressed)// Move Object Right
                break;
            case KeyEvent.VK_A:  // Is A Key Being Pressed?
                renderer.moveObjectLeft(pressed)// Move Object Left
                break;
        }
    }
}


package demos.nehe.lesson25;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

import java.io.*;
import java.util.StringTokenizer;

import demos.common.ResourceRetriever;

class Renderer implements GLEventListener {
    private static final int STEPS = 200// Maximum Number Of Steps

    private float xrot,yrot,zrot;  // X, Y & Z Rotation
    private float xspeed,yspeed,zspeed;  // X, Y & Z Spin Speed
    private boolean increaseXspeed, decreaseXspeed;
    private boolean increaseYspeed, decreaseYspeed;
    private boolean increaseZspeed, decreaseZspeed;
    private float cx,cy,cz = -15;  // X, Y & Z Position
    private boolean moveObjectFarther, moveObjectCloser;
    private boolean moveObjectUp, moveObjectDown;
    private boolean moveObjectLeft, moveObjectRight;

    private int step = 0;    // Step Counter
    private boolean morph = false;  // Default morph To False (Not Morphing)

    private int maxver;  // Will Eventually Hold The Maximum Number Of Vertices
    
    // Our 4 Morphable Objects (morph1,2,3 & 4)
    private Object3D objects[] new Object3D[4];
    private final Object morphLock = new Object();
    
    // Helper Object, Source Object, Destination Object
    private Object3D helper,sour,dest;  

    private GLU glu = new GLU();

    public void morphTo(int morphTarget) {
        if (morphTarget < || morphTarget > 4) {
            throw new IllegalArgumentException(
                    "Morph target must lie between 1 and " + objects.length);
        }
        synchronized (morphLock) {
            if (morph)
                return;
            morph = true;
            dest = objects[morphTarget - 1];
        }
    }

    public void increaseXspeed(boolean increaseXspeed) {
        this.increaseXspeed = increaseXspeed;
    }

    public void decreaseXspeed(boolean decreaseXspeed) {
        this.decreaseXspeed = decreaseXspeed;
    }

    public void increaseYspeed(boolean increaseYspeed) {
        this.increaseYspeed = increaseYspeed;
    }

    public void decreaseYspeed(boolean decreaseYspeed) {
        this.decreaseYspeed = decreaseYspeed;
    }

    public void increaseZspeed(boolean increaseZspeed) {
        this.increaseZspeed = increaseZspeed;
    }

    public void decreaseZspeed(boolean decreaseZspeed) {
        this.decreaseZspeed = decreaseZspeed;
    }

    public void moveObjectUp(boolean moveObjectUp) {
        this.moveObjectUp = moveObjectUp;
    }

    public void moveObjectDown(boolean moveObjectDown) {
        this.moveObjectDown = moveObjectDown;
    }

    public void moveObjectLeft(boolean moveObjectLeft) {
        this.moveObjectLeft = moveObjectLeft;
    }

    public void moveObjectRight(boolean moveObjectRight) {
        this.moveObjectRight = moveObjectRight;
    }

    public void moveObjectFarther(boolean moveObjectFarther) {
        this.moveObjectFarther = moveObjectFarther;
    }

    public void moveObjectCloser(boolean moveObjectCloser) {
        this.moveObjectCloser = moveObjectCloser;
    }

    // Loads Object From File (name)
    private Object3D loadObject(InputStream inputStreamthrows IOException {            
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
        String oneline = in.readLine();
        StringTokenizer tokenizer = new StringTokenizer(oneline);
        tokenizer.nextToken()// Vertices:
        
        // Scans Text For "Vertices: ".  Number After Is Stored In ver
        int nbVertices = Integer.parseInt(tokenizer.nextToken())
        
        // Sets Objects verts Variable To Equal The Value Of ver
        Object3D object = new Object3D(nbVertices);         

        for (int i = 0; i < nbVertices; i++) {  // Loops Through The Vertices
            oneline = in.readLine();     // Reads In The Next Line Of Text
            
            // Searches For 3 Floating Point Numbers, Store In rx,ry & rz
            tokenizer = new StringTokenizer(oneline);
            float rx = Float.parseFloat(tokenizer.nextToken());
            float ry = Float.parseFloat(tokenizer.nextToken());
            float rz = Float.parseFloat(tokenizer.nextToken());
            object.points[inew Vertex();
            object.points[i].x = rx;    // Sets Objects (k) points.x Value To rx
            object.points[i].y = ry;  // Sets Objects (k) points.y Value To ry
            object.points[i].z = rz;  // Sets Objects (k) points.z Value To rz
        }

        // If ver Is Greater Than maxver Set maxver Equal To ver
        if (nbVertices > maxvermaxver = nbVertices;  

        return object;
    }

    // Calculates Movement Of Points During Morphing
    void calculate(int i, Vertex a) {  
        // a.x Value Equals Source x - Destination x Divided By Steps
        a.x = (sour.points[i].x - dest.points[i].x/ STEPS;  
        
        // a.y Value Equals Source y - Destination y Divided By Steps
        a.y = (sour.points[i].y - dest.points[i].y/ STEPS;  
        
        // a.z Value Equals Source z - Destination z Divided By Steps
        a.z = (sour.points[i].z - dest.points[i].z/ STEPS;  
    }  // This Makes Points Move At A Speed So They All Get To Their
    // Destination At The Same Time

    public void init(GLAutoDrawable drawable) {
        GL gl = drawable.getGL();

        // Set The Blending Function For Translucency
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE);
        
        // This Will Clear The Background Color To Black
        gl.glClearColor(0.0f0.0f0.0f0.0f);
        gl.glClearDepth(1.0);           // Enables Clearing Of The Depth Buffer
        gl.glDepthFunc(GL.GL_LESS);  // The Type Of Depth Test To Do
        gl.glEnable(GL.GL_DEPTH_TEST);  // Enables Depth Testing
        gl.glShadeModel(GL.GL_SMOOTH);  // Enables Smooth Color Shading
        
        // Really Nice Perspective Calculations
        gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);  

        maxver = 0;  // Sets Max Vertices To 0 By Default
        try {
            // Load The First Object Into morph1 From File sphere.txt
            objects[0= loadObject(ResourceRetriever.getResourceAsStream(
                    "demos/data/models/Sphere.txt"));  
            // Load The Second Object Into morph2 From File torus.txt
            objects[1= loadObject(ResourceRetriever.getResourceAsStream(
                    "demos/data/models/Torus.txt"));          
            // Load The Third Object Into morph3 From File tube.txt
            objects[2= loadObject(ResourceRetriever.getResourceAsStream(
                    "demos/data/models/Tube.txt"));          
            // Load sphere.txt Object Into Helper (Used As Starting Point)
            helper = loadObject(ResourceRetriever.getResourceAsStream(
                    "demos/data/models/Sphere.txt"));
        catch (IOException e) {
            throw new RuntimeException(e);
        }

        // Manually Reserver Ram For A 4th 468 Vertice Object (morph4)
        objects[3new Object3D(486);  
        for (int i = 0; i < 486; i++)  // Loop Through All 468 Vertices
        {
            objects[3].points[inew Vertex();
            // morph4 x Point Becomes A Random Float Value From -7 to 7
            objects[3].points[i].x = (float) (Math.random() 0.57;  
            // morph4 y Point Becomes A Random Float Value From -7 to 7
            objects[3].points[i].y = (float) (Math.random() 0.57;  
            // morph4 z Point Becomes A Random Float Value From -7 to 7
            objects[3].points[i].z = (float) (Math.random() 0.57;  
        }

        // Source & Destination Are Set To Equal First Object (morph1)
        sour = dest = objects[0]
    }

    public void display(GLAutoDrawable drawable) {
        GL gl = drawable.getGL();

        drawGLScene(gl);
        update();
    }

    private void drawGLScene(GL gl) {
        // Clear The Screen And The Depth Buffer
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);  
        gl.glLoadIdentity();    // Reset The View
        
        // Translate The The Current Position To Start Drawing
        gl.glTranslatef(cx, cy, cz);  
        gl.glRotatef(xrot, 100);  // Rotate On The X Axis By xrot
        gl.glRotatef(yrot, 010);  // Rotate On The Y Axis By yrot
        gl.glRotatef(zrot, 001);  // Rotate On The Z Axis By zrot

        xrot += xspeed;
        yrot += yspeed;
        zrot += zspeed;  // Increase xrot,yrot & zrot by xspeed, yspeed & zspeed

        float tx,ty,tz;  // Temp X, Y & Z Variables
        Vertex q = new Vertex()// Holds Returned Calculated Values For One Vertex

        gl.glBegin(GL.GL_POINTS);  // Begin Drawing Points
        for (int i = 0; i < maxver; i++) {  // Loop Through All The Verts
            if (morph)
                calculate(i, q);
            else
                // If morph Is True Calculate Movement Otherwise Movement=0
                q.x = q.y = q.z = 0;  
            // Subtract q.x Units From helper.points[i].x (Move On X Axis)
            helper.points[i].x -= q.x;  
            
            // Subtract q.y Units From helper.points[i].y (Move On Y Axis)
            helper.points[i].y -= q.y;  
            
            // Subtract q.z Units From helper.points[i].z (Move On Z Axis)
            helper.points[i].z -= q.z;          
            // Make Temp X Variable Equal To Helper's X Variable
            tx = helper.points[i].x;  
            // Make Temp Y Variable Equal To Helper's Y Variable
            ty = helper.points[i].y;        
            // Make Temp Z Variable Equal To Helper's Z Variable
            tz = helper.points[i].z;        

            gl.glColor3f(011);  // Set Color To A Bright Shade Of Off Blue
            
            // Draw A Point At The Current Temp Values (Vertex)
            gl.glVertex3f(tx, ty, tz);  
            
            gl.glColor3f(00.5f1);  // Darken Color A Bit
            tx -= * q.x;
            ty -= * q.y;
            ty -= * q.y;    // Calculate Two Positions Ahead
            
            // Draw A Second Point At The Newly Calculate Position
            gl.glVertex3f(tx, ty, tz);  
            
            gl.glColor3f(001);  // Set Color To A Very Dark Blue
            tx -= * q.x;
            ty -= * q.y;
            ty -= * q.y;    // Calculate Two More Positions Ahead
            
            // Draw A Third Point At The Second New Position
            gl.glVertex3f(tx, ty, tz);  
        }  // This Creates A Ghostly Tail As Points Move
        gl.glEnd();  // Done Drawing Points

        // If We're Morphing And We Haven't Gone Through All 200 Steps 
        // Increase Our Step Counter
        // Otherwise Set Morphing To False, Make Source=Destination And Set 
        // The Step Counter Back To Zero.
        if (morph && step <= STEPS)
            step++;
        else {
            synchronized (morphLock) {
                morph = false;
                sour = dest;
                step = 0;
            }
        }
    }

    private void update() {
        if (increaseZspeed)  // Is Page Up Being Pressed?
            zspeed += 0.001f;  // Increase zspeed

        if (decreaseZspeed)  // Is Page Down Being Pressed?
            zspeed -= 0.001f;  // Decrease zspeed

        if (increaseXspeed)  // Is Page Up Being Pressed?
            xspeed += 0.001f;  // Increase xspeed

        if (decreaseXspeed)  // Is Page Up Being Pressed?
            xspeed -= 0.001f;  // Decrease xspeed

        if (increaseYspeed)  // Is Page Up Being Pressed?
            yspeed += 0.001f;  // Increase yspeed

        if (decreaseYspeed)  // Is Page Up Being Pressed?
            yspeed -= 0.001f;  // Decrease yspeed

        if (moveObjectFarther)  // Is Q Key Being Pressed?
            cz -= 0.01f;  // Move Object Away From Viewer

        if (moveObjectCloser)  // Is Z Key Being Pressed?
            cz += 0.01f;  // Move Object Towards Viewer

        if (moveObjectUp)  // Is W Key Being Pressed?
            cy += 0.01f;  // Move Object Up

        if (moveObjectDown)  // Is S Key Being Pressed?
            cy -= 0.01f;  // Move Object Down

        if (moveObjectRight)  // Is D Key Being Pressed?
            cx += 0.01f;  // Move Object Right

        if (moveObjectLeft)  // Is A Key Being Pressed?
            cx -= 0.01f;  // Move Object Left
    }

    public void reshape(GLAutoDrawable drawable,
                        int xstart,
                        int ystart,
                        int width,
                        int height) {
        GL gl = drawable.getGL();

        height = (height == 0: height;

        gl.glViewport(00, width, height);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();

        glu.gluPerspective(45(floatwidth / height, 0.1100);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    public void displayChanged(GLAutoDrawable drawable,
                               boolean modeChanged,
                               boolean deviceChanged) {
    }

    private static class Vertex {  // Structure For 3D Points
        public float x, y, z;    // X, Y & Z Points
    }

    private static class Object3D {
        public Vertex[] points;    // One Vertice (Vertex x,y & z)

        public Object3D(int nbPoints) {
            points = new Vertex[nbPoints];
        }
    }
}

 Related Tips

 
< Prev   Next >

Page 1 of 0 ( 0 comments )

You can share your information about this topic using the form below!

Please do not post your questions with this form! Thanks.


Name (required)


E-Mail (required)

Your email will not be displayed on the site - only to our administrator
Homepage(optional)



Comment Enable HTML code : Yes No



 
       
         
     
 
 
 
   
 
 
java bottom left
java bottom middle
java bottom right
RSS 0.91 FeedRSS 1.0 FeedRSS 2.0 FeedATOM FeedOPML Feed

Home - About Us - Privacy Policy
Copyright 2005 - 2008 www.java-tips.org
Java is a trademark of Sun Microsystems, Inc.