How do I create simple animations using a WriteableBitmap? - c#

Greetings, everyone.
I'm trying to learn some Silverlight basics, and have decided to write a simple Mandelbrot-set drawing application for that reason. In Silverlight, of course. ;)
The application is mostly done. I'm using a WriteableBitmap to work on the pixels, and a simple Image placed on an empty form to display this bitmap (using the Source property). I've even managed to get zooming and moving the fractal around under control.
Now I wanted to spice things up a little bit by adding just a slight bit of animations; I know I cannot make the fractal move, as it's a scalar graphics object, but for example, when I zoom in, it would be nice if the initial zoom was a smooth animation, after which the application would recalculate the new, "zoomed in and sharp as a knife" image. Likewise, if I drag the image around (which is used to move the fractal) and the mouse leaves the image area, it would be great if the fractal returned smoothly to it's initial position (as it is now, it just "snaps" back as the initial settings are restored).
My problem is that I have no idea which parameter to control in an animation. I'm using ScaleTransform, for example, for zooming, but that is used to render the WriteableBitmap on the bitmap itself rather than use the transform properties of the image object. I did so because when I started manipulating the image properties, then the whole image started to move around the form, when I'd rather it's boundaries stay in place.
I suspect I may be trying to do something which Silverlight wasn't really meant to do in the first place (or I've started doing this whole thing wrong), but if I COULD add such little animations, that would be great. As such, any tips appreciated.

It sounds like you want to use the Silverlight animation engine to animate your own custom properties, that control your image display, rather than the image elements or containers.
If your properties for controlling the appearance of the image were exposed as double Dependancy Properties, then the animation system can use the basic DoubleAnimation objects to change your settings smoothly over time. You can even author animations in Expression Blend.
The animation engine would certainly give you easing functions etc to smooth out motion. If I had more detail on how your object was structured I could be more specific, but I hope this helps.

Related

C# PictureBox control flickering / performance issues

I am currently working in Windows Form Apps and am making what will essentially be a map editor for a game. The way i have gone about this is by having a central TabControl where each TabPage contains a custom PictureBox control and all the other UI controls are around this central TabControl. The PictureBox uses its Paint event to draw everything that is placed on the map, and therefore draws multiple images of many sizes, rotations and scales etc to the single PictureBox. This has all gone well so far. The TabPage is essentially used as a view window for the PictureBox and is of size (1280x720).
The problem is with the scale to which the maps are being produced. The avg (and also maximum) map size on screen is around 19200x10800px and can be made up of hundreds of items at any one point. When drawing just a backdrop image of size 19200x10800px the PictureBox starts to flicker when it redraws and makes the program unusable. As the map is so big you are able to pan around them and this is where the flickering really shows. Also i do not want to use a 19200x10800px image source if possible for the sake of file sizes and the scaled image quality isn't an issue at all.
I have done heaps of reading on why this might be and feel like I have tried everything up until this point. So far ive tried:
Having the background image only 1920x1080 and scaling it up by 10x
Starting with a 1920x1080 image, programatically resizing it and drawing this image
Slicing the background into multiple segments (i tried many different amounts) and drawing only the ones that the view window can see (tried this for both a small(1080p) and large(10800p) images)
Using graphics clipping so that only the things on screen would be drawn
Used Double Buffering on both the picturebox and the form that the picturebox is on
Converting the image at initialisation to an "optimised bitmap" with faster formatting and then drawing the bitmap
I've probably tried a couple other things along with minor optimisations but its taken me so long ive forgotten the rest. From what i've read its most likely something to do with the control redrawing too slowly for some sort of performance reason or a limitation with picturebox's, however exactly what is going on i cannot tell due to lack of experience with form apps controls.
Currently to draw the background in the Paint event i have either:
g.DrawImage(image, new Rectangle(0, 0, (int)(image.Size.Width * levelScale), (int)(image.Size.Height * levelScale)));
or
g.ScaleTransform(levelScale, levelScale);
g.DrawImage(image, new Rectangle(0, 0, (int)(image.Size.Width), (int)(image.Size.Height)));
Where g is the Graphics object.
Have I hit the limit of Win form apps capabilities or is there something i may be missing?
Any and all help appreciated,
Thanks in advance.
Just for formality I though id answer my own question just in case anyone else would like to know the outcome.
Based off the overwhelming consensus that winforms was just not made to do the things I was trying to do with it I decided I had to move to some other platform. Suggested to me was WPF, DirectX and OpenGL but after some extensive searching around I found what I think is the optimal solution.
In order to utilise the power of DirectX hardware acceleration MS has made it so that you can embed XNA graphics devices into a winforms application. Essentially you can create custom controls that run in the normal winform style that have access to a much higher caliber of graphics control. In this manner (with a bit of extra work) I have replaced the picturebox I was using with a custom graphics control which handles all of the drawing. This has worked very well, and on the up side i havent had to take too much of a hit to my development time.
For those looking for more info refer to this question which has further links that should help. Once again thanks to all those who gave their advice!
This is a quoted answer from the URL at the bottom. There are code examples at the link at the bottom. Hope this is helpful; not sure if you tried this yet and maybe it'll help you get a little more juice out of the existing picturebox control. As explain in the other answers, it sounds like you will be forced to a more powerful solution in the near future regardless (DirectX/OpenGL or WPF)
** Partial quote from http://social.msdn.microsoft.com/Forums/en-US/68ecd1f6-2eeb-45ce-a881-24c62145ab0e/c-picturebox-problems
"I'd guess the real problem is that it takes too long to redraw the images. GDI+ is pretty slow, it doesn't use any video hardware acceleration. To speed it up, be sure to avoid rescaling the drawing and to use the Format32PArgb format. It is about 10 times faster than any other format. Load the images into a Bitmap with the right format first."
If you have a LOT of items (Maybe realized as controls), forget about the standard event mechanism of Windows Forms. Some time ago, i've written a logic gate editor/simulator which supported lots of thousands of gates in the editor and was really fast. There, I've used the canvas and draw the gates as custom "images" instead of putting them as controls. You'll have to write a custom GetUnderlyingGate function which resolves the current gate / tile (Is your editor a tilemap editor?) from a coordinate array. Also, there were some visible area optimizations.
Maybe, when i'm back home, I'll upload some sourcecode and notify you.

Resolutions in a XNA Game

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.

is there a way to make a 3D game in winforms or WPF in C#?

I'm thinking about making a 3D point and click game, is it possible to make one in winforms or WPF? I don't need any physics or anything all I need is to make the application render 3D objects. I know that I can use XNA but if I do then I will have to relearn almost everything again. My third approach would be to make the scenes in a 3D game engine and then print the screen and then load it as a image. Any suggestion would be appreciated.
There's a big difference between a 3D game, and just letting players interact with a rendered image.
Your approach of loading a pre-rendered image is possible to do in both Winforms and WPF. You would just need to capture click events on the image and check the location against your list of active areas. Then just handle what needed to be done, ie: move to the next area, activate item, etc.
Edit from comment:
It's not so much which is friendlier. You can host an XNA viewport in Winforms/WPF. It's more about how you want your game to work. If you never have moving 3D scenes, XNA is overkill, and images will work just fine.
If you want dynamic scenes, you'll need to be able to render them on the fly. Then, XNA makes more sense. It is a lot more work though compared to just displaying images.
If you just want to show pre-rendered 3d images in your game, why not create them using a real 3d graphics tool, such as 3D Studio Max or Maya (or a free one, such as Blender)? It sounds like there's no need for actually rendering the 3d scenes in a game engine at all.

What is best way to create scrolling WORLD?

In this game im trying to create, players are going to be able to go in all directions
I added one single image(1024x768 2d texture) as background, or terrain.
Now, when player moves around I want to display some stuff.
For example, lets say a lamp, when player moves enough, he will see lamp. if he goes back, lamp will disappear because it wont be anymore in screen
If Im unclear, think about mario. when you go further, coin-boxes will appear, if you go back they will disappear. but background will always stay same
I thought if I spawn ALL my sprites at screen, but in positions like 1599, 1422 it will be invisible because screen is only 1024x768, and when player moves, I will set place of that sprite to 1599-1,1422-1 and so. Is it a good way to do this ?
Are there better ways?
There are two ways you can achieve this result.
Keep player and camera stationary, move everything else.
Keep everything stationary except the player and the camera.
It sounds like you are trying to implement the first option. This is a fine solution, but it can become complicated quickly as the number of items grows. If you use a tile system, this can become much easier to manage. I recommend you look into using a tile engine of some sort. There are a lot of great tile map editors as well.
Some resources for using Tiles:
Tiled -- Nice Map Editor
TiledLib -- XNA Library for using Tiled Maps
What you're describing there is a Viewport, which describes a portion of the 'world' that is currently visible.
You need to define the contents of your 'world' somehow. This can be done with a data structure such as a scene graph, but for the simple 2D environment you're describing, you could probably store objects in an array. You would need to bind your direction keys to change the coordinates of the viewport (and your character if you want them to stay centered).
It's a good idea to only draw objects that are currently visible. Without knowing which languages or packages you are using it's difficult to comment on that.
I would look into Parallax scrolling. Here is an example of it in action.
If this is what you require, then here is a tutorial with source code.
XNA Parallax Scrolling
After you are finished with basic scrolling, try to implement some frustum culling. That is only draw objects which are actually visible on the screen and avoid unnecessary drawing of stuff that cannot be seen anyway.
I would prefer solution number 2 (move player and camera) - It would be easier for me, but maybe its just personal preference.

Spinning a 3D model in C#

How do I take a 3D model that I created in 3D Studio Max and put it into my Winform C# program and make it spin? I'd prefer not to use DirectX if possible. I don't want anything complex. I simply want my model to rotate along the X axis. Thats it.
Thanks
You should use a 3D rendering engine for C#
Something like
http://axiom3d.net/wiki/index.php/Main_Page
http://www.codeproject.com/KB/GDI-plus/exoengine.aspx
http://irrlicht.sourceforge.net/features.html
http://freegamedev.net/wiki/Free,_cross-platform,_real-time_3D_engines
I have never used any rendering engines but for your requirements (letting the user move the object) i think a 3D engine would do. But perhaps this is over kill
If you want it to be dynamic, then the simplest option would be to render out an animation of the object rotating, but make each frame a separate file. Then you just show the correct image based on how the user is dragging the mouse. If the user drags the mouse to the right, then increment the frame and show the next image. If moving to the left, decrement the frame.
For something non interactive:
Export the animation to an AVI and embed that in your form:
Embedding Video in a WinForms app
It's not really what I'd recommend, but it's an alternative to creating an animated gif.
For something partially interactive (i.e. allowing limited movement):
I've seen QuickTime movies that you can control with the mouse. There's an example on this page. It's not 3D though.
For something fully interactive:
You need a 3D rendering engine of some sort and that does (usually) require DirectX or OpenGL. However, if you're only dealing with simple objects you might (repeat might) get away with a software renderer.

Categories

Resources