How do I make content within a JavaFX Scene transparent? - javafx

The program below is an example of what I'm actually trying to achieve.
I'm trying to do is recreate the picture above in JavaFX. However I am having difficulties because when I set the content of my stage to transparent it doesn't actually go transparent it still remains white.
#Override
public void start(Stage stage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
root.setStyle("-fx-background-color: rgba(0,0,0,0);");
scene.setFill(Color.TRANSPARENT);
stage.setScene(scene);
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
The stage is visible from this code. I also set the content to transparent and changed the default style of the root pane to transparent.
I don't understand why this doesn't work, I'm setting the content to transparent but the background is still not transparent.
The result from the code I posted shows this, as you can see it's not transparent.

This question is almost a duplicate of:
how to make transparent scene and stage in javafx?
The difference being that it is also asking to retain native window decorations, which is not possible with StageStyle.TRANSPARENT.
If you look closely at the sample windows provided in the question, the decoration areas differ slightly (e.g. one includes a stage icon in the upper left and the other does not). My guess is that the transparent window pictured in the question isn't actually using the OS window decorations at all, but is instead rendering its own decorations which look much like the OS window decorations (that is just a guess though).
Anyway, to achieve a similar effect with JavaFX, it is necessary that JavaFX be used to render the window decorations rather than the OS window manager. To do that, refer to the following question:
JavaFX entirely customized windows?
In particular take a look at the Undecorator library:
https://github.com/in-sideFX/UndecoratorBis
You will never be able to get the window decorations to exactly match the OS Window manager decorations, but you can create something that looks different and provides similar functionality. If you work at it, you might be able to achieve something that matches the OS window decorations pretty closely, similar to the window screenshot in your question. Though, if it were me, I would just go for a different look which was still clean and easily comprehensible by the user, similar to the default look provided by Undecorator.
Do you think this could be pulled off by creating an ImageView and using some sort of stage listener so when the stage is moved the imageview displays a new image of what's behind the application? Or is that overly complicating it?
The background capture to imageView approach is a reasonable alternate approach.
If you do want to use the imageView capture approach, you can use some of the ideas from the following answer:
JavaFX effect on background
Note that the imageView capture type answer linked above won't completely accomplish what you wish and you still need to do some additional custom work to get exactly the effect you need as you move the stage around or as the desktop or windows under your window change. Possibly you may need to resort to logic outside of JavaFX to fully realize your goal, and discussion of how to do that is outside the scope of what I would be prepared (or able) to discuss here.
It's complicated no matter what you do, I don't really have a recommendation between the undecorator or the imageView capture approach.
Maybe if you mix JavaFX and Swing/AWT you may be able to do this by using a JFXPanel and the AWT PERPIXEL_TRANSPARENT feature. I haven't tried this combo, but per pixel settings for AWT are demonstrated in this oracle sample as discussed in How to Implement Per-Pixel Translucency.

Related

BabylonJS scene switching stutters

Live Demo
I want to switch between 2 complex scenes for an intro animation. Both scenes load from .gltf or .babylon files and contain camera motion.
The issue that I'm experiencing is that when I switch from scene1 to 2, there's a freeze/stutter before the next scene animation begins. Once the scene is rendered the switching of scenes continues as normal. It may be hard to spot but there's definitely difference between the first switch and the consequent ones.
I've tried using scene2.render(); right after loading the scene and it helps a little but it also makes the first scene stutter while it's trying to render both scenes. Is there something that I may be missing about this? I couldn't find an example of an intro with scene switching that works well online. Only camera switch but that's not what I want.
this is because the shaders of the second scene need to be compiled (as they could be different from the ones used in the first scene).
Babylon.js v4 will support parallel shader compilation but this will not be available on all browsers.
The best option could be to force that compilation beforehand:
scene1.meshes.forEach(mesh => {
mesh.material.forceCompilation(mesh);
});

How to use common background node for many scenes in Cocos2d-x

I have a very simple problem, but can't seem to find a definite answer.
I'm making a game that uses the same static background in every single scene.
Currently I simply added the background everywhere, but it sort of seems unnatural, makes some of scene transitions I want really painful to make and eventually I'd like to make an animated background which wouldn't reload with every scene change.
Is there a way to add the same node as a background of all the nodes other than creating a singleton which I'd need to add/remove during every transition?
In other words, can the scenes have transparent background so I can push them over the background scene?
I know that CCScene doesn't have setOpacity and have seen that some guys advice using CCLayer for scenes, but then CCDirector::pushScene accepts CCScene as the argument.
EDIT.
Ok, now I see that I probably misunderstood the CCLayer solution.. does it mean that the only way of doing it is to change scenes to layers and then adding/removing them from the main scene?
If you one animating/static background and want everything else to change, i would suggest having using only 1 cocos2d-x Scene with your fancy background and all other layers (previously scene) and elements to this scene.
So, technically you would never ever have to transition from a screen .
But, if you find another solution somewhere, do post/share.

JavaFX ImageView without any smoothing

Is it possible to render a scaled image in an ImageView in JavaFX 2.2 without any smoothing applied? I'm rendering a 50x50 image into a 200x200 ImageView, with setSmooth(false), so each pixel in the source image should map to a 4x4 square on the screen.
However, the resulting render still smooths the source pixel across all 16 destination pixels. Does anyone know of a way to do this without manually copying over each pixel into a new image?
In JavaFX 2.2 ImageView is always going to do some smoothing regardless of the smooth hint you provide to the ImageView.
(Based on testing using Java 7u15 and Windows 7 with an ATI HD4600 graphics card).
Perhaps it is a bug that ImageView will always smooth the Image, but the documentation doesn't really specify exactly what smoothing does or doesn't do, so it's hard to say what its real intent is. You may want to post a reference to this question to the openjfx-dev mailing list or log an issue in the JavaFX issue tracker to get a more expert opinion from a developer.
I tried a few different methods for scaling the Image:
Scale in the Image constructor.
Scale in ImageView with fitWidth/fitHeight.
Scale by using the scaleX/scaleY properties on an ImageView.
Scale by sampling the Image with a PixelReader and creating a new Image with a PixelWriter.
I found that methods 1 & 4 resulted in a sharp pixelated image as you wish for and 2 & 3 resulted in a blurry aliased image.
Sample code to generate the above output.
Update with ideas on implementing your own image filter
A JavaFX Effect is not the same as the Filter used for the Image loading routines, though an Effect to filter an image could be created. In JavaFX 2.2 publicly documented API to support creation of custom effects, so creating of a custom effect may prove difficult.
The native code for image support was recently open sourced as part of the openjfx project, so you could look at that to see how the filtering is currently implemented.
You may also want to file a feature request against the JavaFX runtime project to "allow us to make our own 2D filters".
I know this is a bit older, but I recently had a need for such ImageView, and the following little hack does exactly what I want on my (Windows) machine. No guarantees that it works everywhere.
import com.sun.javafx.sg.prism.NGImageView;
import com.sun.javafx.sg.prism.NGNode;
import com.sun.prism.Graphics;
import com.sun.prism.Texture;
import com.sun.prism.impl.BaseResourceFactory;
import com.sun.prism.Image;
import javafx.scene.image.ImageView;
#SuppressWarnings("restriction")
public class PixelatedImageView extends ImageView {
#Override protected NGNode impl_createPeer() {
return new NGImageView() {
private Image image;
#Override public void setImage(Object img) {
super.setImage(img);
image = (Image) img;
}
#Override protected void renderContent(Graphics g) {
BaseResourceFactory factory = (BaseResourceFactory) g.getResourceFactory();
Texture tex = factory.getCachedTexture(image, Texture.WrapMode.CLAMP_TO_EDGE);
tex.setLinearFiltering(false);
tex.unlock();
super.renderContent(g);
}
};
}
}
The trick here is that the texture gets re-used, so the linear filtering setting remains "sticky". Why NGImageView couldn't simply pass the "smooth" flag to the texture's linear filtering setting is beyond me however.
No fix for ImageView, but it helped me a lot.
After searching for ages, I stumbled upon this post: How can I disable antialiasing on a JavaFX Canvas?
For drawing the image on a canvas, the smoothing can be disabled since JavaFX 12
canvas.getGraphicsContext2D().setImageSmoothing(false);
When you add the following constructor to Martin Sojka's answer you can simply pass the javafx Image to the constructor. Also despite the warnings about deprecated functions his answer still works fine (on JDK 1.8_121).
public PixelatedImageView (javafx.scene.image.Image image) {
super(image);
}

Creating a permanent static overlay for QGraphicsView scene

I am making an app using Qt (currently 4.8) which displays a literal map from a large number of QGraphicsScene items. I would like to annotate the view with a scale. My requirement for the scale is that it is permanently fixed w.r.t the viewport widget. It needs to be updated whenever the view scale changes (zoom in, etc). There are other possible overlay items as well (compass, etc) so I'd prefer a generic solution.
I have looked at earlier questions around this which suggest:
using the ItemIgnoresTransform
using an overlay pixmap.
I tried IgnoresTransform but that way didn't work right: I couldn't figure out how to fix it in place in (say) the bottom corner of the viewport and was having some difficulty getting the text and lines always displaying in the correct size.
I scrapped that and subclassed QGraphicsView, adding an overlay pixmap by reimplementing the paintEvent (calls original one, then paints the overlay pixmap on top), and an alignment option to indicate where it goes. Coding some pixmap paint code produces a usable scale on the view. Yay! ... but it doesn't work with scrolls - I get "shattered" renderings of the scale all over, or sometimes no scale at all. I think this is because QGraphicsView::scrollViewportBy() uses viewport()->scroll() so I wondered if switching to ViewportSmartUpdate would help, but it doesn't help enough. I'd prefer not to switch to ViewportFullUpdate as that would likely slow the app down too much (there are millions of items in the scene and that would require a full repaint just to move around).
So. Any ideas from here? Would adapting my pixmap code to write to a new mostly-transparent Widget that is overlaid on the viewport be a better way?
Thanks for any help...
Though it may not be the best way of doing this, in the past I've added custom widgets to the window that holds the QGraphicsView / QGraphicsScene, which have the same graphic style as the QGraphicObjects in the scene. When the view is then used to move objects in the scene, or the scene itself, the items on the window remain in the same place.
Hope that helps.

Flex - Subclassing VBox in MXML to use as a base component, advice needed

I'd like to extend VBox to add some "defaults" and a bit of boilerplate-ish code (let's call it "VBoxSub" here), the idea being that "pages" in the application would extend this VBox subclass.
This seems to work fine except that the final classes extending "VBoxSub" don't inherit the width/height settings set in VBoxSub when in Flash Builder's design mode. When switching to design mode with the component empty, all it shows is a tiny plain box instead of a larger 1000x700 working area with the default VBox css background color. What's going on here? (Yeah I've tried refreshing/restarting design view.)
I'd like to have each of these components all be exactly the same size so that when laying out the UI I know exactly how much space I have to work with - preferably without having to copy/paste the width and height attributes into every darn mxml file (and having to worry about updating each one if the w/h ever change!). (Using Flash Builder 4, SDK 4.1)
I've tried doing this to get it to work, but still no good in Design View:
override protected function measure():void {
super.measure();
measuredWidth=1000;
measuredMinWidth=1000;
measuredHeight=700;
measuredMinHeight=700;
}
Do I really need to hard code width/height in every component "page" within the application?
Flash Builder doesn't execute Actionscript in design mode. Since the AS code doesn't get executed, the VBox doesn't get measured in design mode.
You need to use declarative MXML in such a situation.

Resources