[COMMITTED] Changes to ProjectTextureUtil

One question I have is if by having imports from the renderer libraries in this class, would it require both LWJGL and JOGL to be on the classpath? My hunch is yes. If it does, then we need to move the two concrete implementations into their own classes to avoid this.



To test, try removing JOGL from the classpath and then run the test using LWJGL to see if you get any ClassDefNotFound exceptions, and the other way around.

nymon said:

One question I have is if by having imports from the renderer libraries in this class, would it require both LWJGL and JOGL to be on the classpath? My hunch is yes. If it does, then we need to move the two concrete implementations into their own classes to avoid this.

Yes please, I don't want to deploy LWJGL only to avoid a ClassNotFoundException.

GOOD POINT nymon, problems with testing though:

  1. Im on a MAC and JOGL is included with the OS.
  2. Removing LWJGL out of the classpath makes none of the tests work (the startup dialog is dependent on it…)



    How about this then:


Index: ProjectedTextureUtil.java
--- ProjectedTextureUtil.java Base (BASE)
+++ ProjectedTextureUtil.java Locally Modified (Based On LOCAL)
@@ -58,21 +58,21 @@
  */
 public abstract class ProjectedTextureUtil {
 
+    private static ProjectedTextureUtil currentImplementation = null;
+    //
     private static Matrix4f lightProjectionMatrix = new Matrix4f();
     private static Matrix4f lightViewMatrix = new Matrix4f();
     private static Matrix4f biasMatrix = new Matrix4f( 0.5f, 0.0f, 0.0f, 0.0f,
             0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.5f,
             1.0f ); // bias from [-1, 1] to [0, 1]
 
-    // UTILS
-    private static final FloatBuffer tmp_FloatBuffer = BufferUtils.createFloatBuffer( 16 );
-    private static Vector3f localDir = new Vector3f();
-    private static Vector3f localLeft = new Vector3f();
-    private static Vector3f localUp = new Vector3f();
-    private static IntBuffer matrixModeBuffer = BufferUtils.createIntBuffer( 16 );
-    private static int savedMatrixMode = 0;
-    //
-    private static ProjectedTextureUtil currentImplementation = null;
+    // Shared UTILS
+    protected final FloatBuffer tmp_FloatBuffer = BufferUtils.createFloatBuffer( 16 );
+    protected final Vector3f localDir = new Vector3f();
+    protected final Vector3f localLeft = new Vector3f();
+    protected final Vector3f localUp = new Vector3f();
+    protected final IntBuffer matrixModeBuffer = BufferUtils.createIntBuffer( 16 );
+    protected int savedMatrixMode = 0;
 
     /**
      * Updated texture matrix on the provided texture
@@ -155,10 +155,11 @@
             currentImplementation = new JOGLProjectedTextureUtil();
         }
     }
+}
 
 
 
-    private static class LWJGLProjectedTextureUtil extends ProjectedTextureUtil {
+class LWJGLProjectedTextureUtil extends ProjectedTextureUtil {
 
         protected void _matrixLookAt_( Vector3f location, Vector3f at,
                 Vector3f up, Matrix4f result ) {
@@ -257,26 +258,27 @@
             restoreMatrixMode();
         }
 
-        private static void saveMatrixMode() {
+    private void saveMatrixMode() {
             matrixModeBuffer.rewind();
             GL11.glGetInteger( GL11.GL_MATRIX_MODE, matrixModeBuffer );
             savedMatrixMode = matrixModeBuffer.get( 0 );
         }
 
-        private static void restoreMatrixMode() {
+    private void restoreMatrixMode() {
             getRecord().switchMode( savedMatrixMode );
         }
 
-        private static com.jme.scene.state.lwjgl.records.RendererRecord getRecord() {
-            return (com.jme.scene.state.lwjgl.records.RendererRecord) DisplaySystem.getDisplaySystem().getCurrentContext().getRendererRecord();
+    private com.jme.scene.state.lwjgl.records.RendererRecord getRecord() {
+        return (com.jme.scene.state.lwjgl.records.RendererRecord)
+                DisplaySystem.getDisplaySystem().getCurrentContext().getRendererRecord();
         }
     }
 
 
 
-    private static class JOGLProjectedTextureUtil extends ProjectedTextureUtil {
+class JOGLProjectedTextureUtil extends ProjectedTextureUtil {
 
-        private static final javax.media.opengl.glu.GLU GLU = new javax.media.opengl.glu.GLU();
+    private final javax.media.opengl.glu.GLU GLU = new javax.media.opengl.glu.GLU();
 
         protected void _matrixLookAt_( Vector3f location, Vector3f at,
                 Vector3f up, Matrix4f result ) {
@@ -378,22 +380,22 @@
             restoreMatrixMode();
         }
 
-        private static void saveMatrixMode() {
+    private void saveMatrixMode() {
             matrixModeBuffer.rewind();
             getGL().glGetIntegerv( getGL().GL_MATRIX_MODE, matrixModeBuffer );
             savedMatrixMode = matrixModeBuffer.get( 0 );
         }
 
-        private static void restoreMatrixMode() {
+    private void restoreMatrixMode() {
             getRecord().switchMode( savedMatrixMode );
         }
 
-        private static com.jme.scene.state.jogl.records.RendererRecord getRecord() {
-            return (com.jme.scene.state.jogl.records.RendererRecord) DisplaySystem.getDisplaySystem().getCurrentContext().getRendererRecord();
+    private com.jme.scene.state.jogl.records.RendererRecord getRecord() {
+        return (com.jme.scene.state.jogl.records.RendererRecord)
+                DisplaySystem.getDisplaySystem().getCurrentContext().getRendererRecord();
         }
 
-        private static javax.media.opengl.GL getGL() {
+    private javax.media.opengl.GL getGL() {
             return GLU.getCurrentGL();
         }
     }
-}


Basically the inner classes become outer classes (which makes them actual classes), and are still not accessible to the user.

Yes please, I don't want to deploy LWJGL only to avoid a ClassNotFoundException.

jME depends on LWJGL a lot, in a way JOGL is an 'add-on' to it; although yes (depending on the functionality required) it can run w/o LWJGL quite easily, say that for just about any other engine out there.  Also, I will take the time to say this because I can't stand it any longer.  I have noticed you knocking jME several times recently and I ask you to please knock it off, I for one kind of take it personally (and I am sure there are others) but am too nice to say anything about it; and I am not really even an 'author' or have any right to take it personally.  If you like the ogre3D engine more or think your own is better use one of those....
basixs said:

Yes please, I don't want to deploy LWJGL only to avoid a ClassNotFoundException.

jME depends on LWJGL a lot, in a way JOGL is an 'add-on' to it; although yes (depending on the functionality required) it can run w/o LWJGL quite easily, say that for just about any other engine out there. 

I have always used JME without LWJGL, it seems to work for the moment.

basixs said:
Also, I will take the time to say this because I can't stand it any longer.  I have noticed you knocking jME several times recently and I ask you to please knock it off, I for one kind of take it personally (and I am sure there are others) but am too nice to say anything about it; and I am not really even an 'author' or have any right to take it personally.  If you like the ogre3D engine more or think your own is better use one of those....

Sorry, I didn't want to hurt anyone, I should have been more precise.

JME 2.0 is an excellent engine and if I thought mine or any other engine was better, I wouldn't nor use JME neither invest some time in fixing bugs in JME. I don't want to rewrite existing features, I don't want to reinvent the wheel, that is why I am switching step by step from my own very limited engine to this tougher engine (with plenty of features I need). I didn't use JME at the beginning of my project in October 2006 because some people responsible of JME refused my help to develop the JOGL option inside JME and because I wanted to implement my algorithms in a worse but simpler engine to have a better control on what I was doing and to improve my knowledge of OpenGL. I'm really sorry if you believed that I was insulting the great job that has been done on JME. I meant that I want "le beurre et l'argent du beurre" as we say in French -> "the butter and the money to buy the butter", I want both to use JME and to keep at least the main algorithms I spent a lot of time to implement in my own engine and I'm a bit stressed because if I use JME wrongly, I might get worse performance than with my engine, it will mainly be my fault, not the fault of JME. I have worked more than 2 years on my game, I don't want to get worse frame rate, I sleep only a little, I'm really very sorry if I said something that made you think I would prefer using another engine. I don't know Ogre4J, I spoke once about Ardor3D. Is it clear now? Sorry for this deflection.

wow, thanx for the heart felt apology; I completley understand your view point now :).


I wanted to implement my algorithms in a worse but simpler engine to have a better control on what I was doing and to improve my knowledge of OpenGL

funny, my teachers would have wanted the same thing; I'm surprised you met with resistance, but then again timing is everything sometimes...

I sleep only a little

Me neither :)
(we should be nicer to ourselves ;))


/*
 * Copyright (c) 2003-2008 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package ProjectedTexture;

import com.jme.image.Texture;
import com.jme.math.Matrix4f;
import com.jme.math.Vector3f;
import com.jme.renderer.AbstractCamera;
import com.jme.renderer.Renderer;
import com.jme.system.DisplaySystem;



/**
 * <code>ProjectedTextureUtil</code>
 *
 * @author Rikard Herlitz (MrCoder)
 *
 * @author Joshua Ellen (basixs)
 * Abstracted (removed direct calls to openGL renderer)
 *
 */
public class ProjectedTextureUtil {

    private static final Vector3f[] savedCamera = new Vector3f[ 4 ];
   

    static {
        for( int i = 0; i < savedCamera.length; ++i ){
            savedCamera[i] = new Vector3f();
        }
    }
    //
    private static AbstractCamera camera = null;
    private static Matrix4f lightProjectionMatrix = new Matrix4f();
    private static Matrix4f lightViewMatrix = new Matrix4f();
    private static Matrix4f biasMatrix = new Matrix4f( 0.5f, 0.0f, 0.0f, 0.0f,
            0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.5f,
            1.0f ); // bias from [-1, 1] to [0, 1]

    /**
     * Updated texture matrix on the provided texture
     *
     * @param texture
     *            Texture to update texturematrix on
     * @param fov
     *            Projector field of view, in angles
     * @param aspect
     *            Projector frustum aspect ratio
     * @param near
     *            Projector frustum near plane
     * @param far
     *            Projector frustum far plane
     * @param pos
     *            Projector position
     * @param aim
     *            Projector look at position
     */
    public static void updateProjectedTexture( Texture texture, float fov,
            float aspect, float near, float far, Vector3f pos, Vector3f aim,
            Vector3f up ) {

        if( camera == null ){
            final Renderer renderer = DisplaySystem.getDisplaySystem().getRenderer();
            camera = (AbstractCamera) renderer.createCamera( renderer.getWidth(), renderer.getHeight() );
            camera.setDataOnly( true );
        }

        matrixLookAt( pos, aim, up, lightViewMatrix );
        matrixPerspective( fov, aspect, near, far, lightProjectionMatrix );

        texture.getMatrix().set(
                lightViewMatrix.multLocal( lightProjectionMatrix ).multLocal(
                biasMatrix ) ).transposeLocal();
    }

    private static void matrixLookAt( Vector3f location, Vector3f at,
            Vector3f up, Matrix4f result ) {

        camera.setLocation( location );
        camera.lookAt( at, up );
       
        result.set( camera.getModelViewMatrix() );
    }

    private static void matrixPerspective( float fovY, float aspect,
            float near, float far, Matrix4f result ) {

        camera.setFrustumPerspective( fovY, aspect, near, far );
       
        result.set( camera.getProjectionMatrix() );
    }
   
}



So simply its almost embarrassing ;)

Awesome. And does this render correctly in JOGL, or do we still have the funky coloring issue? Great work baxis!



I tried using your class (it's not a patch btw) but there are function calls from the ProjectedGrid class that no longer exist. Did you have changes to that class as well?

Thanks for spotting that nymon :slight_smile:



Heres the new (tested) patch


Index: ProjectedTextureUtil.java
--- ProjectedTextureUtil.java Base (BASE)
+++ ProjectedTextureUtil.java Locally Modified (Based On LOCAL)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2008 jMonkeyEngine
+ * Copyright (c) 2003-2009 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,20 +31,12 @@
  */
 package com.jmex.effects;
 
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-
-import org.lwjgl.opengl.GL11;
-
 import com.jme.image.Texture;
-import com.jme.math.FastMath;
 import com.jme.math.Matrix4f;
 import com.jme.math.Vector3f;
+import com.jme.renderer.AbstractCamera;
 import com.jme.renderer.Renderer;
-import com.jme.renderer.jogl.JOGLRenderer;
-import com.jme.renderer.lwjgl.LWJGLRenderer;
 import com.jme.system.DisplaySystem;
-import com.jme.util.geom.BufferUtils;
 
 
 
@@ -53,27 +45,19 @@
  *
  * @author Rikard Herlitz (MrCoder)
  *
- * Dual implementation framework:
  * @author Joshua Ellen (basixs)
+ * [1-16-2009] - Abstracted, removed direct calls to openGL
+ *
  */
-public abstract class ProjectedTextureUtil {
+public class ProjectedTextureUtil {
 
+    private static AbstractCamera camera = null;
     private static Matrix4f lightProjectionMatrix = new Matrix4f();
     private static Matrix4f lightViewMatrix = new Matrix4f();
     private static Matrix4f biasMatrix = new Matrix4f( 0.5f, 0.0f, 0.0f, 0.0f,
             0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.5f,
             1.0f ); // bias from [-1, 1] to [0, 1]
 
-    // UTILS
-    private static final FloatBuffer tmp_FloatBuffer = BufferUtils.createFloatBuffer( 16 );
-    private static Vector3f localDir = new Vector3f();
-    private static Vector3f localLeft = new Vector3f();
-    private static Vector3f localUp = new Vector3f();
-    private static IntBuffer matrixModeBuffer = BufferUtils.createIntBuffer( 16 );
-    private static int savedMatrixMode = 0;
-    //
-    private static ProjectedTextureUtil currentImplementation = null;
-
     /**
      * Updated texture matrix on the provided texture
      *
@@ -96,304 +80,100 @@
             float aspect, float near, float far, Vector3f pos, Vector3f aim,
             Vector3f up ) {
 
-        checkImplementation();
-        matrixPerspective( fov, aspect, near, far, lightProjectionMatrix );
         matrixLookAt( pos, aim, up, lightViewMatrix );
+        matrixProjection( fov, aspect, near, far, lightProjectionMatrix );
+
         texture.getMatrix().set(
                 lightViewMatrix.multLocal( lightProjectionMatrix ).multLocal(
                 biasMatrix ) ).transposeLocal();
     }
 
+    /**
+     * Populates a <code>Matrix4f</code> with the proper look at transformations
+     * from the ModelView matrix.
+     * @param location the 'Where' in result matrix
+     * @param at the 'At' in the result matrix
+     * @param up the world up
+     * @param result the altered <code>Matrix4f</code>
+     */
     public static void matrixLookAt( Vector3f location, Vector3f at,
             Vector3f up, Matrix4f result ) {
-        checkImplementation();
-        currentImplementation._matrixLookAt_( location, at, up, result );
-    }
 
-    public static void matrixPerspective( float fovY, float aspect, float near,
-            float far, Matrix4f result ) {
-        checkImplementation();
-        currentImplementation._matrixPerspective_( fovY, aspect, near, far, result );
-    }
+        checkCamera();
 
-    public static void matrixProjection( float fovY, float aspect, float near,
-            float far, Matrix4f result ) {
-        checkImplementation();
-        currentImplementation._matrixProjection_( fovY, aspect, near, far, result );
-    }
+        camera.setLocation( location );
+        camera.lookAt( at, up );
 
-    public static void matrixFrustum( float frustumLeft, float frustumRight,
-            float frustumBottom, float frustumTop, float frustumNear,
-            float frustumFar, Matrix4f result ) {
-        checkImplementation();
-        currentImplementation._matrixFrustum_( frustumLeft, frustumRight,
-                frustumBottom, frustumTop, frustumNear, frustumFar, result );
+        result.set( camera.getModelViewMatrix() );
     }
 
-    protected abstract void _matrixLookAt_( Vector3f location, Vector3f at,
-            Vector3f up, Matrix4f result );
+    /**
+     * Populates a <code>Matrix4f</code> with the proper frustum transformations
+     * from the ModelView matrix.
+     * @param fovY the Field of View
+     * @param aspect the aspect ratio
+     * @param near the near plane of the frustum
+     * @param far the far frame of the frustum
+     * @param result the altered <code>Matrix4f</code>
+     */
+    public static void matrixPerspective( float fovY, float aspect,
+            float near, float far, Matrix4f result ) {
 
-    protected abstract void _matrixPerspective_( float fovY, float aspect,
-            float near, float far, Matrix4f result );
+        checkCamera();
 
-    protected abstract void _matrixProjection_( float fovY, float aspect,
-            float near, float far, Matrix4f result );
+        camera.setFrustumPerspective( fovY, aspect, near, far );
 
-    protected abstract void _matrixFrustum_( float frustumLeft,
-            float frustumRight, float frustumBottom, float frustumTop,
-            float frustumNear, float frustumFar, Matrix4f result );
-
-    private static void checkImplementation() {
-       
-        final Renderer renderer = DisplaySystem.getDisplaySystem().getRenderer();
-        if( renderer instanceof LWJGLRenderer &&
-                !( currentImplementation instanceof LWJGLProjectedTextureUtil ) ){
-            currentImplementation = new LWJGLProjectedTextureUtil();
-
-        } else if( renderer instanceof JOGLRenderer &&
-                !( currentImplementation instanceof JOGLProjectedTextureUtil ) ){
-            currentImplementation = new JOGLProjectedTextureUtil();
+        result.set( camera.getModelViewMatrix() );
         }
-    }
 
-
-
-    private static class LWJGLProjectedTextureUtil extends ProjectedTextureUtil {
-
-        protected void _matrixLookAt_( Vector3f location, Vector3f at,
-                Vector3f up, Matrix4f result ) {
-            localDir.set( at ).subtractLocal( location ).normalizeLocal();
-            localDir.cross( up, localLeft );
-            localLeft.cross( localDir, localUp );
-
-            saveMatrixMode();
-
-            // set view matrix
-            getRecord().switchMode( GL11.GL_MODELVIEW );
-            GL11.glPushMatrix();
-            GL11.glLoadIdentity();
-            org.lwjgl.util.glu.GLU.gluLookAt( location.x, location.y, location.z,
-                    at.x, at.y, at.z, localUp.x, localUp.y, localUp.z );
-
-            if( result != null ){
-                tmp_FloatBuffer.rewind();
-                GL11.glGetFloat( GL11.GL_MODELVIEW_MATRIX, tmp_FloatBuffer );
-                tmp_FloatBuffer.rewind();
-                result.readFloatBuffer( tmp_FloatBuffer );
-            }
-
-            GL11.glPopMatrix();
-            restoreMatrixMode();
-        }
-
-        protected void _matrixPerspective_( float fovY, float aspect, float near,
+    /**
+     * Populates a <code>Matrix4f</code> with the proper frustum transformations
+     * from the Projection matrix.
+     * @param fovY the Field of View
+     * @param aspect the aspect ratio
+     * @param near the near plane of the frustum
+     * @param far the far frame of the frustum
+     * @param result the altered <code>Matrix4f</code>
+     */
+    public static void matrixProjection( float fovY, float aspect, float near,
                 float far, Matrix4f result ) {
-            saveMatrixMode();
 
-            // set view matrix
-            getRecord().switchMode( GL11.GL_MODELVIEW );
-            GL11.glPushMatrix();
-            GL11.glLoadIdentity();
-            org.lwjgl.util.glu.GLU.gluPerspective( fovY, aspect, near, far );
+        checkCamera();
 
-            if( result != null ){
-                tmp_FloatBuffer.rewind();
-                GL11.glGetFloat( GL11.GL_MODELVIEW_MATRIX, tmp_FloatBuffer );
-                tmp_FloatBuffer.rewind();
-                result.readFloatBuffer( tmp_FloatBuffer );
-            }
+        camera.setFrustumPerspective( fovY, aspect, near, far );
 
-            GL11.glPopMatrix();
-            restoreMatrixMode();
+        result.set( camera.getProjectionMatrix() );
         }
 
-        protected void _matrixProjection_( float fovY, float aspect, float near,
-                float far, Matrix4f result ) {
-            float h = FastMath.tan( fovY * FastMath.DEG_TO_RAD * .5f ) * near;
-            float w = h * aspect;
-            float frustumLeft = -w;
-            float frustumRight = w;
-            float frustumBottom = -h;
-            float frustumTop = h;
-            float frustumNear = near;
-            float frustumFar = far;
-
-            saveMatrixMode();
-            getRecord().switchMode( GL11.GL_PROJECTION );
-            GL11.glPushMatrix();
-            GL11.glLoadIdentity();
-            GL11.glFrustum( frustumLeft, frustumRight, frustumBottom, frustumTop,
-                    frustumNear, frustumFar );
-
-            if( result != null ){
-                tmp_FloatBuffer.rewind();
-                GL11.glGetFloat( GL11.GL_PROJECTION_MATRIX, tmp_FloatBuffer );
-                tmp_FloatBuffer.rewind();
-                result.readFloatBuffer( tmp_FloatBuffer );
-            }
-
-            GL11.glPopMatrix();
-            restoreMatrixMode();
-        }
-
-        protected void _matrixFrustum_( float frustumLeft, float frustumRight,
+    /**
+     * Populates a <code>Matrix4f</code> with the proper frustum transformations
+     * from the Projection matrix.
+     * @param frustumLeft the left plane of the frustum
+     * @param frustumRight the right plane of the frustum
+     * @param frustumBottom the bottom plane of the frustum
+     * @param frustumTop the top plane of the frustum
+     * @param frustumNear the near plane of the frustum
+     * @param frustumFar the far plane of the frustum
+     * @param result the altered <code>Matrix4f</code>
+     */
+    public static void matrixFrustum( float frustumLeft, float frustumRight,
                 float frustumBottom, float frustumTop, float frustumNear,
                 float frustumFar, Matrix4f result ) {
-            saveMatrixMode();
-            getRecord().switchMode( GL11.GL_PROJECTION );
-            GL11.glPushMatrix();
-            GL11.glLoadIdentity();
-            GL11.glFrustum( frustumLeft, frustumRight, frustumBottom, frustumTop,
-                    frustumNear, frustumFar );
 
-            if( result != null ){
-                tmp_FloatBuffer.rewind();
-                GL11.glGetFloat( GL11.GL_PROJECTION_MATRIX, tmp_FloatBuffer );
-                tmp_FloatBuffer.rewind();
-                result.readFloatBuffer( tmp_FloatBuffer );
-            }
+        checkCamera();
 
-            GL11.glPopMatrix();
-            restoreMatrixMode();
-        }
+        camera.setFrustum( frustumFar, frustumFar, frustumLeft, frustumRight,
+                frustumTop, frustumFar );
 
-        private static void saveMatrixMode() {
-            matrixModeBuffer.rewind();
-            GL11.glGetInteger( GL11.GL_MATRIX_MODE, matrixModeBuffer );
-            savedMatrixMode = matrixModeBuffer.get( 0 );
+        result.set( camera.getProjectionMatrix() );
         }
 
-        private static void restoreMatrixMode() {
-            getRecord().switchMode( savedMatrixMode );
+    private static void checkCamera() {
+        if( camera == null ){
+            final Renderer renderer = DisplaySystem.getDisplaySystem().getRenderer();
+            camera = (AbstractCamera) renderer.createCamera(
+                    renderer.getWidth(), renderer.getHeight() );
+            camera.setDataOnly( true );
         }
-
-        private static com.jme.scene.state.lwjgl.records.RendererRecord getRecord() {
-            return (com.jme.scene.state.lwjgl.records.RendererRecord) DisplaySystem.getDisplaySystem().getCurrentContext().getRendererRecord();
         }
     }
-
-
-
-    private static class JOGLProjectedTextureUtil extends ProjectedTextureUtil {
-
-        private static final javax.media.opengl.glu.GLU GLU = new javax.media.opengl.glu.GLU();
-
-        protected void _matrixLookAt_( Vector3f location, Vector3f at,
-                Vector3f up, Matrix4f result ) {
-
-            localDir.set( at ).subtractLocal( location ).normalizeLocal();
-            localDir.cross( up, localLeft );
-            localLeft.cross( localDir, localUp );
-
-            saveMatrixMode();
-
-            // set view matrix
-            getRecord().switchMode( getGL().GL_MODELVIEW );
-            getGL().glPushMatrix();
-            getGL().glLoadIdentity();
-            GLU.gluLookAt( location.x, location.y, location.z,
-                    at.x, at.y, at.z, localUp.x, localUp.y, localUp.z );
-
-            if( result != null ){
-                tmp_FloatBuffer.rewind();
-                getGL().glGetFloatv( getGL().GL_MODELVIEW_MATRIX, tmp_FloatBuffer );
-                tmp_FloatBuffer.rewind();
-                result.readFloatBuffer( tmp_FloatBuffer );
-            }
-
-            getGL().glPopMatrix();
-            restoreMatrixMode();
-        }
-
-        protected void _matrixPerspective_( float fovY, float aspect, float near,
-                float far, Matrix4f result ) {
-
-            saveMatrixMode();
-
-            // set view matrix
-            getRecord().switchMode( getGL().GL_MODELVIEW );
-            getGL().glPushMatrix();
-            getGL().glLoadIdentity();
-            GLU.gluPerspective( fovY, aspect, near, far );
-
-            if( result != null ){
-                tmp_FloatBuffer.rewind();
-                getGL().glGetFloatv( getGL().GL_MODELVIEW_MATRIX, tmp_FloatBuffer );
-                tmp_FloatBuffer.rewind();
-                result.readFloatBuffer( tmp_FloatBuffer );
-            }
-
-            getGL().glPopMatrix();
-            restoreMatrixMode();
-        }
-
-        protected void _matrixProjection_( float fovY, float aspect, float near,
-                float far, Matrix4f result ) {
-            float h = FastMath.tan( fovY * FastMath.DEG_TO_RAD * .5f ) * near;
-            float w = h * aspect;
-            float frustumLeft = -w;
-            float frustumRight = w;
-            float frustumBottom = -h;
-            float frustumTop = h;
-            float frustumNear = near;
-            float frustumFar = far;
-
-            saveMatrixMode();
-            getRecord().switchMode( getGL().GL_PROJECTION );
-            getGL().glPushMatrix();
-            getGL().glLoadIdentity();
-            getGL().glFrustum( frustumLeft, frustumRight, frustumBottom, frustumTop,
-                    frustumNear, frustumFar );
-
-            if( result != null ){
-                tmp_FloatBuffer.rewind();
-                getGL().glGetFloatv( getGL().GL_PROJECTION_MATRIX, tmp_FloatBuffer );
-                tmp_FloatBuffer.rewind();
-                result.readFloatBuffer( tmp_FloatBuffer );
-            }
-
-            getGL().glPopMatrix();
-            restoreMatrixMode();
-        }
-
-        protected void _matrixFrustum_( float frustumLeft, float frustumRight,
-                float frustumBottom, float frustumTop, float frustumNear,
-                float frustumFar, Matrix4f result ) {
-
-            saveMatrixMode();
-            getRecord().switchMode( getGL().GL_PROJECTION );
-            getGL().glPushMatrix();
-            getGL().glLoadIdentity();
-            getGL().glFrustum( frustumLeft, frustumRight, frustumBottom, frustumTop,
-                    frustumNear, frustumFar );
-
-            if( result != null ){
-                tmp_FloatBuffer.rewind();
-                getGL().glGetFloatv( getGL().GL_PROJECTION_MATRIX, tmp_FloatBuffer );
-                tmp_FloatBuffer.rewind();
-                result.readFloatBuffer( tmp_FloatBuffer );
-            }
-
-            getGL().glPopMatrix();
-            restoreMatrixMode();
-        }
-
-        private static void saveMatrixMode() {
-            matrixModeBuffer.rewind();
-            getGL().glGetIntegerv( getGL().GL_MATRIX_MODE, matrixModeBuffer );
-            savedMatrixMode = matrixModeBuffer.get( 0 );
-        }
-
-        private static void restoreMatrixMode() {
-            getRecord().switchMode( savedMatrixMode );
-        }
-
-        private static com.jme.scene.state.jogl.records.RendererRecord getRecord() {
-            return (com.jme.scene.state.jogl.records.RendererRecord) DisplaySystem.getDisplaySystem().getCurrentContext().getRendererRecord();
-        }
-
-        private static javax.media.opengl.GL getGL() {
-            return GLU.getCurrentGL();
-        }
-    }
-}






The JOGL water test still has the green stuff in it, I guess I will look at that sometime.  Also, after a few seconds of playing w/ it I got this error:


Jan 16, 2009 12:01:48 AM com.jme.renderer.AbstractCamera <init>
INFO: Camera created.
Jan 16, 2009 12:01:57 AM class jmetest.effects.water.TestProjectedWater start()
SEVERE: Exception in game loop
java.util.NoSuchElementException
        at java.util.LinkedList.remove(LinkedList.java:644)
        at java.util.LinkedList.remove(LinkedList.java:360)
        at com.jmex.awt.input.AWTMouseInput.update(AWTMouseInput.java:195)
        at com.jme.input.InputSystem.update(InputSystem.java:67)
        at com.jme.app.BaseGame.start(BaseGame.java:81)
        at jmetest.effects.water.TestProjectedWater.main(TestProjectedWater.java:79)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at jmetest.TestChooser.start(TestChooser.java:465)
        at jmetest.TestChooser.main(TestChooser.java:444)
Jan 16, 2009 12:01:57 AM com.jme.app.BaseSimpleGame cleanup
INFO: Cleaning up resources.
Jan 16, 2009 12:01:57 AM com.jme.app.BaseGame start
INFO: Application ending.
BUILD SUCCESSFUL (total time: 1 minute 33 seconds)


After 3-4 tries this only happened once :/

I wonder how stable the JOGL stuff really is, especially the input (also the mouse cursor doesn't disappear like it should)

(I know its had a rough go; and was just recently 'dusted off' and put back in after sitting around for a while.)

and IMO while jME may not need JOGL, the rest of the world is starting to embrace it; so it would be in jME's best (future) interest to make sure the JOGL implementation is as strong as LWJGL now before it's too late.

EDIT: added JavaDoc comments to public methods

One thing I found extremly odd though, is that in MrCoders version he is getting the ModelView matrix and storing it into the lightProjectionMatrix;  that was the issue I was having with this.  I believe its supposed to be the Projection (not the ModelView) Matrix…



and once I switched it all was good again.





(I just switched the call in updateProjectedTexture() rather than changing any of the actual methods themselves, which seemed to be named correctly for what they were doing anyways…)

basixs said:

The JOGL water test still has the green stuff in it, I guess I will look at that sometime.  Also, after a few seconds of playing w/ it I got this error:


Jan 16, 2009 12:01:48 AM com.jme.renderer.AbstractCamera <init>
INFO: Camera created.
Jan 16, 2009 12:01:57 AM class jmetest.effects.water.TestProjectedWater start()
SEVERE: Exception in game loop
java.util.NoSuchElementException
        at java.util.LinkedList.remove(LinkedList.java:644)
        at java.util.LinkedList.remove(LinkedList.java:360)
        at com.jmex.awt.input.AWTMouseInput.update(AWTMouseInput.java:195)
        at com.jme.input.InputSystem.update(InputSystem.java:67)
        at com.jme.app.BaseGame.start(BaseGame.java:81)
        at jmetest.effects.water.TestProjectedWater.main(TestProjectedWater.java:79)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at jmetest.TestChooser.start(TestChooser.java:465)
        at jmetest.TestChooser.main(TestChooser.java:444)
Jan 16, 2009 12:01:57 AM com.jme.app.BaseSimpleGame cleanup
INFO: Cleaning up resources.
Jan 16, 2009 12:01:57 AM com.jme.app.BaseGame start
INFO: Application ending.
BUILD SUCCESSFUL (total time: 1 minute 33 seconds)


After 3-4 tries this only happened once :/

I wonder how stable the JOGL stuff really is, especially the input (also the mouse cursor doesn't disappear like it should)

(I know its had a rough go; and was just recently 'dusted off' and put back in after sitting around for a while.)

and IMO while jME may not need JOGL, the rest of the world is starting to embrace it; so it would be in jME's best (future) interest to make sure the JOGL implementation is as strong as LWJGL now before it's too late.

EDIT: added JavaDoc comments to public methods

Why allowing the use of JOGL in JME if lots of people often say it is useless or optional? I'm worried about this bug, lots of classes like this (BaseGame, SimpleGame, StandardGame...) seem to have some problems with JOGL. I'm looking at this bug now.

It is a problem of threading, multiple threads are calling the update method at the same time. Then, the first one succeeds in removing the first element but one of the others believes there is at least an element, tries to remove it where the list has been emptied by another thread.

while ( !swingEvents.isEmpty() )
            {
                MouseEvent event = swingEvents.remove( 0 );



I suggest several possible fixes:
- use the keyword "synchronized" for this method
- force this method to be executed on the same thread, the Event Dispatching Thread for example (use SwingUtilities.invokeAndWait(Runnable runnable))
I prefer the second option, would you like me to prepare a patch?
gouessej said:

It is a problem of threading, multiple threads are calling the update method at the same time. Then, the first one succeeds in removing the first element but one of the others believes there is at least an element, tries to remove it where the list has been emptied by another thread.

while ( !swingEvents.isEmpty() )
            {
                MouseEvent event = swingEvents.remove( 0 );



I suggest several possible fixes:
- use the keyword "synchronized" for this method
- force this method to be executed on the same thread, the Event Dispatching Thread for example (use SwingUtilities.invokeAndWait(Runnable runnable))
I prefer the second option, would you like me to prepare a patch?

This is for the TestProjectedWater, right? Yes, please post a patch.

gouessej said:

Why allowing the use of JOGL in JME if lots of people often say it is useless or optional? I'm worried about this bug, lots of classes like this (BaseGame, SimpleGame, StandardGame...) seem to have some problems with JOGL. I'm looking at this bug now.

It's only because we haven't had dedicated JOGL users like yourself. Please keep the patches coming!
nymon said:

This is for the TestProjectedWater, right? Yes, please post a patch.

I have to check if it would be better to call invokeLater instead in order to avoid blocking the EDT thread.

nymon said:

It's only because we haven't had dedicated JOGL users like yourself. Please keep the patches coming!

The project Wonderland uses the JOGL renderer too, I'm not alone. I found another bug this night in the mouse handling :(

Committed: http://code.google.com/p/jmonkeyengine/source/detail?r=4089



(just the Util, nothing with the test…)

I have solved my problem, I'm going to fill a bug report for another real bug.

basixs said:

Committed: http://code.google.com/p/jmonkeyengine/source/detail?r=4089

(just the Util, nothing with the test..)

Please update the issue for it.