LWJGL directly

Ok, so i've read a ton of posts on using LWJGL directly and they didn't give me much to go on, so here I am on the raggedy edge… (sorry firefly line)



I wanted to port my jogl code over to LWJGL to use in JME.  There are some things that I find are easier with openGl since that's where I got my start.



First, I took my code and put it into a class that extends Geometry… that was one thing that I found helpful from all of the posts, but it came about due to trial and error.



I am calling my code from this:


public class DradisGameState  extends BasicGameStateNode {
    StandardGame game;
    public DradisGameState(StandardGame _game) {
        super("dradisGameStateNode");
        game = _game;
    }

    public void init() {
        rootNode.setRenderQueueMode(Renderer.QUEUE_ORTHO);
        rootNode.setCullMode(SceneElement.CULL_NEVER);

        GameTaskQueueManager.getManager().getQueue(GameTaskQueue.UPDATE).setExecuteAll(true);
        GameTaskQueueManager.getManager().update(new Callable<Object>() {
            public Object call() throws Exception {
                rootNode.attachChild(new Arc());
                return null;
            }
        });

        rootNode.setLightCombineMode(LightState.OFF);
        rootNode.updateRenderState();
    }



which then calls this:


    private class Arc extends Geometry {
        public void findCollisions(Spatial spatial, CollisionResults collisionResults) {
        }

        public boolean hasCollision(Spatial spatial, boolean _active) {
            return false;
        }

        public void draw(Renderer renderer) {
            super.draw(renderer);

            GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping
            GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
            GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
            GL11.glClearDepth(1.0); // Depth Buffer Setup
            GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
            GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do

            GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
            GL11.glLoadIdentity(); // Reset The Projection Matrix

            // Calculate The Aspect Ratio Of The Window
            GLU.gluPerspective(
              45.0f,
              100 / (float) 100,
              0.1f,
              100.0f);
            GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix

            // Really Nice Perspective Calculations
            GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
                GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);          // Clear The Screen And The Depth Buffer
            GL11.glLoadIdentity();                          // Reset The Current Modelview Matrix
            GL11.glTranslatef(-1.5f,0.0f,-6.0f);                // Move Left 1.5 Units And Into The Screen 6.0
            GL11.glBegin(GL11.GL_TRIANGLES);                    // Drawing Using Triangles
                GL11.glVertex3f( 0.0f, 1.0f, 0.0f);         // Top
                GL11.glVertex3f(-1.0f,-1.0f, 0.0f);         // Bottom Left
                GL11.glVertex3f( 1.0f,-1.0f, 0.0f);         // Bottom Right
            GL11.glEnd();                                       // Finished Drawing The Triangle
            GL11.glTranslatef(3.0f,0.0f,0.0f);              // Move Right 3 Units
            GL11.glBegin(GL11.GL_QUADS);                        // Draw A Quad
                GL11.glVertex3f(-1.0f, 1.0f, 0.0f);         // Top Left
                GL11.glVertex3f( 1.0f, 1.0f, 0.0f);         // Top Right
                GL11.glVertex3f( 1.0f,-1.0f, 0.0f);         // Bottom Right
                GL11.glVertex3f(-1.0f,-1.0f, 0.0f);         // Bottom Left
            GL11.glEnd();                                       // Done Drawing The Quad
        }
    }



now there are some lines like the GLU, etc that I've been trying out to see if they improve what's going on.  So far, I've tried to set a viewport and put the display in that, I've tried the perspective, and a few other things.

These things do work with my jogl implementation and my LWJGL implementation.

When I use them with JME it never just shows my display, it always moves the display somewhere else (with or without the gluPerspective or the viewport)

Is there anything that I haven't thought of that might help me just get my OGL started in JME so that the objects display correctly.  This code in the Arc class is not my own, I pulled an LWJGL jar down from nehe's site to see if that helped my cause... it gives me the same results.

http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=02 is what it should look like.

what I get is my scene intermeshed with the polygons.

This could be something else I've done with the game state as well, or I may have used the GameTaskManagerQueue incorrectly.

I'll get a screenshot posted here in the next half hour or so.

any help would be appreciated,

thx,

timo

Is it off by a constant amount, or does it shift as you move the camera?

it was always off by a constant amount… after a lot of rereading the code and scouring my files I found that I had the projection matrix off a bit…



Now, I've got a new problem with the same code that I'll be posting later on.



Basically, the issue is that the shapes are displaying, however, the first iteration they display as they should, after that they display the same color as the background… using simple game



when I use the GameTaskQueueManager the shapes display nice, but they are still the same color as the background as set with the GL11.glClearColor call.



I'll post something later on tonight

here it is:



import com.jme.app.SimpleGame;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;

public class DradisGLTest extends SimpleGame {
    private Arc arc = new Arc();

    protected void simpleInitGame() {
        rootNode.attachChild(arc);
        Box box = new Box("The Box", new Vector3f(-1, -1, -1), new Vector3f(3f, 3f, 3f));
        Quaternion rot = new Quaternion();
        rot.fromAngles(FastMath.DEG_TO_RAD*25, FastMath.DEG_TO_RAD*25, 0.0f);
        box.setLocalRotation(rot);

        rootNode.attachChild(box);
    }

    public static void main(String[] args) {
        DradisGLTest app = new DradisGLTest();
        app.setDialogBehaviour(FIRSTRUN_OR_NOCONFIGFILE_SHOW_PROPS_DIALOG);
        app.start();
    }
}



and the Arc class:



import com.jme.scene.Geometry;
import com.jme.scene.Spatial;
import com.jme.intersection.CollisionResults;
import com.jme.renderer.Renderer;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.glu.GLU;

public class Arc extends Geometry {

        public void findCollisions(Spatial spatial, CollisionResults collisionResults) {
        }

        public boolean hasCollision(Spatial spatial, boolean _active) {
            return false;
        }

        public void draw(Renderer renderer) {
            super.draw(renderer);

            initWindow();
            // the standard for the code display
            meatStart();
            //the meat
            meat();
            //finish the standard for code display
            meatEnd();
        }

        private void initWindow() {
            GL11.glViewport(0, 0, 640, 480);
    //        GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping
    //        GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
            GL11.glClearColor(0.0f, 255.0f, 255.0f, 0.0f); // Greenish background
    //        GL11.glClearDepth(1.0); // Depth Buffer Setup
            GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
            GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do

            GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
            GL11.glLoadIdentity(); // Reset The Projection Matrix

    //        // Calculate The Aspect Ratio Of The Window
            GLU.gluPerspective(
              45.0f,
              (float) 640 / (float) 480,
              0.1f,
              100.0f);
            GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix

            // Really Nice Perspective Calculations
    //        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
    //        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);          // Clear The Screen And The Depth Buffer
    //        GL11.glDisable(GL11.GL_DEPTH_TEST);
        }

        private void meat() {
            // 2D texture
           // draw different sized quads to display different mip levels
           GL11.glEnable(GL11.GL_TEXTURE_2D);

            GL11.glScalef(.4f, .4f, 0);
            GL11.glTranslatef(-1.5f,0.0f, 0.0f);                // Move Left 1.5 Units And Into The Screen 6.0
            GL11.glBegin(GL11.GL_TRIANGLES);                    // Drawing Using Triangles
                GL11.glColor3f(1.0f,0.0f,0.0f);             // Set The Color To Red
                GL11.glVertex3f( 0.0f, 1.0f, 0.0f);         // Move Up One Unit From Center (Top Point)
                GL11.glColor3f(0.0f,1.0f,0.0f);             // Set The Color To Green
                GL11.glVertex3f(-1.0f,-1.0f, 0.0f);         // Left And Down One Unit (Bottom Left)
                GL11.glColor3f(0.0f,0.0f,1.0f);             // Set The Color To Blue
                GL11.glVertex3f( 1.0f,-1.0f, 0.0f);         // Right And Down One Unit (Bottom Right)
            GL11.glEnd();                                       // Finished Drawing The Triangle
    //        GL11.glScalef(.4f, .4f, 0);
            GL11.glTranslatef(2.5f,0.0f,0.0f);              // Move Right 3 Units
            GL11.glColor3f(0.5f,0.5f,1.0f);                 // Set The Color To Blue One Time Only
            GL11.glBegin(GL11.GL_QUADS);                        // Draw A Quad
                GL11.glVertex3f(-1.0f, 1.0f, 0.0f);         // Top Left
                GL11.glVertex3f( 1.0f, 1.0f, 0.0f);         // Top Right
                GL11.glVertex3f( 1.0f,-1.0f, 0.0f);         // Bottom Right
                GL11.glVertex3f(-1.0f,-1.0f, 0.0f);         // Bottom Left
            GL11.glEnd();                                       // Done Drawing The Quad
        }

        private void meatStart() {
            GL11.glMatrixMode(GL11.GL_MODELVIEW);
            GL11.glPushMatrix();
            GL11.glLoadIdentity();
            GL11.glMatrixMode(GL11.GL_PROJECTION);
            GL11.glPushMatrix();
            GL11.glLoadIdentity();
        }

        private void meatEnd() {
            GL11.glPopMatrix();
            GL11.glMatrixMode(GL11.GL_MODELVIEW);
            GL11.glPopMatrix();
        }
    }



this should produce a cube behind a square and a triangle... if you move your mouse left and right you'll see the triangle and box.

now if you put the Arc call inside of the GameTaskQueueManager code from before then it will show the square and the triangle as green.

That's not so bad, but if you notice the colors on the verticies you'll see that the triangle and square have different colors on all sides.

That's the only issue now... the color settings... well and textures... they don't texture either.

BUT, I've successfully ported most of my code over... once I can find an answer on the color/texture thing then I'll be done with it.

thx,

timo

Something to think about… An issue with changine the GL state machine outside of jME is that jME will then no longer know the correct state of opengl and start having issues when deciding what state changes to make and which can be safely ignored.  To handle what you are doing, we could make a state sync call you could make that would force jME to resync to opengl's current state.

I hadn't thought about the GL state machine being out of sync… that's a good point.  I'm so used to always being in sync that I hadn't considered being out of sync.



Is this something you're mulling over Renanse?

or

Is there a better way for me to make the OGL calls that I need to and still stay in sync with the GLSM?



thx,



timo


Any further thoughts about this?



I've been trying to follow some of the LWJGL code and the JME code to see if I can figure it out, but I'm not very familiar with the inner workings.



thx,



timo

I'll be adding a manual reset button to the jme tracking of the gl state machine.  You'd basically push that after doing your manual lwjgl manipulation.  Not much more I can offer until then though.

awesome!  I look forward to it!!



thx



timo

So the solution is going to be

DisplaySystem.getDisplaySystem().getCurrentContext().invalidateStates();



Which essentially sets the state records for a given context as untrustable.  You'd call it after manually messing with opengl state code.  I'm going through the individual states now, changing them to use this information, but it's going to take a bit of time to finish that process.  In the process I might try to make it possible to invalidate just a given state's record for advanced users who know what they are doing.

FYI, I've finished work on this.  In the process I found and corrected unrelated bugs in alpha state and material state.  Expect cvs commit next week.

You tha man!!!  You can bet that once it's out, it'll get a lot of testing by me!

Great.  Keep in mind that this is state stuff only.  If you play with the various matrices, make sure you put things back where they belong.  (use push and pop)

FYI:  The ability to reset jme's opengl tracking just went in today.  Please test and comment.  Also, please excuse this message as it will be crossposted at least once.

ok, I've experimented over and over with this, adjusting matrix pushes and pops.



Here's the new code:



DradisGLTest (main test class)


import com.jme.app.SimpleGame;
import com.jme.scene.shape.Box;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.math.FastMath;

public class DradisGLTest extends SimpleGame {
    private Arc arc2 = new Arc();

    protected void simpleInitGame() {
        rootNode.attachChild(arc2);

        Box box = new Box("Box", new Vector3f(-1, -1, -1), new Vector3f(3f, 3f, 3f));

        Quaternion rot = new Quaternion();
        rot.fromAngles(FastMath.DEG_TO_RAD * 25, FastMath.DEG_TO_RAD * 25, 0.0f);

        box.setLocalRotation(rot);

        rootNode.attachChild(box);
    }

    public static void main(String[] args) {
        DradisGLTest app = new DradisGLTest();
        app.setDialogBehaviour(FIRSTRUN_OR_NOCONFIGFILE_SHOW_PROPS_DIALOG);
        app.start();
    }
}



Arc class


import com.jme.intersection.CollisionResults;
import com.jme.renderer.Renderer;
import com.jme.scene.Geometry;
import com.jme.scene.Spatial;
import com.jme.system.DisplaySystem;
import org.lwjgl.opengl.GL11;

public class Arc extends Geometry {
    public void findCollisions(final Spatial spatial, final CollisionResults collisionResults) {
    }

    public boolean hasCollision(final Spatial spatial, final boolean b) {
        return false;
    }

    public void draw(final Renderer renderer) {
        super.draw(renderer);

            GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping
//            GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
            GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
//            GL11.glClearDepth(1.0); // Depth Buffer Setup
            GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
            GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do

//            GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
//            GL11.glPushMatrix();
//            GL11.glLoadIdentity(); // Reset The Projection Matrix
//
//            // Calculate The Aspect Ratio Of The Window
//            GLU.gluPerspective(
//              45.0f,
//              100 / (float) 100,
//              0.1f,
//              100.0f);
            GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
            GL11.glPushMatrix();
            GL11.glLoadIdentity();
            // Really Nice Perspective Calculations
            GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
//            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);          // Clear The Screen And The Depth Buffer
            GL11.glPushMatrix();
            GL11.glLoadIdentity();                          // Reset The Current Modelview Matrix
            GL11.glTranslatef(-1.5f,0.0f,-6.0f);                // Move Left 1.5 Units And Into The Screen 6.0
            GL11.glBegin(GL11.GL_TRIANGLES);                    // Drawing Using Triangles
                GL11.glVertex3f( 0.0f, 1.0f, 0.0f);         // Top
                GL11.glVertex3f(-1.0f,-1.0f, 0.0f);         // Bottom Left
                GL11.glVertex3f( 1.0f,-1.0f, 0.0f);         // Bottom Right
            GL11.glEnd();                                       // Finished Drawing The Triangle
            GL11.glTranslatef(3.0f,0.0f,0.0f);              // Move Right 3 Units
            GL11.glBegin(GL11.GL_QUADS);                        // Draw A Quad
                GL11.glVertex3f(-1.0f, 1.0f, 0.0f);         // Top Left
                GL11.glVertex3f( 1.0f, 1.0f, 0.0f);         // Top Right
                GL11.glVertex3f( 1.0f,-1.0f, 0.0f);         // Bottom Right
                GL11.glVertex3f(-1.0f,-1.0f, 0.0f);         // Bottom Left
            GL11.glEnd();                                       // Done Drawing The Quad
            GL11.glPopMatrix();

        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glPopMatrix();
//        GL11.glMatrixMode(GL11.GL_PROJECTION);
//        GL11.glPopMatrix();
        GL11.glFlush();
        DisplaySystem.getDisplaySystem().getCurrentContext().invalidateStates();
    }
}



I still have the same issue with the colors not displaying correctly (in this simple case the quad and the triangle should be white.

I have removed the flush and the invalidateStates and it flashes white then all goes black again.

I've done a lot of experimentation with this and nothing really seems to work as it should.

Is there something I missed with the GL and jme?

I've left the commented out code in this code so that you can see what I did and didn't try.

thx,

timo

It's your use of this:


GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping



disable it, instead.

Since you have not specified a texture or texture uvs, when the fps texture is bound and enabled to draw the fps, it is still bound when drawing the triangle/quad and because you have no uvs set, it uses the black pixel from the corner of the texture.

For example, you can verify this by changing the triangle drawing code to:

            GL11.glBegin(GL11.GL_TRIANGLES);                    // Drawing Using Triangles
                GL11.glVertex3f( 0.0f, 1.0f, 0.0f);         // Top
                GL11.glTexCoord2f( 0.0f, 0.0f);       
                GL11.glVertex3f(-1.0f,-1.0f, 0.0f);         // Bottom Left
                GL11.glTexCoord2f( 1.0f, 0.0f);       
                GL11.glVertex3f( 1.0f,-1.0f, 0.0f);         // Bottom Right
                GL11.glTexCoord2f( 1.0f, 1.0f);        
            GL11.glEnd();                                       // Finished Drawing The Triangle


that makes sense.



I have been so used to including it with my OGL code, I wasn't looking at it to be the issue.



All of my test cases work now!



Renanse is my current Hero!!!