Search code examples
webglhaxe

Rendering image using texSubImage2D in Haxe


I am learning how to stamp an image onto my canvas using Haxe and I have read that texSubImage2D should be the function I need to do the job.

I have read some documentation found here and thought I could implement what I was after by completing the following params:

void gl.texSubImage2D(target, level, xoffset, yoffset, format, type, HTMLImageElement? pixels);  

This is what I did:

gl.texSubImage2D (cast fluid.dyeRenderTarget.writeToTexture, 0, Math.round(mouse.x), Math.round(mouse.y), gl.RGB, gl.UNSIGNED_BYTE, document.querySelector('img[src="images/myImage.jpg"]'));

However, when I try to build the project, I am getting the following errors:

src/Main.hx:571: characters 135-191 : js.html.Element should be Int
src/Main.hx:571: characters 135-191 : For function argument 'format'

When I went back to the docs, the format I have passed gl.RGB is an accepted param, so I am not sure where I am going wrong.

Any guidance would be really appreciated.


Solution

  • I can't quite reproduce the error message you're getting, I think the errors might have improved a bit in more in recent Haxe versions. Anyway, there's a few issues here:

    • Firstly, by doing gl.RGB / gl.UNSIGNED_BYTE, you're trying to access static fields from an instance. I actually get a helpful error for this:

      Cannot access static field RGB from a class instance

      While other languages allow this, Haxe does not, you have to access them through the class name. To fix this, simply prefix js.html.webgl.RenderingContext.

    • Secondly, querySelector() returns a plain js.html.Element, which none of the overloads accepts. They all want something more specific: VideoElement, ImageElement or CanvasElement. So you'd have to cast it first:

      var image:js.html.ImageElement = cast document.querySelector('img[src="images/myImage.jpg"]');
      
    • Finally, it seems a bit suspicious that you'd need to cast the first parameter. Even if it works, there might be a nicer way of doing that with the wrapper you're using.

    So in summary, the following should compile:

    gl.texSubImage2D(cast fluid.dyeRenderTarget.writeToTexture, 0,
        Math.round(mouse.x), Math.round(mouse.y),
        RenderingContext.RGB, RenderingContext.UNSIGNED_BYTE, image);