WebGL4J - Simple GWT based WebGL wrapper for Java

Thank you again! That worked perfectly!

I actually had to explicitly set the canvas to black canvas.getElement().getStyle().setBackgroundColor(“black”); otherwise, the white from it would bleed through.

While I’m a beginner at WebGL, I’ve been working with GWT for about 6 years now, so if you have any issues with the GWT side of things, I’d be more than happy to lend a hand.

Hey @SHC
Just started using WebGL4J (literally few hours ago so might be missing something) but I think you’re missing a function.

In WebGL there is a variant of glBufferData() which takes a long for initializing an empty buffer of a certain size.

void bufferData(enum target, long size, enum usage)

That’s its definition on the WebGL quick reference card.

Anyway it certainly works for me using WebGL straight from JS but doesn’t seem to exist in WebGL4J. Obviously easily worked around but just letting you know.

@quew8

Thanks for the find, will push this into snapshot build immediately. Will let you know once the build is published.

EDIT:

WebGL4J 0.2.9-SNAPSHOT is up in the OSSRH snapshot repositories.


compile 'com.goharsha:webgl4j:0.2.9-SNAPSHOT'

Also added documentation from docs.gl to some of the functions, so update daily to receive more documentations.

Thanks very much. I actually just found something else as well.

For glBufferSubData(), it’s spec is,


void bufferSubData(enum target, long offset, Object data)

but WebGL4J has a prototype like the desktop GL version with a size parameter: “glBufferSubData(int target, int offset, long size, ArrayBufferView data)” which causes a crash when you try to use it “No function was found that matched the signature provided.”

Thanks again, I have fixed them. Now there are JS style standard glBufferData variants and also the desktop ones. The desktop style call is emulated with the WebGL standard function.


glBufferSubData(GL_ARRAY_BUFFER, 5, 10, bufferView);

is the same as the following call.


DataView dataView = DataViewNative.create(bufferView.buffer(), 10);
glBufferSubData(GL_ARRAY_BUFFER, 5, dataView);

Notice that we only create a new view, not copy the data into another buffer. The snapshot build is also updated.

Amazing. Thanks so much. One last thing, not a bug this time I promise, a suggestion. I was updating my graphics driver the other day and once it installed it messed around with already open Chrome and long and the short I notice that the default behaviour for your library if it cannot get a WebGL context is to blast you with an alert saying you don’t have WebGL which then takes you to the get WebGL website.

A lot of the time this is desirable behaviour but not always. For example WebGL might only be a section of the page and the other stuff is still useful even if the WebGL isn’t working in which case it’s pretty annoying if you keep getting redirected whenever you tried to load it up. Also redirecting with alerts like that can screw up the back button on some browsers I think (because you can’t go back twice since you keep getting redirected). So perhaps A) include a function to test if WebGL is supported (also turns out you can test whether it is the browser not supporting WebGL or the hardware) and B) make the popup behaviour default but optional for the developer?

Anyway here is a quick function I wrote to test for WebGL support:


/**
 * Returns null is WebGL is supported otherwise a String giving the reason why not.
 */
private static native String isWebGLSupported() /*-{
    var canvas = $doc.createElement("canvas");
    var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
    if(gl && gl instanceof $wnd.WebGLRenderingContext) {
        return null;
    } else {
        if($wnd.WebGLRenderingContext ) {
            return "Hardware does not support WebGL";
        } else {
            return "Browser does not support WebGL";
        }
    }
}-*/;

I think there are a few reasons you might not be able to create a WebGL context if the browser supports it but I’m pretty sure I’m getting this from the WebGL spec on MDN so seems fairly legit. Also not 100% on the creating an offscreen canvas and canvas just to test for support but this is apparently the established method according to MDN again. Also if you incorporate this into the actual context creation then it’s a non-problem.

Obviously just my penny’s worth but what do you think?

Your idea is good, and it is already present in the WebGL4J library since 0.2.7. You can use the [icode]WebGL10.isSupported()[/icode] to test for WebGL 1.0 support, and for WebGL2, there is [icode]WebGL20.isSupported()[/icode]. These methods return a boolean so you can use them in a if check and they work pretty fine.

This method is also available in all the extensions too, and it is the recommended way if you want to get custom error handling.

Ah very good. Knew they existed for the extensions but just never thought to look on the core classes, sorry.

Hey @SHC, I found another little bug.

glGetUniformLocation() is supposed to return a “-1” if the uniform doesn’t exist in regular OpenGL. Obviously WebGL returns a “null” instead but the WebGLObjectMap maps a null to a zero. I suppose technically not a bug but I’m thinking undesirable behaviour?

Done, I actually never noticed that, so used the 0th location as null. Corrected it as per the documentation. Thanks @quew8 for mentioning it.

The change is in the commit d61533f and there is now a new snapshot build uploaded into the OSSRH repository.

Much appreciated as ever.

It’s a very useful library btw. At first I tried to write in pure JS but then as ever the application got bigger than 3/4 files and JS began to become increasingly untenable so I thought to myself oh no I’m going to have to write the bridge between WebGL and GWT myself and it’s going to be messy and horrible and then I remembered you posting about this and, as one of the most important marks of a good library, it just worked. So thank you.

Unlocked topic :point:

WebGL4J version 0.2.9 is now released into maven central. It fixes two bugs with the bindings, and also got partially documented.

[icode]Maven[/icode]


<dependency>
    <groupId>com.goharsha</groupId>
    <artifactId>webgl4j</artifactId>
    <version>0.2.9</version>
    <scope>compile</scope>
</dependency>

[icode]Gradle[/icode]


compile group: 'com.goharsha', name: 'webgl4j', version: '0.2.9'

// or shorthand notation
compile 'com.goharsha:webgl4j:0.2.9'

Also released on GitHub for those who are not using Gradle or Maven.