0

Currently I am trying to convert browser based client side volume rendering code to server side pure javascript based rendering.

I use node-webgl at server side. My main goal is to send the canvas content of server to client, later this image data is displayed on the client.

But before this I need to check whether the rendering is proper. So I used canvas.toDataURL() to extract canvas data and want to display it on a separate window. But I am facing the error.

Below is my code:

exp.js

var nodejs=true,
WebGL = require('./node_modules/node-webgl/index'),
document = WebGL.document();

document.setTitle("Lesson02");
requestAnimationFrame = document.requestAnimationFrame;
alert=console.error;

//Read and eval library
fs=require('fs');
eval(fs.readFileSync(__dirname+ '/sylvester.js','utf8'));
eval(fs.readFileSync(__dirname+ '/glUtils.js','utf8'));
eval(fs.readFileSync(__dirname+ '/glAux.js','utf8'));
eval(fs.readFileSync(__dirname+ '/volumercserver.js','utf8'));

volumerc_main('./raycast-color.frag','./aorta-high512.jpg','./tfold.png');

and volumerc_main is contained in volumercserver.js (including here only required code)

var Image = require("node-webgl").Image;

var canvas = document.createElement("canvas");
canvas.id = 'canvas_win';
canvas.width= 512;
canvas.height= 512;
var gl;

var canvas1 = document.createElement("canvas");
canvas1.width= 512;
canvas1.height= 512;
var ctx = canvas1.getContext('2d');

try {
    gl = canvas.getContext("webgl", {premultipliedAlpha: false}) ||    canvas.getContext("experimental-webgl",{premultipliedAlpha: false});
} catch (e) {
}
if (!gl) {
    alert("Could not initialise WebGL, sorry :-(");
}   

// All computations take place here
//................
//..................
//.............

     var dataURLstring = canvas.toDataURL();

     var img1 = new Image;
     img1.src = dataURLstring;
    // img1.onload = function(){
     ctx.drawImage(img1,0,0); // Or at whatever offset you like
    // };

Now, when I run node npm.js I get the error,

C:\Users\z003npra\Desktop\node>node exp.js
Status: Using GLEW 1.13.0
Status: Using GLEW 1.13.0
undefined:443
            var dataURLstring = canvas.toDataURL();
                                       ^

TypeError: canvas.toDataURL is not a function
at drawVolume (eval at <anonymous> (C:\Users\z003npra\Desktop\node\exp.js:15
:9), <anonymous>:443:30)
at Timer.listOnTimeout (timers.js:92:15)

Log of canvas just befor I get error at toDataURL()

{ type: 'nodeGLFW',
ratio: 1,
setTitle: [Function],
setIcon: [Function],
flip: [Function],
getElementById: [Function],
createElement: [Function],
createWindow: [Function],
getContext: [Function],
on: [Function],
addEventListener: [Function],
removeEventListener: [Function],
requestAnimationFrame: [Function],
drawingBufferWidth: 800,
width: 512,
drawingBufferHeight: 800,
height: 512,
canvas: [Circular],
id: 'canvas_win',
onmousedown: [Function: handleMouseDown],
onmouseup: [Function: handleMouseUp],
onmousemove: [Function: handleMouseMove] }

Please help me to solve this.

Prajwal_7
  • 109
  • 1
  • 16
  • What happens when you use `canvas[0].toDataURL();` instead of `canvas.toDataURL();` ? – David R Sep 20 '16 at 10:45
  • @DavidR If I use canvas[0].toDataURL(), I am still getting the error. undefined:443 var dataURLstring = canvas[0].toDataURL(); ^ TypeError: Cannot read property 'toDataURL' of undefined at drawVolume (eval at (C:\Users\z003npra\Desktop\node\exp.js:15 :9), :443:32) at Timer.listOnTimeout (timers.js:92:15) – Prajwal_7 Sep 20 '16 at 10:51
  • Seems your canvas creation is wrong, You have written it as `var canvas = document.createElement("canvas_win");` where as the valid way to create a canvas using javascript is like, `var canvas = document.createElement('canvas');canvas.id = 'canvas_win';` – David R Sep 20 '16 at 10:57
  • @DavidR I have changed as per your suggestion, I am still getting the same error. Maybe .toDataURL() error might get solved if I use 'canvas' using 'node-Canvas' library, but I will face another issue of Image() definition, Here is the detail --> http://stackoverflow.com/questions/39577911/alternative-to-new-image-of-browser-implementation-into-node-webgl-javascrip – Prajwal_7 Sep 20 '16 at 11:04
  • a fake dom of node.js may help. –  Sep 20 '16 at 12:01
  • @LearnHowToBeTransparent Could you please elaborate or provide a basic example? Currently I am trying with jsdom, but still struggling. – Prajwal_7 Sep 21 '16 at 16:05
  • i am a node js noob anyway. –  Sep 22 '16 at 01:50
  • Can you log `canvas` right before that error so we know what that variable really is at that point? – canon Sep 22 '16 at 14:11
  • @canon Do you mean console.log(canvas)? or something other. If the question is simple, I am sorry, I am very new to webGL, just working on it from past month. – Prajwal_7 Sep 22 '16 at 14:27
  • @Prajwal_7 Yes. – canon Sep 22 '16 at 14:35
  • @canon I have updated the same in original post. Is toDataURL() feature available in node-webGL ? I tried toDataURL() with node-canvas library, there I was able to use the function properly. But it does not support WebGL. I want to ask you another question, I am converting the browser based WebGL volume rendering code to server based node.js volume rendering code, will the webgl functions remain same of browser webgl and node.js node-webgl? I hope they are same, but available through different packages. – Prajwal_7 Sep 22 '16 at 17:03
  • I could read it somewhere that, .toDataURL() function is not implemented in node-webGL wrapper (not yet confirmed). I need to impolement this function now. Do you know how to create that? Should I create a separate post for the same? I a newbie in WebGL, used the open-source code for my application. Now I need to write some functions for this dependent module . – Prajwal_7 Sep 23 '16 at 13:45

1 Answers1

1

.toDataURL() function is not defined in node-webGL wrapper. An alternative method is to make use of gl.readPixels (suggested by a member of this group).

Here is the way to use it.

var pixels = new Uint8Array(canvas.width * canvas.height * 4);
gl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

after the execution of gl.readPixels, the buffer data is present in pixels. The data is of ImageData() format. With this data, further required process can be done.

Prajwal_7
  • 109
  • 1
  • 16