Thread Tools Display Modes
04-11-10, 09:49 AM   #1
TravisWatson
A Deviate Faerie Dragon
Join Date: Apr 2010
Posts: 11
Lightbulb Pixel Perfection for Specific Resolution

This post has been updated per Haleth's information below. Thanks Haleth!

I came across an issue I didn't like while designing my UI: in-game pixels were not "real" pixels. They were close, but not exactly. So sometimes textures/borders/etc would get fudged when WoW scales up from its in-game resolution to your monitor's resolution.

The solution is to manually set the uiscale CVar (which just stores the value from this slider in the Video Options).

Here's the quick'n'dirty macro line:

Code:
/run SetCVar("uiScale", 768/string.match(({GetScreenResolutions()})[GetCurrentResolution()], "%d+x(%d+)"))
Here's the explanation and longer more hands-on method:

To calculate the value, you need your resolution height (mine was 1050 for a 1680x1050 resolution) and need to know the game's height is always (?) 768. You can verify that your in-game height is 768 by running the following lines:

Code:
/console useuiscale 1
/console uiscale 1
/run print(GetScreenHeight())
Your UI scale is the ratio between your actual resolution and the in-game resolution. For me, it's:

Code:
768 / 1050 = 0.731428571
/console uiscale 0.731428571
NOTE: The minimum value is 0.64. Below 0.64 will not work!

You can see what your resulting size is by:

Code:
/run print(GetScreenWidth(), "x", GetScreenHeight())
And there you have it, the exact resolution of your monitor (within floating point accuracy) to work with when designing your UI. Since we were modifying a CVar, this will save across sessions.

Disclaimer: This is possibly/probably a bad idea if you plan to package your UI. I use it only for my own UI.

Last edited by TravisWatson : 04-11-10 at 11:11 AM.
  Reply With Quote
04-11-10, 10:04 AM   #2
Gsusnme
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Jun 2008
Posts: 55
I too have noticed "fudging" or "blending" with my UI but I always simply thought of it as a limitation of the UI overlay, thanks so much for this! Now my OCD is satiated.

Last edited by Gsusnme : 07-03-10 at 12:27 AM.
  Reply With Quote
04-11-10, 10:08 AM   #3
TravisWatson
A Deviate Faerie Dragon
Join Date: Apr 2010
Posts: 11
@Gsusnme, Glad I could help! Indeed it was also my OCD that led me down this path!
  Reply With Quote
04-11-10, 10:30 AM   #4
Haleth
This Space For Rent
 
Haleth's Avatar
Featured
Join Date: Sep 2008
Posts: 1,173
It's much easier if you just do:

/script SetCVar("uiScale", 768/string.match(({GetScreenResolutions()})[GetCurrentResolution()], "%d+x(%d+)"))
  Reply With Quote
04-11-10, 10:42 AM   #5
TravisWatson
A Deviate Faerie Dragon
Join Date: Apr 2010
Posts: 11
Originally Posted by Haleth View Post
It's much easier if you just do:

/script SetCVar("uiScale", 768/string.match(({GetScreenResolutions()})[GetCurrentResolution()], "%d+x(%d+)"))
Ha, I didn't even look at the height! Had no clue that it always sets that value to 768. Good call! Will this always be the case? Is 768 *always* the base height?
  Reply With Quote
04-11-10, 10:55 AM   #6
Haleth
This Space For Rent
 
Haleth's Avatar
Featured
Join Date: Sep 2008
Posts: 1,173
Originally Posted by TravisWatson View Post
Ha, I didn't even look at the height! Had no clue that it always sets that value to 768. Good call! Will this always be the case? Is 768 *always* the base height?
Yes, afaik the WoW screen height is always 768.
  Reply With Quote
04-11-10, 11:38 AM   #7
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
UI Scale is one way, but when I'm making an addon, I can't set the users UI scale to my value. So I have to make a workaround. If I scale any value with the following function, there comes out the value needed to represent the amount of "virtual pixels" needed by the frame to get the amount of "real pixels".

Code:
local mult = SetCVar("uiScale", 768/string.match(({GetScreenResolutions()})[GetCurrentResolution()], "%d+x(%d+)"))/GetCVar("uiScale")
local function scale(x) return mult*x end

someframe:SetHeight(scale(10))
someframe:SetWidth(scale(10))
I implemented this method in TukUI and ncUI to get them both pixelperfect.
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
04-11-10, 01:28 PM   #8
Saiket
A Chromatic Dragonspawn
 
Saiket's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 154
If you don't want to override the user's uiScale, you can use the following code to position a frame on real pixel boundaries: http://pastey.net/134131

It includes some test code that renders pixel-wide nested borders. The top one in this screenshot is adjusted, the bottom one isn't.
  Reply With Quote
04-11-10, 01:34 PM   #9
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Originally Posted by Saiket View Post
If you don't want to override the user's uiScale, you can use the following code to position a frame on real pixel boundaries: http://pastey.net/134131

It includes some test code that renders pixel-wide nested borders. The top one in this screenshot is adjusted, the bottom one isn't.
Hence my above post

One problem though, neither GetCVar("uiScale") or UIParent:GetScale() return values instantly, you'll have to hook an event like PLAYER_ENTERING_WORLD(I don't know the first event that they are available, I do know that they are available at PLAYER_ENTERING_WORLD).
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
04-11-10, 01:56 PM   #10
Saiket
A Chromatic Dragonspawn
 
Saiket's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 154
Originally Posted by nightcracker View Post
Hence my above post

One problem though, neither GetCVar("uiScale") or UIParent:GetScale() return values instantly, you'll have to hook an event like PLAYER_ENTERING_WORLD(I don't know the first event that they are available, I do know that they are available at PLAYER_ENTERING_WORLD).
Since GetScreenWidth() is already scaled by the current uiScale, GetScreenWidth() * UIParent:GetScale() is constant no matter what uiScale is set to.
  Reply With Quote
04-11-10, 02:47 PM   #11
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Originally Posted by Saiket View Post
Since GetScreenWidth() is already scaled by the current uiScale, GetScreenWidth() * UIParent:GetScale() is constant no matter what uiScale is set to.
I'm saying, there is no way to get the UIScale before VARIABLES_LOADED(I think).
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
04-11-10, 03:09 PM   #12
Recluse
A Cliff Giant
 
Recluse's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 70
Do any of these methods take into consideration using windowed mode (sans Maximized option)? I ask because, say your Windows desktop resolution is 1024x768. If you run WoW at 1024x768 in a non-maximized windowed mode, the actual resolution is a bit lower due to the WoW window's borders, title bar, and even the task bar.
__________________
We'd be together, but only diamonds last forever...
  Reply With Quote
04-11-10, 03:35 PM   #13
Saiket
A Chromatic Dragonspawn
 
Saiket's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 154
Originally Posted by nightcracker View Post
I'm saying, there is no way to get the UIScale before VARIABLES_LOADED(I think).
Even before VARIABLES_LOADED, UIParent:GetScale() returns 1 and GetScreenWidth() returns a value scaled to 1. No matter when its run, the product of those two will be the same.

Originally Posted by recluse View Post
Do any of these methods take into consideration using windowed mode (sans Maximized option)? I ask because, say your Windows desktop resolution is 1024x768. If you run WoW at 1024x768 in a non-maximized windowed mode, the actual resolution is a bit lower due to the WoW window's borders, title bar, and even the task bar.
Since there's no way for a mod to know how big the window is, or where it's positioned on-screen, that can't be done.
  Reply With Quote
04-11-10, 03:36 PM   #14
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Originally Posted by recluse View Post
Do any of these methods take into consideration using windowed mode (sans Maximized option)? I ask because, say your Windows desktop resolution is 1024x768. If you run WoW at 1024x768 in a non-maximized windowed mode, the actual resolution is a bit lower due to the WoW window's borders, title bar, and even the task bar.
Resolution is virtual in this context, even if you play at windowed mode REALLY small, it still counts as 1024*768.
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
04-11-10, 06:12 PM   #15
TravisWatson
A Deviate Faerie Dragon
Join Date: Apr 2010
Posts: 11
Originally Posted by nightcracker View Post
UI Scale is one way, but when I'm making an addon, I can't set the users UI scale to my value.
I guess I should have been clear, I did not intend to create a standalone addon that modified the UI Scale. My whole purpose was to set my overall resolution for every addon to use, while maintaining my screen resolution so that everything looks pixel perfect and I can create my custom textures more easily. The way this should be used for addon creators is to create their addons/ui packs in a precise and realistic environment, which is in my opinion when the number of pixels you're working with is identical to your native resolution.

In fact, if I understand what you guys are doing here, I highly disapprove. It looks like you guys are making your addons ignore the UI scale... and in my opinion, this is a terrible idea! This is not what I had in mind AT ALL. Your addons should never ignore a user's UI scale. If I found one that did, I would probably promptly trash it.

Please correct me if I misunderstood what this code is doing.
  Reply With Quote
04-11-10, 06:17 PM   #16
Waverian
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Dec 2006
Posts: 188
It doesn't ignore the scale. It just (optionally, per element) multiplies the value of a real pixel so that it fits the size of a full ui pixel and won't be anti-aliased.

Both solutions are acceptable, but the fact is not everybody is going to have their UI set to this scale. Also, just as importantly, changing the UI scale modifies your entire UI. When switching to a normalized UI scale I had to drastically modify every individual element of my UI to be ~20% smaller and in a position to match the old.

If I'm releasing an addon that requires pixel-perfect borders, should I tell all of my users to change every UI element's scale and position, or should I emulate the value of a pixel in my own UI and leave everything else alone?

I'd always choose the latter.
  Reply With Quote
04-11-10, 07:29 PM   #17
TravisWatson
A Deviate Faerie Dragon
Join Date: Apr 2010
Posts: 11
Originally Posted by Waverian View Post
It doesn't ignore the scale.


What am I missing here? This is exact code from Saiket. From the looks, it blatantly ignores scale. (It should scale with the map, but it doesn't)

Originally Posted by Waverian View Post
Both solutions are acceptable, but the fact is not everybody is going to have their UI set to this scale. Also, just as importantly, changing the UI scale modifies your entire UI. When switching to a normalized UI scale I had to drastically modify every individual element of my UI to be ~20% smaller and in a position to match the old.
This is exactly what I'm trying to get at... I don't want to do this AFTER I create my UI, I want to do it BEFORE everything gets set up at an improper resolution for one of 2 purposes:
  1. Creating a custom UI for myself or for a UI Pack.
  2. Creating an addon. When I design web pages, I create for 1:1 pixels in my images and browser. If they user chooses to scale, that's their option, but my optimization is 1:1. Why would you not optimize my WoW addon font sizes and textures the same way? Do you have some other suggestion for best practice?

If an addon developer runs at a UI Scale of 2 and optimizes font sizes, etc for that, it's going to look like hell for someone with a default of 0.9 (no ui scale).

And by using the UIScale method when setting up my custom UI or pack, I'm making every addon pixel perfect, not just some random one that I'm creating. This goal isn't to create one pixel perfect addon, but an entire pixel perfect UI regardless of the addons I use. I really believe we're talking about two completely different problems. Hopefully you'll see my intents now.

Originally Posted by Waverian View Post
If I'm releasing an addon that requires pixel-perfect borders, should I tell all of my users to change every UI element's scale and position, or should I emulate the value of a pixel in my own UI and leave everything else alone?

I'd always choose the latter.
Again, you're completely misunderstanding the purpose of this thread. Although I think the method presented could possibly be useful in rare situations, like I showed it clearly ignores scale, and I strongly disagree with this implementation other than very rare situations (1 pixel borders, for instance).
  Reply With Quote
04-11-10, 08:50 PM   #18
Saiket
A Chromatic Dragonspawn
 
Saiket's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 154
Originally Posted by TravisWatson View Post


What am I missing here? This is exact code from Saiket. From the looks, it blatantly ignores scale. (It should scale with the map, but it doesn't)



This is exactly what I'm trying to get at... I don't want to do this AFTER I create my UI, I want to do it BEFORE everything gets set up at an improper resolution for one of 2 purposes:
  1. Creating a custom UI for myself or for a UI Pack.
  2. Creating an addon. When I design web pages, I create for 1:1 pixels in my images and browser. If they user chooses to scale, that's their option, but my optimization is 1:1. Why would you not optimize my WoW addon font sizes and textures the same way? Do you have some other suggestion for best practice?

If an addon developer runs at a UI Scale of 2 and optimizes font sizes, etc for that, it's going to look like hell for someone with a default of 0.9 (no ui scale).

And by using the UIScale method when setting up my custom UI or pack, I'm making every addon pixel perfect, not just some random one that I'm creating. This goal isn't to create one pixel perfect addon, but an entire pixel perfect UI regardless of the addons I use. I really believe we're talking about two completely different problems. Hopefully you'll see my intents now.



Again, you're completely misunderstanding the purpose of this thread. Although I think the method presented could possibly be useful in rare situations, like I showed it clearly ignores scale, and I strongly disagree with this implementation other than very rare situations (1 pixel borders, for instance).
The test code doesn't parent to UIParent, and I can't remember if I set it up to account for UIParent's scale even if you did reparent the pyramids. It only shows the mapping between UI units and pixels. If you want to scale things, you're welcome to do that math. There's no magic to UIScale.

I'm still not entirely sure what you want, or what you don't want. If you want everything pixel perfect, you must either use the uiScale method or hook every SetPoint operation in the API. If you want only your mod to be pixel perfect, position your frames using the formula in my test code.
  Reply With Quote
04-11-10, 10:03 PM   #19
TravisWatson
A Deviate Faerie Dragon
Join Date: Apr 2010
Posts: 11
Originally Posted by Saiket View Post
I'm still not entirely sure what you want, or what you don't want.
I want my addons, all of them, to be pixel perfect. I also want to be able to design textures for my native resolution, not some crazy number that WoW decided. I'm not saying everyone wants this, but for me this feels like a very natural way to design a user interface.

I also wanted to suggest a method for addon authors to design a more consistent user interface experience. All too often I see an author that designed his options GUI when his scale was set crazy, and it ends up not blending at all with the rest of the UI components. I'm suggesting that by designing at your native monitor resolution, you can deliver a more quality, consistent experience.

Originally Posted by Saiket View Post
If you want to scale things, you're welcome to do that math. There's no magic to UIScale.
I agree, it's not special, but it was an answer so simple that has bugged the hell out of me for over a year, and I couldn't find another resource on it, so I thought I would post. Hopefully others will find it and appreciate it. For me, if I redesign my UI again (very likely), this is the first step on my list.
  Reply With Quote
04-26-10, 02:48 PM   #20
Sideshow
A Flamescale Wyrmkin
 
Sideshow's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 103
Originally Posted by nightcracker View Post

Code:
local mult = GetCVar("uiScale", 768/string.match(({GetScreenResolutions()})[GetCurrentResolution()], "%d+x(%d+)"))/GetCVar("uiScale")
local function scale(x) return mult*x end

someframe:SetHeight(scale(10))
someframe:SetWidth(scale(10))
You say SetCVar / GetCVar ??? I corrected it to GetCVar / GetCVar
I'll probably lack knowledge, but all scale(1) does is multiply by 1.
So scale(23.124578) is still 23.124578 with this function of yours

Last edited by Sideshow : 04-26-10 at 02:51 PM.
  Reply With Quote

WoWInterface » Developer Discussions » Tutorials & Other Helpful Info. » Pixel Perfection for Specific Resolution

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off