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
Sitemap
Java Network
Java Forums
Java Tips 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: 769
Java SE Tips: 614
Java ME Tips: 201
Java EE Tips: 184
Other API Tips: 779
Java Applications: 298
Java Libraries: 209
Java Games: 16
Book Reviews:
 
 
 
Shadows - NeHe Tutorial JOGL Port E-mail
User Rating: / 0
PoorBest 

This example shows how to create shadows with JOGL.

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

/*--.          .-"-.
/   o_O        / O o \
\_  (__\       \_ v _/
//   \\        //   \\
((     ))      ((     ))
¤¤¤¤¤¤¤¤¤¤¤¤¤¤--""---""--¤¤¤¤--""---""--¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
¤                 |||            |||                             ¤
¤                  |              |                              ¤
¤                                                                ¤
¤ Programmer:Abdul Bezrati                                       ¤
¤ Program   :Nehe's 27th 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°--¤¤*/

import demos.common.GLDisplay;

/**
 @author Abdul Bezrati
 */
public class Lesson27 {
    public static void main(String[] args) {
        GLDisplay neheGLDisplay = GLDisplay.createGLDisplay("Lesson 27: Shadows");
        Renderer renderer = new Renderer();
        InputHandler inputHandler = new InputHandler(renderer, neheGLDisplay);
        neheGLDisplay.addGLEventListener(renderer);
        neheGLDisplay.addKeyListener(inputHandler);
        neheGLDisplay.start();
    }
}


package demos.nehe.lesson27;

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 glDisplay) {
        this.renderer = renderer;
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)
                "Decrease X-axis rotation speed");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)
                "Increase X-axis rotation speed");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)
                "Decrease Y-axis rotation speed");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0)
                "Increase Y-axis rotation speed");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_L, 0)
                "Move light right");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_J, 0)
                "Move light left");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_I, 0)
                "Move light up");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_K, 0)
                "Move light down");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_O, 0)
                "Move light forward");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_U, 0)
                "Move light backward");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_D, 0)
                "Move ball right");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_A, 0)"Move ball left");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_W, 0)"Move ball up");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_S, 0)"Move ball down");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_E, 0)"Move ball forward");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0)"Move ball backward");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD6, 0)"Move cross right");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD4, 0)"Move cross left");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD8, 0)"Move cross up");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD5, 0)"Move cross down");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD9, 0)"Move cross forward");
        
        glDisplay.registerKeyStrokeForHelp(
                KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD7, 0)"Move cross backward");
    }
    
    public void keyPressed(KeyEvent e) {
        processKeyEvent(e, true);
    }
    
    public void keyReleased(KeyEvent e) {
        processKeyEvent(e, false);
    }
    
    private void processKeyEvent(KeyEvent e, boolean pressed) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_UP:
                renderer.decreaseXspeed(pressed);
                break;
            case KeyEvent.VK_DOWN:
                renderer.increaseXspeed(pressed);
                break;
            case KeyEvent.VK_RIGHT:
                renderer.increaseYspeed(pressed);
                break;
            case KeyEvent.VK_LEFT:
                renderer.decreaseYspeed(pressed);
                break;
                // Adjust Light's Position
            case KeyEvent.VK_L:
                renderer.translateLightRight(pressed);   // 'L' Moves Light Right
                break;
            case KeyEvent.VK_J:
                renderer.translateLightLeft(pressed);    // 'J' Moves Light Left
                break;
                
            case KeyEvent.VK_I:
                renderer.translateLightUp(pressed);      // 'I' Moves Light Up
                break;
            case KeyEvent.VK_K:
                renderer.translateLightDown(pressed);    // 'K' Moves Light Down
                break;
                
            case KeyEvent.VK_O:
                // 'O' Moves Light Toward Viewer
                renderer.translateLightForward(pressed)
                break;
            case KeyEvent.VK_U:
                // 'U' Moves Light Away From Viewer
                renderer.translateLightBackward(pressed)
                break;
                
                // Adjust Object's Position
            case KeyEvent.VK_NUMPAD6:
                // 'Numpad6' Move Object Right
                renderer.translateObjectRight(pressed);  
                break;
            case KeyEvent.VK_NUMPAD4:
                // 'Numpad4' Move Object Left
                renderer.translateObjectLeft(pressed);  
                break;
                
            case KeyEvent.VK_NUMPAD8:
                renderer.translateObjectUp(pressed);  // 'Numpad8' Move Object Up
                break;
            case KeyEvent.VK_NUMPAD5:
                // 'Numpad5' Move Object Down
                renderer.translateObjectDown(pressed);  
                break;
                
            case KeyEvent.VK_NUMPAD9:
                // 'Numpad9' Move Object Toward Viewer
                renderer.translateObjectForward(pressed);  
                break;
            case KeyEvent.VK_NUMPAD7:
                // 'Numpad7' Move Object Away From Viewer
                renderer.translateObjectBackward(pressed);  
                break;
                
                // Adjust Ball's Position
            case KeyEvent.VK_D:
                renderer.translateSphereRight(pressed);  // 'D' Move Ball Right
                break;
            case KeyEvent.VK_A:
                renderer.translateSphereLeft(pressed);  // 'A' Move Ball Left
                break;
                
            case KeyEvent.VK_W:
                renderer.translateSphereUp(pressed);  // 'W' Move Ball Up
                break;
            case KeyEvent.VK_S:
                renderer.translateSphereDown(pressed);  // 'S' Move Ball Down
                break;
                
            case KeyEvent.VK_E:
                // 'E' Move Ball Toward Viewer
                renderer.translateSphereForward(pressed);  
                break;
            case KeyEvent.VK_Q:
                // 'Q' Move Ball Away From Viewer
                renderer.translateSphereBackward(pressed);  
                break;
        }
    }
}


package demos.nehe.lesson27;

import demos.common.ResourceRetriever;
import javax.media.opengl.GL;

import java.io.IOException;
import java.io.InputStream;
import java.util.StringTokenizer;

class Object3D {
    private int nPlanes, nPoints;
    private Point points[] new Point[100];
    private Plane planes[] new Plane[100];

    public Object3D() {
        for (int i = 0; i < 100; i++) {
            points[inew Point();
            planes[inew Plane();
        }
    }

    // load object
    public static Object3D readObject(String stthrows IOException {
        StringBuffer data = new StringBuffer();
        InputStream inputStream = ResourceRetriever.getResourceAsStream(st);
        int info;
        while ((info = inputStream.read()) != -1)
            data.append((charinfo);
        inputStream.close();

        Object3D o = new Object3D();

        //points
        StringTokenizer tokenizer = new StringTokenizer(data.toString());
        o.nPoints = Integer.parseInt(tokenizer.nextToken());

        for (int i = 1; i <= o.nPoints; i++) {
            o.points[i].x = Float.parseFloat(tokenizer.nextToken());
            o.points[i].y = Float.parseFloat(tokenizer.nextToken());
            o.points[i].z = Float.parseFloat(tokenizer.nextToken());
        }

        //planes
        o.nPlanes = Integer.parseInt(tokenizer.nextToken());

        for (int i = 0; i < o.nPlanes; i++) {
            o.planes[i].p[0= Integer.parseInt(tokenizer.nextToken());
            o.planes[i].p[1= Integer.parseInt(tokenizer.nextToken());
            o.planes[i].p[2= Integer.parseInt(tokenizer.nextToken());

            o.planes[i].normals[0].x = Float.parseFloat(tokenizer.nextToken());
            o.planes[i].normals[0].y = Float.parseFloat(tokenizer.nextToken());
            o.planes[i].normals[0].z = Float.parseFloat(tokenizer.nextToken());
            o.planes[i].normals[1].x = Float.parseFloat(tokenizer.nextToken());
            o.planes[i].normals[1].y = Float.parseFloat(tokenizer.nextToken());
            o.planes[i].normals[1].z = Float.parseFloat(tokenizer.nextToken());
            o.planes[i].normals[2].x = Float.parseFloat(tokenizer.nextToken());
            o.planes[i].normals[2].y = Float.parseFloat(tokenizer.nextToken());
            o.planes[i].normals[2].z = Float.parseFloat(tokenizer.nextToken());
        }

        o.setConnectivity();  // Set Face To Face Connectivity
        o.calcPlanes();

        return o;
    }

    // connectivity procedure - based on Gamasutra's article
    // hard to explain here
    public void setConnectivity() {
        for (int i = 0; i < nPlanes - 1; i++)
            for (int j = i + 1; j < nPlanes; j++)
                for (int ki = 0; ki < 3; ki++)
                    if (planes[i].neigh[ki== 0) {
                        for (int kj = 0; kj < 3; kj++) {
                            int p1i = ki;
                            int p1j = kj;
                            int p2i = (ki + 13;
                            int p2j = (kj + 13;

                            p1i = planes[i].p[p1i];
                            p2i = planes[i].p[p2i];
                            p1j = planes[j].p[p1j];
                            p2j = planes[j].p[p2j];

                            int P1i = ((p1i + p2i- Math.abs(p1i - p2i)) 2;
                            int P2i = ((p1i + p2i+ Math.abs(p1i - p2i)) 2;
                            int P1j = ((p1j + p2j- Math.abs(p1j - p2j)) 2;
                            int P2j = ((p1j + p2j+ Math.abs(p1j - p2j)) 2;

                            if ((P1i == P1j&& (P2i == P2j)) { //they are neighbours
                                planes[i].neigh[ki= j + 1;
                                planes[j].neigh[kj= i + 1;
                            }
                        }
                    }
    }

    private void calcPlanes() {
        for (int i = 0; i < nPlanes; i++)   // Loop Through All Object Planes
            calcPlane(planes[i]);          // Compute Plane Equations For All Faces
    }

    // function for computing a plane equation given 3 points
    private void calcPlane(Plane plane) {
        Point v[] new Point[4];

        for (int i = 0; i < 3; i++) {
            v[i + 1new Point();
            v[i + 1].x = points[plane.p[i]].x;
            v[i + 1].y = points[plane.p[i]].y;
            v[i + 1].z = points[plane.p[i]].z;
        }
        plane.PlaneEq.a = v[1].y * (v[2].z - v[3].z+ v[2].y * (v[3].z - v[1].z)
                + v[3].y * (v[1].z - v[2].z);
        
        plane.PlaneEq.b = v[1].z * (v[2].x - v[3].x+ v[2].z * (v[3].x - v[1].x)
                + v[3].z * (v[1].x - v[2].x);
        plane.PlaneEq.c = v[1].x * (v[2].y - v[3].y+ v[2].x * (v[3].y - v[1].y)
                + v[3].x * (v[1].y - v[2].y);
        
        plane.PlaneEq.d = -(v[1].x * (v[2].y * v[3].z - v[3].y * v[2].z+
                v[2].x * (v[3].y * v[1].z - v[1].y * v[3].z+
                v[3].x * (v[1].y * v[2].z - v[2].y * v[1].z));
    }

    // procedure for drawing the object - very simple
    public void draw(GL gl) {
        gl.glBegin(GL.GL_TRIANGLES);
        for (int i = 0; i < nPlanes; i++) {
            for (int j = 0; j < 3; j++) {
                gl.glNormal3f(planes[i].normals[j].x,
                        planes[i].normals[j].y,
                        planes[i].normals[j].z);
                gl.glVertex3f(points[planes[i].p[j]].x,
                        points[planes[i].p[j]].y,
                        points[planes[i].p[j]].z);
            }
        }
        gl.glEnd();
    }

    public void castShadow(GL gl, float[] lp) {
        Point v1 = new Point();
        Point v2 = new Point();

        //set visual parameter
        for (int i = 0; i < nPlanes; i++) {
            // chech to see if light is in front or behind the plane (face plane)
            float side = planes[i].PlaneEq.a * lp[0+
                    planes[i].PlaneEq.b * lp[1+
                    planes[i].PlaneEq.c * lp[2+
                    planes[i].PlaneEq.d * lp[3];
            if (side > 0)
                planes[i].visible = true;
            else
                planes[i].visible = false;
        }

        gl.glDisable(GL.GL_LIGHTING);
        gl.glDepthMask(false);
        gl.glDepthFunc(GL.GL_LEQUAL);

        gl.glEnable(GL.GL_STENCIL_TEST);
        gl.glColorMask(false, false, false, false);
        gl.glStencilFunc(GL.GL_ALWAYS, 10xffffffff);

        // first pass, stencil operation increases stencil value
        gl.glFrontFace(GL.GL_CCW);
        gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_INCR);

        for (int i = 0; i < nPlanes; i++) {
            if (planes[i].visible)
                for (int j = 0; j < 3; j++) {
                    int k = planes[i].neigh[j];
                    if ((k == 0|| (!planes[k - 1].visible)) {
                        // here we have an edge, we must draw a polygon
                        int p1 = planes[i].p[j];
                        int jj = (j + 13;
                        int p2 = planes[i].p[jj];

                        //calculate the length of the vector
                        v1.x = (points[p1].x - lp[0]) 100;
                        v1.y = (points[p1].y - lp[1]) 100;
                        v1.z = (points[p1].z - lp[2]) 100;

                        v2.x = (points[p2].x - lp[0])