Tuesday 7 February 2017

Updating JOGL to 2.3.2 in Amber - Haven and Hearth Client because we can

Today I was looking at Amber Haven and Hearth client and thing I noticed was that it was running some really old JOGL (library used to do graphics - OpenGL). So I thought - why would I want to run something from 2013 - most likely JOGL supplied with Amber is 2.1.2 released 1 November 2013.

Get your libraries

Amber has JOGL libraries predownloaded into "lib" directory and uses slightly different naming notation than the actual JOGL release.
So we need to update "gluegen-rt.jar" and "jogl.jar" in lib folder and then download native library jar's into "jogl-natives" folder.  Note that on the above screenshot we already have updated libraries, plus I downloaded armv6hf since I am playing with Haven and Hearth client on Raspberry Pi. Once we identified which libraries we need we can download them from https://jogamp.org/deployment/v2.3.2/

A couple of things worth mentioning - as stated above JOGL release uses a slightly different naming scheme, so "jogl.jar" in Amber client is "jogl-all.jar" in JOGL release, and "jogl-natives-X-Y.jar" on Amber side matches "jogl-all-natives-X-Y.jar" on JOGL release side.

There are several pitfalls that we need to avoid:
  1. All libraries should be from the same version - we can not use library of one release and native library from another that would cause a "Certificate mismatch" exception when trying to run the client
  2. Naming convention should be intact - build.xml expects particular jar names:

  3. jogl-jar and gluegen.jar can come double compressed, so you might need to extract jar from jar:

Fixing errors

Once we are done updating libraries and try to compile we are going to get multiple errors majority of which are going to be of two types:
    [javac] C:\workspace\amber\src\haven\HavenPanel.java:43: error: package javax.media.opengl does not exist
    [javac] import javax.media.opengl.*;
    [javac] ^
    [javac] C:\workspace\amber\src\haven\HavenPanel.java:71: error: cannot find symbol
    [javac]     private static GLCapabilities stdcaps() {
    [javac]                    ^
    [javac]   symbol:   class GLCapabilities
    [javac]   location: class HavenPanel
We are going to fix those that are about packages that do not exist. Reason for those errors is that in new libraries (not sure when the change happened, but who cares and why?) have "opengl" moved from "javax.media" package to "com.jogamp".

Once all packages are fixed there are two more things to be addressed. One of them are screenshots, it happens so, that com.jogamp.opengl.util.awt.Screenshot was deprecated in JOGL 2.x and is completely removed in 2.3.2. To address this we will have to modify "takescreenshot()" method defined within an anonymous GLEventListener object in initgl() method in HavenPanel.

            public void takescreenshot(GLAutoDrawable d) {
                try {
                    String curtimestamp = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss.SSS").format(new Date());
                    File outputfile = new File(String.format("screenshots/%s.png", curtimestamp));
                    outputfile.getParentFile().mkdirs();
                    AWTGLReadBufferUtil glReadBufferUtil=new AWTGLReadBufferUtil(d.getGLProfile(),false);
                    BufferedImage image=glReadBufferUtil.readPixelsToBufferedImage(d.getGL(),true);
                    ImageIO.write(image, "png", outputfile);                  
                    ui.root.findchild(GameUI.class).msg(String.format("Screenshot has been saved as \"%s\"", outputfile.getName()), Color.WHITE);
                } catch (Exception ex) {
                    System.out.println("Unable to take screenshot: " + ex.getMessage());
                }
            }

            public void display(GLAutoDrawable d) {
                if (HavenPanel.needtotakescreenshot) {
                    takescreenshot(d);
                    HavenPanel.needtotakescreenshot = false;
                }

As you can see, we no longer pass width and height into functional and we use AWTGLReadBufferUtil to get image data and then save it into the file via ImageIO.write().

This should leave us with two issues in GLProgram.create() and GLShadre.create() methods. Root cause of these issues is that gl.glCreateProgramObjectARB() and gl.glCreateShaderObjectARB() no longer return and Integer type, but Long type - so we'll cast result to Integer - this might not be perfect and might cause some issues going forward, but that seems to be the easiest fix, since changing type of id to Long is causing further incompatibilities.

Time to run

Ok, now we finally should be able to compile our code with new libraries and enjoy Haven and Hearth Client with JOGL 2.3.2

No comments:

Post a Comment