Manual rendering???

Hello,
I have ported my game engine graphics engine to JOGL, it’s working already, however it’s really messy :frowning:
Since JOGL use it’s own thread (I guess) for rendering.
JOGL use listener with addGLEventListener(GLEventListener listener) to listen when to display, init, etc using Animator class (I guess again).
It’s nice to have this utility, however the bad news is my game engine already has the game loop that render and stuff like the Animator class do.
Is there a way to manually do everything?
I mean do initialization, painting, and everything, not using listener.
Cos right now I do not know the flow when the init(), display() actually called, and therefore I wait in my game loop until all things set, and that’s why it really messy right now :frowning:

Thank you so much for any enlightment.

JOGL doesn’t enforce what thread performs the rendering; this is left up to the application. The Animator class does create its own animation thread, but if you have your own game loop you shouldn’t use the Animator. Instead, just call GLDrawable.display() on demand, which will end up calling your GLEventListener immediately, if possible. The reason it is necessary to say “if possible” is that the underlying AWT component is created in the background on another thread, so OpenGL rendering may have to wait until it has actually been created.

For better multithreading behavior you can call GLDrawable.setNoAutoRedrawMode(true), which will prevent the AWT from trying to render in the background, and GLDrawable.setRenderingThread(Thread.current()) once you are in your main game loop, which will optimize the OpenGL context handling behind the scenes.

Hmmm, still not working :frowning:
Could you please tell me how the listener actually works?
I mean, when the init(GLDrawable drawable), display(GLDrawable drawable) actually called?
I have set the GLDrawable.setRenderingThread(Thread.currentThread());
And wait (Thread.sleep(…)) until the GL is setup in init(GLDrawable drawable), but the init(GLDrawable drawable) never called??
Oh yeah, I have turn on GLDrawable.setNoAutoRedrawMode(true) too.

This is my code :


        // sets game frame
            frame = new Frame("Golden T Game Engine");
            try {
                  frame.setIconImage(ImageUtil.getImage(WindowExitListener.class.getResource("Icon.png")));
            } catch (Exception e) { }
            frame.addWindowListener(WindowExitListener.getInstance());
            frame.setResizable(false);            // not resizable frame
          frame.setIgnoreRepaint(true);      // turn off all paint events
                                                            // since we doing active rendering

            canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
            canvas.addGLEventListener(this);
            canvas.setNoAutoRedrawMode(true);
            canvas.setRenderingThread(Thread.currentThread());

            canvas.setFocusable(true);
            canvas.setSize(size);

            // frame title bar and border (frame insets) makes
            // game screen smaller than requested size
            // we must enlarge the frame by it's insets size
            frame.setVisible(true);
        Insets inset = frame.getInsets();
        frame.setVisible(false);
        frame.setSize(size.width + inset.left + inset.right,
                                size.height + inset.top + inset.bottom);
        frame.add(canvas);
        frame.pack();
            frame.setLayout(null);
        frame.setLocationRelativeTo(null); // centering game frame
        frame.setVisible(true);

            while (currentGraphics == null) {
                  System.out.println("waiting GL setup...");

                  try {
                      Thread.sleep(4000L);
                  } catch (Exception e) {
                        e.printStackTrace();
                  }
            }

Anything I did wrong??

Thx

There is nothing going on behind the scenes in JOGL – you have to call GLDrawable.display() to cause rendering to occur. GLEventListener.init() will be called when the OpenGL context is first created, and GLEventListener.display() will be called for normal rendering operations.

Wow thank you! So the listener is not too complicated as I thought, I got it working now! Whoopieee!!
You really enlightment me Ken Russel! ;D
Guess I pick a wrong JOGL introduction at first… I’m too focus with that listener thing! :slight_smile:

This is it, the game (webstart) that using Java2D, JOGL, and LWJGL :
http://goldenstudios.or.id/products/games/bin/robosick.jnlp

Please tell me whether there are some mode that not working, it’s Java2D windowed/fullscreen bufferstrategy/volatile image, JOGL windowed/fullscreen, LWJGL windowed/fullscreen vsync/not
PS: my site server is frequently down recently, if the connection failed/refused/reset please wait an hour or so before try it again, they upgrading the site server

Yippie now I have a working game engine that utilize Java2D <-> JOGL <-> LWJGL, anyone would like to try this bloody fantastic game library? ;D
The engine is designed specially to make 2D games only, using Java2D for the default and support/utilize the power of OpenGL via JOGL and LWJGL! Of course use OpenGL to get more fps if only the game still slow with Java2D :slight_smile:
So if anyone want to make 2D games that supporting OpenGL easily, you could try my game engine.

Anyway I have 4 questions (only one that important) :

  • what is setAutoSwapBufferMode(boolean onOrOff) do exactly?
    Do I get more performance if I turn it off and do the swapBuffers() manually?
    Got any tips for me to do optimized 2D rendering with JOGL?

  • What is gl.glFlush(); I set it in display(GLDrawable drawable), got it from sample code.
    Right now my display(GLDrawable drawable) function is empty, only call the gl.glFlush(); but I see no difference if remove it??


    public void display(GLDrawable drawable) {
            // flush the graphics commands to the card
            gl.glFlush();
    }

  • Is the rendering automatically synchronize with vsync?
    Cos I set the rendering should be at maximum fps and I got only 75 fps, and I’m sure it should be not that low, cos I got 260 fps with Java2D
    Is there anyway I can disable the vsync? Not too necessary though, only for showing the max fps the game can game using JOGL.

  • And the last, the irritating one, I got this exception :


java.lang.NoClassDefFoundError: net/java/games/jogl/GLEventListener
                        at java.lang.ClassLoader.defineClass0(Native Method)
                        at java.lang.ClassLoader.defineClass(ClassLoader.java:502)
                        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
                        at java.net.URLClassLoader.defineClass(URLClassLoader.java:250)
                        at java.net.URLClassLoader.access$100(URLClassLoader.java:54)
                        at java.net.URLClassLoader$1.run(URLClassLoader.java:193)
                        at java.security.AccessController.doPrivileged(Native Method)
                        at java.net.URLClassLoader.findClass(URLClassLoader.java:186)
                        at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
                        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)
                        at java.lang.ClassLoader.loadClass(ClassLoader.java:255)
                        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:315)
                        at com.golden.roboticswar.RoboticsWarGame.main(RoboticsWarGame.java:168)

The exception thrown when I’m not including the JOGL library (jogl.jar).
JOGL library not needed when someone want only making Java2D game or LWJGL game, so they won’t include JOGL library.
But when the JOGL library is not included, even the game not touching the JOGL API directly, but still there is JOGL API inside the class, but not touched, it’s in another function that never be called if the game not using JOGL, that exception is thrown :frowning:
This method is working for LWJGL, if the game only use one of JOGL or Java2D, then the LWJGL library is removed, no exception is thrown.
Any thought about this? Anything to wrap with try catch? I have wrap the method that call JOGL API with try catch, but still not working :frowning:
Right now I’m using reflection to create the JOGL graphics engine class, it’s working, but I guess it’s pretty weird way to do it.

Once again thank you very much for the enlightment!! :slight_smile:

On gl.glFlush(), all it basically does is force OpenGL to execute any current graphics operations.

As for your exception, could you post your reflection code. I could more clearly identify the cause of the exception.

[quote]- what is setAutoSwapBufferMode(boolean onOrOff) do exactly?
Do I get more performance if I turn it off and do the swapBuffers() manually?
Got any tips for me to do optimized 2D rendering with JOGL?
[/quote]
setAutoSwapBufferMode() changes whether the GLDrawable calls OpenGL’s swapBuffers function at the end of GLDrawable.display(), or whether it is left up to the end user. This was only added for special circumstances where the user wants to swap the buffers many times in their GLEventListener.display() method; usually the default setting doesn’t need to be touched. Swapping the buffers manually has basically the same cost or possibly slightly higher depending on the structure of the application.

Using an Animator and/or the setRenderingThread API is the key optimization which enables higher performance for JOGL on Windows. Right now it doesn’t speed things up on Linux or the Mac although we’re thinking about ways to make that happen at least on X11 platforms.

[quote]- What is gl.glFlush(); I set it in display(GLDrawable drawable), got it from sample code.
Right now my display(GLDrawable drawable) function is empty, only call the gl.glFlush(); but I see no difference if remove it??


    public void display(GLDrawable drawable) {
            // flush the graphics commands to the card
            gl.glFlush();
    }

[/quote]
I don’t understand how your app works if it doesn’t do any rendering work inside your GLEventListener’s display() method. It’s only during the invocation of that method that the OpenGL context is current so all calls to GL methods must be done in that method or methods that one calls.

glFlush() / glFinish() have slightly different semantics but basically ensure that all OpenGL rendering has completed before doing other operations like swapping the buffers. Most applications don’t need to use these calls, although they probably should be done at the end of your GLEventListener.display() for complete correctness.

[quote]- Is the rendering automatically synchronize with vsync?
Cos I set the rendering should be at maximum fps and I got only 75 fps, and I’m sure it should be not that low, cos I got 260 fps with Java2D
Is there anyway I can disable the vsync? Not too necessary though, only for showing the max fps the game can game using JOGL.
[/quote]
Probably. This is typically a driver-level option that can be changed in the Display control panel on Windows. You can test for the presence of Windows and call GL.wglSwapIntervalEXT(0) (defined in the WGL interface). I don’t know how to do the same thing on X11. We have an RFE filed on the JOGL Issue Tracker to provide platform-independent disabling of sync-to-vertical-refresh.

You definitely need to use reflection to instantiate your engine because otherwise it is likely that the verifier will try to load JOGL-related classes even when using LWJGL and vice versa. It sounds like gamehacer2000 can help you here.

Thanks for the clear explanation Ken Russel :slight_smile:

Then is nothing to change, it’s perfect already ;D
Thanks, if it must be use reflection, then I got it working with my code, I just hope that there’s alternative clean way to do it :slight_smile:

Thank you guys!

PS: my site is up again! try out the Java2D + LWJGL + JOGL webstart game, and please tell me which one not works?
I have alpha test it, and everything is working perfectly.
Time to beta test it :wink:
And I have one complain already that said the JOGL is not working :frowning: but the LWJGL and Java2D is working flawlessly with 700 fps increment :smiley: from 400 fps using Java2D to 1100 fps using LWJGL!

It works pretty well on my machine (Windows XP, NVidia Quadro FX Go700). There is a bug where the character occasionally gets “stuck” and won’t move to the left or right. This happens pretty frequently with the LWJGL version (both full-screen and windowed) but also occasionally with the JOGL version. It probably has something to do with your keyboard event handling. Also an InvocationTargetException is thrown from the JOGL fullscreen version.

The robo stuck is my code bugs, so it’s not a problem.
It is not key even handling problem, but rounding position that cause it “enter” the block and therefore can’t move ;D
It’s not a problem tho, cos it stuck only if the fps is maxed out, isn’t it? Or is it happen too in the default fps (50 fps)? If yes then I have to figure this out :slight_smile:

So the windowed JOGL is working but the fullscreen JOGL is not?
Hmmm it’s pretty weird, in here all modes are working perfectly.
What Java version do you use? And JOGL version?
Anyway some of my friends got even worse, they said the LWJGL version is smooth, but the JOGL version messed the screen, and it even worse in JOGL fullscreen mode.
For exactly it’s two person that said that (and only these two that report to me) :frowning:
Guess I should make a new post for this beta test.

Thanks

[quote]It’s not a problem tho, cos it stuck only if the fps is maxed out, isn’t it?
[/quote]
You’re right, it was only happening at the maximum FPS.

[quote]So the windowed JOGL is working but the fullscreen JOGL is not?
Hmmm it’s pretty weird, in here all modes are working perfectly.
What Java version do you use? And JOGL version?
Anyway some of my friends got even worse, they said the LWJGL version is smooth, but the JOGL version messed the screen, and it even worse in JOGL fullscreen mode.
[/quote]
In the resources section of your JNLP file you should specify the following:


<property name="sun.java2d.noddraw" value="true"/>

You might even want to try specifying the following:


<property name="ATI_WORKAROUND" value="true"/>

In the forthcoming 1.1 b08 you shouldn’t need to specify the ATI_WORKAROUND property. It will be renamed to JOGL_SINGLE_THREADED_WORKAROUND and the underlying code will be enabled earlier in the startup sequence when running on ATI cards.

Hmm if I put java2d.noddraw, is that won’t affect the Java2D performance?

Anyway where the best place should I put those lines in my jnlp file?
Does anyone know how to make the webstart checking any updates before running the app?
I guess if anyone that has the old one installed, it won’t check the change of this property name.

[quote]Hmm if I put java2d.noddraw, is that won’t affect the Java2D performance?
[/quote]
Good point. The problem is that Java2D uses DirectDraw on Windows, and OpenGL and DirectDraw are fundamentally incompatible at the driver level. We recommend that all JOGL applications specify -Dsun.java2d.noddraw=true for best compatibility on all graphics cards. However, you may be able to get away with not specifying this property, at least on some cards. Try the single-threaded workaround first, and if people are still seeing problems then provide an alternate, “compatibility” JNLP file which specifies the sun.java2d.noddraw=true property.

[quote]Anyway where the best place should I put those lines in my jnlp file?
Does anyone know how to make the webstart checking any updates before running the app?
I guess if anyone that has the old one installed, it won’t check the change of this property name.
[/quote]
Those lines should go in the platform-independent section. In theory you could put the sun.java2d.noddraw one in the section because it only affects the Windows platform. Download a couple of the JNLP files from the jogl-demos website and see what they look like.

Flushing the disk cache in your browser should force the .jnlp file to be reloaded the next time. If you update your jars, Java Web Start should pick up the new jars automatically, but you can also clear out applications using the Java Control Panel.

Hmmm my tester said the problem still exists (the messy screen)
The ATI_WORKAROUND and noddraw not fix the problem :frowning:
He use ATI Radeon 8500, and the other ATI Radeon 9600 pro…
Got other suggestion?
Anyway are you sure it’s name not key?


<property name="ATI_WORKAROUND" value="true"/> 

Is it not like this :


<property key="ATI_WORKAROUND" value="true"/> 

Cos I have other property to set library path like this :


<property key="java.library.path" value="." />

This is my jnlp, I remove the sun.java2d.noddraw right now like you said :


<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+"
      codebase="http://goldenstudios.or.id/products/games/bin/"
      href="robosick.jnlp">
<information>
   <title>RoboticsWar Java2D/OpenGL via LWJGL</title>
   <vendor>Paulus Tuerah - Golden T Studios</vendor>
   <homepage href="http://goldenstudios.or.id/"/>
   <description>Platformer game created by GTGE support for OpenGL via LWJGL, press Z to turn on transclucent to see the power of OpenGL!</description>
   <offline-allowed/>
</information>
<security>
   <all-permissions/>
</security>
<resources>
   <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/>
   <jar href="robosick.jar"/>
   <jar href="golden_0_2_1.jar"/>
   <jar href="GTGE_add_ons.jar"/>
   <jar href="lwjgl.jar"/>
   <jar href="jogl.jar"/>
</resources>
<resources os="Windows">
   <j2se version="1.4+"/>
   <nativelib href="lwjgl-windows.jar"/>
   <nativelib href="jogl-natives-win32.jar"/>
</resources>
<resources os="MacOS">
   <j2se version="1.4+"/>
   <nativelib href="lwjgl-osx.jar"/>
   <nativelib href="jogl-natives-macosx.jar"/>
</resources>
<resources os="Linux" arch="i386">
   <j2se version="1.4+"/>
   <nativelib href="lwjgl-linux.jar"/>
   <nativelib href="jogl-natives-linux.jar"/>
</resources>
<resources os="SunOS" arch="sparc">
    <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+"/>
    <nativelib href="jogl-natives-solsparc.jar"/>
</resources>
<property key="java.library.path" value="." />
<property name="ATI_WORKAROUND" value="true"/> 
<application-desc/>
</jnlp>

Any thoughts?

[quote]Hmmm my tester said the problem still exists (the messy screen)
The ATI_WORKAROUND and noddraw not fix the problem :frowning:
He use ATI Radeon 8500, and the other ATI Radeon 9600 pro…
Got other suggestion?
[/quote]
There were one or two bugs in the actual code for the ATI_WORKAROUND that have been fixed in the JOGL CVS repository. We’re trying to get a new beta out which will fix these. If you have the ability to build the source tree on your machine, you could provide a binary to the end user. (We’re also working on getting our nightly build infrastructure back on line…)

I’m pretty sure it’s “name”, not “key”; I just checked the JNLP spec.