Widescreen resolutions

Discussion in 'Game Development (Technical)' started by ggambett, Jan 6, 2010.

  1. ggambett

    Moderator Original Member Indie Author

    Joined:
    Jul 26, 2004
    Messages:
    1,982
    Likes Received:
    6
    I'm rewriting part of my rendering code so I wonder how you guys handle widescreen.

    My situation is as follows. We use fixed size backgrounds (say 800x600). When players go fullscreen in a widescreen monitor, we add black bars to the sides, to make sure the game isn't stretched.

    There are several ways to do this, though, and I wonder what approach you use :

    1) Find a resolution that closely matches the native aspect ratio of the monitor, and scale up the rendered image to fit the height. For example, my monitor is 1280x800, so I set that resolution, and scale the images by 1.33 - it takes 1066x800 but it looks fine. Drawbacks : scaling up, but scaling is uniform (so pixels are still square)

    2) Set 800x600 fullscreen, scaling down the width, so the rendered image looks not-stretched. Drawbacks : non-uniform scaling. Does this look good?

    3) Something else

    What do you think is the best way to do this?
     
    #1 ggambett, Jan 6, 2010
    Last edited: Jan 6, 2010
  2. PoV

    PoV
    Indie Author

    Joined:
    Jul 27, 2004
    Messages:
    2,132
    Likes Received:
    0
    - I make my art at HD 1080p, then half and quarter it depending on the target platform.
    - Art is designed to look good when scaled down to the PSP's resolution (480x272).
    - Bilinear filtering with mip-maps (i.e. trilinear filtering) makes stuff look good at any scale.
    - Currently my backgrounds are procedural, so they support any screen shape.
    - The plan for future stuff is to either composite on to solid colors/gradients/textures patterns/3d models, or to black bar it.
    - If black baring, Widescreen is preferred. However making a seamless/infinite background isn't that hard, so I'll probably just do that.
    - On Netbooks I currently take the native desktop resolution and just use that. I haven't decided if I'll Window on normal PC's or not.
     
  3. jpoag

    jpoag New Member

    Joined:
    Mar 15, 2008
    Messages:
    806
    Likes Received:
    0
    Look for a widescreen resolution that has the same height as the game (600), say 1280x600. If you can't find one, then the next one up. In fact, you can write a small list of resolutions that you know look good and look for those in order (after the 600 height check). If you can't find a height that matches the game height, or one from the prefered list, then use the Desktop Resolution.

    Be sure to have a checkbox to disable the widescreen support and use 800x600. A couple of weirdos out there prefer stretching to black bars.
     
  4. Mattias Gustavsson

    Original Member

    Joined:
    Aug 10, 2005
    Messages:
    669
    Likes Received:
    0
    I never change the screen resolution at all. Whatever resolution the game runs at, I just stretch the image to fit the current screen - which means there could be black bars top/bottom or left/right depending on the specific combination of game resolution vs screen resolution.
     
  5. Emmanuel

    Moderator Original Member

    Joined:
    Nov 23, 2004
    Messages:
    859
    Likes Received:
    0
    If you're switching to a widescreen resolution by detecting that the customer has a widescreen desktop, stick with the desktop resolution.

    Some monitors can't display all of the enumerated resolutions, so your game will show a powered off screen; yet some other screens have horrible hardware scalers, so your game will look all blocky.

    To solve both issues, always stay with the same resolution as the desktop (only changing the bitdepth if needed). That's the logic we've shipped in tens of millions of downloads.

    Best regards,
    Emmanuel
     
  6. jpoag

    jpoag New Member

    Joined:
    Mar 15, 2008
    Messages:
    806
    Likes Received:
    0
    I've fielded more problems with the native desktop resolution causing the blockiness issues than power-off issues. People don't like it when you tell them to change the resolution of their desktop so they can play in fullscreen.

    99.99% of the time, sticking with the desktop resolution (in a widescreen scenario) will not cause any problems. However, I've recently added an option to search for a better resolution in case of the blockiness issues. The power-off issue can be handled the same way OSes have been handling it for years: a confirmation dialog with 15 second time-out.
     
  7. ggambett

    Moderator Original Member Indie Author

    Joined:
    Jul 26, 2004
    Messages:
    1,982
    Likes Received:
    6
    That's more or less what I had; however it also means scaling up (the 800x600 rendered image to a rectangle in, say, a 1280x800 mode) which in my case led to blockyness. What do you do to avoid this?
     
  8. Sol_HSA

    Indie Author

    Joined:
    Feb 27, 2005
    Messages:
    470
    Likes Received:
    1
    Use hardware acceleration - for instance OpenGL. That solves both the blockyness and performance issues. That's what I did with the Death Rally windows port.
     
  9. ggambett

    Moderator Original Member Indie Author

    Joined:
    Jul 26, 2004
    Messages:
    1,982
    Likes Received:
    6
    I do - OpenGL in Linux and Mac and Direct3D in Windows. Some combinations of video cards / drivers make Direct3D stretch the image using a point filter, it seems :(
     
  10. Emmanuel

    Moderator Original Member

    Joined:
    Nov 23, 2004
    Messages:
    859
    Likes Received:
    0
    Gabriel, all I do is to set the viewport (SetViewPort and glViewPort); provided all textures use linear filtering and all sprites with transparency drawn from subregions of textures have at least a fully transparent pixel around them, it works great.

    Best regards,
    Emmanuel
     
  11. James C. Smith

    Moderator Original Member

    Joined:
    Aug 21, 2004
    Messages:
    1,768
    Likes Received:
    0
    Stick to the desktop resolution.
     
  12. JGOware

    Indie Author

    Joined:
    Aug 22, 2007
    Messages:
    1,578
    Likes Received:
    0
    You do take a hit on performance if your game ends up running / upscaling to a very large desktop resolution. And with Blitzmax, there's that bug if you try to run your game in a resolution that is available, but there's not enough video memory to run the game, it will just exit with no trappable error support. ugh..
     
  13. ggambett

    Moderator Original Member Indie Author

    Joined:
    Jul 26, 2004
    Messages:
    1,982
    Likes Received:
    6
    @Emmanuel and James : Roger that, stick to desktop res it is.

    @Emmanuel : That's what I did at first. It caused a lot of trouble to the artists and we had many, many instances of "there are white/black outlines around some images". We could fix some of these assets as a preprocessing step, but not all of them - most notably instances where we split large assets, such as UI frames, in several pieces that would line up perfectly. I'll take a look at that solution again.

    In the meantime, I'm experimenting with rendering to a 800x600 texture and then drawing a quad of the appropriate size. Any obvious drawbacks with that, besides the additional 1024x1024 texture?
     
  14. ggambett

    Moderator Original Member Indie Author

    Joined:
    Jul 26, 2004
    Messages:
    1,982
    Likes Received:
    6
    If I'm not mistaken, I had found it was more complex than that - in some cases, when the fully transparent border pixel (N+1) was being interpolated with pixel N, it looked like it used N's alpha (opaque) and N+1's color (usually black), which led to black outlines. In some cases when I upload images to textures I'm copying the entire last row/column or pixels though... maybe that could help.
     
  15. Emmanuel

    Moderator Original Member

    Joined:
    Nov 23, 2004
    Messages:
    859
    Likes Received:
    0
    Yeah, if you line parts of an image up perfectly, draw to a 800x600 render target that has no alpha channel, and then rendering that as a quad would work better.

    About the borders, my texture loading code does replace the color of fully transparent pixels by the color of the a non-transparent neighbor, so you're right about that too. Rendering to a target and then to the screen would avoid that too. Both things presupposed that you don't do much to those images outside of widescreen aspect correction (ie, no zooming, etc.)

    Best regards,
    Emmanuel
     
  16. Pogacha

    Original Member

    Joined:
    Jan 21, 2005
    Messages:
    605
    Likes Received:
    0
    To fix that problem I use a preprocess I call transparent pixel rebuild, which does a pseudo blur on fully transparent pixels with the non transparent pixels colors. That way interpolation is right in any case.

    PS: Actually the code:

    Code:
    	void Overlay::Transparent_Pixel_Rebuild(Rectangle rectangle)
    	{
    		if(Get_Bpp() != 32) return;
    
    		rectangle.x1 = clamp<int>(rectangle.x1,0, Get_Width());
    		rectangle.x2 = clamp<int>(rectangle.x2,0, Get_Width());
    		rectangle.y1 = clamp<int>(rectangle.y1,0, Get_Height());
    		rectangle.y2 = clamp<int>(rectangle.y2,0, Get_Height());
    
    		for(unsigned int j=rectangle.y1; j<rectangle.y2; j++) 
    			for(unsigned int i=rectangle.x1; i<rectangle.x2; i++)
    				if( pmaBitmap[j*Get_Pitch()+i*4 + 3] == 0 )
    				//			  if( Get_PixelI(i,j).a == 0 )
    				{
    				int r, g, b, a;
    
    				r=g=b=a=0;
    
    				iColor c;
    
    				c = Get_PixelI(i-1, j-1); if(c.a) { r += c.r * c.a; g += c.g * c.a; b += c.b * c.a; a += c.a; }
    				c = Get_PixelI(i-1, j); if(c.a) { c.a*=2; r += c.r*c.a; g += c.g*c.a; b += c.b*c.a; a += c.a; }
    				c = Get_PixelI(i-1, j+1); if(c.a) { r += c.r*c.a; g += c.g*c.a; b += c.b*c.a; a += c.a; }
    
    				c = Get_PixelI(i, j-1); if(c.a) { c.a*=2; r += c.r*c.a; g += c.g*c.a; b += c.b*c.a; a += c.a; }
    				c = Get_PixelI(i, j+1); if(c.a) { c.a*=2; r += c.r*c.a; g += c.g*c.a; b += c.b*c.a; a += c.a; }
    
    				c = Get_PixelI(i+1, j-1); if(c.a) { r += c.r*c.a; g += c.g*c.a; b += c.b*c.a; a += c.a; }
    				c = Get_PixelI(i+1, j); if(c.a) { c.a*=2; r += c.r*c.a; g += c.g*c.a; b += c.b*c.a; a += c.a; }
    				c = Get_PixelI(i+1, j+1); if(c.a) { r += c.r*c.a; g += c.g*c.a; b += c.b*c.a; a += c.a; }
    
    				if(a) {
    				  a = (1<<16)/a;
    				  Put_Pixel(i, j, iColor( (r*a)>>16, (g*a)>>16, (b*a)>>16, 0 ) );
    			}
    		}
    	}
     
  17. Andrej Vojtas

    Andrej Vojtas New Member

    Joined:
    Jan 9, 2009
    Messages:
    354
    Likes Received:
    2
  18. jetro

    Original Member

    Joined:
    Jan 21, 2005
    Messages:
    130
    Likes Received:
    0
    I use the same pixel color dilation technique for alpha=0 pixels in textures - this is a simple way to fix the fringe issues without touching code.

    However, using pre-multiplied alpha works better. Here's an article about it:
    http://home.comcast.net/~tom_forsyth/blog.wiki.html#[[Premultiplied alpha]]

    You just have to modify the code as well to use different blending mode.

    PS. here's a tool (w/source) to do such offline preprocessing of png-images, both single-time pixel dilation for alpha=0 pixels or pre-multiplication with alpha:
    http://jet.ro/2009/10/17/tool-pngprep/
     
  19. Pogacha

    Original Member

    Joined:
    Jan 21, 2005
    Messages:
    605
    Likes Received:
    0
    Very good article, I had to found all of that by myself :(
    It would have been really good to not lost all that time in terms of production (but in terms of fun it is actually a lot better)

    BTW: Your site is quite amazing, you have 2 things done that I was intereted to research/develop and they for sure will be very useful :O
    Thanks so much for sharing :)
     
  20. ggambett

    Moderator Original Member Indie Author

    Joined:
    Jul 26, 2004
    Messages:
    1,982
    Likes Received:
    6
    Thanks for all the info, Emmanuel. The render target trick seems to work fine.
     

Share This Page

  • About Indie Gamer

    When the original Dexterity Forums closed in 2004, Indie Gamer was born and a diverse community has grown out of a passion for creating great games. Here you will find over 10 years of in-depth discussion on game design, the business of game development, and marketing/sales. Indie Gamer also provides a friendly place to meet up with other Developers, Artists, Composers and Writers.
  • Buy us a beer!

    Indie Gamer is delicately held together by a single poor bastard who thankfully gets help from various community volunteers. If you frequent this site or have found value in something you've learned here, help keep the site running by donating a few dollars (for beer of course)!

    Sure, I'll Buy You a Beer