DPI awareness and a full-screen

Started by
6 comments, last by Swatter555 10 years, 9 months ago

I have been trying to Google combinations of those terms like crazy and I can find very little info. I am coding a full-screen application using the DIrect2D API, which automatically scales rendering to current DPI setting. That is all fine and dandy, but higher DPIs effectively decreases resolution. If I were creating a windowed app, I would create a larger window and everything would scale nicely. However, for full-screen, part of the screen is going to be clipped.

I have turned up very little info on my internet searches, so I am kinda stuck about what I should do. I could make the app use windowed mode, but that opens up a can of worms in itself. Direct2D uses dips for everything, so I don't think I can tell it not to scale things. What am I missing about DPI awareness and full-screen applications?

Advertisement

I think that there's something wrong with your algorithms or you may have missed a step in the declaring that the api is dpi-aware. Seeing as higher dpi should always effectively increase resolution.

Quick googling found me this msdn article http://msdn.microsoft.com/en-us/library/windows/desktop/dd756693%28v=vs.85%29.aspx on how to make sure the api is dpi aware.

If you have already done that then you should see if your problem is aspect ratio related. When writing the code for drawing things especially for the UI it is way too easy to forget that the aspect ratio can change and cut off part of the ui. for example if your api is 4:3 in windowed mode and then you switch to fullscreen with your 16:9 display you very likely are just drawing outside of the screen. This is easy to test by changing the aspect ratio of the window and see if it results in clipping.

If you want true DPI awareness, you need to be able to fetch the actual physical dimensions of the screen and calculate DPI from the current resolution. You can then design your UI for a certain fixed DPI and scale everything based on the ratio between the two.

Any methods that Windows provides to directly query the DPI do not work as they're fixed to a legacy resolution of 96 DPI. In fact, AFAIK there's only one (full source code provided) way that can be used to reliably query the actual physical dimensions of the monitor in Windows to derive the actual DPI from. Most other OS's seem to offer far easier methods - you can probably google for them yourself if needed.

NOTE that getting screen dimensions from the EDID will fail if there's no valid monitor device. This occasionally happens on my laptop after bringing it back from sleep mode and can, to the best of my knowledge, only be fixed by restarting the computer. You'll know this is the case when no device is found.

I will do my best to understand here, I am pretty tired so hopefully I make sense.

PunCrathod-

In Visual Studio Express 2012, there is a flag for DPI awareness that says it automatically makes changes to the manifest. At least that's what it says. Does that not really work?

I may be tired, but doesn't the formula: <horizontal DPI> * <width, in pixels> / <default horizontal DPI> result in a larger window at higher DPI?

I must not be understanding what is going on correctly, but when someone changes their DPI, they are wanting larger text and icons. I read one MSDN page that encouraged people to use their max monitor resolutions and just use higher DPI settings if they have trouble with small icons and print. I just don't see how that effectively increases monitor resolution. You have bigger text and other items in the same space.

Unless you are truly dealing with a display device that handles higher dpi, your just resizing your display elements. I am missing something.

irreversible- Thanks for the link. Once I understand what the heck Windows and Direct2D is doing, that something I can look into.

Don't bother with any sort of "built-in DPI awareness" - no automatic process can and will do this properly for you. I don't think even MS knows what is going on there (at least I couldn't figure it out, even after extensive searching, so I signed any DPI-related stuff off as legacy functionality).

If you want to be able to either stick to physically static dimensions (eg you want a box to always measure 5x5 mm on screen) or you need to do consistent baseline scaling (eg you want your GUI to look exactly the same regardless of the resolution and screen size, eg on 21in, 15.6in and 8in screens), then the only reliable way to go is with a ground-up solution as I linked.

Well, since you have receive lots of the how-to's for the coding side of this and you have this to absorb, I'll just go for a bit of theory on how graphics tie into your display system.

Your screen is in essence, a dot-art drawing device, except it draws little squares instead of little dots. http://rukahtsubasa.deviantart.com/art/Pokemon-Dot-art-114056647. If you grabbed a television at random in the 90's, used or otherwise, you might have ended up with a screen that had a resolution of 640*480 pixels. You would have, roughly 300,000 little dots to work with. You could make a fairly detailed piece of art by touching your pencil to the paper that many times using a dot art technique. That is lot more dots than what you see on that fan-art Pokemon character picture posted above.

But now, if you decide to constrain your artwork to that grid and yet add extra fine details, you would start running into problems. Sure you could draw a button on a character's shirt but if you wanted to draw a little highlight on that button to make it shiny looking, you might have to break away from the grid system you created for your dot art. Or you could make a new grid system that has more little evenly spaced slots for you to draw your dots.

If you expanded your dot-art drawing to have 2, 000, 000, dots evenly spaced on your canvas, then you would have a picture that has a fine detail quality that is approximate to a modern High Definition T.V. That's a lot of dots and gives you a lot of room to put lots of fine detail dots into your drawing. You could now easily draw in little highlights on the various pieces of your drawing. That's what increasing your computer screen resolution gives you. More dots to draw with.

Part of the reason that this idea can become confusing is because many Operating Systems will actually change the size of a message box and text when the resolution is changed. Some games use the underlying window system in their game's menu. This may cause the same thing to happen in-game. Increasing the resolution appears to make things smaller then they were before. This, once again, creates a bit of confusion for people as to what is taking place when the resolution changes.

In my opinion, and most every game I've ever seen behaves this way, I'm sure I'll get no complaints from people for saying what I'm about to say.

When you change the screen resolution, the model or character that you have drawn on the screen should be the exact same size, and the model should be in the exact same place that it was before you changed the screen's resolution.

Even though this may not always be what happens, so far as I'm concerned, this should be what happens. If this is not happening for you then this might be something you want to strive towards.

The only change that you should see is that the artwork on screen has a lot more little dots drawn into its picture. It will have more fine detail. For some types of flat art, the extra detail might only be seen around the edges.

If the screen is high-res enough, then you should be able to see individual strands of hair or fur.

(i) There are several ways to configure your start-up window system using programming API's that are a part of your computer's operating system.

(ii) There are also several ways to configure your drawing code's camera or viewing system.

(iii) The 2nd thing listed here is being fed information by the 1st thing listed. They both have to sync-up properly or what you are drawing will become skewed.

When you set up the drawing camera, and also when you draw on paper, you can make things perspective correct, like when you make a long brick wall shrink off into the distance. Or you can also draw a cube that has all sides drawn with an equal length, no depth correction, this would be orthographic.

What is common to both is that the camera has to know how wide your screen is and how high it is. Now what you draw hopefully matches up with your computer screen. One good way to see if everything is working properly would be to grab a ruler and cut out a square of paper. Make sure the square is measured properly right down to the smallest increment on your ruler. Next, carefully and patiently cut the square from the rest of the paper.

Now use the drawing calls for Direct2D, or Direct3D or OpenGL, etc... and draw a plain white square to your screen. Now hold the piece of paper that you cut out, up against your computer screen where the white square is drawn. Re-size the draw calls so both the real square and the computer rendered square match up in size, then compare them to see if the computer rendering is perfectly square or not.

If both match up perfectly then I'd say now try and get that white piece of paper stuck to the screen somehow temporarily, even if you have to pay someone to hold it there for a couple minutes. Now change the game's resolution. I'd say... ideally anyways: the square should still match up perfectly in both size and position, and not be stretched either across its width or across the height. It should still be a perfect square. Especially if it's at the center of the screen and you're using an orthographic matrix.

If that happens then you probably have things set up pretty well.

p.s. On a side note.. I've measured screens and found that the physical measurements of the device did not match up perfectly with the screen resolution ratio.

For instance, if your screen is 1000*500, then your screen ratio would be 2.

If, however, you take out a ruler and find that the screen is really 1000 millimeters by 490 millimeters. This means that your screen is not physically symmetrical to its pixel ratio. If this screen were proportionate then it would be 500 mm high instead of 490 mm. Same as the resolution. When this happens, the pixels might actually be rectangles or there might be a tiny bit more space between the rows or columns of the screen's pixels.

If this were the case then your cut-out square piece of paper would not match up properly with the computer-rendered square piece of paper.

It would be possible to fix this with a bit of government lobbying. For instance, if it were mandatory for computer and T.V. screen manufacturers to report in their device specifications if their screen's are out of proportion and by how much, then games and movie-player software could automatically adjust themselves to display properly on that particular device.

A game's camera could now be set to display slightly out of proportion to compensate for the actual screen being out of proportion. Now everything would display properly without any stretching regardless of which machine it is running on.

Consider it pure joy, my brothers and sisters, whenever you face trials of many kinds, 3 because you know that the testing of your faith produces perseverance. 4 Let perseverance finish its work so that you may be mature and complete, not lacking anything.

marcClintDion-

Thanks for the tutorial. It helps to go back and think about the basics. As I was thinking about supporting different resolutions, my first thought was just to express all graphical elements as a percentage of the viewing surface. Say a button would be 2% by 1.5%. I haven't really had much time to test it, but it seems like a good idea. Although, I would imagine the screen would not be a carbon copy across all resolutions, but then again that might be ok.

Then again, I really cannot escape the logic of what irreversible is saying. I guess that is the answer.

As I said though, Direct2D automatically scales, but I would assume that can be disabled. I wish someone would write a book on Direct2D, MSDN is only so useful.

Let me see about implementing a true scaling method like irrev is talking about. Ill test it across various settings and get back to you.

I am stuck.

- I cannot compile the linked program because I have a poor mans version of Visual Studio.

- Even if I could compile the program and use it, DIrect2D automatically scales everything if I declare my application as DPI aware.

Bottom line, unless I figure out how to disable Direct2D automatic scaling, I cannot implement a custom scaling solution. Unless someone can tell me a way to disable virtualization without making my application DPI aware.

This topic is closed to new replies.

Advertisement