I'm writing a sketch in Processing and I'm curious how I can get the position of the OS's window that the sketch lives in. If I use getPosition() (part of java.awt) I only get the position of the viewport within the window.
You can use the getLocationOnScreen() inherited from java.awt.Component, but you need to make sure the applet isShowing() first:
void draw(){
if(frame.isShowing()) println(frame.getLocationOnScreen());
}
or slightly more graphical:
void draw(){
if(frame.isShowing()) {
java.awt.Point pt = frame.getLocationOnScreen();
background(255);
rectMode(CENTER);
rect(map(pt.x,0,displayWidth,0,width),//use screenWidth instead of displayWidth in Processing 1.5.1 or older
map(pt.y,0,displayHeight,0,height),//use screenHeight instead of displayHeight in Processing 1.5.1 or older
10,10);
}
}
where
Frame frame = ( (PSurfaceAWT.SmoothCanvas) ((PSurfaceAWT)surface).getNative()).getFrame();
(For other renderers such as P2D or FX2D check out this answer)
Related
In Processing, how can I modify an existing sketch which saves each frame to an image file so that it does not render to the screen?
I saw in https://forum.processing.org/one/topic/how-can-i-save-calculate-frame-without-displaying-them-in-real-time.html that you can use PGraphics to draw graphics into an offline buffer, which seems like it would be what I am after, but I am not sure how I can easily modify my existing sketch to use the PGraphics class in that way.
On top of this, I would like the option to render to screen as well if needed by setting a toggle variable.
Is there an easy way of "retrofitting" an existing sketch so that it can use PGraphics instead of the default rendering method (say, in the setup method) so I don't have to go into my sketch and change every single draw command?
You can use a PGraphics object and draw on it just like you would with a canvas. Here's an example sketch with no draw loop which outputs an image file:
void setup() {
PGraphics pg = createGraphics(150, 150);
pg.beginDraw();
pg.background(255);
pg.stroke(0);
pg.fill(color(0, 0, 200));
pg.rect(50, 50, 50, 50);
pg.endDraw();
pg.save("fileName.png");
}
In my sketch's folder, it created this file:
About the other question: I don't think that you can retrofit a written draw loop into a similar output without rendering it in the sketch's window without heavily modifying the code, BUT... if your goal is yo be able to choose between drawing to the sketch window or to a file, you can draw in PGraphics every frame and choose whether if you want to show the PGraphics or not depending on your business rules. You'll still have a lot of refactoring to do, but it's unavoidable.
Here's the same example than before, but implementing this idea:
boolean showFrame = true;
boolean saveFrame = false;
void setup() {
size(150, 150);
}
void draw() {
PGraphics pg = createGraphics(150, 150);
pg.beginDraw();
pg.background(255);
pg.stroke(0);
pg.fill(color(0, 0, 200));
pg.rect(50, 50, 50, 50);
pg.endDraw();
if (showFrame) {image(pg, 0, 0);}
if (saveFrame) {pg.save("fileName.png");}
}
Hope this helps. Have fun!
I want to pick up a color from drawn canvas.
I found get() function, but it can get color only from image.
Is there some way to get color from current canvas?
You can get() colour from your current canvas: just address the PGraphics instance you need (even the global one) and be sure to call loadPixels() first.
Here's tweaked version of Processing > Examples > Basics > Image > LoadDisplayImage:
/**
* Load and Display
*
* Images can be loaded and displayed to the screen at their actual size
* or any other size.
*/
PImage img; // Declare variable "a" of type PImage
void setup() {
size(640, 360);
// The image file must be in the data folder of the current sketch
// to load successfully
img = loadImage("https://processing.org/examples/moonwalk.jpg"); // Load the image into the program
}
void draw() {
// Displays the image at its actual size at point (0,0)
image(img, 0, 0);
// Displays the image at point (0, height/2) at half of its size
image(img, 0, height/2, img.width/2, img.height/2);
//load pixels so they can be read via get()
loadPixels();
// colour pick
int pickedColor = get(mouseX,mouseY);
// display for demo purposes
fill(pickedColor);
ellipse(mouseX,mouseY,30,30);
fill(brightness(pickedColor) > 127 ? color(0) : color(255));
text(hex(pickedColor),mouseX+21,mouseY+6);
}
It boils down to calling loadPixels(); before get().
Above we're reading pixels from the sketch's global PGraphics buffer.
You can apply the same logic but reference a different PGraphics buffer depending on your setup.
I'm using Processing to create a learning experience project that allows users to join network components together. I have links using standard lines, but I want to be able to show a signal moving through the line if there is a valid connection. Think of the line as a network cable for example. Is there anyway I can animate this line?
void draw(){
pushStyle();
stroke(0);
line(from.x, from.y, to.x, to.y);
popStyle();
}
} //draw function in the 'link' file
Of course you can, but your question is a little broad. You do have a particular type of animation in mind? Endless possibilities ;)
The basic way to handle something like this in processing is to increase some animation-variables every frame (or use time management - though that is beyond the basics).
Because the animation-variables (for instance position or color) are changed every frame, the animation is different every frame. It's animated.
Below I give an example of a small green line traveling over a black 'connection' line. If you read through the code I think you'll figure it out. This should be incorporated in a nice 'connection' class for ease of use on a larger scale.
//set coordinates for connection-line
int fromX = 100;
int toX = 600;
int fromY = 100;
int toY = 200;
//copy start coordinate for animation
int animx = fromX;
int animy = fromY;
//determine animation stepsize
int stepX = (toX-fromX)/10;
int stepY = (toY-fromY)/10;
void setup() {
size(800, 300);
//set framerate so animation is not to fast
frameRate(5);
//draw thick lines
strokeWeight(10);
}
void draw() {
background(255);
// draw connection in black
stroke(0);
line(fromX, fromY, toX, toY);
//draw animation in green
stroke(0, 255, 0);
line(animx, animy, animx+stepX, animy+stepY);
// step animation for next frame
animx = animx+stepX;
animy = animy+stepY;
// check for reset (if the animation on the next frame is drawn outside the line)
if (animx+stepX > toX)
{
animx = fromX;
}
if (animy+stepY > toY)
{
animy = fromY;
}
}
I have a question regarding rendering with box2d and libgdx.
As you can see in the screenshot below I have a problem when changing the window resolution.
Box2d gets scaled over the entire screen although the viewport is only using a small portion of it. Also the lights get scaled and do not match the real position anymore (but I think this is related to the same issue).
My idea is that I somehow need to adjust the matrix (b2dCombinedMatrix) for box2d before rendering but I have no idea how.
Personally I think that I need to tell it that it should use the same "render boundaries" as the viewport but I cannot figure out how to do that.
Here is the render method (the issue is after the draw lights comments part):
public void render(final float alpha) {
viewport.apply();
spriteBatch.begin();
AnimatedTiledMapTile.updateAnimationBaseTime();
if (mapRenderer.getMap() != null) {
mapRenderer.setView(gameCamera);
for (TiledMapTileLayer layer : layersToRender) {
mapRenderer.renderTileLayer(layer);
}
}
// render game objects first because they are in the same texture atlas as the map so we avoid a texture binding --> better performance
for (final Entity entity : gameObjectsForRender) {
renderEntity(entity, alpha);
}
for (final Entity entity : charactersForRender) {
renderEntity(entity, alpha);
}
spriteBatch.end();
// draw lights
b2dCombinedMatrix.set(spriteBatch.getProjectionMatrix());
b2dCombinedMatrix.translate(0, RENDER_OFFSET_Y, 0);
rayHandler.setCombinedMatrix(b2dCombinedMatrix, gameCamera.position.x, gameCamera.position.y, gameCamera.viewportWidth, gameCamera.viewportHeight);
rayHandler.updateAndRender();
if (DEBUG) {
b2dRenderer.render(world, b2dCombinedMatrix);
Gdx.app.debug(TAG, "Last number of render calls: " + spriteBatch.renderCalls);
}
}
And this is the resize method which moves the viewport up by 4 world units:
public void resize(final int width, final int height) {
viewport.update(width, height, false);
// offset viewport by y-axis (get distance from viewport to viewport with offset)
renderOffsetVector.set(gameCamera.position.x - gameCamera.viewportWidth * 0.5f, RENDER_OFFSET_Y + gameCamera.position.y - gameCamera.viewportHeight * 0.5f, 0);
gameCamera.project(renderOffsetVector, viewport.getScreenX(), viewport.getScreenY(), viewport.getScreenWidth(), viewport.getScreenHeight());
viewport.setScreenY((int) renderOffsetVector.y);
}
After hours of fiddling around with the matrix I finally got it to work but there is actually a very easy solution to my problem :D
Basically the render method of the rayhandler was messing up my matrix calculations all the time and the reason is that I did not tell it to use a custom viewport.
So adjusting the resize method to this
public void resize(final int width, final int height) {
viewport.update(width, height, false);
// offset viewport by y-axis (get distance from viewport to viewport with offset)
renderOffsetVector.set(gameCamera.position.x - gameCamera.viewportWidth * 0.5f, RENDER_OFFSET_Y + gameCamera.position.y - gameCamera.viewportHeight * 0.5f, 0);
gameCamera.project(renderOffsetVector, viewport.getScreenX(), viewport.getScreenY(), viewport.getScreenWidth(), viewport.getScreenHeight());
viewport.setScreenY((int) renderOffsetVector.y);
rayHandler.useCustomViewport(viewport.getScreenX(), viewport.getScreenY(), viewport.getScreenWidth(), viewport.getScreenHeight());
}
and simplifying the render method to
// draw lights
rayHandler.setCombinedMatrix(gameCamera);
rayHandler.updateAndRender();
if (DEBUG) {
b2dRenderer.render(world, b2dCombinedMatrix);
Gdx.app.debug(TAG, "Last number of render calls: " + spriteBatch.renderCalls);
}
solved my problem.
Maybe I am stupid but I did not find useCustomViewport method in any of the documentations.
Anyway , solved!
I am trying to create a small program which displays an Image. This image will be resized to fit the window size.
Until now you can already see the image on the screen but to make it change its size when resizing the window I have to know how to get the window width and height of my Window.
The problem is, I havent found a good way to do this... and would like to know if somebody could help me with that.
(I am programming with vala in elementary os if that is necessary to know)
I can also post my code if that would help
Here is a simple example to get the width and Height of the window when it resizes. On the signal you can do stuff like resizing the child image pixbuf/image or whatever. Hope it helps.
using Gtk;
public void main (string[] args) {
Gtk.init (ref args);
var window = new Gtk.Window ();
window.configure_event.connect ((event) => {
print ("Width: %d Height: %d\n", event.width, event.height);
return false;
});
window.destroy.connect (Gtk.main_quit);
window.show_all ();
Gtk.main ();
}