I've been scouring the internet trying to find a way to fix my problem. I am creating a top-down rpg style game in JavaFX and have run into a bit of a snag. I'm trying to create a game area of 544 x 416 (area the you can see) but this is obviously pretty small so I've scaled the StackPane to 2.0. The game area is still 544 x 416 it's just larger on the screen.
The way my program is built, I have a StackPane called root that is attached to the Scene (and the Scene is attached to the Stage set at fullscreen), then I have another StackPane called frame attached to root. The StackPane size of frame is 544 x 416 and the StackPane root is scaled on the x and y axis 2.0 (which obviously scales frame). The StackPane frame is in the middle of the screen.
The issue comes when I actually try to load a map image. The edge pixels of each ImageView are blurred ever so lightly which creates a thin line whenever two images are placed on top of each other.
This image is not scaled at all and is exactly the way it should look.
This final image has been blurred by the scale factor and has a thin black line visible where the two images are. You can also see that the image has been blurred quite a bit. I am very good with Photoshop and know inherently that some pixel blurring will occur when making images larger BUT this issue did not occur with Swing.
I need to know if there is a better way to do this entirely OR how to get rid of the blurring. There is another topic here with a problem somewhat similar but it doesn't really address my particular problem. Any help on this matter would be greatly appreciated.
Related
however, i have a weird issue, when drawing, it seems the outside 1px of an image is stretched to fit a rectangle, but the inside is only stetched to an extend, i was drawing to 48x48 tiles, but drew a 500x500 tile to show the issue. [ 500x500 draws fine ]
the worst part seems to be, it chooses when to stretch and not to stretch. and also what to strech. im sorry this is hard to explain but i have attached a image that i hope does a better job.
it could just be misunderstanding how to use a draw with spritebatch
edit: Tile is 48x48 not 64x64, ive just been working all day.
This is because you are not rendering "pixel perfect" which means your image does not line up with the pixel grid of your monitor. A quick fix might be to set a linear filter for your textures, since by default it uses nearest and thus a pixel on the screen will inherit the closest color it can get. A linear filter will interpolate colors and make that line "look" thinner.
texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
If you are using texturepacker you can do this in one go by altering it's settings.
texturePackerSetting.filterMin = Texture.TextureFilter.Linear;
texturePackerSetting.filterMag = Texture.TextureFilter.Linear;
Or you could edit the atlas file itself by by changing the filter parameter to:
filter: Linear,Linear
This obviously costs more power since it needs to do more calculations for each pixel you drawn to the screen but I would not worry about this until your drawing is starting to get a bottleneck.
Another solutions is to draw pixel perfect which means you need to set your viewport to the size of the device gdx.graphics.getWidth, gdx.graphics.getHeight, in other words a ScreenViewport and draw your textures at exact sizes you want them. Of course this means a screen with more pixels sees more of your game world then a screen with less pixels and the more pixels a device has the smaller your textures will look. Another drawback of this is that you have to forget about any zooming or draw sprites for each level of zoom so they line up with the pixel grid of the device again.
I have javafx pane containing about 50000 of shapes. When I cache pane with CacheHint.Speed it is fine for Zooming and Panning. But it is so blurry when zoom. If set to CacheHint.Quality it becomes so sluggish.
I am trying the solution of playing with CacheHint but unable to catch OnScrollFinished event on desktop. Clipping the pane doesn't help.
I am thinking of selecting viewed shapes to render instead of rendering all shapes but what is the efficient way for checking about 50000 shapes?
Could some please help me with some options.
Thank you
The first thing I would do is to analyze which of your primitive types has the major effect on performance and then start optimizing that.
Paths are notoriously slow in JavaFX (compared to Lines and Rectangles for example).
Replace SVGPaths which just represent simple Lines and Rectangles by
the JavaFX counter parts if you can.
Simplify the paths if you can.
Remove all geometries from the scene graph which are currently not visible.
Use a triangle mesh to display your geometries. If done right this gives you a real performance boost but it is a lot of work (I've done it :-)
Using lots of tiny images may also be very slow. If that is the bottleneck it might help to create a texture atlas from your images and use a triangle mesh to display them.
I'm programming an Android App where a grid is drawn, which you can move around and move in it's direction. The grid consists of about 2000 to 5000 quads, each with a different texture. I defined 4 vertices and use an index buffer to draw each quad. Before drawing I position it using a model matrix. As you can move in my scene I use view frustum culling, which increases the performance in some situations. Unfortunately there might be the case where I will need to draw all of the quads, so I want to ask how I prevent slow drawing.
I can't use a texture atlas as all of the textures are pretty big (from 256x256 to 1024x1024). I think calling glDrawElements() for each squad is what makes me slow, but I don't know how I can change it.
Another idea I had would be to draw the scene to a texture and just bind this texture to a single quad to create an illusion of the scene being drawn. As the user gets closer I could redraw it for better resolution. Could this work?
I look forward for any kind of help.
I can't use a texture atlas as all of the textures are pretty big (from 256x256 to 1024x1024).
You can fit 64 256x256 textures into a 2048x2048 atlas, that's a huge amount, so you should definitely atlas. Even getting 4 1024x1024 onto a 2048x2048 is worth doing, it can quarter your draw call count.
And as WLGfx says in the comments to your question, you should batch up any quads that use the same texture (with atlasing there will be a lot more of these).
I think this would be enough, but you still might have a pretty high drawcall count in your fully zoomed-out view. After implementing atlasing and batching, if performance here is still a problem, you could create a separate asset set of thumb-nail textures at, say, quarter resolution (so a 256x256 becomes 64x64). This thumbnail asset set would fit onto just a handful of 2048x2048 atlas sheets, and you could switch to it when zoomed out far enough.
Another idea I had would be to draw the scene to a texture and just bind this texture to a single quad to create an illusion of the scene being drawn. As the user gets closer I could redraw it for better resolution. Could this work?
This could work, as long as your scene is very static, if the quads are moving/changing every frame, then it might not help. Also, there might be a noticeable framerate hitch when you have to do the full redraw.
I've created a isometric tile based game in Libgdx. The textures I'm using are 64x64 and packed using TexturePacker into a TextureAtlas. They are then drawn onto the screen. However, while moving around the pixelated edges of the 64x64 texture flicker and they are distorted, which can be seen in the images below. I have used all filters available in texturepacker, below you can see the results of the Linear and Nearest filters. Apart from flickering, the linear filter adds a black outline to the textures. I would be fine with this if it wasn't for the flickering when the camera moves around.
How the tile should appear:
Linear filtering (You can clearly see the black lines distorting):
Nearest filtering (Harder to see, but the pixelated lines are not straight):
The easiest place to spot it is on the top and bottom of the brown cube. The distortion happens on different places depending on camera movement (this causes flickering).
Anyone know what causes this, or has a possible solution? I'm not sure if any code snippets are needed.
It is also worth mentioning that the camera is set to windowHeight/ppm (ppm = 64) and windowWidth/ppm, then the textures are drawn onto a batch that has its projection matrix set to camera.combined.
Edit: Somehow it's better when reducing the window height from 800 to 710 (nearest):
Turn on the premultiplyAlpha option in TexturePacker and set setBlendFunction.(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA) on the SpriteBatch. This should get rid of the flickering black fringing. Basically, when using linear filtering, when the sprite's edges don't exactly line up with the pixels on the screen, the color of the pixel is linearly sampled from an image pixel on the edge of your sprite and an image pixel in the invisible black space (RGBA = 0000) next to it, so the edges can appear darker and more transparent than intended. Pre-multiplying the alpha cures this problem by changing the order of operations of the interpolation. Detailed explanation here and here.
Also, use filterMin of MipMapLinearNearest or MipMapLinearLinear to make sure you aren't getting minifying artifacts. (The first one performs better and the second one looks better at certain zoom levels and should be used if your camera zooms in and out.)
And finally, filterMax should be Linear.
Nearest filtering will always produce uneven artifacts if the sprites are not drawn at exactly 1X, 2X, 3X, etc. of their original size, because there will be certain rows and columns of the screen where a pixel in the image is drawn twice.
I have a image added with scene builder. It has a viewport with this characteristics: 400,400 300x300. As you can imagine there're a part of the image that isn't showing. I want to move the image but all. Rotate it in Z. So, the part that now isn't visible becomes visible.
For example, see that attitude indicator (my project is also an attitude indicator):
The background is rotated. But the image is bigger than you can see, so although it rotates you do't see white parts.
How can I do that??
What you actually want to do is rotate around a pivot point (in your case the center of the screen).
http://download.java.net/jdk8/jfxdocs/javafx/scene/transform/Rotate.html