I have been using XNA to make a PC game and I am doing lighting with RenderTarget2D by drawing the world stuff in one and then drawing the lightmask stuff in another. Anyway I wasn't running into any problems at first using my 1920x1080 monitor, but I just upgraded to a 27" 2560x1440 S-IPS monitor and now I'm getting an error because my monitor resolution is set higher than 2048 and that's apparently the largest size a texture can be.
It's trying to draw a texture of size 2560 by 1440 so I need to find a way around that limitation. I suppose with large screens I could somehow split it into multiple RenderTarget2Ds. My issue with that is how I pass in the light mask:
drawMain();
drawLightMask();
ScreenManager.SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
lightingEffect.Parameters["lightMask"].SetValue(lightMask);
lightingEffect.CurrentTechnique.Passes[0].Apply();
ScreenManager.SpriteBatch.Draw(mainScene, new Vector2(0, 0), Color.White);
ScreenManager.SpriteBatch.End();
I'm sure others have had to deal with this issue so maybe someone has some ideas on how I could approach this 2048 limitation?
Edit: Another thought.. perhaps when I detect that have a large resolution I just set it lower instead of default setting it to their current resolution. That way wouldn't really have to worry about it. The problem with this way is that in fullscreen mode it's changing their screen's resolution so when they exit the game it has to change resolutions again and is kind of messy. Then in borderless winowed mode the window is smaller but it doesn't seem to change your resolution.
Related
I am having issues with some applications (mainly dashboard) that some user uses windows display scaling to make their icons bigger but this cause huge problems in my software. I am looking for a way to disable completely the scaling on my application and leave the application scaled to the pixels of the display resolution instead.
I have found this thread but it is 8 years old and windows 10 didn't exist at the time and another user gave an answer but it doesn't work either.
A simple example of the behavior happen mostly on dashboards as there is a lot of controls and widget on these kind of screens and they are critical for thing like robot machinery controller.
One example dashboard window is in it's minimum possible size 1900 x 980 (could be 4-5 pixel smaller in both direction but we rounded up to get rounded positions XY values). This resolution is just shy of 1920 x 1080. It Cannot be smaller but you can make it larger if you have a bigger screen like 4K and all you gain is more date in treeviews, better display in the 3d Engine renderer etc.
So some users have small laptop screen such as 15 inches that have a maximum resolution of 1920 x 1080 resolution but they use 150% scaling so my screen minimum size become 2850 x 1470 in their screen which make the application bigger than the screen and goes outside the screen.
An another example if i use a Windows Surface Pro which have a 2736 x 1824 resolution which is about 80% bigger than 1920 x 1080 the window does indeed still take the original 1900 x 980 pixels on the screen which make it look quite small so if you full screen it you see much more information in all controls. But then if you change scaling to 150% the screen now take again 2850 x 1470 pixels on the screen which is fitting perfectly on the height but on the width i am short by 100 pixels, and 100 pixels that's enough to loose the right part of my screen and you either cannot see the left most part or the right most part of the screen.
I tried the 3 auto scaling mode : DPI, Font and None and it doesn't work at all. It still stretch the screen no matter what. Changing the font of the forms doesn't help either, i manage to make it once work for few labels directly in the form but anything inside group box fail to change or grow twice in size compare to the rest.
Important points :
Project are .net 4.5 and 4.6 but there is no problem compiling them in 4.7if i need to for specific features.
WPF is out of the question. We took 3 years to implement it and ended up quickly with very bad performance with third party DLL and 3D Cad performance were simply abysmal.
Screens are already optimized with the least amount of controls possible. out of the couple hundreds of screen and thousands of user controls about half of them are very close to the limit of 1920 x 1080 which is around 90% of our clients
I have received a suggestion of running a Virtual Machine on the client computer with 100% scaling which is not affected by the host computer. It is probably my last resort as it's very difficult to handle dedicated video card through VM especially CAD card such as Quadro and FireGL.
Half the users use touch screen and we tried putting everything in a panel with 2 scrollbar and god it's awful and works once in a blue moon. So it's only good for mouse users and these users all have desktop AFAIK so 99% of them doesn't use scaling so they don't have the issue.
So is there anything nowadays that can fix or work around this issue ?
Did you try making your Process DPI aware?
You can either do it through a pinvoke:
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
and call
SetProcessDPIAware();
in your Main or create a Manifest and add
<dpiAware>true</dpiAware>
There is a tutorial here.
Declearing it DPIAware should stop windows from scaling by its own.
When developing a xna game for pc, one problem is that people use different resolutions.
But what happens when the target pc has a lower resolution than the game? Do I have to use vector graphics?
The only way to use a lower resolution is by making the view port smaller, but I don't want to do that. I tested setting the resolution to ultra hd but it stays on full hd on my full hd screen. Is full hd just the maximum of xna or does the game automatically use the screens resolution when it's lower?
The game runs on fullscreen.
A common solution to this problem is to always render one's game to a set resolution and then scale the entire screen image to fit. Examples of how to do this can be found at XNA resize window without increasing resolution
I am going to play around with making an XNA game.
The windows store has two base resolutions it reccommends you support: 1024x768 and 1366x768
But after that there are no restrictions.
The common advice is to use a ViewBox that will scale your content for you.
But an XNA game does not have a viewbox. It has a draw method where you render your content.
What is the common way for Games (XNA or DirectX) to adapt to different resolutions?
I would rather not have to make images for each and evey resolution out there. It would be a lot of work and I am bound to miss some.
Is there a better way?
GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Widthand.Height will give you the current desktop resolution.
Then you can update Game.GraphicsDevice.Viewport variables to use these settings.
The above code usually goes in Game1.cs constructor
The link provided then documents one technique that makes your sprites, backgrounds etc look correct independently of the resolution(the theory should be sound if the code is not 100% up to date)
http://msdn.microsoft.com/en-us/library/bb447674%28v=xnagamestudio.10%29.aspx
There are two different approachs I read in a tutorial:
Resize everything to the new viewport (even with changing aspect ratio)
Just draw more surroundings around
Of course you can mix both: Resize everything as long as it can still be in the same aspect ratio (e.g. 4:3 or 16:9) and then show more or less background / surroundings.
You can also decide to display black content instead of the more surroundings, if it is important for everyone to have exactly the same sight (e.g. due to fairness), but in such a case it might be a better idea to use fog of war to reduce sight.
I am having a major performance problem with a game I'm developing for Windows Phone 7 in C# XNA 4.0.
There's a lot of code going on, like collision, input, animations, physics and so on.
The frame rate has been set to 60fps, but is only running at 32fps. I have tried a lot of things, like disabling though stuff like collision detection, but nothing helped getting higher frame rate. Now randomly I discovered when disabling the drawing of the background, which is just a standard 480x800 sized image (Same as the Windows Phone Resolution), and uses the default method "spriteBatch.Draw(Textures.background, Vector2.Zero, Color.White)" the frame rate goes from 32 to 55 fps. I have also tried changing the texture to a plain white one, but that does not help either, and I have also tried moving the drawing of the background to another place in the code, but nothing changed either. I tried making a new project, and just having the background drawed, but the fps would be at 60 fps then as it should. I'm only having one SpriteBatch.Begin() and SpriteBatch.End(), where all the needed sprites are drawed inside. There's 256 Texture2Ds loaded into the game, which all is loaded at the beginning of the game. The game is a sidescroller, so the background needs to move to the left all the time, but even if I just set it to Vector2.Zero, it would still ruin the fps by -20fps. I hope anyone has a solution to this, or at least an idea of why this is happening.
If you have 256 individual Texture2Ds being used within the same SpriteBatch Begiin/End call it's not surprising that performance isn't optimal unless you are ordering the sprites by texture, which you likely are not for a platformer. All that texture switching within the same batch will cause a decrease in framerate - it's likely that the background image is just the straw that breaks the camels back for your particular game setup.
Have you tried combining those 256 separate images into a smaller number of Texture2Ds (i.e. using spritesheets or a texture atlas)? Here is an older link about how proper sprite sorting can affect performance
In my XNA game, I program and design the entire thing for 1920x1080 resolution and then scale scale and letterbox to fit the running system (XBox or PC).
This has been a great solution as it allows me to only ever worry about one resolution.
However, I'm now wondering if this will come back to bite me in the future as the game becomes more complex.
Since I'm having to scale everything with every draw (I scale SpriteBatch.Begin() with the scale factor only once, do all drawing, then call End()), is this going to have any detrimental effect on performance? I know the XBox already does this for XNA games for you when set to 720p natively (which, I actually am when running on XBox, it just gets the appropriate scaling factor).... so I can't imagine it's too bad, even for the PC.
The xbox does its scale in a specialized scaler in the video output - there is zero performance hit to your app.
The scale factor you pass in to SpriteBatch just translates the vertices of your sprite. Its done with a factor of 1 even if you don't pass in a scale so there is no extra load there.
With different screen sizes there will be different fill rates (more or less pixels) and texture lookups will be different too so that will show some variances.
Just using a 1028x720 backbuffer is the safest to do. The xbox can hardware scale that into ANY resolution or ratio without a single line of code or any perf issues. It will letter box properly and the hardware scaler is very good quality. You cannot claim 1080p support is really the only downside.
If you chose 1020x1080 as your back buffer note that the hardware scaler cannot scale that down to 480i and WILL fail in peer review (well it should if anyone notices)
On WIndows the easiest thing is probably to draw everything to a RenderTarget and then just scale the whole darn thing on one go at the end. See the SpaceWar starterkit for the few lines of code it takes to do that. (All inside #if !XBOX so you dont waste cycles doing it on the 360)
This shouldn't cost you. The scaling is done by he video card.
However, if this does worry you, another option to handle different resolutions is to change the render target to an off screen buffer, render to that, and then draw a square on the screen with the buffer as the texture. More pixels are rendered, but you don't need to do a transform on each vertex.