Clearing the drawn SpriteFont in XNA 4.0 - windows-phone-7

This code is used to basically display number of times the user touches the screen. But the problem is every time the Update method(XNA 4.0), the previous texture is Drawn upon , therefore the count cannot be read. How do i clear the SpriteFont texture each time when it is redrawn?.
//Code used to draw the Sprite Font.!
batch.DrawString(fontSegoe, "Touches "+count, new Vector2(100, 100), Color.Black, 0, Vector2.Zero, 1, SpriteEffects.None, 0f);

Make sure to clear the screen at the beginning of Draw()
GraphicsDevice.Clear(Color.Black); //Use any color of your choice

Related

p5js only drawing what's needed

I'm looking for a way to limit what gets done in the draw loop.
I have a system where when I click, it add's a rect.
This rect then starts spawning circles that move.
since the rect does not change location, it isn't ideal to redraw it in every frame.
Is there a way to put the rects on a different layer of sorts, or is there another mechanism that I can use to limit the rect-drawing without impeding the circle-drawing?
I've tried with createGraphic to make a background with the rects, but I can't make the 'foreground' where the circles reside to be transparant.
Curious about this I tried myself. My idea was simply grabbing the canvas and interacting with it regardless of p5.js.
My result was that the draw... in this case ctx.fillRect did not render on screen.
However the fillStyle was changed.
Canvas is surprisingly efficient as well as WebGL and can handle the performance usually... unless you are rendering hundreds(mobile) to thousands(laptop/desktop) of objects.
I would have liked to have a better outcome but I think it was worthwhile posting what I had tried and my outcome nonetheless.
//P5 Setup
function setup(){
createCanvas(1500, 750);
background('rgba(0, 0, 0, 0.3)');
stroke(255);
fill(255)
doNonP5Drawing();
}
//Render
function draw(){
background(0);
frame();
}
function doNonP5Drawing(){
let canvas = document.querySelector('canvas'),
ctx = canvas.getContext('2d');
ctx.fillStyle="red";
ctx.fillRect(canvas.innerWidth/2 - 100,canvas.innerHeight/2 - 100,200,200);
}

Suggestion on how to create a window over a wall

I am working on a three.js application where I have to create a building structure (all on ground floor), the height, width, length will be specified by user. User can change wall and roof color (which are applied using texture, as I have images for each color with some texture). They can also add any accessory on a selected wall (like a window or a door), which can be then dragged and dropped on that same selected wall. After deciding where they want to put the window (for eg.) they will click a button to confirm the position. Now I have to create a window in the wall, so that I can see inside of the room. Please suggest your views on following approaches:
Once the user confirms the position of the door -
a.) I can add the mesh of the window in the main building mesh mainMesh.add(windowMesh);. But the problem is even if I set the transparent material to the window , the wall material still shows.
b.) I can subtract the window mesh from the main building mesh (using CSG, threeCSG) buildingmeshcsg.subtract(windowmeshcsg) which creates a hole in the building mesh, and then I put the window mesh over that hole. Now the problem is after any CSG operation the faces of the original geometry gets all mixed up, so after the csg operation, the color, UV of faces goes away.
c.) I can create wall in small sections,
like from one corner to window corners then, from another window corner to another wall corner. But this messes up the texture I have applied on walls, because I have created UV for front and back walls, as the texture was not applying correctly.
Please suggest your views.
Have to make something like this :https://forum.unity.com/threads/make-a-seethrough-window-without-making-hole-in-the-wall.286393/
THREE * (any version)
This sounds like a good candidate for the stencil buffer. Draw the window and write to stencil, draw the wall around the written values (0) then draw the wall within the written value (1).
These are the methods you are interested in:
https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/stencilOp
https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/stencilFunc
You need to do this first:
const gl = renderer.getContext() //obtain the actual webgl context, because three has no stencil functionality
And then you need to manage your render logic, this is where Object3D.onBeforeRender callback should help.
So let's assume that you have something like this:
const myWindow, myWall //two meshes, you loaded them, instantiated them
//for a proof of concept you can do something like this
const maskScene = new THREE.Scene()
const wallScene = new THREE.Scene()
const windowScene = new THREE.Scene()
maskScene.add(myWindow)
wallScene.add(myWall)
windowScene.add(myWindow)
render(){
gl.enable(gl.STENCIL_TEST) //enable stencil testing
gl.clearStencil( 0 ) //set stencil clear value
gl.clear( _gl.STENCIL_BUFFER_BIT ) //clear the stencil buffer with set value
gl.stencilFunc( gl.ALWAYS, 1, 1) //always pass the stencil test, with ref 1
gl.stencilOp( gl.REPLACE , gl.REPLACE , gl.REPLACE ) //replace the stencil value with the ref
gl.colorMask(false, false, false, false) //do not write any color
gl.depthMask(false) //do not write to depth
myRenderer.render(maskScene, myCamera) //only the stencil is drawn
//now you have a region in the frame buffer with stencil value of 1, and the rest 0, you can draw the wall in 0 and the window back at 1
gl.colorMask(true, true, true, true) //enable writing
gl.depthMask(true)
gl.stencilFunc( gl.EQUAL , 0 , 1 ) //set the stencil function to EQUAL
gl.stencilOp( gl.KEEP, gl.KEEP, gl.KEEP ) //keep the stencil value in all three tests
myRenderer.render( wallScene, myCamera ) //draw the wall where stencil is 0 (around the window)
gl.stencilFunc( gl.EQUAL , 1 , 1 ) // now func is EQUAL but to value 1
myRenderer.render( windowScene, myCamera ) //draw the window
}
This is the most basic attempt and it is not tested. Since it's working directly with the WebGL API it should work with any version of three. stencilOp takes two more arguments with which you can manage what happens with the depth tests.

In Processing, how can I save part of the window as an image?

I am using Processing under Fedora 20, and I want to display an image of the extending tracks of objects moving across part of the screen, with each object displayed at its current position at the end of the track. To avoid having to record all the co-ordinates of the tracks, I usesave("image.png"); to save the tracks so far, then draw the objects. In the next frame I use img = loadImage("image.png"); to restore the tracks made so far, without the objects, which would still be in their previous positions.. I extend the tracks to their new positions, then usesave("image.png"); to save the extended tracks, still without the objects, ready for the next loop round. Then I draw the objects in their new positions at the end of their extended tracks. In this way successive loops show the objects advancing, with their previous positions as tracks behind them.
This has worked well in tests where the image is the whole frame, but now I need to put that display in a corner of the whole frame, and leave the rest unchanged. I expect that createImage(...) will be the answer, but I cannot find any details of how to to so.
A similar question asked here has this recommendation: "The PImage class contains a save() function that exports to file. The API should be your first stop for questions like this." Of course I've looked at that API, but I don't think it helps here, unless I have to create the image to save pixel by pixel, in which case I would expect it to slow things down a lot.
So my question is: in Processing can I save and restore just part of the frame as an image, without affecting the rest of the frame?
I have continued to research this. It seems strange to me that I can find oodles of sketch references, tutorials, and examples, that save and load the entire frame, but no easy way of saving and restoring just part of the frame as an image. I could probably do it using Pimage but that appears to require an awful lot of image. in front of everything to be drawn there.
I have got round it with a kludge: I created a mask image (see this Processing reference) the size of the whole frame. The mask is defined as grey areas representing opacity, so that white, zero opacity (0), is transparent and black, fully opaque (255) completely conceals the background image, thus:
{ size (1280,800);
background(0); // whole frame is transparent..
fill(255); // ..and..
rect(680,0,600,600); // ..smaller image area is now opaque
save("[path to sketch]/mask01.jpg");
}
void draw(){}
Then in my main code I use:
PImage img, mimg;
img = loadImage("image4.png"); // The image I want to see ..
// .. including the rest of the frame which would obscure previous work
mimg = loadImage("mask01.jpg"); // create the mask
//apply the mask, allowing previous work to show though
img.mask(mimg);
// display the masked image
image(img, 0, 0);
I will accept this as an answer if no better suggestion is made.
void setup(){
size(640, 480);
background(0);
noStroke();
fill(255);
rect(40, 150, 200, 100);
}
void draw(){
}
void mousePressed(){
PImage img =get(40, 150, 200, 100);
img.save("test.jpg");
}
Old news, but here's an answer: you can use the pixel array and math.
Let's say that this is your viewport:
You can use loadPixels(); to fill the pixels[] array with the current content of the viewport, then fish the pixels you want from this array.
In the given example, here's a way to filter the unwanted pixels:
void exportImage() {
// creating the image to the "desired size"
PImage img = createImage(600, 900, RGB);
loadPixels();
int index = 0;
for(int i=0; i<pixels.length; i++) {
// filtering the unwanted first 200 pixels on every row
// remember that the pixels[] array is 1 dimensional, so some math are unavoidable. For this simple example I use the modulo operator.
if (i % width >= 200) { // "magic numbers" are bad, remember. This is only a simplification.
img.pixels[index] = pixels[i];
index++;
}
}
img.updatePixels();
img.save("test.png");
}
It may be too late to help you, but maybe someone else will need this. Either way, have fun!

Need to draw arrows and circles on canvas without clearing the whole canvas

I'm trying to draw arrows and circles on a canvas, currently the whole canvas is cleared on mousemove and mousedown or whenever the draw function is called, I am not able to draw multiple arrows and circles. Is there any other to accomplish this task?
heres a fiddle: http://jsfiddle.net/V7MRL/
Stack two canvases on top of each over, and draw the temporary arrows/circle on the one on top, and do the final draw on the canvas below.
This way you can clear the top canvas with no issue, and your draws 'accumulate' in the lower canvas.
http://jsfiddle.net/V7MRL/5/ (updated)
I changed your draw function so it takes a 'final' flag that states wether the draw is final.
For a final draw, lower canvas is used, for an temporary draw, upper canvas is cleared then used.
function draw(final) {
var ctx = final ? context : tempContext ;
if (final == false) ctx.clearRect(0, 0, canvas.width, canvas.height);
Edit : for the issue #markE mentionned, i just handled mouseout event to cancel the draw if one is ongoing :
function mouseOut(eve) {
if ( mouseIsDown ) {
mouseIsDown = 0;
cancelTempDraw();
}
}
with :
function cancelTempDraw() {
tempContext.clearRect(0, 0, canvas.width, canvas.height);
}
Rq that your undo logic is not working as of now. I changed it a bit so that in draw, if the draw is final, i save the final canvas prior to drawing the latest figure to quickly have a 1-step undo. i just created a third temp canvas to/from which you copy.
Rq also that you cannot store one canvas for each stroke, or the memory will soon explode. Store the figures + their coordinates in an array if you want a full undo... or just allow 1-step undo for now.
i updated the jsfiddle link.

HTML Canvas clip area - Context restore?

Am trying to set a "dirty zone" on my canvas to prevent the repainting of unmoved items (background image, static items, etc.)
i.e. only the background painted behind a moving player needs to be redrawn
EDIT: As suggested, here's the jsfiddle of it
http://jsfiddle.net/7kbzj/3/
The "update" method doesn't work out there, so it's moveSprite() you can get run by clicking the "move sprite" link... Basically, the clipping zone shouldmove by 10px to the right each time you click. Clipping mask stays at initial position, only the re-paint occurs. Weird o_O
So as I init my canvas, once the background is painted, set I use the ctx.save() method:
function init() {
canvas = document.getElementById('kCanvas');
ctx = canvas.getContext('2d');
ctx.fillStyle = "rgb(0,128,0)";
ctx.fillRect (0,0,320,240);
ctx.save();
setInterval(function () { update(); }, tpf);
}
In order to see the clipping works, I draw a different color background (blue one) in the area that I wanted clipped... the result is bad, only the first clipped area is painted blue :(
function update() {
setDirtyArea(x,y,w+1,h)
ctx.fillStyle = "rgb(0,0,128)";
ctx.fillRect (0,0,320,240);
x++;
// paint image
ctx.clearRect(x,y,w,h);
ctx.drawImage(imageObj, x, y);
}
function setDirtyArea(x,y,w,h) {
ctx.restore();
// define new dirty zone
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.clip();
}
I'd love to se the blue zone propagate itself towards the right of the screen... please help, I don't understand what's wrong!
Thanks,
J.
You need to wrap the actual drawing and clipping of the box with the save and restore methods. and include the closePath method. I have modified your fiddle to work the way I believe you are trying to make it.
http://jsfiddle.net/jaredwilli/7kbzj/7/
ctx.save(); // save the context
// define new dirty zone
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.clip();
ctx.restore(); // restore the context
I also have learned that using save and restore can get really complex, and confusing to know which context your in. It came up with a pretty huge canvas app im working on, and i found that indenting your canvas code helps immensely. Especially the save/restores. I have even decided it should be considered a best practice, so the more people who know and do it the better.
Hope this helps.

Resources