![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
|
Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
br> br> |
| |||||||
![]() |
| | Thread Tools | Display Modes |
| | #1 (permalink) |
| Guest | WPF Visual Layer Performance Issues I am currently developing a turn-based strategy game similar to the Master of Orion series, and I have decided to use the Windows Presentation Framework (WPF) for the graphical client. So far, this has worked out even better than I had hoped, except for a few performance problems. Specifically, the main game screen must display a galactic map in the form of a square sector grid. This grid should have several optional “layers” that may be toggled ‘on’ or ‘off’. Ideally, the grid should update itself very quickly when one of these layers is toggled (more than 1 second would be unacceptable). The galaxy is divided into square sectors, and the galaxy size may range anywhere from 20x20 to 80x80, for a total of up to 6,400 sectors. On average, one out of every eight sectors contains a star system. I have tried two different designs for this galaxy grid control, but each approach had performance issues. My first solution was to create a GalaxyGridControl that derived from FrameworkElement and served as a Visual element host. I then created a SectorVisual class derived from DrawingVisual and had a property that specified its corresponding sector location on the game map (so it would know what contents to draw). I created an Update() method in SectorVisual that would open a DrawingContext via RenderOpen() and draw the following: * If the sector is owned by a player, the background (a 72x72 square area) is filled with a translucent solid color brush representing the color of the owner’s empire. * Two out of the four edges of the sector are drawn as light, translucent solid color lines (plus additional edges if the sector has no neighbors to the right or bottom). * If the sector is within scanning range of any of the player’s ships, an opaque solid color line is drawn along the edges of the sector (using the same logic as above). * If the sector contains a star system, a star image is drawn in the center of the sector. The name of the star is also drawn as a FormattedText block. This solution worked fairly well once the grid had been rendered. However, updating the map at the end of each turn required re-rendering each sector’s visual, which took far too long (20+ seconds on a Core Duo 2.16GHz w/ ATI Radeon Mobility X1600 256mb video). My second solution was to use a few large drawings (one for each layer) that I could update individually as needed, and then re-composite whenever a layer was toggled or the grid had to be updated. I created the following DrawingVisuals, in order from bottom to top: * A backdrop with a transparent fill (to enable hit-testing of empty sectors) and the 1pt-thick translucent grid lines. This layer would never have to be changed after the game had started. * A layer containing the sector background fills (for owned sectors only), star images, star names, and solid color borders for sectors within scanning range. Note that there would be additional layers added later containing fleet indicators, trade routes, ship range lines, etc. The grid had two visual children: a DrawingVisual that was a composite of the layers above, and a DrawingVisual containing a 3px solid color rectangle to indicate the currently selected sector. This second solution decreased rendering time dramatically. It is still higher than I would like, with a large (80x80) galaxy taking 6-11 seconds to render. I would be very happy if I could halve that time. A new problem emerged, however, in that scrolling through the map was much choppier than it was using individual drawings like in my first solution. The choppiness is noticeable on my high-end mobile workstation, and much more annoying on slower machines. I am eager to hear if anyone could offer suggestions for improving visual performance in this scenario. Note that the individual layers of the grid control do not necessarily need to be available for hit testing, and most of them will only need to be updated after each game turn. Therefore, rasterizing those layers would be acceptable, if that is actually possible, and if it would improve rendering speed. Rasterizing the layers would also allow me to use dotted lines in place of solid lines for sector borders (which I had attempted before, but abandoned because scrolling became excessively choppy). Thanks in advance to anyone who takes the time to read this and reply. Best regards, Mike Strobel |
My System Specs![]() |
| | #2 (permalink) |
| Guest | RE: WPF Visual Layer Performance Issues I should probably add that I *am* freezing all of my brush, pen, and image resources. |
My System Specs![]() |
| | #3 (permalink) |
| Guest | RE: WPF Visual Layer Performance Issues At this point, doing that many operations is going to bottleneck your GPU. D3D likes large batches of vertices to render efficiently, and typically WPF has a lot of small batches. With this said, it sounds like the best solution is to render your tiles into a bitmap (using BitmapRenderTarget) and then just draw 1 or more rectangles with that bitmap as the fill. This should give you the perf you need at the cost of a few megs of memory. You have a few options if I understand your game correctly. 1) render the sectors into bitmaps and compose those each frame with a grid of rectangles 2) render the whole map into bitmaps (1 for each layer) and compose layers each frame 3) render whole map for each layer and pick the correct one to show each frame. with any of these solutions you can still render stuff on top of the map like grid lines and player ships, etc. "Mike Strobel" wrote: > I am currently developing a turn-based strategy game similar to the Master of > Orion series, and I have decided to use the Windows Presentation Framework > (WPF) for the graphical client. So far, this has worked out even better than > I had hoped, except for a few performance problems. Specifically, the main > game screen must display a galactic map in the form of a square sector grid. > This grid should have several optional “layers” that may be toggled ‘on’ or > ‘off’. Ideally, the grid should update itself very quickly when one of these > layers is toggled (more than 1 second would be unacceptable). > > The galaxy is divided into square sectors, and the galaxy size may range > anywhere from 20x20 to 80x80, for a total of up to 6,400 sectors. On > average, one out of every eight sectors contains a star system. I have tried > two different designs for this galaxy grid control, but each approach had > performance issues. > > My first solution was to create a GalaxyGridControl that derived from > FrameworkElement and served as a Visual element host. I then created a > SectorVisual class derived from DrawingVisual and had a property that > specified its corresponding sector location on the game map (so it would know > what contents to draw). I created an Update() method in SectorVisual that > would open a DrawingContext via RenderOpen() and draw the following: > > * If the sector is owned by a player, the background (a 72x72 square area) > is filled with a translucent solid color brush representing the color of the > owner’s empire. > * Two out of the four edges of the sector are drawn as light, translucent > solid color lines (plus additional edges if the sector has no neighbors to > the right or bottom). > * If the sector is within scanning range of any of the player’s ships, an > opaque solid color line is drawn along the edges of the sector (using the > same logic as above). > * If the sector contains a star system, a star image is drawn in the center > of the sector. The name of the star is also drawn as a FormattedText block. > > This solution worked fairly well once the grid had been rendered. However, > updating the map at the end of each turn required re-rendering each sector’s > visual, which took far too long (20+ seconds on a Core Duo 2.16GHz w/ ATI > Radeon Mobility X1600 256mb video). > > My second solution was to use a few large drawings (one for each layer) that > I could update individually as needed, and then re-composite whenever a layer > was toggled or the grid had to be updated. I created the following > DrawingVisuals, in order from bottom to top: > > * A backdrop with a transparent fill (to enable hit-testing of empty > sectors) and the 1pt-thick translucent grid lines. This layer would never > have to be changed after the game had started. > * A layer containing the sector background fills (for owned sectors only), > star images, star names, and solid color borders for sectors within scanning > range. > > Note that there would be additional layers added later containing fleet > indicators, trade routes, ship range lines, etc. The grid had two visual > children: a DrawingVisual that was a composite of the layers above, and a > DrawingVisual containing a 3px solid color rectangle to indicate the > currently selected sector. This second solution decreased rendering time > dramatically. It is still higher than I would like, with a large (80x80) > galaxy taking 6-11 seconds to render. I would be very happy if I could halve > that time. A new problem emerged, however, in that scrolling through the map > was much choppier than it was using individual drawings like in my first > solution. The choppiness is noticeable on my high-end mobile workstation, > and much more annoying on slower machines. > > I am eager to hear if anyone could offer suggestions for improving visual > performance in this scenario. Note that the individual layers of the grid > control do not necessarily need to be available for hit testing, and most of > them will only need to be updated after each game turn. Therefore, > rasterizing those layers would be acceptable, if that is actually possible, > and if it would improve rendering speed. Rasterizing the layers would also > allow me to use dotted lines in place of solid lines for sector borders > (which I had attempted before, but abandoned because scrolling became > excessively choppy). > > Thanks in advance to anyone who takes the time to read this and reply. > > Best regards, > Mike Strobel |
My System Specs![]() |
| | #4 (permalink) |
| Guest | RE: WPF Visual Layer Performance Issues Brandon, Thanks for taking the time to read my long post and respond. Your suggestion of using RenderTargetBitmaps sounds like an ideal solution. Cheers, Mike "Brandon Furtwangler" wrote: > At this point, doing that many operations is going to bottleneck your GPU. > D3D likes large batches of vertices to render efficiently, and typically WPF > has a lot of small batches. > > With this said, it sounds like the best solution is to render your tiles > into a bitmap (using BitmapRenderTarget) and then just draw 1 or more > rectangles with that bitmap as the fill. This should give you the perf you > need at the cost of a few megs of memory. > > You have a few options if I understand your game correctly. > 1) render the sectors into bitmaps and compose those each frame with a grid > of rectangles > 2) render the whole map into bitmaps (1 for each layer) and compose layers > each frame > 3) render whole map for each layer and pick the correct one to show each > frame. > > with any of these solutions you can still render stuff on top of the map > like grid lines and player ships, etc. |
My System Specs![]() |
![]() |
| Thread Tools | |
| Display Modes | |
| |
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Visual Studio 2005 & Vista 64 issues | nzmike | .NET General | 3 | 06-23-2008 11:15 PM |
| Audio/Visual problem associated with IE Defender Issues? | AFmodelboy23 | Vista security | 1 | 12-20-2007 01:10 PM |
| Performance improvement by ajust visual effects | Deco | Vista performance & maintenance | 1 | 08-07-2007 10:31 PM |
| Serious performance issues | Webkennection | Vista General | 2 | 02-13-2007 12:24 PM |