Reputation: 5269
A decade ago, I created a simple Tetris game to learn .NET and WinForms. I created a 10 by 30 grid made of label controls. Those labels are linked to an ImageList which contains the image of every blocks. After a couple of weeks ago, my friends asked for a tetris game for a LAN Party so I took my old Tetris game and I duplicated the grid and label in order to support 10 players.
The game core is working perfectly. However, with more than 3 000 labels, the rendering is starting to struggle.
So here's my question: Is there a way to improve the rendering of my application?
I can replace the labels for an other user control but I would like to avoid falling into DirectX / OpenGL drawing (even if it's the best solution, I don't have enough time to go thru the learning curve)
Upvotes: 0
Views: 2492
Reputation: 123
Each control on your form has it's own handle and is treated as a separate window. Windowing won't handle large numbers of controls well (On the point of Windowing, WPF doesn't use a separate window handle per control but instead one for the entire window.).
3000+ controls isn't a great idea and you know that, but let's try and apply a band aid although we know little about your application!
Try not to use Transparent BackColor or you will incur an additional paint call. The control is not really transparent, it looks at the background of it's parent control and copies the background onto itself (OnPaintBackground). Repeat that for a couple thousand controls in your example and you can see this compounding. (if you are using it of course)
Are you hiding any of the controls, if so are you using the Visible property or achieving this with the BackColor of the control? By making unnecessary controls invisible you can save on unnecessary paints. Be mindful of the effect of hiding controls versus disabling them. Disabled controls are still drawn.
Although it won't affect the render speed, if you have any flicker I would look into double buffering. Use the WS_EX_COMPOSITED flag that was introduced from XP onward and (reportedly works in Windows 8 too), this will ensure double-buffering of the form and it's controls. It is covered in this question: Winforms Double Buffering
Upvotes: 3
Reputation: 733
That's a very slow way and you can't really expect it to perform fast. What you could do is use only 1 control instead of thousands - it would serve as a drawing canvas.
You should override the onpaint event on the control and draw your game state in this way. You will find a graphics object in event args and using functions like FillRectangle you should be able to draw everything.
While this can also cause some flicker, WinForms is not intended for this kind of stuff in the first place - but it should be fine for your case.
I also understand that this changes your concept and will require a lot of coding changes but it's by far easier than directx / opengl route.
Good luck!
Upvotes: 3