{"id":494,"date":"2015-08-26T08:45:48","date_gmt":"2015-08-26T07:45:48","guid":{"rendered":"http:\/\/www.pixnbgames.com\/blog\/?p=494"},"modified":"2016-12-30T01:30:59","modified_gmt":"2016-12-30T00:30:59","slug":"how-to-smooth-textures-when-they-are-resized-in-libgdx-filters-i","status":"publish","type":"post","link":"https:\/\/www.pixnbgames.com\/blog\/tratamiento-imagenes\/how-to-smooth-textures-when-they-are-resized-in-libgdx-filters-i\/","title":{"rendered":"How to smooth textures when they are resized in LibGDX (filters I)"},"content":{"rendered":"<p style=\"text-align: justify;\">When working with LibGDX, we normally use a \u00abvitual\u00bb screen (whether through using <a href=\"https:\/\/github.com\/libgdx\/libgdx\/wiki\/Viewports\" target=\"_blank\">Viewports<\/a> or with transformation matrices) with a defined dimensions, and all textures \/ images will have a size according to that virtual dimensions.<\/p>\n<p style=\"text-align: justify;\">If the viewport size matches with the real size of the screen where our game is running, the textures are shown as we have created they. On the other hand, if the dimensions of the real screen does not match with our viewport world size, this will be scaled to match with the real width and height of the screen (the scaling will be done depending of the viewport type). When this happens, OpenGL uses texture filters, which basically define the algorithm used to scale the textures.<\/p>\n<h1 style=\"text-align: justify;\">Texture filters<\/h1>\n<p style=\"text-align: justify;\">A further explanation will be given later (in another article). This time I will only say that there are basically two types of filters:<\/p>\n<ul>\n<li style=\"text-align: justify;\"><code>GL_NEAREST<\/code>. To represent each pixel on the screen, it is used the pixel of the texture (texel) that best matches to the pixel of the screen. This is the default filter. As this filter only uses one texel for every pixel on the screen, its a very quickly to apply filter. The result is an image with \u00abhard\u00bb borders.<\/li>\n<li style=\"text-align: justify;\"><code>GL_LINEAR<\/code>. To represent each pixel on the screen, it is used a bilinear interpolation taking the four closest texels that best match with the screen pixel. The result is a smooth scaling. But its important to consider that the processing costs will also be bigger than <code>GL_NEAREST<\/code>.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Below, it&#8217;s\u00a0shown a texture in its original size (left), a resized version with default <code>GL_NEAREST<\/code> (center) and then another resized version using <code>GL_LINEAR<\/code>\u00a0(right):<\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-514\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/original.png\" alt=\"original\" width=\"92\" height=\"112\" \/> <img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-516\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/GL_NEAREST.png\" alt=\"GL_NEAREST\" width=\"178\" height=\"229\" \/> <img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-515\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/GL_LINEAR.png\" alt=\"GL_LINEAR\" width=\"178\" height=\"229\" \/><\/div>\n<h2 style=\"text-align: justify;\">Applying filters on textures<\/h2>\n<p style=\"text-align: justify;\">To apply a filter in a texture, we only need to set it with\u00a0<code>setFilter()<\/code>\u00a0method:<\/p>\n<pre lang=\"Java\">Texture myTexture = new Texture( Gdx.files.internal(\"texture.png\") );\r\nmyTexture.setFilter(Textue.TextureFilter.Linear, Textue.TextureFilter.Linear);<\/pre>\n<p style=\"text-align: justify;\">Filters also applies when the textures are used in actors. For example, in the next\u00a0case when the actor will be scaled, the filter <code>Texture.TextureFilter.Linear<\/code> (<code>GL_LINEAR<\/code>) will be used:<\/p>\n<pre lang=\"Java\">Texture actorTexture = new Texture( Gdx.files.internal(\"texture.png\") );\r\nactorTexture.setFilter(Textue.TextureFilter.Linear, Textue.TextureFilter.Linear);\r\nImage imageActor = new Image(actorTexture);<\/pre>\n<h2 style=\"text-align: justify;\">Applying filters on texture atlases<\/h2>\n<p style=\"text-align: justify;\">If we use texture atlases, we can also use filters. We do this by setting the filter with the key \u00ab<em>filter<\/em>\u00bb on <em>.atlas<\/em> file:<\/p>\n<pre>filter: Linear,Linear<\/pre>\n<h2 style=\"text-align: justify;\">Clarification<\/h2>\n<p style=\"text-align: justify;\">When we specify the filter applied to a texture, we need to indicate two filters. Without going into too many details (this will take place in another post), the first filter is used when the texture is minimized, and the second one is used when the texture is maximized.<\/p>\n<h1 style=\"text-align: justify;\">At last&#8230;<\/h1>\n<p style=\"text-align: justify;\">Applying the <code>GL_LINEAR<\/code>\u00a0filter we get our textures with a smooth scaling. However, there are situations where we don&#8217;t need this effect. For example, consider a game with pixelated aesthetics. This time, maybe is more interesting to scale using the default filer (<code>GL_NEAREST<\/code>)\u00a0to preserve the pixelated aesthetics. We can test different filter and choose which one is better in each case.<\/p>\n<p style=\"text-align: justify;\">Regards,<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When working with LibGDX, we normally use a \u00abvitual\u00bb screen (whether through using Viewports or with transformation matrices) with a defined dimensions, and all textures \/ images will have a size according to that virtual dimensions. If the viewport size <a class=\"more-link\" href=\"https:\/\/www.pixnbgames.com\/blog\/tratamiento-imagenes\/how-to-smooth-textures-when-they-are-resized-in-libgdx-filters-i\/\">Seguir leyendo <span class=\"screen-reader-text\">  How to smooth textures when they are resized in LibGDX (filters I)<\/span><span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":515,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[14,11],"tags":[15],"language":[4],"_links":{"self":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/494"}],"collection":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/comments?post=494"}],"version-history":[{"count":14,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/494\/revisions"}],"predecessor-version":[{"id":559,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/494\/revisions\/559"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media\/515"}],"wp:attachment":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media?parent=494"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/categories?post=494"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/tags?post=494"},{"taxonomy":"language","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/language?post=494"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}