I have an issue with the libgdx ttf font generator. No matter what I try, I get the font pixelated. This is what I have right now that minimizes but makes it still visible:
FreeTypeFontGenerator.FreeTypeFontParameter parameter;
FreeTypeFontGenerator generator;
parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
parameter.minFilter = Texture.TextureFilter.Linear;
parameter.magFilter = Texture.TextureFilter.Linear;
generator = new FreeTypeFontGenerator(Gdx.files.internal(Constants.ROBOTO_CONDENSED_BOLD));
parameter.size = Constants.SELECTION_DESCRIPTION_FONT_SIZE;
parameter.color = Constants.GARAGE_FONT_COLOR;
generator.scaleForPixelHeight(Constants.SELECTION_DESCRIPTION_FONT_SIZE);
descriptionFont = generator.generateFont(parameter);
generator.dispose();
Is it possible that the camera I am using is 854x480 per say, but the screen size is 1920x1080 that causes the pixaltion?
The problem does indeed lie within the resolutions. My hud camera was converting to 854 - 600 width range and height accordingly. Having a screen with resolution 1920x1080 makes the font considerably pixelated with spritebatch being set to hud camera with twice the lower resolution.
Related
ImageViews do not seem to scale but buttons do when I apply the following code
var myDisplayMetrics = Resources.DisplayMetrics;
myDisplayMetrics.DensityDpi = DisplayMetricsDensity.Low;
myDisplayMetrics.SetTo(myDisplayMetrics);
This came about because I noticed the ImageButtons were larger on the screen than the pixels size delivered. I investigated this and found a way to calculated the DP.
On hardware which gives DisplayMetrics as density=1.5, width=1920, height=1200, scaledDensity=1.83, xdpi=225.777, ydpi=225.77701 and this apparently gives a DP of 1280 x 800 hence the unexpected size
I applied the code above and the ImageButton appeared at the right size however the animation in the ImageView was still too big..
What is the standard way of fixing this? I am using Xamarin.
I've read some articles about Viewports to solve the problem with different resolution. But in every example they used a smaller size for the texture than the resolution of the screen. But what happens when my texture size is for example 1920 x 1080 and my screen is just 800 x 400?
Is there any kind of Viewport that can scale the texture? I didn't found anything for this problem.
Looks like you mean scaling and not compressing. Compressing is a technique to lower the file size of a file, like a .jpg does over a uncompressed .bmp. So if you mean scaling then it completely depends on what you want. If you have a 1920x1080 texture and want this to completely fit the 800x400 screen it needs to be stretched since 1920x1080 = 16x9 and 800x400 = 2:1 = 16:8.
To stretch the image you need to use StretchViewport. You would create the viewport with the world dimensions you want to show. So in this case the 1920x1080 image, or perhaps 16x9 and put that texture with there "world units) in your world. StretchViewport will make sure the viewport is stretched to whatever size you use.
If you want it to fit as much as possible but remain the aspect ratio of 16:9 then you can use the FitViewport. Like StretchViewport each viewport (except ScreenViewport) need to be supplied with world units, this is a important concept. World units are not meters nor pixels until you define your world units as such. Anyway, FitViewport will also make sure each device sees as much of your world as you supply it but your assets won't stretch/deform. Instead it will create a "black" bar, much like TV's do when the aspect ratio is not equal.
ScreenViewport, by default just takes the size of the screen. So a 1920x1080 pixel screen would show 1920x1080 world units and a 640x480 pixel screen would show 640x480 world units. Therefore, the higher resolution the screen has the more of the world is visible. The amount of world units a screen pixel represents can be changed.
There are a view others: FillViewport is like FitViewport it will remain aspect ratio but always fills the screen. And thus some parts may not be visible. For that reason I can't think of a use for this one over FitViewport. And there is ExtentVieport, a mix between FitViewport and ScreenViewport.
I am converting an existing cocos2d game in to android but i am getting resolution problem there.In the existing cocos game , i am using there two resources folder one for IPAD and one for IPHONE.I want that using these existing resources folder , i can execute my android game. please give me any sample code which also work with android resolution.
previously i am using this below code for IOS
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
std::vector searchPaths;
Size frameSize = glview->getFrameSize();
if (frameSize.height > 640)
{
UserDefault::getInstance()->setIntegerForKey(DEVICE_TYPE,IPAD);
searchPath.push_back(largeResource.directory);
if(frameSize.height>768)
{
UserDefault::getInstance()->setBoolForKey("RETINA",true);
Director::getInstance()->setContentScaleFactor(0.5f);
UserDefault::getInstance()->setBoolForKey("RET", true);
}
}
else
{
UserDefault::getInstance()->setIntegerForKey(DEVICE_TYPE,IPHONE);
searchPath.push_back(smallResource.directory);
if(director->getWinSize().width == 960)
{
UserDefault::getInstance()->setBoolForKey(IPOD_5,false);
}
else
{
UserDefault::getInstance()->setBoolForKey(IPOD_5,true);
}
}
UserDefault::getInstance()->flush();
FileUtils::getInstance()->setSearchPaths(searchPath);
There’s too many different screen sizes on the android devices. For example, below is most common values for now on phones (first value - resolution, second & third - aspect ratio):
480x800 - 3:5 or 0.6
480x854 - 0.5621
768x1280 - 3:5 or 0.6
720x1280 - 9:16 or 0.5625
1080x1920 - 9:16 or 0.5625
1440x2560 - 9:16 or 0.5625
And for the tablets:
2048x1536 (2048x1440) - 3:4 or 0.75 (0.7031)
1280x800 (1280x752) - 10:16 or 0.625 (0.5875)
1920x1200 (1920x1104) - 10:16 or 0.625 (0.575)
2560x1600 (2560x1504) - 10:16 or 0.625 (0.5875)
1024x600 (1024x552) - 0.5859 (0.539)
Keep in mind that there’s status bar on the tablets. It take some resolution, and cocos application can’t see the total device resolution, but only truncated (I showed it in the brackets). Accordingly changes aspect ratio.
All this leads to a very large selection of resolution values. Therefore it would be better to group the values for aspect ratio devices. In this case I use this method in AppDelegate.cpp:
static Size designResolutionSize = Size(2560, 1600); // you can choose your designResolutionSize at the top of AppDelegate
In applicationDidFinishLaunching() method:
bool AppDelegate::applicationDidFinishLaunching() {
…
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLViewImpl::create("My Game");
director->setOpenGLView(glview);
}
glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::FIXED_HEIGHT);
std::vector <std::string> searchPaths;
singleton->setScreenRelation(glview->getFrameSize().height / glview->getFrameSize().width);
if (singleton->getScreenRelation() > 1)
singleton->setScreenRelation(1 / singleton->getScreenRelation()); // isn’t depend on the screen orientation
if (singleton->getScreenRelation() <= 0.563) // phones with 9:16 aspect ratio
{
searchPaths.push_back("PhoneBacks");
}
if ((singleton->getScreenRelation() > 0.563)&(singleton->getScreenRelation() <= 0.625)) // phones and tablets with 10:16 and 3:5 aspect ratio
{
log("WideTablet, %d", singleton->getScreenRelation());
}
if (singleton->getScreenRelation() > 0.625) // tablets with 3:4 aspect ratio
{
searchPaths.push_back("TabletBacks");
}
cocos2d::FileUtils::getInstance()->setSearchPaths(searchPaths);
So, you need only background with three different aspect ratios.
Here is most important part – ResolutionPolicy::FIXED_HEIGHT (or FIXED_WIDTH) option. For landscape screen orientation you need FIXED_HEIGHT policy. It means that you have fixed designResolution.height = 1600 pixels on the all devices, and variable width. For example, on the 720x1280 phone you have background.width= 1600, and background.height = 1600/0.5625 = 2844 pixels. Analogically use FIXED_WIDTH for the portrait screen orientation.
This method is not perfect. For similar values of aspect ratio backgrounds can be cut into several pixels, or vice versa, can be seen at the edges of black stripes is several pixels wide. Also this method isn’t suitable for moving backgrounds. But for the fixed backgrounds it gives a good picture and requires only three resolutions of backgrounds.
So, LibGDX rants in a bunch of tutorials about how it is not recommended to use device pixels as coordinates in your world. I can understand the logic and it seems reasonable, so I am updating my camera code to do this:
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
aspect = h / w;
camera = new OrthographicCamera(1.0f, aspect);
camera.setToOrtho(true, 1.0f, aspect);
However a large part of what I do is working with fonts. Currently my font loader looks like this:
glyphLayout = new GlyphLayout();
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("myfont.ttf"));
FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
parameter.size = 100;
parameter.characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.!'()>?:";
parameter.flip = true;
font = generator.generateFont(parameter);
This results in huge sized fonts. I am confused by the apparently conflicting coordinates systems in LibGDX - why do they not recommend using pixels, and yet all font functions deal with pixels?
How can I update this font loading code, so I get fonts which are approximately 20% of the screen size?
You can develop for one resolution (using viewports) and set your preferred font size.
At runtime, you can scale your font size based on the new screen width.
1920x1080, parameter.size = 16 => 1280x720, parameter.size = 16 / 1920 * 1280
Also, with distance field fonts, you can render smooth fonts without using the font ganerator at runtime.
I'm using multi resolution technique number three as written in this article
and to determine the scale factor and stage size, I'm using this piece of code originally written by Jeff :
if (Capabilities.screenDPI >= 200) {
if (Capabilities.screenDPI >= 280) {
AssetFactory.contentScaleFactor = 2;
}
else {
AssetFactory.contentScaleFactor = 1.5;
}
}
else {
AssetFactory.contentScaleFactor = 1;
}
var mViewPort:Rectangle = new Rectangle(0, 0, stage.fullScreenWidth, stage.fullScreenHeight);
mStarling = new Starling(Startup, stage,mViewPort);
mStarling.stage.stageWidth = stage.fullScreenWidth / AssetFactory.contentScaleFactor;
mStarling.stage.stageHeight = stage.fullScreenHeight / AssetFactory.contentScaleFactor;
Then I use this scale factor to determine which sized assets I need to pick.
So now, I have a background which I strech to stage width and size. This technique works great when I'm testing with most devices but then we have devices like the Barnes and Noble Nook Color.
The device has a resolution of 600x1024 with 170 dpi. This means that it's going to pick the smallest assets (320x480) and strech it to 600x1024. Which ofcourse is pixalated. Any ideas on how to get over this issue?
I'm also attaching a test application which shows the issue in detail https://dl.dropbox.com/u/2192209/scaling%20test.zip
What worked for me best so far is not scaling Starling's viewport at all. It should always remain the base size (320x480).
Then you have a scale factor about how big the texture should be. It's a built feature of Starling when creating a texture - passing a scale factor.
What this means is that if your stage is 640x960, your scale factor will be 2. Your image (Bitmap object), will have ACTUAL SCREEN size of 320x480 (fullscreen, 1:1 with stage size), BUT it's texture (loaded asset BitmapData) will be twice as big (640x960, 1:1 with phone size).
For easier understanding - the stage of Starling (320x480) will be scaled up to fit your phone's resolution (320 -> 640). But your images will be scaled down to fit in the stage (640 -> 320). So you get perfectly normal images.
This helps you maintain fixed size of stage. It's really helpful, because otherwise it would be hard to position objects - if you want the object to be in the middle, it's sometimes 160, sometimes 320, etc. This means you always have to set position/size with calculations, which is an overload.
Hope that helps!
edit: Just remembered of a site I've used to determine my main size and assets ratios: http://screensiz.es/phone
How about setting max scale size? If the conclusion of the calculations above takes you to scale that is grater than 2, use bigger assets to reduce the scale ratio.
Your calculation only takes screenDPI in count, try combining them with screen resolution as well.