Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2018-04

Next language feature for pas2js...

41 messages · 10 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Ingemar Ragnemalm
Michael Van Canneyt wrote 13 lines
Hello, Now that interface support has been added to the list of implemented language features of pas2js, we're looking to get feedback on what best to tackle next. This time, the poll is not on the forum, so you do not need to have an account to vote. Here is a link to the poll: https://docs.google.com/forms/d/e/1FAIpQLScPVu6Y_X1QhOrYLWia4TVeKoZ3wiu-_PiMqJ0Zm8KW39FdCQ/viewform?usp=sf_link Michael.

I am very happy with pas2js and couldn't select any particular feature. What I want the most are more APIs, but I have been quite successful in implementing the ones I need so far. However, WebGL (which is interesting for me) is a big API so if anyone is working on that, or have figured out a way to auto-convert or something, I am interested.

Have I mentioned that I used pas2js on this year's Global Game Jam? Successfully!

/Ingemar

Michael Van Canneyt
to Ingemar Ragnemalm
Ingemar Ragnemalm wrote 23 lines
Michael Van Canneyt wrote: > Hello, > > Now that interface support has been added to the list of implemented language > features of pas2js, we're looking to get feedback on what best to tackle next. > > This time, the poll is not on the forum, so you do not need to have an > account to vote. > > Here is a link to the poll: > > https://docs.google.com/forms/d/e/1FAIpQLScPVu6Y_X1QhOrYLWia4TVeKoZ3wiu-_PiMqJ0Zm8KW39FdCQ/viewform?usp=sf_link > > Michael. I am very happy with pas2js and couldn't select any particular feature. What I want the most are more APIs, but I have been quite successful in implementing the ones I need so far. However, WebGL (which is interesting for me) is a big API so if anyone is working on that, or have figured out a way to auto-convert or something, I am interested.

Ah, webgl...

I had a look at this some time ago, and got depressed. Quickly closed the browser and didn't look back.
Same for webaudio :(

We have a test project that helps with converting APIs, but it's still very rudimentary and needs lots of help. Check democlasstopas.pas in the demos.

Have I mentioned that I used pas2js on this year's Global Game Jam? Successfully!

Glad to hear it, we need more such success stories !

If you could make a new wiki page with some information about it, and link to it from the main pas2js page, that would be hugely appreciated !

Michael.

Michael Schnell
to Michael Van Canneyt: Now that interface support has been added to the list of implemented language features of…
Michael Van Canneyt wrote
Now that interface support has been added to the list of implemented language features of pas2js, we're looking to get feedback on what best to tackle next.

Of course rather off-topic here, but as you ask:
How usable is Lazarus for pas2js development (code writing, GUI design, compiling, starting, debugging) at this point in time ?

-Michael

Benito van der Zander
to Michael Van Canneyt: Now that interface support has been added to the list of implemented language features of…

Hi,

I would like to vote for pointer support...

Cheers,
Benito

Michael Van Canneyt wrote 20 lines
Hello, Now that interface support has been added to the list of implemented language features of pas2js, we're looking to get feedback on what best to tackle next. This time, the poll is not on the forum, so you do not need to have an account to vote. Here is a link to the poll: https://docs.google.com/forms/d/e/1FAIpQLScPVu6Y_X1QhOrYLWia4TVeKoZ3wiu-_PiMqJ0Zm8KW39FdCQ/viewform?usp=sf_link Michael. _______________________________________________ fpc-pascal maillist  -  http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Michael Van Canneyt
to Benito van der Zander
Benito van der Zander wrote
Hi, I would like to vote for pointer support...

"Pointers to records" are supported.

But general purpose pointers and such are not planned.

Michael.

Mattias Gaertner
to Michael Van Canneyt
Show quoted text 8 lines
On Thu, 26 Apr 2018, Benito van der Zander wrote: > > Hi, > > I would like to vote for pointer support... "Pointers to records" are supported.

Basically pointers are implemented as JS references. For example a pointer can be assigned a class instance, an array, a procedure var, a method var, a @proc address, a @method address, record, etc.

That's why there is no pointer arithmetic, i.e. no p+1.

Mattias

Michael Van Canneyt
to Michael Schnell: Of course rather off-topic here, but as you ask: How usable is Lazarus for pas2js…
Michael Schnell wrote 8 lines
On 25.04.2018 15:20, Michael Van Canneyt wrote: > Now that interface support has been added to the list of implemented > language > features of pas2js, we're looking to get feedback on what best to > tackle next. Of course rather off-topic here, but as you ask: How usable is Lazarus for pas2js development (code writing, GUI design, compiling, starting, debugging) at this point in time ?

Better than Delphi for coding.
Worse than delphi for UI Design.

Debugging must be done in the browser.

Michael.

Ryan Joseph
to Michael Van Canneyt: Ah, webgl... I had a look at this some time ago, and got depressed. Quickly closed the…
Show quoted text 5 lines
On Apr 25, 2018, at 9:43 PM, Michael Van Canneyt wrote: Ah, webgl... I had a look at this some time ago, and got depressed. Quickly closed the browser and didn't look back. Same for webaudio :(

I’m actually a little curious about this myself because I’ve been using OpenGL often recently. I’ve seen the Ingemar’s demos but I only slightly grasp how it’s working.

The wiki says you’re actually parsing the Pascal (not compiling it) and outputting JavaScript. If that’s the case then how does porting libraries work in practice? For examples lets say I want to translate a single OpenGL function, how does that look?

Regards,
Ryan Joseph

Michalis Kamburelis
to Ryan Joseph

2018-05-01 4:50 GMT+02:00 Ryan Joseph :

Show quoted text 7 lines
> On Apr 25, 2018, at 9:43 PM, Michael Van Canneyt wrote: > > Ah, webgl... > > I had a look at this some time ago, and got depressed. Quickly closed the browser and didn't look back. Same for webaudio :(

The API of WebGL is actually mostly a subset of OpenGLES which is a subset of OpenGL. WebGL is quite small, if you compare it to other graphic APIs :) OpenGL(ES), Direct3D, Vulkan, Metal are way more complicated and larger.

Show quoted text 5 lines
I’m actually a little curious about this myself because I’ve been using OpenGL often recently. I’ve seen the Ingemar’s demos but I only slightly grasp how it’s working. The wiki says you’re actually parsing the Pascal (not compiling it) and outputting JavaScript. If that’s the case then how does porting libraries work in practice? For examples lets say I want to translate a single OpenGL function, how does that look?

I suspect that we will have a unit like WebGL in pas2js that exposes the necessary JS functions for Pascal applications. Engine like Castle Game Engine will used this unit when compiled with pas2js (instead of GL when compiled with FPC for desktop, or GLES20 when compiled with FPC for mobile). And then CGE can expose an API that looks the same (both in pas2js and FPC).

(Yes, I want to port Castle Game Engine one day to pas2js :) )

Regards,
Michalis

Ryan Joseph
to Michalis Kamburelis
On May 1, 2018, at 11:27 AM, Michalis Kamburelis wrote: I suspect that we will have a unit like WebGL in pas2js that exposes the necessary JS functions for Pascal applications.

Sure but how does the porting process look? I’m reading the wiki and it looks like it wraps JavaScript classes by doing stuff like:

TJSFunction = class external name 'Function'(TJSObject)

where “Function” is the JavaScript class name.

Looking at https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API I see WebGLRenderingContext has the entire OpenGL API (I think). Does that mean we just do something like:

const
  GLfloat = MAP_TO_SOMETHING; // do we have external consts?
type
  TWebGLRenderingContext = class external name 'WebGLRenderingContext' (TJSObject)
    procedure clearColor (red, green, blue, alpha: GLfloat); external name 'clearColor';
  end;
var
  context:
begin
  context := GetCurrentContext; // document.getElementById(‘canvas’).getContext()
  context.clearColor(0, 0, 0, 0);

Regards,
Ryan Joseph

Michael Van Canneyt
to Michalis Kamburelis: 2018-05-01 4:50 GMT+02:00 Ryan Joseph : The API of WebGL is actually mostly a subset of…
Michalis Kamburelis wrote 7 lines
>> >> I had a look at this some time ago, and got depressed. Quickly closed the browser and didn't look back. Same for webaudio :( The API of WebGL is actually mostly a subset of OpenGLES which is a subset of OpenGL. WebGL is quite small, if you compare it to other graphic APIs :) OpenGL(ES), Direct3D, Vulkan, Metal are way more complicated and larger.

Somehow this doesn't really lift my spirits. :)

Show quoted text 7 lines
> I’m actually a little curious about this myself because I’ve been using OpenGL often recently. I’ve seen the Ingemar’s demos but I only slightly grasp how it’s working. > > The wiki says you’re actually parsing the Pascal (not compiling it) and outputting JavaScript. If that’s the case then how does porting libraries work in practice? For examples lets say I want to translate a single OpenGL function, how does that look? > I suspect that we will have a unit like WebGL in pas2js that exposes the necessary JS functions for Pascal applications.

Correct.

Show quoted text 7 lines
Engine like Castle Game Engine will used this unit when compiled with pas2js (instead of GL when compiled with FPC for desktop, or GLES20 when compiled with FPC for mobile). And then CGE can expose an API that looks the same (both in pas2js and FPC). (Yes, I want to port Castle Game Engine one day to pas2js :) )

Good to hear it :)

Michael.

Michael Van Canneyt
to Ryan Joseph: Sure but how does the porting process look? I’m reading the wiki and it looks like it…
Ryan Joseph wrote 12 lines
> On May 1, 2018, at 11:27 AM, Michalis Kamburelis wrote: > > I suspect that we will have a unit like WebGL in pas2js that exposes > the necessary JS functions for Pascal applications. Sure but how does the porting process look? I’m reading the wiki and it looks like it wraps JavaScript classes by doing stuff like: TJSFunction = class external name 'Function'(TJSObject) where “Function” is the JavaScript class name.

This is actually a less good example, it's a little tricky.

Show quoted text 5 lines
Looking at https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API I see WebGLRenderingContext has the entire OpenGL API (I think). Does that mean we just do something like: const GLfloat = MAP_TO_SOMETHING; // do we have external consts?

Of sorts.
MyClass = Class external name 'my'

   const
     MyConst : integer
   end;

Will emit MyClass.MyConst. The compiler needs to know the type.

Show quoted text 11 lines
type TWebGLRenderingContext = class external name 'WebGLRenderingContext' (TJSObject) procedure clearColor (red, green, blue, alpha: GLfloat); external name 'clearColor'; end; var context : begin context := GetCurrentContext; // document.getElementById(‘canvas’).getContext() context.clearColor(0, 0, 0, 0);

That seems about correct.
You don't need the "external name 'n'" if the name is typed correctly.

Michael.

Ryan Joseph
to Michael Van Canneyt
Show quoted text 9 lines
On May 1, 2018, at 2:03 PM, Michael Van Canneyt wrote: Of sorts. MyClass = Class external name 'my' const MyConst : integer end; Will emit MyClass.MyConst. The compiler needs to know the type.

I’m confused now. The class is named WebGLRenderingContext in JS (I think that’s what it’s called by JS doesn’t really have classes does it?) so how does it look?

// no external name because the names are the same
type
  WebGLRenderingContext = class
    procedure clearColor (red, green, blue, alpha: GLfloat);
  end;

So constants must be part of the class? In the example below gl.COLOR_BUFFER_BIT is scoped to WebGLRenderingContext so I guess that’s the reason.

Also I mistyped, GLfloat is a type so how do this map to JS, or do I even need to since the names are the same?

How does this JS translate to Pascal then? drawingBufferWidth are read only properties but no type is specified so how does Pascal handle all the untyped variables we see in JS?

var canvas = document.createElement("canvas");
var gl = canvas.getContext("webgl")
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);

Regards,
Ryan Joseph

Ryan Joseph
to Mattias Gaertner
Show quoted text 5 lines
On May 1, 2018, at 2:55 PM, Mattias Gaertner wrote: GLFloat is a type, not a const. type GLFloat = double;

Yeah I mistyped. We shouldn’t be redefining GLfloat though (I doubt it’s a double in OpenGLES/WebGL either) so how does this (or other types) translate for the parser?

Regards,
Ryan Joseph

Mattias Gaertner
to Ryan Joseph
Show quoted text 7 lines
> On May 1, 2018, at 2:55 PM, Mattias Gaertner wrote: > > GLFloat is a type, not a const. > > type GLFloat = double; Yeah I mistyped. We shouldn’t be redefining GLfloat though (I doubt it’s a double in OpenGLES/WebGL either) so how does this (or other types) translate for the parser?

JS only knows double for numbers.

At compile time you can use almost all the normal types: byte, word, longint, etc.
pas2js has an alias single, but because internally it is a double this gives warnings.

Mattias

Michael Van Canneyt
to Ryan Joseph: I’m confused now. The class is named WebGLRenderingContext in JS (I think that’s what…
Ryan Joseph wrote 15 lines
> On May 1, 2018, at 2:03 PM, Michael Van Canneyt wrote: > > Of sorts. > MyClass = Class external name 'my' > const > MyConst : integer > end; > > Will emit MyClass.MyConst. The compiler needs to know the type. I’m confused now. The class is named WebGLRenderingContext in JS (I think that’s what it’s called by JS doesn’t really have classes does it?) so how does it look?

See below.

// no external name because the names are the same

That is only so for methods and fields. I corrected the class below:

type
   WebGLRenderingContext = class external name 'WebGLRenderingContext'
     procedure clearColor (red, green, blue, alpha: GLfloat);
   end;
So constants must be part of the class? In the example below gl.COLOR_BUFFER_BIT is scoped to WebGLRenderingContext so I guess that’s the reason.

Yes.

Constants without expression can only exist in an external class.

Also I mistyped, GLfloat is a type so how do this map to JS, or do I even need to since the names are the same?

You need to define types.

type
   GLfloat = double;
How does this JS translate to Pascal then? drawingBufferWidth are read only properties but no type is specified so how does Pascal handle all the untyped variables we see in JS?

This is pascal. You need a type.

https://www.khronos.org/registry/webgl/specs/latest/1.0/

shows that drawingBufferWidth has type GLsizei, which is a long.

If you don't know the type, use JSValue. It's the 'unknown type'. It has limited possibilities, in essence you'll need to typecast a JSValue before using it. You can assign JSValues of course.

Michael.

Ryan Joseph
to Mattias Gaertner: On Tue, 1 May 2018 15:03:30 +0700 JS only knows double for numbers. At compile time you…
Show quoted text 8 lines
On May 1, 2018, at 3:17 PM, Mattias Gaertner wrote: JS only knows double for numbers. At compile time you can use almost all the normal types: byte, word, longint, etc. pas2js has an alias single, but because internally it is a double this gives warnings.

what do we do for records then? We often need to pass arrays of specific types for functions such as glBufferData.

type
  TVec2f = record
    x, y: GLfloat;
  end;
type
  TVec2b = record
    x, y: GLubyte;
  end;
var
  verts: array[0..2] of TVec2f;
begin
  glBufferData(GL_ARRAY_BUFFER, sizeof(TVec2f) * 3, @verts, GL_STATIC_DRAW); // pass an array of TVec2 but how does JS know this?

Regards,
Ryan Joseph

Mattias Gaertner
to Ryan Joseph: I’m confused now. The class is named WebGLRenderingContext in JS (I think that’s what…
Show quoted text 11 lines
> On May 1, 2018, at 2:03 PM, Michael Van Canneyt wrote: > > Of sorts. > MyClass = Class external name 'my' > const > MyConst : integer > end; > > Will emit MyClass.MyConst. The compiler needs to know the type. I’m confused now.

I think you confused Michael. ;)

At the moment you can define external const like this:
var
  NaN: Double; external name 'NaN';
  Infinity: Double; external name 'Infinity';
  NegInfinity: Double; external name '-Infinity';

Note that the 'var' is a workaround till eventually pas2js supports external 'const' without expression.

A const inside an external class already works:

type
  TMyExt = class external name 'Bla'
    const LoVersion: GLFloat;
    const HiVersion: GLFloat; external name 'hiversion';
  end;

Mattias

Ryan Joseph
to Michael Van Canneyt: See below. That is only so for methods and fields. I corrected the class below: type…
Show quoted text 7 lines
On May 1, 2018, at 3:17 PM, Michael Van Canneyt wrote: > So constants must be part of the class? In the example below gl.COLOR_BUFFER_BIT is scoped to WebGLRenderingContext so I guess that’s the reason. Yes. Constants without expression can only exist in an external class.

Just curious but why can’t you declare a const anywhere for any reasons?

Show quoted text 8 lines
> > Also I mistyped, GLfloat is a type so how do this map to JS, or do I even need to since the names are the same? You need to define types. type GLfloat = double;

Why do we need to redefine the type if it’s already defined in the JS library? GLfloat isn’t a double also but see my other reply.

From the link you posted there are these types. Is that even JavaScript? I don’t remember there being typedefs in it or void functions.

typedef unsigned long  GLenum;
typedef boolean        GLboolean;
typedef unsigned long  GLbitfield;
typedef byte           GLbyte;         /* 'byte' should be a signed 8 bit type. */
typedef short          GLshort;
typedef long           GLint;
typedef long           GLsizei;
typedef long long      GLintptr;
typedef long long      GLsizeiptr;
// Ideally the typedef below would use 'unsigned byte', but that doesn't currently exist in Web IDL.
typedef octet          GLubyte;        /* 'octet' should be an unsigned 8 bit type. */
typedef unsigned short GLushort;
typedef unsigned long  GLuint;
typedef unrestricted float GLfloat;
typedef unrestricted float GLclampf;

There’s other types also like dictionaries and interface. How do those work? I don’t remember those being in JS either….

dictionary WebGLContextAttributes
 {
    GLboolean alpha = true;
    GLboolean depth = true;
    GLboolean stencil = false;
    GLboolean antialias = true;
    GLboolean premultipliedAlpha = true;
    GLboolean preserveDrawingBuffer = false;
    WebGLPowerPreference powerPreference = "default";
    GLboolean failIfMajorPerformanceCaveat = false;
};
interface WebGLActiveInfo
 {
    readonly attribute GLint size;
    readonly attribute GLenum type;
    readonly attribute DOMString name;
};
Show quoted text 13 lines
> > How does this JS translate to Pascal then? drawingBufferWidth are read only properties but no type is specified so how does Pascal handle all the untyped variables we see in JS? This is pascal. You need a type. https://www.khronos.org/registry/webgl/specs/latest/1.0/ shows that drawingBufferWidth has type GLsizei, which is a long. If you don't know the type, use JSValue. It's the 'unknown type'. It has limited possibilities, in essence you'll need to typecast a JSValue before using it. You can assign JSValues of course.

I see, that reference I used wasn’t complete.

Regards,
Ryan Joseph

Michael Van Canneyt
to Ryan Joseph
Ryan Joseph wrote 11 lines
> On May 1, 2018, at 3:17 PM, Michael Van Canneyt wrote: > >> So constants must be part of the class? In the example below gl.COLOR_BUFFER_BIT is scoped to WebGLRenderingContext so I guess that’s the reason. > > Yes. > > Constants without expression can only exist in an external class. Just curious but why can’t you declare a const anywhere for any reasons?

As far as I know, all consts in Javascript are scoped ?

If this is not the case, then of course we should allow it.

Show quoted text 11 lines
> >> >> Also I mistyped, GLfloat is a type so how do this map to JS, or do I even need to since the names are the same? > > You need to define types. > > type > GLfloat = double; Why do we need to redefine the type if it’s already defined in the JS library? GLfloat isn’t a double also but see my other reply.

You must define the type to something the compiler knows, so the compiler knows what operations it can do.

Imagine:

Type
   MyOpaqueType external;
Var
   I : MyOpaqueType;
begin
   // What can I do with I ?  Can I add it ? Can I multiply it ?...
end.

If you really do not know the type, use JSValue. But there is little you can do with a JSValue except assign or typecast it.

From the link you posted there are these types. Is that even JavaScript? I don’t remember there being typedefs in it or void functions.

The link is a spec. All javascript constructs have such a spec, and they are a form of IDL, which does specifie types.

Show quoted text 10 lines
interface WebGLActiveInfo { readonly attribute GLint size; readonly attribute GLenum type; readonly attribute DOMString name; }; > >> >> How does this JS translate to Pascal then? drawingBufferWidth are read only properties but no type is specified so how does Pascal handle all the untyped variables we see in JS?

You are mistaken where that is concerned.

See above: Most APIs _do_ specify a type. You must look it up. Have a look at the web.pas or js.pas or even libjquery.pas units. Most identifiers have a type, the use of JSValue is quite limited.

Read-only Attributes can be translated to read-only properties.

The above would be

Type
    WebGLActiveInfo = class external name 'WebGLActiveInfo'
    Private
     fSize : GLint; external name 'size';
     ftype: GLEnum; external name 'type';
     fName : DOMString ; external name 'name';
   Public
     Property size : GLInt Read FSize;
     Property &type : GLEnum Read fType;
     Propert Name : DomString read FName;
   end;

Michael.

Michael Van Canneyt
to Mattias Gaertner: On Tue, 1 May 2018 14:20:12 +0700 I think you confused Michael. ;) At the moment you can…
Mattias Gaertner wrote 25 lines
On Tue, 1 May 2018 14:20:12 +0700 Ryan Joseph wrote: > > On May 1, 2018, at 2:03 PM, Michael Van Canneyt wrote: > > > > Of sorts. > > MyClass = Class external name 'my' > > const > > MyConst : integer > > end; > > > > Will emit MyClass.MyConst. The compiler needs to know the type. > > I’m confused now. I think you confused Michael. ;) At the moment you can define external const like this: var NaN: Double; external name 'NaN'; Infinity: Double; external name 'Infinity'; NegInfinity: Double; external name '-Infinity'; Note that the 'var' is a workaround till eventually pas2js supports external 'const' without expression.

Well, I specially did not mention this, because I consider it a dirty hack. a var doesn't protect you from assigning to it (it's a variable, after all).

One preferably shouldn't teach people bad habits. :)

Michael.

Mattias Gaertner
to Ryan Joseph: Just curious but why can’t you declare a const anywhere for any reasons? Why do we need…
[...] > Constants without expression can only exist in an external class. Just curious but why can’t you declare a const anywhere for any reasons?

You can.

Show quoted text 8 lines
>> Also I mistyped, GLfloat is a type so how do this map to JS, or do I even need to since the names are the same? > > You need to define types. > > type > GLfloat = double; Why do we need to redefine the type if it’s already defined in the JS library?

JS has (almost) no types. WebGL has some intrinsic types. The unit webgl will be defining the corresponding Pascal types.

Mattias

Ryan Joseph
to Michael Van Canneyt: As far as I know, all consts in Javascript are scoped ? If this is not the case, then of…
Show quoted text 6 lines
On May 1, 2018, at 3:50 PM, Michael Van Canneyt wrote: As far as I know, all consts in Javascript are scoped ? If this is not the case, then of course we should allow it.

I think they added const. In the past I’ve seen using “let” but I don’t think that’s a real const if that matters or not.

Show quoted text 5 lines
You must define the type to something the compiler knows, so the compiler knows what operations it can do. If you really do not know the type, use JSValue. But there is little you can do with a JSValue except assign or typecast it.

I see. So the type is really for the parser but it gets passed on as the real name to JS.

Show quoted text 22 lines
You are mistaken where that is concerned. See above: Most APIs _do_ specify a type. You must look it up. Have a look at the web.pas or js.pas or even libjquery.pas units. Most identifiers have a type, the use of JSValue is quite limited. Read-only Attributes can be translated to read-only properties. The above would be Type WebGLActiveInfo = class external name 'WebGLActiveInfo' Private fSize : GLint; external name 'size'; ftype: GLEnum; external name 'type'; fName : DOMString ; external name 'name'; Public Property size : GLInt Read FSize; Property &type : GLEnum Read fType; Propert Name : DomString read FName; end;

Interface is just a class? That makes sense but “dictionary” is a real type I assume because I know JS has “associative arrays” or hash maps. How do those work in Pascal?

Shouldn’t there be some automatic tool to parse JS api's to Pascal then? Makes sense so API’s like this can be dumped out easily.

Regards,
Ryan Joseph

Michael Van Canneyt
to Ryan Joseph: what do we do for records then? We often need to pass arrays of specific types for…
Ryan Joseph wrote 27 lines
> On May 1, 2018, at 3:17 PM, Mattias Gaertner wrote: > > JS only knows double for numbers. > > At compile time you can use almost all the normal types: byte, > word, longint, etc. > pas2js has an alias single, but because internally it is a double this > gives warnings. what do we do for records then? We often need to pass arrays of specific types for functions such as glBufferData. type TVec2f = record x, y: GLfloat; end; type TVec2b = record x, y: GLubyte; end; var verts: array[0..2] of TVec2f; begin glBufferData(GL_ARRAY_BUFFER, sizeof(TVec2f) * 3, @verts, GL_STATIC_DRAW); // pass an array of TVec2 but how does JS know this?

Arrays are arrays in JS. 'records' in JS are (literal) objects.

Note that the above call does not exist in webGL. But if something like it existed, it would probably be simply

glBufferData(verts, GL_STATIC_DRAW);
defined as
glBufferData(data : JSValue; aType : int);

The WebGL API would then presumably internally inspect the data, and if it is an array, convert the Javascript array of objects to something the underlying GL understands.

Michael.

Mattias Gaertner
to Ryan Joseph: what do we do for records then? We often need to pass arrays of specific types for…
Show quoted text 17 lines
[...] what do we do for records then? We often need to pass arrays of specific types for functions such as glBufferData. type TVec2f = record x, y: GLfloat; end; type TVec2b = record x, y: GLubyte; end; var verts: array[0..2] of TVec2f; begin glBufferData(GL_ARRAY_BUFFER, sizeof(TVec2f) * 3, @verts, GL_STATIC_DRAW); // pass an array of TVec2 but how does JS know this?

Here is an JS example:

---JS-START---
var vertices = [-0.5, 0.5, -0.5, -0.5, 0.0, -0.5,];
// Create a new buffer object
var vertex_buffer = gl.createBuffer();
// Bind an empty array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Pass the vertices data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
// Unbind the buffer
gl.bindBuffer(gl.ARRAY_BUFFER, null);
---JS-END---

In pas2js it will probably look similar to this:

var vertices: array of glfloat = (-0.5, 0.5, -0.5, -0.5, 0.0, -0.5);
var vertex_buffer: TInsertNameHere;
begin
  // Create a new buffer object
  vertex_buffer = gl.createBuffer();
  // Bind an empty array buffer to it
  gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
  // Pass the vertices data to the buffer
  gl.bufferData(gl.ARRAY_BUFFER, Float32Array.new(vertices), gl.STATIC_DRAW);
  // Unbind the buffer
  gl.bindBuffer(gl.ARRAY_BUFFER, nil);
end;

Mattias

Michael Van Canneyt
to Ryan Joseph: I think they added const. In the past I’ve seen using “let” but I don’t think…
Ryan Joseph wrote 16 lines
> > The above would be > > Type > WebGLActiveInfo = class external name 'WebGLActiveInfo' > Private > fSize : GLint; external name 'size'; > ftype: GLEnum; external name 'type'; > fName : DOMString ; external name 'name'; > Public > Property size : GLInt Read FSize; > Property &type : GLEnum Read fType; > Propert Name : DomString read FName; > end; Interface is just a class? That makes sense but “dictionary” is a real type I assume because I know JS has “associative arrays” or hash maps. How do those work in Pascal?

Dictionary is just a TJSObject. The properties are the dictionary.

Shouldn’t there be some automatic tool to parse JS api's to Pascal then? Makes sense so API’s like this can be dumped out easily.

If all you have is the Javascript type of things, then you can dump out the api, given an instance of an object.

There is a demo project in the SVN which shows how.

But since in Javascript there are no types, the types will be blank.

If you have access to the underlying API spec in the form of an IDL, then we could make a tool that parses the IDL and dumps the API in the form of "external" declarations.

Michael.

Michael Van Canneyt
to Mattias Gaertner: On Tue, 1 May 2018 15:23:25 +0700 Here is an JS example: ---JS-START--- var vertices =…
Mattias Gaertner wrote 34 lines
On Tue, 1 May 2018 15:23:25 +0700 Ryan Joseph wrote: > [...] > what do we do for records then? We often need to pass arrays of specific types for functions such as glBufferData. > > type > TVec2f = record > x, y: GLfloat; > end; > > type > TVec2b = record > x, y: GLubyte; > end; > > var > verts: array[0..2] of TVec2f; > begin > glBufferData(GL_ARRAY_BUFFER, sizeof(TVec2f) * 3, @verts, GL_STATIC_DRAW); // pass an array of TVec2 but how does JS know this? Here is an JS example: ---JS-START--- var vertices = [-0.5, 0.5, -0.5, -0.5, 0.0, -0.5,]; // Create a new buffer object var vertex_buffer = gl.createBuffer(); // Bind an empty array buffer to it gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer); // Pass the vertices data to the buffer gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

So it does exist :)
Nice, I should have typed gl.bufferData instead of glbufferdata when searching :-)

Michael.

Ryan Joseph
to Michael Van Canneyt: Dictionary is just a TJSObject. The properties are the dictionary. If all you have is the…
Show quoted text 5 lines
On May 1, 2018, at 4:12 PM, Michael Van Canneyt wrote: If you have access to the underlying API spec in the form of an IDL, then we could make a tool that parses the IDL and dumps the API in the form of "external" declarations.

There it is. A parser needs to be made I guess. You could chop that us pretty easily with a regex based PHP script.

https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl

Regards,
Ryan Joseph

Michael Van Canneyt
to Ryan Joseph
Ryan Joseph wrote 9 lines
> On May 1, 2018, at 4:12 PM, Michael Van Canneyt wrote: > > If you have access to the underlying API spec in the form of an IDL, then we > could make a tool that parses the IDL and dumps the API in the form of > "external" declarations. There it is. A parser needs to be made I guess. You could chop that us pretty easily with a regex based PHP script.

You were doing great just up to the letters PHP ;-)

Michael.

Ryan Joseph
to Mattias Gaertner: On Tue, 1 May 2018 15:23:25 +0700 Here is an JS example: ---JS-START--- var vertices =…
Show quoted text 20 lines
On May 1, 2018, at 4:10 PM, Mattias Gaertner wrote: In pas2js it will probably look similar to this: var vertices: array of glfloat = (-0.5, 0.5, -0.5, -0.5, 0.0, -0.5); var vertex_buffer: TInsertNameHere; begin // Create a new buffer object vertex_buffer = gl.createBuffer(); // Bind an empty array buffer to it gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer); // Pass the vertices data to the buffer gl.bufferData(gl.ARRAY_BUFFER, Float32Array.new(vertices), gl.STATIC_DRAW); // Unbind the buffer gl.bindBuffer(gl.ARRAY_BUFFER, nil); end;

Strange they renamed glGenBuffers to createBuffer().

That aside though not having records is a problem I imagine. They don’t exist in JS right, so how do they deal with that? I guess you could pack a record into an array literal if all the types were the same. Arrays of arrays in literals works also.

can’t we do that? We’re at the mercy of Float32Array.new packing that though or we need another method. What a waste of processing to convert that. That would be a nightmare for real applications to iterate all the verticies like that every time they were copied to the GPU.

verts: array[0..2] of TVec2f; // var arr = [[0,0],[0,0],[0,0]]

Regards,
Ryan Joseph

Michael Van Canneyt
to Ryan Joseph
Ryan Joseph wrote 28 lines
> On May 1, 2018, at 4:10 PM, Mattias Gaertner wrote: > > In pas2js it will probably look similar to this: > > var vertices: array of glfloat = (-0.5, 0.5, -0.5, -0.5, 0.0, -0.5); > var vertex_buffer: TInsertNameHere; > begin > // Create a new buffer object > vertex_buffer = gl.createBuffer(); > > // Bind an empty array buffer to it > gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer); > > // Pass the vertices data to the buffer > gl.bufferData(gl.ARRAY_BUFFER, Float32Array.new(vertices), gl.STATIC_DRAW); > > // Unbind the buffer > gl.bindBuffer(gl.ARRAY_BUFFER, nil); > end; > Strange they renamed glGenBuffers to createBuffer(). That aside though not having records is a problem I imagine. They don’t exist in JS right, so how do they deal with that? I guess you could pack a record into an array literal if all the types were the same. Arrays of arrays in literals works also. can’t we do that? We’re at the mercy of Float32Array.new packing that though or we need another method. What a waste of processing to convert that. That would be a nightmare for real applications to iterate all the verticies like that every time they were copied to the GPU.

What's wrong with the above code ?

It obviously works well enough, otherwise they wouldn't have made the API so.

The float32 array is a Javascript type that encapsulates a memory buffer. I assume the webgl creators decided it has the optimal layout for their needs.

Michael.

Ryan Joseph
to Michael Van Canneyt
Show quoted text 8 lines
On May 1, 2018, at 4:37 PM, Michael Van Canneyt wrote: What's wrong with the above code ? It obviously works well enough, otherwise they wouldn't have made the API so. The float32 array is a Javascript type that encapsulates a memory buffer. I assu

It’s difficult to work with. With OpenGL what you have is a record with all the fields that are the data for vertex (positions, colors, normals etc…) and you tell OpenGL at what offset and stride the data starts. If you use to just array literals like that it would be very messy.

    void vertexAttribPointer(GLuint index, GLint size, GLenum type,
                             GLboolean normalized, GLsizei stride, GLintptr offset);

That’s what I would expect not using WebGL before. Getting that down to typed arrays using wrapper functions would be a mess though. Ouch. No idea how that’s supposed to look in WebGL.

// array of TVertex
[

  // vertex 1
  [
  [0, 0], // position (vec2f)
  [255, 255, 255], // color (vec4b)
  [0, 1], // texture coord (vec2f)
  ],
  // vertex 2
  [
  [0, 0], // position (vec2f)
  [255, 255, 255], // color (vec4b)
  [0, 1], // texture coord (vec2f)
  ],
  // vertex 3
  [
  [0, 0], // position (vec2f)
  [255, 255, 255], // color (vec4b)
  [0, 1], // texture coord (vec2f)
  ]

]

type
  TVertex = record
    pos: TVec2f;
    color: TVec4b;
    texCoord: TVec2f;
  end;
verts: array[0..2] of TVertex;

The parser could break down records into those arrays but it would be complicated I suspect.

Regards,
Ryan Joseph

Mattias Gaertner
to Michael Van Canneyt: Well, I specially did not mention this, because I consider it a dirty hack. a var doesn't…
Show quoted text 6 lines
[...] > Note that the 'var' is a workaround till eventually pas2js supports > external 'const' without expression. Well, I specially did not mention this, because I consider it a dirty hack. a var doesn't protect you from assigning to it (it's a variable, after all).

Trunk now supports external const. :)

One preferably shouldn't teach people bad habits. :)

Good point.

Mattias

Michael Van Canneyt
to Ryan Joseph: It’s difficult to work with. With OpenGL what you have is a record with all the fields…
Ryan Joseph wrote 52 lines
> On May 1, 2018, at 4:37 PM, Michael Van Canneyt wrote: > > What's wrong with the above code ? > > It obviously works well enough, otherwise they wouldn't have made the API so. > > The float32 array is a Javascript type that encapsulates a memory buffer. > I assu It’s difficult to work with. With OpenGL what you have is a record with all the fields that are the data for vertex (positions, colors, normals etc…) and you tell OpenGL at what offset and stride the data starts. If you use to just array literals like that it would be very messy. void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); That’s what I would expect not using WebGL before. Getting that down to typed arrays using wrapper functions would be a mess though. Ouch. No idea how that’s supposed to look in WebGL. // array of TVertex [ // vertex 1 [ [0, 0], // position (vec2f) [255, 255, 255], // color (vec4b) [0, 1], // texture coord (vec2f) ], // vertex 2 [ [0, 0], // position (vec2f) [255, 255, 255], // color (vec4b) [0, 1], // texture coord (vec2f) ], // vertex 3 [ [0, 0], // position (vec2f) [255, 255, 255], // color (vec4b) [0, 1], // texture coord (vec2f) ] ] type TVertex = record pos: TVec2f; color: TVec4b; texCoord: TVec2f; end; verts: array[0..2] of TVertex; The parser could break down records into those arrays but it would be complicated I suspect.

I don't think we'll introduce language tricks for such things.

The WebGL people made do with what Javascript offers. Likewise, we make do with what pascal and Javascript offer...

Michael.

Marco van de Voort
to Michael Van Canneyt: You were doing great just up to the letters PHP ;-) Michael.

In our previous episode, Michael Van Canneyt said:

Show quoted text 7 lines
>> If you have access to the underlying API spec in the form of an IDL, then we >> could make a tool that parses the IDL and dumps the API in the form of >> "external" declarations. > > There it is. A parser needs to be made I guess. You could chop that us pretty easily with a regex based PHP script. You were doing great just up to the letters PHP ;-)

I already stumbled on regex :_)

Ryan Joseph
to Marco van de Voort
On May 1, 2018, at 5:55 PM, Marco van de Voort wrote: I already stumbled on regex :_)

Anyone feel free to make a good example of a token parser in Pascal so I can see how it looks. I never an actual good parser that understands syntax so I don’t have any good examples to go by.

In PHP I always just load the file into string and loop over it line by line using regex to cut out the parts I need. I like it because it’s so easy to write and gets the job done. What ever I would make it Pascal would be 10x larger probably.

Regards,
Ryan Joseph

Unknown author
to Ryan Joseph
Ryan Joseph wrote
In PHP I always just load the file into string and loop over it line by line using regex to cut out the parts I need. I like it because it’s so easy to write and gets the job done. What ever I would make it Pascal would be 10x larger probably.

FWIW: you can do this (line parsing) in any language that supports regex...

the size thing you speak of is the difference between scripted languages and compiled binary languages...

kinda makes one wonder if pascal script might be able to handle the task...

NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list unless* *a signed and pre-paid contract is in effect with us.*