dbawel Posted May 24, 2015 Share Posted May 24, 2015 Hello, I'm wrapping up a realtime multi-user drawing app using elements from an example joshcamas posted recently. I'm not including the GUI and much of the server calls in my example below, so running this script wil provide errors, but the whole script is 3x as large. However, if someone might help me to accomplish 2 things, I would be grateful. 1. Draw on a plane using a dynamic texture.2. The base color of the plane is a color3 white (or other.) Here's the example: var createScene = function () { var scene = new BABYLON.Scene(engine); var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene); camera.setTarget(BABYLON.Vector3.Zero()); var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene); light.intensity = 0.7; var groundSize = 20; var textureResolution = 1024; var ground = BABYLON.Mesh.CreateGround("ground1", groundSize, groundSize, 2, scene); //Create dynamic texture var texture = new BABYLON.DynamicTexture("dynamic texture", textureResolution, scene, true); var textureContext = texture.getContext(); var materialGround = new BABYLON.StandardMaterial("Mat", scene); materialGround.diffuseTexture = texture; //materialGround.alpha = 0.2; //materialGround.diffuseColor = new BABYLON.Color3(1.0, 1.0, 1.0); ground.material = materialGround; var textureSize = texture.getSize(); texture.update(); //Here var maskcanvas = document.createElement('canvas'); maskcanvas.width = textureSize.width; maskcanvas.height = textureSize.height; var maskcontext = maskcanvas.getContext('2d'); //And var brushcanvas = document.createElement('canvas'); brushcanvas.width = textureSize.width; brushcanvas.height = textureSize.height; var brushcontext = brushcanvas.getContext('2d'); // we will call var textureComplete = false; var texture_complete = function() { textureComplete = true; }; //Prepare var mask = new Image(); //mask.crossOrigin = "Anonymous"; // if mask.src = http:// mask.src = 'mask_1.png'; mask.onload = texture_complete; // Prepare var img = new Image(); //img.crossOrigin = "Anonymous"; img.src = 'grass.jpg'; img.onload = texture_complete; var isDown = false; //Updater var draw = function(pickResult) { var x = pickResult.x, z = pickResult.z, brushSize = 5; //Check if(textureComplete == false) { return; } // x = (x + (groundSize/2)); x = (x - (ground.position.x)); z = (z - (ground.position.z)); z = ((groundSize/2) - z); // x = (x/groundSize)*textureSize.width; z = (z/groundSize)*textureSize.height; //Ok! brushcontext.save(); brushcontext.clearRect(0, 0, textureResolution, textureResolution); //maskcontext.globalAlpha = 0.4; brushcontext.drawImage(img, 0, 0, textureResolution, textureResolution, x-(brushSize), z-(brushSize), brushSize*2, brushSize*2); brushcontext.restore(); //Now maskcontext.save(); maskcontext.clearRect(0, 0, textureSize.width, textureSize.height); //maskcont maskcontext.drawImage(mask, 0, 0, mask.width, mask.height, x-(brushSize), z-(brushSize), brushSize*2, brushSize*2); maskcontext.globalCompositeOperation = 'source-in'; //Now maskcontext.drawImage(brushcanvas, 0, 0); maskcontext.restore(); textureContext.save(); //And textureContext.drawImage(maskcanvas, 0, 0); textureContext.restore(); texture.update(); }; var draw2 = function(xval,yval,zval) { var x = xval, z = zval, brushSize = 5; //Check if(textureComplete == false) { return; } // x = (x + (groundSize/2)); x = (x - (ground.position.x)); z = (z - (ground.position.z)); z = ((groundSize/2) - z); // x = (x/groundSize)*textureSize.width; z = (z/groundSize)*textureSize.height; //Ok! brushcontext.save(); brushcontext.clearRect(0, 0, textureResolution, textureResolution); //maskcontext.globalAlpha = 0.4; brushcontext.drawImage(img, 0, 0, textureResolution, textureResolution, x-(brushSize), z-(brushSize), brushSize*2, brushSize*2); brushcontext.restore(); //Now maskcontext.save(); maskcontext.clearRect(0, 0, textureSize.width, textureSize.height); //maskcont maskcontext.drawImage(mask, 0, 0, mask.width, mask.height, x-(brushSize), z-(brushSize), brushSize*2, brushSize*2); maskcontext.globalCompositeOperation = 'source-in'; //Now maskcontext.drawImage(brushcanvas, 0, 0); maskcontext.restore(); textureContext.save(); //And textureContext.drawImage(maskcanvas, 0, 0); textureContext.restore(); texture.update(); }; var onPointerDown = function() { isDown = true; var pickinfo = scene.pick(scene.pointerX, scene.pointerY); if (pickinfo.hit) { draw(pickinfo.pickedPoint); // Send Poninter Down Info to Server if (connected){ WInfo.move=0; WInfo.x= pickinfo.pickedPoint.x; WInfo.y= pickinfo.pickedPoint.y; WInfo.z= pickinfo.pickedPoint.z; socket.emit('writing',WInfo); } } } var onPointerUp = function() { isDown = false; } var onPointerMove = function() { if(isDown) { var pickinfo = scene.pick(scene.pointerX, scene.pointerY); if (pickinfo.hit) { draw(pickinfo.pickedPoint); // Send Pointer Move Info to Server if (connected){ WInfo.move=1; WInfo.x= pickinfo.pickedPoint.x; WInfo.y= pickinfo.pickedPoint.y; WInfo.z= pickinfo.pickedPoint.z; socket.emit('writing',WInfo); } } } } canvas.addEventListener("pointerdown", onPointerDown, false); canvas.addEventListener("pointerup", onPointerUp, false); canvas.addEventListener("pointermove", onPointerMove, false); scene.onDispose = function () { canvas.removeEventListener("pointerdown", onPointerDown); canvas.removeEventListener("pointerup", onPointerUp); canvas.removeEventListener("pointermove", onPointerMove); } // LG return scene; // LG }; // ------------------------------------------------------------- // Now, call// LG var scene = createScene(); // Register a engine.runRenderLoop(function () { scene.render(); }); Thanks, DB Quote Link to comment Share on other sites More sharing options...
fenomas Posted May 25, 2015 Share Posted May 25, 2015 For part 1 I'm not sure what you're asking. For part 2, I think the only way to draw a texture with a different base color is to give the mesh vertex colors, and then use your texture as an ambient texture rather than a diffuse texture. Demo: http://www.babylonjs-playground.com/#1W9YYU Quote Link to comment Share on other sites More sharing options...
dbawel Posted May 25, 2015 Author Share Posted May 25, 2015 Isn't a dynamic texture an ambient texture? Quote Link to comment Share on other sites More sharing options...
jerome Posted May 25, 2015 Share Posted May 25, 2015 A dynamic texture is just a texture generated from a html canvas 2D... it can be used as any other texture then : ambient, diffuse, etc Quote Link to comment Share on other sites More sharing options...
dbawel Posted May 25, 2015 Author Share Posted May 25, 2015 So I need to apply the dynamic texture to a plane which I can rotate and translate - but send the texture through the canvas to the plane. I have a mask canvas in the script above, which I will remove as it's not necessary. Any thoughts to how I can use a plane to pass color to a dynamic texture applied to the plane? I've tried within my script, but have failed - perhaps due to the methods I'm employing. Any help would be greatly appriciated as I'm almost a week behind and should finish the app today. Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 26, 2015 Share Posted May 26, 2015 Hi DB and others! send the texture through the canvas to the plane I'm not sure what you are saying, with this. You don't need to 'send' anything, because dynamicTextures are derived from 2D Canvas... but it's all done behind the scene... with the BJS dynamicTexture code. You can simply call drawText... like the docs show. If you want a transparent background (so the color of the plane is used for the DT background color)... then you set the dynamicTexture.hasAlpha = true... and then use the word "transparent" (with quotes), like this... dynamicTexture.drawText("test", 0, 0, ?, ?, "transparent") There's a few demos around that have DT "transparent" background set. Search the forum with some tasty fodder. And, of course, if you want the TEXT to take-on the color of the plane, just peek the plane.diffuseColor and then use that color as your text color. But I could be misunderstanding the entire issue... here. You might be wanting to use dynamicTextures for something OTHER-THAN text (such as lines, circles, strokes, etc). But, fills is fills, right? The context2D object that lies behind dynamicTextures... is a real sweetheart. Lots of knobs to play-with. Essentially, SVG on a stick. Have you looked at that beast? It is the basis of our drawtext func. Caution: People have toured that 2d context webpage... and never returned. Thank goodness context2D is a DOM object and not a BJS object... so we don't have the task of debugging it, ever. heh But yeah, you can do createPlane, createGround (both gen standard UVs), or plot a plane with vertex data (and still set basic UVs)... then use a STANDARD material on it, and then use a dynamicTexture in one or more of the StandardMaterial's texture-able slots... diffuseTexture, ambientTexture, emissiveTexture, opacityTexture, specularTexture, etc. It takes a little while to learn how BJS wrangles textures, but once you get comfortable with it, you'll love it. Mega-versatile. Quote Link to comment Share on other sites More sharing options...
dbawel Posted May 26, 2015 Author Share Posted May 26, 2015 My script is not easy to read, as I had to remove most remarks to optimize for the node.js server - until I upgrade to mass users today. If you see I create a ground object, a canvas for a 1024 texture, and a 16x16 canvas as a mask. I'm able to draw on the ground object, but have been unable to draw on a plane in BJS. This is not a huge issue now, as I've been able to manipulate the camera to orient the ground to be framed the way I need. However, it would be good to know why I'm not able to replace the ground object with another object to draw directly on the object. No text, simply passing pointer events through the texture and mask canvas' to the dynamic texture on the ground. Quote Link to comment Share on other sites More sharing options...
Wingnut Posted May 31, 2015 Share Posted May 31, 2015 Hi DB... I want to help with this if I can... but I'm not sure how. Allow me to try to clarify? When you say "draw on the ground object", you mean... like... dynamicTexture.getContext().lineTo()... for example? Sorry if I'm being rudimentary, here. You are a pretty smart chap, and it's a challenge for my brain to keep-up with yours, whatsoever. I assume that the mask texture is some crosshairs and/or brush shape. Correct me as needed. There is nothing better for getting click points on grounds... then the code used by Deltakosh in our drag'n'drop playground demo. Notice the getGroundPosition() function. I don't understand the word 'predicate' much at all, but see the return mesh == ground; out on the end of line 66? That ensures that getGroundPosition returns pickinfo.pickedPoint only when a mesh named 'ground' is clicked-upon. Here's a modification of that demo... and you can see in line 12... that I have changed createGround to createPlane. Drag'n'drop is still working, so standard planes CAN use pointer pick/click positions. I suggest using this method or similar. If you want to create your own plane primitive, just steal the createPlane code (on the vertexData obj) and do your plane in a similar fashion (adjusting positions as wanted). Keep in mind that there is also a createPlane() func on BABYLON.Mesh, which is a wrapper func for the createPlane() on vertexData. This demo also has starting and ending points, so it is ready for dynamicTexture.getContext().lineTo()... right? Anyway, I hope this helps. If not, could you use the modified demo, and adjust it in a way that more-clearly shows the issue? (then make another SAVE and send us the URL) Thanks! Sorry it took me so long to respond. You are probably WAY beyond this issue, by now. Be well! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.