Testing Browser.hx externs with WebGL

97 views
Skip to first unread message

Jonathan Hardie

unread,
Feb 1, 2013, 10:39:47 PM2/1/13
to haxe...@googlegroups.com
I've been starting to have a play with WebGL via the new Browser.hx externs and current Haxe SVN, but I've started noticing things that don't seem to be quite right, and are making me question if the approach of generating these externs programatically from Webkit/MDN is the correct one.

Please let me know if I'm missing something obvious, but following are some examples of the kinds of things I've noticed.  I'm using Haxe SVN in IntelliJ with the Haxe plugin.

* there is `canvas.getContext2d`, should there also be `canvas.getContext3d` which either gets "experimental-webgl" or "webgl" and returns `js.html.webgl.RenderingContext`?  I found `RenderingContext` difficult to find at first since I had to look for it in the webgl package, while `CanvasRenderingContext2D` is in the html package.  Just using `canvas.getContext("experimental-webgl")` returns a `CanvasRenderingContext` type, which would need casting into a variable of type `webgl.RenderingContext`.

* WebGL RenderingContext has a bunch of inline static vars, that *look* like constants because of their uppercase naming, but are actually just regular instance variables.  For instance, I can write `glContext.clearColor(1, 0, 0, 1)` to set the `COLOR_BUFFER_BIT` to red.  However, `COLOR_BUFFER_BIT` and other variables like it belong to the current webGL context.  If I have another webgl context in the same document it should have it's own version of `COLOR_BUFFER_BIT`, that can be set to a different value.  Currently I can't access `glContext.COLOR_BUFFER_BIT`, only `RenderingContext.COLOR_BUFFER_BIT` - this doesn't seem like it should be a static variable.

This works in pure JS:
 var canvas = document.createElement("canvas");
 document
.body.appendChild(canvas);
 canvas
.width = 300;
 canvas
.height = 300;
 
 
var canvas2 = document.createElement("canvas");
 document
.body.appendChild(canvas2);
 canvas2
.width = 300;
 canvas2
.height = 300;
 
 
var gl = canvas.getContext("experimental-webgl");
 
var gl2 = canvas2.getContext("experimental-webgl");
 
 gl
.clearColor(1, 0, 0, 1);
 gl2
.clearColor(0, 1, 0, 1);
 
 gl
.clear(gl.COLOR_BUFFER_BIT);
 gl2
.clear(gl2.COLOR_BUFFER_BIT);


-- Gives me two different WebGL/canvas contexts with different colours.
* `Console.log` and other console functions don't currently accept *any* arguments.  This one is tricky I know, since `console.log` can take an arguments list of arbitrary length. `js.Browser.window.console.log("foo");` gives an error "Too many arguments, Function 'log' requires no arguments".  Attempting to use via `js.html.Console.log("foo");` gives the error "js.html.#Console has no field log" – surely this should be a static function, since it's not possible to instantiate Console?  ( know I could just use `trace` for this use-case, but that's not the point. )

A final note, and I know this has been discussed before:  the IDE auto-completion list for js.html.webgl.* is HUGE, and it's difficult to find what you're looking for unless you know exactly what it's called.  I think it would be good to break this down into further categories if possible.

I'd really like to be able to contribute to this project in the future, as I think it's a really important one for Haxe to get right, but I'm not sure of exactly the best way to proceed while the externs are dynamically generated.  Is there a way to patch these types of things into the generator system being used so that manual changes are respected when the externs are regenerated?

Cheers,
Jonathan

Nicolas Cannasse

unread,
Feb 2, 2013, 3:38:44 AM2/2/13
to haxe...@googlegroups.com
Le 02/02/2013 04:39, Jonathan Hardie a �crit :
> I've been starting to have a play with WebGL via the new Browser.hx
> externs and current Haxe SVN, but I've started noticing things that
> don't seem to be quite right, and are making me question if the approach
> of generating these externs programatically from Webkit/MDN is the
> correct one.
>
> Please let me know if I'm missing something obvious, but following are
> some examples of the kinds of things I've noticed. I'm using Haxe SVN
> in IntelliJ with the Haxe plugin.

Hi,

First thank you for giving it some test. We are actually looking for
feedback and given the API size the more users we hear from the better
it will be.

> * there is `canvas.getContext2d`, should there also be
> `canvas.getContext3d` which either gets "experimental-webgl" or "webgl"
> and returns `js.html.webgl.RenderingContext`?

Right. That's the kind of small improvement that we can add. Done on SVN.

> * WebGL RenderingContext has a bunch of inline static vars, that *look*
> like constants because of their uppercase naming, but are actually just
> regular instance variables.

To my knowledge they are actual real constants. The WebGL specification
even gives their actual integer value which is inlined by Haxe code.
Please tell us if you experiment actual issues with they way it's done
for some constants.

> * `Console.log` and other console functions don't currently accept *any*
> arguments. This one is tricky I know, since `console.log` can take an
> arguments list of arbitrary length.

You're right. I think that might be because the generator don't handle
"rest" arguments.

@Bruno : could you check if that's doable to add
(?p1:Dynamic,?p2:Dynamic,?p3:Dynamic,?p4:Dynamic) for these cases ?

> `js.Browser.window.console.log("foo");` gives an error "Too many
> arguments, Function 'log' requires no arguments". Attempting to use via
> `js.html.Console.log("foo");` gives the error "js.html.#Console has no
> field log" � surely this should be a static function, since it's not
> possible to instantiate Console? ( know I could just use `trace` for
> this use-case, but that's not the point. )

The console is instantiated in the js.Browser.window instance, so
there's no reason it should be static here.

> A final note, and I know this has been discussed before: the IDE
> auto-completion list for js.html.webgl.* is HUGE, and it's difficult to
> find what you're looking for unless you know exactly what it's called.
> I think it would be good to break this down into further categories if
> possible.

I don't think that breaking it down is a good idea, because it would
clearly change the way it's used in JS.

Also, after hitting one ore two letters, the list of functions highly
decrease so I guess it's just a matter of getting used to the API.

> I'd really like to be able to contribute to this project in the future,
> as I think it's a really important one for Haxe to get right, but I'm
> not sure of exactly the best way to proceed while the externs are
> dynamically generated. Is there a way to patch these types of things
> into the generator system being used so that manual changes are
> respected when the externs are regenerated?

That's a good question. Right now we can make some patches but for
systematic things such as the Console.log one that might require a full
regeneration. In that case we will have to make sure not to overwrite
some patches but there's not a lot atm.

Best,
Nicolas

Bruno Garcia

unread,
Feb 2, 2013, 6:49:38 PM2/2/13
to haxe...@googlegroups.com
On Fri, 1 Feb 2013 19:39:47 -0800 (PST)
Jonathan Hardie <jonatha...@gmail.com> wrote:

> * there is `canvas.getContext2d`, should there also be
> `canvas.getContext3d` which either gets "experimental-webgl" or
> "webgl" and returns `js.html.webgl.RenderingContext`? I found
> `RenderingContext` difficult to find at first since I had to look for
> it in the webgl package, while `CanvasRenderingContext2D` is in the
> html package. Just using `canvas.getContext("experimental-webgl")`
> returns a `CanvasRenderingContext` type, which would need casting
> into a variable of type `webgl.RenderingContext`.

canvas.getContextWebGL is now on SVN.

> * WebGL RenderingContext has a bunch of inline static vars, that
> *look* like constants because of their uppercase naming, but are
> actually just regular instance variables.

They actually are constants. WebGL does let you access them as static
properties on the RenderingContext class or as readonly instance
variables. Haxe can't support both (not allowed to have a static named
the same as a member) and using the static has the benefit of being
inlinable.

I'd recommend doing something like this:

import js.html.webgl.RenderingContext in GL;
// ...
ctx.clear(GL.COLOR_BUFFER_BIT);

Maybe we should just rename RenderingContext to GL?

> * `Console.log` and other console functions don't currently accept
> *any* arguments. This one is tricky I know, since `console.log` can
> take an arguments list of arbitrary length.

Fixed on SVN, thanks!

> I'd really like to be able to contribute to this project in the
> future, as I think it's a really important one for Haxe to get right,
> but I'm not sure of exactly the best way to proceed while the externs
> are dynamically generated. Is there a way to patch these types of
> things into the generator system being used so that manual changes
> are respected when the externs are regenerated?

Send patches to the Python generator at
https://github.com/aduros/Browser.hx. Any manual changes to the
generated Haxe will be overwritten.

Bruno

Bruno Garcia

unread,
Feb 2, 2013, 8:24:25 PM2/2/13
to Bruno Garcia, haxe...@googlegroups.com
On Sat, 2 Feb 2013 15:49:38 -0800
Bruno Garcia <b...@aduros.com> wrote:

> Maybe we should just rename RenderingContext to GL?

Instead of the rename, I added a typedef GL = RenderingContext for
easier access to the constants.

Bruno

Jonathan Hardie

unread,
Feb 2, 2013, 9:31:33 PM2/2/13
to haxe...@googlegroups.com, b...@aduros.com


On Sunday, 3 February 2013 12:49:38 UTC+13, Bruno Garcia wrote:
On Fri, 1 Feb 2013 19:39:47 -0800 (PST)
Jonathan Hardie <jonatha...@gmail.com> wrote:

> * there is `canvas.getContext2d`, should there also be
> `canvas.getContext3d` which either gets "experimental-webgl" or
> "webgl" and returns `js.html.webgl.RenderingContext`?  I found
> `RenderingContext` difficult to find at first since I had to look for
> it in the webgl package, while `CanvasRenderingContext2D` is in the
> html package.  Just using `canvas.getContext("experimental-webgl")`
> returns a `CanvasRenderingContext` type, which would need casting
> into a variable of type `webgl.RenderingContext`.

canvas.getContextWebGL is now on SVN.

> * WebGL RenderingContext has a bunch of inline static vars, that
> *look* like constants because of their uppercase naming, but are
> actually just regular instance variables.

They actually are constants. WebGL does let you access them as static
properties on the RenderingContext class or as readonly instance
variables. Haxe can't support both (not allowed to have a static named
the same as a member) and using the static has the benefit of being
inlinable.

Okay, that makes sense, I was following some WebGL tutorials that treated them as instance variables, perhaps we just need to make clear in the documentation somewhere that Haxe doesn't support some features/side effects of having multiple WebGL contexts in the same document.  I don't think this is much of an issue, as I think it's quite an edge case?
 

I'd recommend doing something like this:

    import js.html.webgl.RenderingContext in GL;
    // ...
    ctx.clear(GL.COLOR_BUFFER_BIT);

Maybe we should just rename RenderingContext to GL?

This is a nice, convenience, thanks!  I hadn't seen the import X in Y syntax before, it's nice.
 

> * `Console.log` and other console functions don't currently accept
> *any* arguments.  This one is tricky I know, since `console.log` can
> take an arguments list of arbitrary length.

Fixed on SVN, thanks!
 
Great, I'm sure I've never needed to pass more than 5 arguments at one time. 


> I'd really like to be able to contribute to this project in the
> future, as I think it's a really important one for Haxe to get right,
> but I'm not sure of exactly the best way to proceed while the externs
> are dynamically generated.  Is there a way to patch these types of
> things into the generator system being used so that manual changes
> are respected when the externs are regenerated?

Send patches to the Python generator at
https://github.com/aduros/Browser.hx. Any manual changes to the
generated Haxe will be overwritten.

Bruno

I guess I will have to try my hand at some python if I have anything to contribute :-P

I'll be sure to note anything else I notice as I continue my exploration.  

@Nicolas: Already I'm longing for GLSL support from HxSL ;-)

Cheers,

Jonathan 

David Peek

unread,
Feb 2, 2013, 11:12:19 PM2/2/13
to haxe...@googlegroups.com
Hi guys,

Though I'm not sure it's a great idea, I thought it was worth mentioning since we're talking about it.

When I was playing with WebGL a while ago, I had the idea of using enums to group huge number of integer constants into groups. It's possible with @:fakeEnum, and means you get some compiler check on the many methods that take SOME_GL_CONSTANT, only to tell you it's not the right one at run time.

Pros: Slightly less typing, better autocompletion, and compile time checking.
Cons: a bit too "magical", values aren't inlined (because we're getting them all from WebGLRenderingContext) but this should be possible (see https://groups.google.com/forum/?fromgroups=#!searchin/haxelang/inline$20fakeEnum/haxelang/5QylhNwDZpU/SfwfTGgHx60J)

As I said, not sure if it's a great idea, but it's certainly another area where the compiler can help catch errors.

Here's the (not quite complete) extern I was using:

Best,
David

Nicolas Cannasse

unread,
Feb 3, 2013, 4:13:48 AM2/3/13
to haxe...@googlegroups.com
Le 03/02/2013 03:31, Jonathan Hardie a �crit :
> They actually are constants. WebGL does let you access them as static
> properties on the RenderingContext class or as readonly instance
> variables. Haxe can't support both (not allowed to have a static named
> the same as a member) and using the static has the benefit of being
> inlinable.
>
>
> Okay, that makes sense, I was following some WebGL tutorials that
> treated them as instance variables, perhaps we just need to make clear
> in the documentation somewhere that Haxe doesn't support some
> features/side effects of having multiple WebGL contexts in the same
> document.

Haxe does support multiple WebGL contexts. They are real constants so
they do not depend on the context.

Best,
Nicolas

Nicolas Cannasse

unread,
Feb 3, 2013, 4:16:27 AM2/3/13
to haxe...@googlegroups.com
Le 03/02/2013 05:12, David Peek a �crit :
> Hi guys,
>
> Though I'm not sure it's a great idea, I thought it was worth mentioning
> since we're talking about it.
>
> When I was playing with WebGL a while ago, I had the idea of using enums
> to group huge number of integer constants into groups. It's possible
> with @:fakeEnum, and means you get some compiler check on the many
> methods that take SOME_GL_CONSTANT, only to tell you it's not the right
> one at run time.
>
> Pros: Slightly less typing, better autocompletion, and compile time
> checking.
> Cons: a bit too "magical", values aren't inlined (because we're getting
> them all from WebGLRenderingContext) but this should be possible
> (see https://groups.google.com/forum/?fromgroups=#!searchin/haxelang/inline$20fakeEnum/haxelang/5QylhNwDZpU/SfwfTGgHx60J)
>
> As I said, not sure if it's a great idea, but it's certainly another
> area where the compiler can help catch errors.
>
> Here's the (not quite complete) extern I was using:
> https://gist.github.com/4700522

Quite a good idea. This would both strictly type the API and reduce the
amount of statics constants.

Do someone volunteer to get that into the SVN ?

Best,
Nicolas

Reply all
Reply to author
Forward
0 new messages