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: 3932
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:
 
 
 
3D lens flare with occlusion testing - NeHe Tutorial JOGL Port E-mail
User Rating: / 7
PoorBest 

This example shows how to do lens flares by extending a glCamera class.

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.lesson44;

import demos.common.GLDisplay;
                  /*--.          .-"-.
                 /   o_O        / O o \
                 \_  (__\       \_ v _/
                 //   \\        //   \\
                ((     ))      ((     ))
 ¤¤¤¤¤¤¤¤¤¤¤¤¤¤--""---""--¤¤¤¤--""---""--¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
 ¤                 |||            |||                             ¤
 ¤                  |              |                              ¤
 ¤                                                                ¤
 ¤ Programmer:Abdul Bezrati                                       ¤
 ¤ Program   :Nehe's 44th lesson port to JOGL                     ¤
 ¤ Comments  :None                                                ¤
 ¤    _______                                                     ¤
 ¤  /` _____ `\;,     This e-mail address is being protected from spam bots, you need JavaScript enabled to view it                          ¤
 ¤ (__(^===^)__)';,                                 ___           ¤
 ¤   /  :::  \   ,;                               /^   ^\         ¤
 ¤  |   :::   | ,;'                              ( Ö   Ö )        ¤
 ¤¤¤'._______.'`¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ --°oOo--(_)--oOo°--¤¤*/
public class Lesson44 {
    public static void main(String[] args) {
        GLDisplay neheGLDisplay = GLDisplay.createGLDisplay("Lesson 44: Lens flare");
        Renderer renderer = new Renderer();
        InputHandler inputHandler = new InputHandler(renderer, neheGLDisplay);
        neheGLDisplay.addGLEventListener(renderer);
        neheGLDisplay.addKeyListener(inputHandler);
        neheGLDisplay.start();
    }
}


package demos.nehe.lesson44;

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)"Show info");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_2, 0)"Hide info");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_W, 0)"Pitch camera up");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_S, 0)"Pitch camera down");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_A, 0)"Yaw camera right");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_D, 0)"Yaw camera left");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0)"Move camera forward");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_E, 0)"Move camera backward");
        
        display.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_X, 0)"Stop camera movement");
    }

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

    public void keyReleased(KeyEvent e) {
        switch (e.getKeyCode()) {
            // Toggle properties
            case KeyEvent.VK_1:
                renderer.setInfoDisplayed(true);
                break;
            case KeyEvent.VK_2:
                renderer.setInfoDisplayed(false);
                break;
            case KeyEvent.VK_Q:
                renderer.moveCameraForward();
                break;
            case KeyEvent.VK_E:
                renderer.moveCameraBackward();
                break;
            case KeyEvent.VK_X:
                renderer.stopCamera();
                break;
            default:
                // Unset flags
                processKeyEvent(e, false);
        }
    }

    private void processKeyEvent(KeyEvent e, boolean pressed) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_W:
                renderer.pitchCameraUp(pressed);
                break;
            case KeyEvent.VK_S:
                renderer.pitchCameraDown(pressed);
                break;
            case KeyEvent.VK_A:
                renderer.yawCameraLeft(pressed);
                break;
            case KeyEvent.VK_D:
                renderer.yawCameraRight(pressed);
                break;
        }
    }
}


package demos.nehe.lesson44;

import com.sun.opengl.util.BufferUtil;

import javax.media.opengl.GL;
import java.nio.ByteBuffer;

/**
 * I don't mind if you use this class in your own code. All I ask is
 * that you give me and Giuseppe D'Agata credit for it if you do.
 * And plug NeHe while your at it! :P  Thanks go to Giuseppe D'Agata
 * for the code that this class is based off of. Thanks Enjoy.
 @author Vic Hollis
 @author Abdul Bezrati
 */
class Font {
    private double m_WindowHeight;
    private double m_WindowWidth;
    private int m_FontTexture;
    private int m_ListBase;
    private ByteBuffer stringBuffer = BufferUtil.newByteBuffer(512);

    public Font() {
        m_FontTexture = 0;    // Initalize the texture to 0
        m_ListBase = 0;    // Initalize the List base to 0
    }

    public void setFontTexture(int tex) {
        if (tex != 0) {          // If the texture is valid
            m_FontTexture = tex; // Set the font texture
        }
    }

    public void buildFont(GL gl, float scale) {
        m_ListBase = gl.glGenLists(256);  // Creating 256 Display Lists
        if (m_FontTexture != 0) {
            // Select Our Font Texture
            gl.glBindTexture(GL.GL_TEXTURE_2D, m_FontTexture)
            for (int loop = 0; loop < 256; loop++) {   // Loop Through All 256 Lists
                float cx = (float) (loop % 1616.0f;  // X Position Of Current Character
                float cy = (float) (loop / 1616.0f;  // Y Position Of Current Character

                gl.glNewList(m_ListBase + loop, GL.GL_COMPILE)// Start Building A List
                gl.glBegin(GL.GL_QUADS)// Use A Quad For Each Character
                gl.glTexCoord2f(cx, - cy - 0.0625f)// Texture Coord (Bottom Left)
                gl.glVertex2f(00);   // Vertex Coord (Bottom Left)
                // Texture Coord (Bottom Right)
                gl.glTexCoord2f(cx + 0.0625f- cy - 0.0625f)
                gl.glVertex2f(16 * scale, 0);           // Vertex Coord (Bottom Right)
                gl.glTexCoord2f(cx + 0.0625f- cy);  // Texture Coord (Top Right)
                gl.glVertex2f(16 * scale, 16 * scale);  // Vertex Coord (Top Right)
                gl.glTexCoord2f(cx, - cy);            // Texture Coord (Top Left)
                gl.glVertex2f(016 * scale);           // Vertex Coord (Top Left)
                // Done Building Our Quad (Character)
                gl.glEnd();                             
                // Move To The Right Of The Character
                gl.glTranslated(10 * scale, 00);      
                // Done Building The Display List
                gl.glEndList();                         
            }   // Loop Until All 256 Are Built
        }
    }

    public void glPrintf(GL gl, int x, int y, int set, String format) {
        if (format == null)  // If There's No Text
            return;

        byte text[] = format.getBytes();

        if (set > 1)  // Did User Choose An Invalid Character Set?
            set = 1;

        gl.glEnable(GL.GL_TEXTURE_2D);  // Enable 2d Textures
        gl.glEnable(GL.GL_BLEND);       // Enable Blending
        gl.glBlendFunc(GL.GL_SRC_COLOR, GL.GL_ONE_MINUS_SRC_COLOR);
        gl.glBindTexture(GL.GL_TEXTURE_2D, m_FontTexture)// Select Our Font Texture
        gl.glDisable(GL.GL_DEPTH_TEST);                    // Disables Depth Testing
        gl.glMatrixMode(GL.GL_PROJECTION);                 // Select The Projection Matrix
        gl.glPushMatrix();                                 // Store The Projection Matrix
        gl.glLoadIdentity();                               // Reset The Projection Matrix
        gl.glOrtho(0, m_WindowWidth, 0, m_WindowHeight, -11)// Set Up An Ortho Screen
        gl.glMatrixMode(GL.GL_MODELVIEW);                  // Select The Modelview Matrix
        gl.glPushMatrix();                                 // Store The Modelview Matrix
        gl.glLoadIdentity();                               // Reset The Modelview Matrix
        // Position The Text (0,0 - Bottom Left)
        gl.glTranslated(x, y, 0);                          
        gl.glListBase(m_ListBase - 32 (128 * set));      // Choose The Font Set (0 or 1)

        if (stringBuffer.capacity() < format.length()) {
            stringBuffer = BufferUtil.newByteBuffer(format.length());
        }

        stringBuffer.clear();
        stringBuffer.put(format.getBytes());
        stringBuffer.flip();

        // Write The Text To The Screen
        gl.glCallLists(text.length, GL.GL_BYTE, stringBuffer)
        gl.glMatrixMode(GL.GL_PROJECTION);  // Select The Projection Matrix
        gl.glPopMatrix();                   // Restore The Old Projection Matrix
        gl.glMatrixMode(GL.GL_MODELVIEW);   // Select The Modelview Matrix
        gl.glPopMatrix();                   // Restore The Old Projection Matrix
        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glDisable(GL.GL_BLEND);
        gl.glDisable(GL.GL_TEXTURE_2D);
    }

    public void setWindowSize(int width, int height) {
        m_WindowWidth = width;              // Set the window size width
        m_WindowHeight = height;            // Set the window size height
    }
}


package demos.nehe.lesson44;

import javax.media.opengl.GL;

/**
 * I don't mind if you use this class in your own code. All I ask is
 * that you give me credit for it if you do.  And plug NeHe while your
 * at it! :P  Thanks go to David Steere, Cameron Tidwell, Bert Sammons,
 * and Brannon Martindale for helping me test all the code!  Enjoy.
 @author Vic Hollis
 @author Abdul Bezrati
 */
class Camera {
    Tuple3f vLightSourceToIntersect;
    Tuple3f vLightSourceToCamera;
    Tuple3f m_DirectionVector;
    Tuple3f m_LightSourcePos;
    Tuple3f ptIntersect;
    Tuple3f m_Position;
    Tuple3f pt;

    float m_MaxForwardVelocity;
    float m_ForwardVelocity;
    float m_MaxHeadingRate;
    float m_HeadingDegrees;
    float m_PitchDegrees;
    float m_MaxPitchRate;
    float m_MaxPointSize;
    float[][] m_Frustum;

    int[] m_BigGlowTexture;
    int[] m_StreakTexture;
    int[] m_HaloTexture;
    int[] m_GlowTexture;
    int m_WindowHeight;
    int m_WindowWidth;

    public Camera() {
        // Initalize all our member varibles.
        vLightSourceToIntersect = new Tuple3f();
        vLightSourceToCamera = new Tuple3f();
        m_DirectionVector = new Tuple3f();
        m_LightSourcePos = new Tuple3f();
        ptIntersect = new Tuple3f();
        m_Position = new Tuple3f();
        pt = new Tuple3f();
        m_Frustum = new float[6][4];
        m_MaxForwardVelocity = 0;
        m_LightSourcePos.x = 0;
        m_LightSourcePos.y = 0;
        m_LightSourcePos.z = 0;
        m_ForwardVelocity = 0;
        m_MaxHeadingRate = 0;
        m_HeadingDegrees = 0;
        m_BigGlowTexture = new int[1];
        m_StreakTexture = new int[1];
        m_PitchDegrees = 0;
        m_MaxPointSize = 0;
        m_MaxPitchRate = 0;
        m_GlowTexture = new int[1];
        m_HaloTexture = new int[1];
    }

    public void setPrespective(GL gl) {
        Tuple3f v = new Tuple3f();  // A vector to hold our cameras direction * 
                                    // the forward velocity
        float Matrix[] new float[16];  // A array to hold the model view matrix.
        // we don't want to destory the Direction vector by using it instead.

        // Going to use glRotate to calculate our direction vector
        gl.glRotatef(m_HeadingDegrees, 0.0f1.0f0.0f);
        gl.glRotatef(m_PitchDegrees, 1.0f0.0f0.0f);

        // Get the resulting matrix from OpenGL it will have our
        // direction vector in the 3rd row.
        gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, Matrix, 0);

        // Get the direction vector from the matrix. Element 10 must
        // be inverted!
        m_DirectionVector.x = Matrix[8];
        m_DirectionVector.y = Matrix[9];
        m_DirectionVector.z = -Matrix[10];

        // Ok erase the results of the last computation.
        gl.glLoadIdentity();

        // Rotate the scene to get the right orientation.
        gl.glRotatef(m_PitchDegrees, 1.0f0.0f0.0f);
        gl.glRotatef(m_HeadingDegrees, 0.0f1.0f0.0f);

        // Scale the direction by our speed.
        v.scale(m_ForwardVelocity, m_DirectionVector);

        // Increment our position by the vector
        m_Position.add(v);

        // Translate to our new position.
        gl.glTranslatef(-m_Position.x, -m_Position.y, -m_Position.z);
    }

    public void changePitch(float degrees) {

        if (Math.abs(degrees< Math.abs(m_MaxPitchRate)) {
            // Our pitch is less than the max pitch rate that we
            // defined so lets increment it.
            m_PitchDegrees += degrees;
        else {
            // Our pitch is greater than the max pitch rate that
            // we defined so we can only increment our pitch by the
            // maximum allowed value.
            if (degrees < 0) {
                // We are pitching down so decrement
                m_PitchDegrees -= m_MaxPitchRate;
            else {
                // We are pitching up so increment
                m_PitchDegrees += m_MaxPitchRate;
            }
        }

        // We don't want our pitch to run away from us. Although it
        // really doesn't matter I prefer to have my pitch degrees
        // within the range of -360.0f to 360.0f
        if (m_PitchDegrees > 360.0f) {
            m_PitchDegrees -= 360.0f;
        else if (m_PitchDegrees < -360.0f) {
            m_PitchDegrees += 360.0f;
        }
    }

    public void changeHeading(float degrees) {

        if (Math.abs(degrees< Math.abs(m_MaxHeadingRate)) {
            // Our Heading is less than the max heading rate that we
            // defined so lets increment it but first we must check
            // to see if we are inverted so that our heading will not
            // become inverted.
            if (m_PitchDegrees > 90 && m_PitchDegrees < 270 || 
                    (m_PitchDegrees < -90 && m_PitchDegrees > -270)) {
                m_HeadingDegrees -= degrees;
            else {
                m_HeadingDegrees += degrees;
            }
        else {
            // Our heading is greater than the max heading rate that
            // we defined so we can only increment our heading by the
            // maximum allowed value.
            if (degrees < 0) {
                // Check to see if we are upside down.
                if ((m_PitchDegrees > 90 && m_PitchDegrees < 270|| 
                        (m_PitchDegrees < -90 && m_PitchDegrees > -270)) {
                    // Ok we would normally decrement here but since we are upside
                    // down then we need to increment our heading
                    m_HeadingDegrees += m_MaxHeadingRate;
                else {
                    // We are not upside down so decrement as usual
                    m_HeadingDegrees -= m_MaxHeadingRate;
                }
            else {
                // Check to see if we are upside down.
                if (m_PitchDegrees > 90 && m_PitchDegrees < 270 || 
                        (m_PitchDegrees < -90 && m_PitchDegrees > -270)) {
                    // Ok we would normally increment here but since we are upside
                    // down then we need to decrement our heading.
                    m_HeadingDegrees -= m_MaxHeadingRate;
                else {
                    // We are not upside down so increment as usual.
                    m_HeadingDegrees += m_MaxHeadingRate;
                }
            }
        }

        // We don't want our heading to run away from us either. Although it
        // really doesn't matter I prefer to have my heading degrees
        // within the range of -360.0f to 360.0f
        if (m_HeadingDegrees > 360.0f) {
            m_HeadingDegrees -= 360.0f;
        else if (m_HeadingDegrees < -360.0f) {
            m_HeadingDegrees += 360.0f;
        }
    }

    public void changeVelocity(float vel) {

        if (Math.abs(vel< Math.abs(m_MaxForwardVelocity)) {
            // Our velocity is less than the max velocity increment that we
            // defined so lets increment it.
            m_ForwardVelocity += vel;
        else {
            // Our velocity is greater than the max velocity increment that
            // we defined so we can only increment our velocity by the
            // maximum allowed value.
            if (vel < 0) {
                // We are slowing down so decrement
                m_ForwardVelocity -= -m_MaxForwardVelocity;
            else {
                // We are speeding up so increment
                m_ForwardVelocity += m_MaxForwardVelocity;
            }
        }
    }

    // I found this code here: http://www.markmorley.com/opengl/frustumculling.html
    // and decided to make it part of
    // the camera class just in case I might want to rotate
    // and translate the projection matrix. This code will
    // make sure that the Frustum is updated correctly but
    // this member is computational expensive with:
    // 82 muliplications, 72 additions, 24 divisions, and
    // 12 subtractions for a total of 190 operations. Ouch!
    private void updateFrustum(GL gl) {

        float clip[] new float[16],
                proj[] new float[16],
                modl[] new float[16],
                t;

        /* Get the current PROJECTION matrix from OpenGL */
        gl.glGetFloatv(GL.GL_PROJECTION_MATRIX, proj, 0);

        /* Get the current MODELVIEW matrix from OpenGL */
        gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, modl, 0);

        /* Combine the two matrices (multiply projection by modelview) */
        clip[0= modl[0* proj[0+ modl[1* proj[4+ modl[2* proj[8
                modl[3* proj[12];
        clip[1= modl[0* proj[1+ modl[1* proj[5+ modl[2* proj[9
                modl[3* proj[13];
        clip[2= modl[0* proj[2+ modl[1* proj[6+ modl[2* proj[10
                modl[3* proj[14];
        clip[3= modl[0* proj[3+ modl[1* proj[7+ modl[2* proj[11
                modl[3* proj[15];

        clip[4= modl[4* proj[0+ modl[5* proj[4+ modl[6* proj[8
                modl[7* proj[12];
        clip[5= modl[4* proj[1+ modl[5* proj[5+ modl[6* proj[9+
                modl[7* proj[13];
        clip[6= modl[4* proj[2+ modl[5* proj[6+ modl[6* proj[10
                modl[7* proj[14];
        clip[7= modl[4* proj[3+ modl[5* proj[7+ modl[6* proj[11
                modl[7* proj[15];

        clip[8= modl[8* proj[0+ modl[9* proj[4+ modl[10* proj[8
                modl[11* proj[12];
        clip[9= modl[8* proj[1+ modl[9* proj[5+ modl[10* proj[9
                modl[11* proj[13];
        clip[10= modl[8* proj[2+ modl[9* proj[6+ modl[10* proj[10
                modl[11* proj[14];
        clip[11= modl[8* proj[3+ modl[9* proj[7+ modl[10* proj[11
                modl[11* proj[15];

        clip[12= modl[12* proj[0+ modl[13* proj[4+ modl[14* proj[8
                modl[15* proj[12];
        clip[13= modl[12* proj[1+ modl[13* proj[5+ modl[14* proj[9
                modl[15* proj[13];
        clip[14= modl[12* proj[2+ modl[13* proj[6+ modl[14* proj[10
                modl[15* proj[14];
        clip[15= modl[12* proj[3+ modl[13* proj[7+ modl[14* proj[11
                modl[15* proj[15];

        /* Extract the numbers for the RIGHT plane */
        m_Frustum[0][0= clip[3- clip[0];
        m_Frustum[0][1= clip[7- clip[4];
        m_Frustum[0][2= clip[11- clip[8];
        m_Frustum[0][3= clip[15- clip[12];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[0][0* m_Frustum[0][0+ m_Frustum[0][1
                m_Frustum[0][1+ m_Frustum[0][2* m_Frustum[0][2]));
        m_Frustum[0][0/= t;
        m_Frustum[0][1/= t;
        m_Frustum[0][2/= t;
        m_Frustum[0][3/= t;

        /* Extract the numbers for the LEFT plane */
        m_Frustum[1][0= clip[3+ clip[0];
        m_Frustum[1][1= clip[7+ clip[4];
        m_Frustum[1][2= clip[11+ clip[8];
        m_Frustum[1][3= clip[15+ clip[12];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[1][0* m_Frustum[1][0+ m_Frustum[1][1
                m_Frustum[1][1+ m_Frustum[1][2* m_Frustum[1][2]));
        m_Frustum[1][0/= t;
        m_Frustum[1][1/= t;
        m_Frustum[1][2/= t;
        m_Frustum[1][3/= t;

        /* Extract the BOTTOM plane */
        m_Frustum[2][0= clip[3+ clip[1];
        m_Frustum[2][1= clip[7+ clip[5];
        m_Frustum[2][2= clip[11+ clip[9];
        m_Frustum[2][3= clip[15+ clip[13];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[2][0* m_Frustum[2][0+ m_Frustum[2][1
                m_Frustum[2][1+ m_Frustum[2][2* m_Frustum[2][2]));
        m_Frustum[2][0/= t;
        m_Frustum[2][1/= t;
        m_Frustum[2][2/= t;
        m_Frustum[2][3/= t;

        /* Extract the TOP plane */
        m_Frustum[3][0= clip[3- clip[1];
        m_Frustum[3][1= clip[7- clip[5];
        m_Frustum[3][2= clip[11- clip[9];
        m_Frustum[3][3= clip[15- clip[13];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[3][0* m_Frustum[3][0+ m_Frustum[3][1
                m_Frustum[3][1+ m_Frustum[3][2* m_Frustum[3][2]));
        m_Frustum[3][0/= t;
        m_Frustum[3][1/= t;
        m_Frustum[3][2/= t;
        m_Frustum[3][3/= t;

        /* Extract the FAR plane */
        m_Frustum[4][0= clip[3- clip[2];
        m_Frustum[4][1= clip[7- clip[6];
        m_Frustum[4][2= clip[11- clip[10];
        m_Frustum[4][3= clip[15- clip[14];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[4][0* m_Frustum[4][0+ m_Frustum[4][1
                m_Frustum[4][1+ m_Frustum[4][2* m_Frustum[4][2]));
        m_Frustum[4][0/= t;
        m_Frustum[4][1/= t;
        m_Frustum[4][2/= t;
        m_Frustum[4][3/= t;

        /* Extract the NEAR plane */
        m_Frustum[5][0= clip[3+ clip[2];
        m_Frustum[5][1= clip[7+ clip[6];
        m_Frustum[5][2= clip[11+ clip[10];
        m_Frustum[5][3= clip[15+ clip[14];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[5][0* m_Frustum[5][0+ m_Frustum[5][1
                m_Frustum[5][1+ m_Frustum[5][2* m_Frustum[5][2]));
        m_Frustum[5][0/= t;
        m_Frustum[5][1/= t;
        m_Frustum[5][2/= t;
        m_Frustum[5][3/= t;
    }

    // This is the much faster version of the above member
    // function, however the speed increase is not gained
    // without a cost. If you rotate or translate the projection
    // matrix then this member will not work correctly. That is acceptable
    // in my book considering I very rarely do such a thing.
    // This function has far fewer operations in it and I
    // shaved off 2 square root functions by passing in the
    // near and far values. This member has:
    // 38 muliplications, 28 additions, 24 divisions, and
    // 12 subtractions for a total of 102 operations. Still hurts
    // but at least it is decent now. In practice this will
    // run about 2 times faster than the above function.
    public void updateFrustumFaster(GL gl) {

        float clip[] new float[16],
                proj[] new float[16],
                modl[] new float[16],
                t;

        /* Get the current PROJECTION matrix from OpenGL */
        gl.glGetFloatv(GL.GL_PROJECTION_MATRIX, proj, 0);

        /* Get the current MODELVIEW matrix from OpenGL */
        gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, modl, 0);

        /* Combine the two matrices (multiply projection by modelview)
           but keep in mind this function will only work if you do NOT
          rotate or translate your projection matrix                  */
        clip[0= modl[0* proj[0];
        clip[1= modl[1* proj[5];
        clip[2= modl[2* proj[10+ modl[3* proj[14];
        clip[3= modl[2* proj[11];

        clip[4= modl[4* proj[0];
        clip[5= modl[5* proj[5];
        clip[6= modl[6* proj[10+ modl[7* proj[14];
        clip[7= modl[6* proj[11];

        clip[8= modl[8* proj[0];
        clip[9= modl[9* proj[5];
        clip[10= modl[10* proj[10+ modl[11* proj[14];
        clip[11= modl[10* proj[11];

        clip[12= modl[12* proj[0];
        clip[13= modl[13* proj[5];
        clip[14= modl[14* proj[10+ modl[15* proj[14];
        clip[15= modl[14* proj[11];

        /* Extract the numbers for the RIGHT plane */
        m_Frustum[0][0= clip[3- clip[0];
        m_Frustum[0][1= clip[7- clip[4];
        m_Frustum[0][2= clip[11- clip[8];
        m_Frustum[0][3= clip[15- clip[12];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[0][0* m_Frustum[0][0+ m_Frustum[0][1
                m_Frustum[0][1+ m_Frustum[0][2* m_Frustum[0][2]));
        m_Frustum[0][0/= t;
        m_Frustum[0][1/= t;
        m_Frustum[0][2/= t;
        m_Frustum[0][3/= t;

        /* Extract the numbers for the LEFT plane */
        m_Frustum[1][0= clip[3+ clip[0];
        m_Frustum[1][1= clip[7+ clip[4];
        m_Frustum[1][2= clip[11+ clip[8];
        m_Frustum[1][3= clip[15+ clip[12];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[1][0* m_Frustum[1][0+ m_Frustum[1][1
                m_Frustum[1][1+ m_Frustum[1][2* m_Frustum[1][2]));
        m_Frustum[1][0/= t;
        m_Frustum[1][1/= t;
        m_Frustum[1][2/= t;
        m_Frustum[1][3/= t;

        /* Extract the BOTTOM plane */
        m_Frustum[2][0= clip[3+ clip[1];
        m_Frustum[2][1= clip[7+ clip[5];
        m_Frustum[2][2= clip[11+ clip[9];
        m_Frustum[2][3= clip[15+ clip[13];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[2][0* m_Frustum[2][0+ m_Frustum[2][1
                m_Frustum[2][1+ m_Frustum[2][2* m_Frustum[2][2]));
        m_Frustum[2][0/= t;
        m_Frustum[2][1/= t;
        m_Frustum[2][2/= t;
        m_Frustum[2][3/= t;

        /* Extract the TOP plane */
        m_Frustum[3][0= clip[3- clip[1];
        m_Frustum[3][1= clip[7- clip[5];
        m_Frustum[3][2= clip[11- clip[9];
        m_Frustum[3][3= clip[15- clip[13];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[3][0* m_Frustum[3][0+ m_Frustum[3][1
                m_Frustum[3][1+ m_Frustum[3][2* m_Frustum[3][2]));
        m_Frustum[3][0/= t;
        m_Frustum[3][1/= t;
        m_Frustum[3][2/= t;
        m_Frustum[3][3/= t;

        /* Extract the FAR plane */
        m_Frustum[4][0= clip[3- clip[2];
        m_Frustum[4][1= clip[7- clip[6];
        m_Frustum[4][2= clip[11- clip[10];
        m_Frustum[4][3= clip[15- clip[14];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[4][0* m_Frustum[4][0+ m_Frustum[4][1
                m_Frustum[4][1+ m_Frustum[4][2* m_Frustum[4][2]));
        m_Frustum[4][0/= t;
        m_Frustum[4][1/= t;
        m_Frustum[4][2/= t;
        m_Frustum[4][3/= t;

        /* Extract the NEAR plane */
        m_Frustum[5][0= clip[3+ clip[2];
        m_Frustum[5][1= clip[7+ clip[6];
        m_Frustum[5][2= clip[11+ clip[10];
        m_Frustum[5][3= clip[15+ clip[14];

        /* Normalize the result */
        t = (float) (Math.sqrt(m_Frustum[5][0* m_Frustum[5][0+ m_Frustum[5][1
                m_Frustum[5][1+ m_Frustum[5][2* m_Frustum[5][2]));
        m_Frustum[5][0/= t;
        m_Frustum[5][1/= t;
        m_Frustum[5][2/= t;
        m_Frustum[5][3/= t;
    }

    // This member function checks to see if a sphere is in
    // the viewing volume.
    private boolean sphereInFrustum(Tuple3f p, float Radius) {

        int i;
        // The idea here is the same as the PointInFrustum function.

        for (i = 0; i < 6; i++) {
            // If the point is outside of the plane then its not in the viewing volume.
            if (m_Frustum[i][0* p.x + m_Frustum[i][1* p.y + m_Frustum[i][2* p.z + 
                    m_Frustum[i][3<= -Radius) {
                return false;
            }
        }
        return true;
    }

    // This member fuction checks to see if a point is in
    // the viewing volume.
    public boolean pointInFrustum(Tuple3f p) {

        int i;

        // The idea behind this algorithum is that if the point
        // is inside all 6 clipping planes then it is inside our
        // viewing volume so we can return true.

        for (i = 0; i < 6; i++) {
            if (m_Frustum[i][0* p.x + m_Frustum[i][1* p.y + m_Frustum[i][2* p.z + 
                    m_Frustum[i][3<= 0) {
                return false;
            }
        }
        return true;
    }

    // This member function checks to see if a sphere is in
    // the viewing volume.
    private boolean sphereInFrustum(float x, float y, float z, float Radius) {

        int i;
        // The idea here is the same as the PointInFrustum function.

        for (i = 0; i < 6; i++) {
            // If the point is outside of the plane then its not in the viewing volume.
            if (m_Frustum[i][0* x + m_Frustum[i][1* y + m_Frustum[i][2* z + 
                    m_Frustum[i][3<= -Radius) {
                return false;
            }
        }
        return true;
    }

    // This member fuction checks to see if a point is in
    // the viewing volume.

    public boolean pointInFrustum(float x, float y, float z) {

        int i;
        // The idea behind this algorithum is that if the point
        // is inside all 6 clipping planes then it is inside our
        // viewing volume so we can return true.

        for (i = 0; i < 6; i++) {  // Loop through all our clipping planes
            // If the point is outside of the plane then its not in the viewing volume.
            if (m_Frustum[i][0* x + m_Frustum[i][1* y + m_Frustum[i][2* z + 
                    m_Frustum[i][3<= 0) {
                return false;
            }
        }
        return true;
    }

    public void renderLensFlare(GL gl) {

        float Length = 0.0f;

        // Draw the flare only If the light source is in our line of sight
        if (sphereInFrustum(m_LightSourcePos, 1.0f)) {

            // Lets compute the vector that points to the camera from
            vLightSourceToCamera.sub(m_Position, m_LightSourcePos);     
            // the light source.
            // Save the length we will need it in a minute
            Length = vLightSourceToCamera.length();                     
            // Now lets find an point along the cameras direction
            ptIntersect.scale(Length, m_DirectionVector);                
            // vector that we can use as an intersection point.
            // Lets translate down this vector the same distance
            // that the camera is away from the light source.
            ptIntersect.add(m_Position);
            // Lets compute the vector that points to the Intersect
            vLightSourceToIntersect.sub(ptIntersect, m_LightSourcePos)
            // point from the light source
            // Save the length we will need it later.
            Length = vLightSourceToIntersect.length();                  
            // Normalize the vector so its unit length
            vLightSourceToIntersect.normalize();                        

            
            // You should already know what this does
            gl.glEnable(GL.GL_BLEND);                                   
            // You should already know what this does
            gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE);                  
            // You should already know what this does
            gl.glDisable(GL.GL_DEPTH_TEST);                             
            // You should already know what this does
            gl.glEnable(GL.GL_TEXTURE_2D);                              

            /////////// Differenet Color Glows & Streaks /////////////////////
            //RenderBigGlow(1.0f, 1.0f, 1.0f, 1.0f, m_LightSourcePos, 1.0f);
            //RenderStreaks(1.0f, 1.0f, 0.8f, 1.0f, m_LightSourcePos, 0.7f);
            //
            //RenderBigGlow(1.0f, 0.9f, 1.0f, 1.0f, m_LightSourcePos, 1.0f);
            //RenderStreaks(1.0f, 0.9f, 1.0f, 1.0f, m_LightSourcePos, 0.7f);
            //////////////////////////////////////////////////////////////////

            // Render the large hazy glow
            renderBigGlow(gl, 0.60f0.60f0.8f1.0f, m_LightSourcePos, 16.0f);
            // Render the streaks
            renderStreaks(gl, 0.60f0.60f0.8f1.0f, m_LightSourcePos, 16.0f);
            // Render the small Glow
            renderGlow(gl, 0.8f0.8f1.0f0.5f, m_LightSourcePos, 3.5f);

            // Lets compute a point that is 20%
            pt.scaleAdd(Length * .1f, vLightSourceToIntersect, m_LightSourcePos);      
            // away from the light source in the
            // direction of the intersection point.
            renderGlow(gl, 0.9f0.6f0.4f0.5f, pt, 0.6f)// Render the small Glow

            // Lets compute a point that is 30%
            pt.scaleAdd(Length * .15f, vLightSourceToIntersect, m_LightSourcePos);  
            // away from the light source in the
            // direction of the intersection point.
            renderHalo(gl, 0.8f0.5f0.6f0.5f, pt, 1.7f)// Render the a Halo

            // Lets compute a point that is 35%
            pt.scaleAdd(Length * .175f, vLightSourceToIntersect, m_LightSourcePos)
            // away from the light source in the
            // direction of the intersection point.
            renderHalo(gl, 0.9f0.2f0.1f0.5f, pt, 0.83f)// Render the a Halo

            
            // Lets compute a point that is 57%
            pt.scaleAdd(Length * .285f, vLightSourceToIntersect, m_LightSourcePos)
            // away from the light source in the
            // direction of the intersection point.
            renderHalo(gl, 0.7f0.7f0.4f0.5f, pt, 1.6f);  // Render the a Halo

            // Lets compute a point that is 55.1%
            pt.scaleAdd(Length * .2755f, vLightSourceToIntersect, m_LightSourcePos);
            // away from the light source in the
            // direction of the intersection point.
            renderGlow(gl, 0.9f0.9f0.2f0.5f, pt, 0.8f);  // Render the small Glow

            // Lets compute a point that is 95.5%
            pt.scaleAdd(Length * .4775f, vLightSourceToIntersect, m_LightSourcePos);
            // away from the light source in the
            // direction of the intersection point.
            // Render the small Glow
            renderGlow(gl, 0.93f0.82f0.73f0.5f, pt, 1.0f)

            // Lets compute a point that is 98%
            pt.scaleAdd(Length * .49f, vLightSourceToIntersect, m_LightSourcePos);  
            // away from the light source in the
            // direction of the intersection point.
            renderHalo(gl, 0.7f0.6f0.5f0.5f, pt, 1.4f)// Render the a Halo

            // Lets compute a point that is 130%
            pt.scaleAdd(Length * .65f, vLightSourceToIntersect, m_LightSourcePos);  
            // away from the light source in the
            // direction of the intersection point.
            renderGlow(gl, 0.7f0.8f0.3f0.5f, pt, 1.8f)// Render the small Glow

            // Lets compute a point that is 126%
            pt.scaleAdd(Length * 0.63f, vLightSourceToIntersect, m_LightSourcePos)
            // away from the light source in the
            // direction of the intersection point.
            renderGlow(gl, 0.4f0.3f0.2f0.5f, pt, 1.4f)// Render the small Glow

            // Lets compute a point that is 160%
            pt.scaleAdd(Length * 0.8f, vLightSourceToIntersect, m_LightSourcePos);  
            // away from the light source in the
            // direction of the intersection point.
            renderHalo(gl, 0.7f0.5f0.5f0.5f, pt, 1.4f)// Render the a Halo

            // Lets compute a point that is 156.5%
            pt.scaleAdd(Length * .7825f, vLightSourceToIntersect, m_LightSourcePos);
            // away from the light source in the
            // direction of the intersection point.
            renderGlow(gl, 0.8f0.5f0.1f0.5f, pt, 0.6f)// Render the small Glow

            // Lets compute a point that is 200%
            pt.scaleAdd(Length * 1.0f, vLightSourceToIntersect, m_LightSourcePos);  
            // away from the light source in the
            // direction of the intersection point.
            renderHalo(gl, 0.5f0.5f0.7f0.5f, pt, 1.7f)// Render the a Halo

            // Lets compute a point that is 195%
            pt.scaleAdd(Length * 0.975f, vLightSourceToIntersect, m_LightSourcePos);
            // away from the light source in the
            // direction of the intersection point.
            renderGlow(gl, 0.4f0.1f0.9f0.5f, pt, 2.0f)// Render the small Glow

            gl.glDisable(GL.GL_BLEND);       // You should already know what this does
            gl.glEnable(GL.GL_DEPTH_TEST);   // You should already know what this does
            gl.glDisable(GL.GL_TEXTURE_2D);  // You should already know what this does
        }
    }

    private void renderHalo(GL gl, float r, float g, float b, float a, Tuple3f p, 
            float scale) {

        Tuple3f[] q = new Tuple3f[4];
        for (int i = 3; i >= 0; i--)
            q[inew Tuple3f();
        // Basically we are just going to make a 2D box
        // from four points we don't need a z coord because
        // we are rotating the camera by the inverse so the
        // texture mapped quads will always face us.
        q[0].x = (p.x - scale)// Set the x coordinate -scale units from the center point.
        q[0].y = (p.y - scale)// Set the y coordinate -scale units from the center point.

        q[1].x = (p.x - scale)// Set the x coordinate -scale units from the center point.
        q[1].y = (p.y + scale)// Set the y coordinate scale units from the center point.

        q[2].x = (p.x + scale)// Set the x coordinate scale units from the center point.
        q[2].y = (p.y - scale)// Set the y coordinate -scale units from the center point.

        q[3].x = (p.x + scale)// Set the x coordinate scale units from the center point.
        q[3].y = (p.y + scale)// Set the y coordinate scale units from the center point.

        gl.glPushMatrix();               // Save the model view matrix
        gl.glTranslatef(p.x, p.y, p.z);  // Translate to our point
        gl.glRotatef(-m_HeadingDegrees, 0.0f1.0f0.0f);
        gl.glRotatef(-m_PitchDegrees, 1.0f0.0f0.0f);
        // Bind to the Big Glow texture
        gl.glBindTexture(GL.GL_TEXTURE_2D, m_HaloTexture[0])
        gl.glColor4f(r, g, b, a);  // Set the color since the texture is a gray scale

        gl.glBegin(GL.GL_TRIANGLE_STRIP)// Draw the Big Glow on a Triangle Strip
        gl.glTexCoord2f(0.0f0.0f);
        gl.glVertex2f(q[0].x, q[0].y);
        gl.glTexCoord2f(0.0f1.0f);
        gl.glVertex2f(q[1].x, q[1].y);
        gl.glTexCoord2f(1.0f0.0f);
        gl.glVertex2f(q[2].x, q[2].y);
        gl.glTexCoord2f(1.0f1.0f);
        gl.glVertex2f(q[3].x, q[3].y);
        gl.glEnd();
        gl.glPopMatrix()// Restore the model view matrix
    }

    private void renderGlow(GL gl, float r, float g, float b, float a, Tuple3f p, 
            float scale) {

        Tuple3f[] q = new Tuple3f[4];
        for (int i = 3; i >= 0; i--)
            q[inew Tuple3f();

        // Basically we are just going to make a 2D box
        // from four points we don't need a z coord because
        // we are rotating the camera by the inverse so the
        // texture mapped quads will always face us.
        q[0].x = (p.x - scale)// Set the x coordinate -scale units from the center point.
        q[0].y = (p.y - scale)// Set the y coordinate -scale units from the center point.

        q[1].x = (p.x - scale)// Set the x coordinate -scale units from the center point.
        q[1].y = (p.y + scale)// Set the y coordinate scale units from the center point.

        q[2].x = (p.x + scale)// Set the x coordinate scale units from the center point.
        q[2].y = (p.y - scale)// Set the y coordinate -scale units from the center point.

        q[3].x = (p.x + scale)// Set the x coordinate scale units from the center point.
        q[3].y = (p.y + scale)// Set the y coordinate scale units from the center point.

        gl.glPushMatrix();              // Save the model view matrix
        gl.glTranslatef(p.x, p.y, p.z)// Translate to our point
        gl.glRotatef(-m_HeadingDegrees, 0.0f1.0f0.0f);
        gl.glRotatef(-m_PitchDegrees, 1.0f0.0f0.0f);
        // Bind to the Big Glow texture
        gl.glBindTexture(GL.GL_TEXTURE_2D, m_GlowTexture[0])
        gl.glColor4f(r, g, b, a);  // Set the color since the texture is a gray scale

        gl.glBegin(GL.GL_TRIANGLE_STRIP);  // Draw the Big Glow on a Triangle Strip
        gl.glTexCoord2f(0.0f0.0f);
        gl.glVertex2f(q[0].x, q[0].y);
        gl.glTexCoord2f(0.0f1.0f);
        gl.glVertex2f(q[1].x, q[1].y);
        gl.glTexCoord2f(1.0f0.0f);
        gl.glVertex2f(q[2].x, q[2].y);
        gl.glTexCoord2f(1.0f1.0f);
        gl.glVertex2f(q[3].x, q[3].y);
        gl.glEnd();
        gl.glPopMatrix();  // Restore the model view matrix
    }

    private void renderBigGlow(GL gl, float r, float g, float b, float a, 
            Tuple3f p, float scale) {

        Tuple3f[] q = new Tuple3f[4];
        for (int i = 3; i >= 0; i--)
            q[inew Tuple3f();

        // Basically we are just going to make a 2D box
        // from four points we don't need a z coord because
        // we are rotating the camera by the inverse so the
        // texture mapped quads will always face us.
        q[0].x = (p.x - scale)// Set the x coordinate -scale units from the center point.
        q[0].y = (p.y - scale)// Set the y coordinate -scale units from the center point.

        q[1].x = (p.x - scale)// Set the x coordinate -scale units from the center point.
        q[1].y = (p.y + scale)// Set the y coordinate scale units from the center point.

        q[2].x = (p.x + scale)// Set the x coordinate scale units from the center point.
        q[2].y = (p.y - scale)// Set the y coordinate -scale units from the center point.

        q[3].x = (p.x + scale)// Set the x coordinate scale units from the center point.
        q[3].y = (p.y + scale)// Set the y coordinate scale units from the center point.

        gl.glPushMatrix();     // Save the model view matrix
        gl.glTranslatef(p.x, p.y, p.z)// Translate to our point
        gl.glRotatef(-m_HeadingDegrees, 0.0f1.0f0.0f);
        gl.glRotatef(-m_PitchDegrees, 1.0f0.0f0.0f);
        // Bind to the Big Glow texture
        gl.glBindTexture(GL.GL_TEXTURE_2D, m_BigGlowTexture[0])
        gl.glColor4f(r, g, b, a)// Set the color since the texture is a gray scale

        gl.glBegin(GL.GL_TRIANGLE_STRIP)// Draw the Big Glow on a Triangle Strip
        gl.glTexCoord2f(0.0f0.0f);
        gl.glVertex2f(q[0].x, q[0].y);
        gl.glTexCoord2f(0.0f1.0f);
        gl.glVertex2f(q[1].x, q[1].y);
        gl.glTexCoord2f(1.0f0.0f);
        gl.glVertex2f(q[2].x, q[2].y);
        gl.glTexCoord2f(1.0f1.0f);
        gl.glVertex2f(q[3].x, q[3].y);
        gl.glEnd();
        gl.glPopMatrix()// Restore the model view matrix
    }

    private void renderStreaks(GL gl, float r, float g, float b, float a, 
            Tuple3f p, float scale) {

        Tuple3f[] q = new Tuple3f[4];
        for (int i = 3; i >= 0; i--)
            q[inew Tuple3f();
        // Basically we are just going to make a 2D box
        // from four points we don't need a z coord because
        // we are rotating the camera by the inverse so the
        // texture mapped quads will always face us.
        q[0].x = (p.x - scale)// Set the x coordinate -scale units from the center point.
        q[0].y = (p.y - scale)// Set the y coordinate -scale units from the center point.

        q[1].x = (p.x - scale)// Set the x coordinate -scale units from the center point.
        q[1].y = (p.y + scale)// Set the y coordinate scale units from the center point.

        q[2].x = (p.x + scale)// Set the x coordinate scale units from the center point.
        q[2].y = (p.y - scale)// Set the y coordinate -scale units from the center point.

        q[3].x = (p.x + scale)// Set the x coordinate scale units from the center point.
        q[3].y = (p.y + scale)// Set the y coordinate scale units from the center point.

        gl.glPushMatrix();   // Save the model view matrix
        gl.glTranslatef(p.x, p.y, p.z);    // Translate to our point
        gl.glRotatef(-m_HeadingDegrees, 0.0f1.0f0.0f);
        gl.glRotatef(-m_PitchDegrees, 1.0f0.0f0.0f);
        // Bind to the Big Glow texture
        gl.glBindTexture(GL.GL_TEXTURE_2D, m_StreakTexture[0])
        gl.glColor4f(r, g, b, a)// Set the color since the texture is a gray scale

        gl.glBegin(GL.GL_TRIANGLE_STRIP)// Draw the Big Glow on a Triangle Strip
        gl.glTexCoord2f(0.0f0.0f);
        gl.glVertex2f(q[0].x, q[0].y);
        gl.glTexCoord2f(0.0f1.0f);
        gl.glVertex2f(q[1].x, q[1].y);
        gl.glTexCoord2f(1.0f0.0f);
        gl.glVertex2f(q[2].x, q[2].y);
        gl.glTexCoord2f(1.0f1.0f);
        gl.glVertex2f(q[3].x, q[3].y);
        gl.glEnd();
        gl.glPopMatrix();  // Restore the model view matrix
    }
}


package demos.nehe.lesson44;

/**
 @author Abdul Bezrati
 */
class Tuple3f{
    float x, y, z;

    public Tuple3f(){
      x = y = z = 0;
    }

    public Tuple3f(Tuple3f p){
      x = p.x;
      y = p.y;
      z = p.z;
    }

    public Tuple3f(float x, float y, float z){
      this.x = x;
      this.y = y;
      this.z = z;
    }

    public void set(float x, float y, float z){
      this.x = x;
      this.y = y;
      this.z = z;
    }

    public void set(Tuple3f vec){
      x = vec.x;
      y = vec.y;
      z = vec.z;
    }

    public void cross(Tuple3f u,Tuple3f v){
      x =  (u.y*v.z(u.z*v.y);
      y =  (u.z*v.x(u.x*v.z);
      z =  (u.x*v.y(u.y*v.x);
    }

    public float Dot(Tuple3f u){
      return  u.x*this.x +
              u.y*this.y +
              u.z*this.z;
    }

    public void add(Tuple3f u,Tuple3f v){
      x =  u.x + v.x;
      y =  u.y + v.y;
      z =  u.z + v.z;
    }

    public void scaleAdd(float f,Tuple3f u,Tuple3f v){
      x = f*u.x + v.x;
      y = f*u.y + v.y;
      z = f*u.z + v.z;
    }

    public void add(Tuple3f u){
      x +=  u.x;
      y +=  u.y;
      z +=  u.z;
    }

    public void add(float a){
      x += a;
      y += a;
      z += a;
    }

    public void sub(Tuple3f u,Tuple3f v){
      x =  u.x - v.x;
      y =  u.y - v.y;
      z =  u.z - v.z;
    }

    public void sub(Tuple3f u){
      x -=  u.x;
      y -=  u.y;
      z -=  u.z;
    }

    public void scale(float mul){
      x*=   mul;
      y*=   mul;
      z*=   mul;
    }

    public void scale(float mul, Tuple3f v){
      x =   mul*v.x;
      y =   mul*v.y;
      z =   mul*v.z;
    }

    public void mul(Tuple3f v1,Tuple3f v2){
      x =   v1.x*v2.x;
      y =   v1.y*v2.y;
      z =   v1.z*v2.z;
    }

    public void normalize(){
      float length = (float)Math.sqrt(x*x + y*y + z*z);
      x/=length;
      y/=length;
      z/=length;
    }

    public float distance(Tuple3f u){
      return (float)Math.sqrt((this.x - u.x)*(this.x - u.x+
                              (this.y - u.y)*(this.y - u.y+
                              (this.z - u.z)*(this.z - u.z));
  }

    public float length(){
      return (float)Math.sqrt(x*x + y*y + z*z);
    }

    public void negate(){
      x = - x;
      y = - y;
      z = - z;
    }
  }


package demos.nehe.lesson44;

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

import java.io.IOException;

import demos.common.TextureReader;

class Renderer implements GLEventListener {
    private boolean infoOn = false;
    private double gCurrentTime;
    private double gStartTime;
    private float gFPS;

    private int gFrames;

    private Camera gCamera;
    private Font gFont;
    private boolean pitchCameraUp = false;
    private boolean pitchCameraDown = false;
    private boolean yawCameraLeft = false;
    private boolean yawCameraRight = false;

    private GLU glu = new GLU();

    public void setInfoDisplayed(boolean infoOn) {
        this.infoOn = infoOn;
    }

    public void moveCameraBackward() {
        // Start moving the camera backwards 0.01 units every frame
        gCamera.m_ForwardVelocity = -.01f;
    }

    public void moveCameraForward() {
        // Start moving the camera forward 0.01 units every frame
        gCamera.m_ForwardVelocity = .01f
    }

    public void stopCamera() {
        gCamera.m_ForwardVelocity = 0.0f// Stop the camera from moving.
    }

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

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

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

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

    private void loadTexture(String fileName, int[] texid, GLAutoDrawable drawable
            throws IOException // Creates Texture From A Bitmap File
        TextureReader.Texture texture = TextureReader.readTexture(fileName);
        GL gl = drawable.getGL();
        gl.glGenTextures(1, texid, 0)// Create The Texture

        // Pixel Storage Mode (Word Alignment / 4 Bytes)
        gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 4)

        // Typical Texture Generation Using Data From The Bitmap
        gl.glBindTexture(GL.GL_TEXTURE_2D, texid[0])// Bind To The Texture ID
        // Linear Min Filter
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);  
        // Linear Mag Filter
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);  
        gl.glTexImage2D(GL.GL_TEXTURE_2D, 03, texture.getWidth(), texture.getHeight(),
                0, GL.GL_BGR, GL.GL_UNSIGNED_BYTE, texture.getPixels());
    }

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

        int[] tex = {0};

        gCamera = new Camera();
        gFont = new Font();

        gl.glShadeModel(GL.GL_SMOOTH);               // Enable Smooth Shading
        gl.glClearColor(0.0f0.0f0.0f0.5f);     // Black Background
        gl.glClearDepth(1.0f);                       // Depth Buffer Setup
        gl.glEnable(GL.GL_DEPTH_TEST);               // Enables Depth Testing
        gl.glDepthFunc(GL.GL_LEQUAL);                // The Type Of Depth Testing To Do
        // Really Nice Perspective Calculations
        gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);

        try {
            // Load the font texture
            loadTexture("demos/data/images/Font.bmp", tex, drawable);               
        catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (tex[0!= 0) {                    // Make sure it was loaded
            gFont.setFontTexture(tex[0]);     // Set the font texture
            // The font class needs to know the window size
            gFont.setWindowSize(1024768);   
            gFont.buildFont(gl, 1.0f);        // Build the font
        }

        gCamera.m_MaxHeadingRate = 1.0f;      // Set our Maximum rates for the camera
        gCamera.m_HeadingDegrees = 0.0f;      // Set our Maximum rates for the camera
        gCamera.m_MaxPitchRate = 1.0f;        // Set our Maximum rates for the camera

        // Try and load the HardGlow texture tell the user if we can't find it then quit
        try {
            loadTexture("demos/data/images/HardGlow2.bmp"
                    gCamera.m_GlowTexture, drawable);
        catch (IOException e) {
            throw new RuntimeException(e);
        }


        // Try and load the BigGlow texture tell the user if we can't find it 
        // then quit
        try {
            loadTexture("demos/data/images/BigGlow3.bmp"
                    gCamera.m_BigGlowTexture, drawable);
        catch (IOException e) {
            throw new RuntimeException(e);
        }

        // Try and load the Halo texture tell the user if we can't find it then quit
        try {
            loadTexture("demos/data/images/Halo3.bmp"
                    gCamera.m_HaloTexture, drawable);
        catch (IOException e) {
            throw new RuntimeException(e);
        }

        // Try and load the Streaks texture tell the user if we can't find it then quit
        try {
            loadTexture("demos/data/images/Streaks4.bmp"
                    gCamera.m_StreakTexture, drawable);
        catch (IOException e) {
            throw new RuntimeException(e);
        }

        gStartTime = System.currentTimeMillis();
    }

    private void update() {
        if (pitchCameraUp)             // Is the W key down?
            gCamera.changePitch(-0.2f);// Pitch the camera up 0.2 degrees

        if (pitchCameraDown)             // Is the S key down?
            gCamera.changePitch(0.2f);        // Pitch the camera down 0.2 degrees

        if (yawCameraLeft)             // Is the D key down?
            gCamera.changeHeading(0.2f);      // Yaw the camera to the left

        if (yawCameraRight)             // Is the A key down?
            gCamera.changeHeading(-0.2f);     // Yaw the camera to the right
    }

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

        // Clear Screen And Depth Buffer
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);  
        gl.glLoadIdentity();   // Reset The Current Modelview Matrix

        // We want our light source to be 50 units if front
        // of the camera all the time to make it look like
        // it is infinately far away from the camera. We only
        // do this to the z coordinate because we want to see
        // the flares adjust if we fly in a straight line.
        gCamera.m_LightSourcePos.z = gCamera.m_Position.z - 50.0f;

        gCamera.setPrespective(gl)// Set our perspective/oriention on the world
        gCamera.renderLensFlare(gl)// Render the lens flare
        gCamera.updateFrustumFaster(gl);  // Update the frustum as fast as possible.
        if (infoOn) {   // Check to see if info has been toggled by 1,2
            drawGLInfo(gl);  // Info is on so draw the GL information.
        }

        update();
    }

    private void drawGLInfo(GL gl) {

        float modelMatrix[] new float[16]// This will hold the model view matrix
                projMatrix[] new float[16]// This will hold the projection matrix
                DiffTime;   // This is will contain the difference in time
        String string;      // A temporary string to use to format information
        // that will be printed to the screen.

        // Grab the projection matrix
        gl.glGetFloatv(GL.GL_PROJECTION_MATRIX, projMatrix, 0)
        // Grab the modelview matrix
        gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, modelMatrix, 0)

        // Print out the cameras position
        gl.glColor4f(1.0f1.0f1.0f1.0f);
        string = "m_Position............. = " + twoFracsMax(gCamera.m_Position.x
                ", " + twoFracsMax(gCamera.m_Position.y", " 
                twoFracsMax(gCamera.m_Position.z);
        
        gFont.glPrintf(gl, 107201, string);

        // Print out the cameras direction
        string = "m_DirectionVector...... = " + twoFracsMax(gCamera.m_DirectionVector.x
                ", " + twoFracsMax(gCamera.m_DirectionVector.y", " 
                twoFracsMax(gCamera.m_DirectionVector.z);
        
        gFont.glPrintf(gl, 107001, string);

        // Print out the light sources position
        string = "m_LightSourcePos....... = " + twoFracsMax(gCamera.m_LightSourcePos.x
                ", " + twoFracsMax(gCamera.m_LightSourcePos.y", " 
                twoFracsMax(gCamera.m_LightSourcePos.z);
        
        gFont.glPrintf(gl, 106801, string);

        // Print out the intersection point
        string = "ptIntersect............ = " + twoFracsMax(gCamera.ptIntersect.x
                ", " + twoFracsMax(gCamera.ptIntersect.y", " 
                twoFracsMax(gCamera.ptIntersect.x);
        
        gFont.glPrintf(gl, 106601, string);

        // Print out the vector that points from the light source to the camera
        string = "vLightSourceToCamera... = " + twoFracsMax(gCamera.vLightSourceToCamera.x
                ", " + twoFracsMax(gCamera.vLightSourceToCamera.y", " 
                twoFracsMax(gCamera.vLightSourceToCamera.z);
        
        gFont.glPrintf(gl, 106401, string);

        // Print out the vector that points from the light source to the intersection point.
        string = "vLightSourceToIntersect = " + twoFracsMax(gCamera.vLightSourceToIntersect.x
                ", " + twoFracsMax(gCamera.vLightSourceToIntersect.y", " 
                twoFracsMax(gCamera.vLightSourceToIntersect.z);
        
        gFont.glPrintf(gl, 106201, string);

        // Let everyone know the below matrix is the model view matrix
        string = "GL_MODELVIEW_MATRIX";
        gFont.glPrintf(gl, 105801, string);

        // Print out row 1 of the model view matrix
        string = twoFracsMax(modelMatrix[0]) ", " + twoFracsMax(modelMatrix[1]) 
                ", " + twoFracsMax(modelMatrix[2]) ", " 
                twoFracsMax(modelMatrix[3]);
        gFont.glPrintf(gl, 105601, string);

        // Print out row 2 of the model view matrix
        string = twoFracsMax(modelMatrix[4]) ", " + twoFracsMax(modelMatrix[5]) 
                ", " + twoFracsMax(modelMatrix[6]) ", " 
                twoFracsMax(modelMatrix[7]);
        gFont.glPrintf(gl, 105401, string);

        // Print out row 3 of the model view matrix
        string = twoFracsMax(modelMatrix[8]) ", " + twoFracsMax(modelMatrix[9]) 
                ", " + twoFracsMax(modelMatrix[10]) ", " 
                twoFracsMax(modelMatrix[11]);
        gFont.glPrintf(gl, 105201, string);

        // Print out row 4 of the model view matrix
        string = twoFracsMax(modelMatrix[12]) ", " + twoFracsMax(modelMatrix[13]) 
                ", " + twoFracsMax(modelMatrix[14]) ", " 
                twoFracsMax(modelMatrix[15]);
        
        gFont.glPrintf(gl, 105001, string);

        // Let everyone know the below matrix is the projection matrix
        string = "GL_PROJECTION_MATRIX";
        gFont.glPrintf(gl, 104601, string);

        // Print out row 1 of the projection view matrix
        string = twoFracsMax(projMatrix[0]) ", " + twoFracsMax(projMatrix[1]) 
                ", " + twoFracsMax(projMatrix[2]) ", " 
                twoFracsMax(projMatrix[3]);
        
        gFont.glPrintf(gl, 104401, string);

        // Print out row 2 of the projection view matrix
        string = twoFracsMax(projMatrix[4]) ", " + twoFracsMax(projMatrix[5]) 
                ", " + twoFracsMax(projMatrix[6]) ", " 
                twoFracsMax(projMatrix[7]);
        
        gFont.glPrintf(gl, 104201, string);

        // Print out row 3 of the projection view matrix
        string = twoFracsMax(projMatrix[8]) ", " + twoFracsMax(projMatrix[9]) 
                ", " + twoFracsMax(projMatrix[10]) ", " 
                twoFracsMax(projMatrix[11]);
        
        gFont.glPrintf(gl, 104001, string);

        // Print out row 4 of the projection view matrix
        string = twoFracsMax(projMatrix[12]) ", " + twoFracsMax(projMatrix[13]) 
                ", " + twoFracsMax(projMatrix[14]) ", " 
                twoFracsMax(projMatrix[15]);
        
        gFont.glPrintf(gl, 103801, string);

        // Let everyone know the below values are the Frustum clipping planes
        gFont.glPrintf(gl, 103201"FRUSTUM CLIPPING PLANES");

        // Print out the right clipping plane
        string = twoFracsMax(gCamera.m_Frustum[0][0]) ", " 
                twoFracsMax(gCamera.m_Frustum[0][1]) ", " 
                twoFracsMax(gCamera.m_Frustum[0][2]) ", " 
                twoFracsMax(gCamera.m_Frustum[0][3]);
        
        gFont.glPrintf(gl, 103001, string);

        // Print out the left clipping plane
        string = twoFracsMax(gCamera.m_Frustum[1][0]) ", " 
                twoFracsMax(gCamera.m_Frustum[1][1]) ", " 
                twoFracsMax(gCamera.m_Frustum[1][2]) ", " 
                twoFracsMax(gCamera.m_Frustum[1][3]);
        
        gFont.glPrintf(gl, 102801, string);

        // Print out the bottom clipping plane
        string = twoFracsMax(gCamera.m_Frustum[2][0]) ", " 
                twoFracsMax(gCamera.m_Frustum[2][1]) ", " 
                twoFracsMax(gCamera.m_Frustum[2][2]) ", " 
                twoFracsMax(gCamera.m_Frustum[2][3]);
        
        gFont.glPrintf(gl, 102601, string);

        // Print out the top clipping plane
        string = twoFracsMax(gCamera.m_Frustum[3][0]) ", " 
                twoFracsMax(gCamera.m_Frustum[3][1]) ", " 
                twoFracsMax(gCamera.m_Frustum[3][2]) ", " 
                twoFracsMax(gCamera.m_Frustum[3][3]);
        
        gFont.glPrintf(gl, 102401, string);

        // Print out the far clipping plane
        string = twoFracsMax(gCamera.m_Frustum[4][0]) ", " 
                twoFracsMax(gCamera.m_Frustum[4][1]) ", " 
                twoFracsMax(gCamera.m_Frustum[4][2]) ", " 
                twoFracsMax(gCamera.m_Frustum[4][3]);
        
        gFont.glPrintf(gl, 102201, string);

        // Print out the near clipping plane
        string = twoFracsMax(gCamera.m_Frustum[5][0]) ", " 
                twoFracsMax(gCamera.m_Frustum[5][1]) ", " 
                twoFracsMax(gCamera.m_Frustum[5][2]) ", " 
                twoFracsMax(gCamera.m_Frustum[5][3]);
        
        gFont.glPrintf(gl, 102001, string);

        if (gFrames >= 100) {  // if we are due for another FPS update
            gCurrentTime = System.currentTimeMillis()// Get the current time
            // Find the difference between the start and end times
            DiffTime = (float) (gCurrentTime - gStartTime);            
            gFPS = (gFrames / DiffTime1000.0f// Compute the FPS
            gStartTime = gCurrentTime; // Set the current start time to the current time
            gFrames = 1;   // Set the number of frames to 1
        else {
            // We are not due to for another update so add one to the frame count
            gFrames++; 
        }

        // Print out the FPS
        string = "FPS " + twoFracsMax(gFPS);
        gFont.glPrintf(gl, 101601, string);
    }

    private float twoFracsMax(float f) {
        return (int) (100 * f100f;
    }

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

        gCamera.m_WindowHeight = height;  // The camera needs to know the window height
        gCamera.m_WindowWidth = width;   // The camera needs to know the window width

        height = (height == 0: height;

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

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

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

 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.