Scalable video game graphics - c#

I'm looking to make a relatively simple game using solely graphics primitives (Arcs, Lines, Polygons, etc.).
I started doing this in C# by drawing to a Panel, but right now I'm hung up on how all the scaling works in terms of keeping the proportions the same when changing resolutions. Does anyone have any advice and / or tips on how to do something like this?

There are two options:
1 - Scale everything so that it is sized at a certain percentage of the screen/window. For example, if you want your object to be 1/4 of the screen, then it's width is ScreenWidth/4 and height is ScreenHeight/4. The problem with this technique is that a screen's aspect ratio may make things short and fat or tall and wide. Usually this is addressed by determining one dimension and then using the screen's aspect ratio to determine the other dimension. Ie, Width=Height*AspectRatio.
2 - Make everything the same physical dimension. For example, you may want an object to appear exactly 1" by 1". You can use the screen's resolution (dots per inch) to scale your drawings accordingly. The problem with this is that while it may work well for 'average' sized screens, images may be too small on large screens or too large on small screens.
Most games use technique #1 (with compensation made for the aspect ratio). AR was not always a big deal, but now with widescreen monitors being so popular, it's almost required.
Also, like Richard said, WinForms is not great for games (except minesweeper!), but probably okay for teaching yourself.

Not really a helpful answer but, don't use WinForms!!
If you want a good gaming platform, use DirectX, or XNA Game Studio.

You can do this using GDI+, and transforms. For details on using Matrix to do transforms, see this article on CodeProject.
That being said, this is much, much simpler using WPF's drawing options. In addition to being a retained mode model, which is much simpler when doing simple graphics (ie: move an object instead of constantly redrawing), it has some other nice benefits. The main benefit is that everything in WPF is done using floating point values, and is completely scalable, with no extra real effort. For details on this, see Shapes and Basic Drawing with WPF, which includes both drawing and transforming of shapes.

Related

C#-HatchBrush-"large" checker board hatch style not large enough

I'm trying to draw something like the transparent-indicating background when you use Photoshop or other image processing software.
Like I said in the title, I'm using HatchBrush, and the large checker board style is not large enough for me. Beyond that, I would rather like to be able to control how large each tile is based on current zoom factor or other stuff in my environment.
I have also written the code to draw a lot of filled rectangles, but this was way too slow for some reason (this allows me to control tile size though).
I have not tried Texture Brush yet, but to have a texture means I can not change the colors on the fly easily, so I would rather avoid that unless run out of options.
Is there any ways that I can configure HatchBrush or do something more basic but efficient?
I found the answer when looking at WPF. A solution was on their tutorial with brushes.
https://msdn.microsoft.com/en-us/library/aa970904%28v=vs.110%29.aspx

How resolution independence work in WPF?

This is more out of curiosity. I was studying that WPF applications are resolution independent. Does this means that we need not bother about the monitor resolution size? because being a windows application developer I have faced several challenges making the application compatible to different resolutions.
My question here is how WPF manages the resolution independent property? Do we need to provide ratios in which controls would appear? And how would the quality of the image will be effected if used as background (will it distort in high resolutions or maintain its clarity)?
Please help. This can be a deciding factor for a project.
As far as I know, WPF uses vector graphics for Buttons isntead of Bitmaps like the older WinForms. Due to this, resizizing and adapting to different screen resolutions is easy for WPF.
I have no direct experience with Background images etc. but if they are pixel-based I would provide them in a higher resolution than needed in 96 DPI, maybe twice as high? That should guarantee, that they are not looking poor in higher resolutions.
As a practical note: WPF applications are always readable and are looking good on all monitors I have tried so far. But if you use far smaller resolutions to display a program which was developed for bigger resolutions you can run into problems with fixed objects. E.g. defining text boxes to a certain minimal size, which than eats too much of the available screen. So it seems best for me to define as few constraints as possible and test the applications on other monitors before you ship the product simply because it will always be readable but you might find a few problems with usabillity.
The key thing about WPF and resolution independance is that it uses device independent units and uses this to work correctly with the system dpi setting ( 'Large Fonts' etc); so for example if you are working on a system set to the default 96 dpi, and draw a textbox 96 units wide, WPF knows that this is one logical inch. If you then change the resolution to 144 dpi, WPF will draw the textbox using 144 physical pixels. All the GUI elements scale flawlessly like this. If you try the same thing with a Winforms GUI you will see that it does not scale properly - you end up with big fonts in small textboxes etc
ETA
Another way to put this is to clarify what you mean by resolution - I guess 1024 x 768 is really 'screen size in pixels' and the 96dpi is more accurately the actual resolution, and it's changes to this that WPF handles correctly whilst other platforms don't; both Winforms etc and WPF will display correctly if you simply change from 800 x 600 to 1024 x 768.
WPF is vector based and contains a lot of powerful layout features to ensure scaling works nicely on any device (the simple but powerful Grid control is one of my faves here). It basically uses a measurement and arrangement system that ensures that child controls know how much space they have to work with and therefore can size themselves accordingly
Having said that, it is up to the UI designer to ensure that the application layout is scalable, since it is still very possible to create hard-coded fixed, non-fluid layouts by setting explicit sizes etc
If this does happen, it's possible to scale the entire UI (by using a transforms and other methods) which would have the effect of a zoom in/zoom out depending on if the app is targeting a larger or smaller resolution. This has the disadvantage of making any non-vector content such as bitmaps look blocky or distorted if they are not designed for this scaling
In conclusion, WPF doesn't manage any resolution independence directly so to speak, but by using a few simple layout concepts it's possible to make a resolution independent UI without resorting to scaling (similar to using anchoring in WinForms...but much better)
A small example:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100">
<ColumnDefinition Width="auto">
<ColumnDefinition Width="*">
<ColumnDefinition Width="2*">
</Grid.ColumnDefinitions>
</Grid>
This would create a two column grid layout in which the first column is a fixed width at 100 units, the second column takes up only enough space to fit its child controls and the fourth column takes up proportionately two times the space of the third column. These columns would stretch to completely fill their parent container, be that a small area of the screen or a full window.
This works by measuring how much available space there is to play with, making the 1st column a fixed 100 units, making the second column the size of the child controls that are in it and then working out what space is remaining and dividing it amongst the other columns based on their ratios. (the number before the asterisk * is the proportion of space each dynamically sized column should take. * on it's own is equivalent to 1*)
This with the standard Margin and alignment properties allows for almost any layout imaginable...and this is just a single control!
Edit:
I'd probably add that whilst most people don't use silly resolutions it is surprising how many people are still running 1024x768 or running widescreen mid resolution monitors that have a vertical resolution of less than 800 pixels, so the only way to be sure is to test!
Question 1: My question here is how WPF manages the resolution independent property?
from MSDN:
Resolution-independent and device-independent graphics. The basic unit of measurement in the WPF graphics system is the device independent pixel, which is 1/96th of an inch, regardless of actual screen resolution, and provides the foundation for resolution-independent and device-independent rendering. Each device-independent pixel automatically scales to match the dots-per-inch (dpi) setting of the system it renders on.
Question 2: how would the quality of the image will be effected if used as background (will it distort in high resolutions or maintain its clarity)?
I guess this would mostly depend on the quality of the given picture. a high quality image wont loose of it clarity while being scaled.
I would recommend reading the following articles:
Introduction to WPF you will learn that there is more to wpf than resolution in dependency (DataBinding, layouts, styles, templates, 2D, 3D, animation....)
Imaging Overview WPF Graphics Rendering Overview

Pix-elated Drawing and 3D representations

I am writing a program to imitate Natural Physics. I want to know whether there is a better way to draw an object other than overriding the OnDraw method, and FillRectangle(x,y,1,1) for each pixel.
Is there a way to do a similar action using DirectX or OpenGL? Because to my knowledge the Graphics does not utilize the video card of ones computer (please correct me if I am wrong).
Saying this I would like some thoughts in relation to creating a 3D environment using mathematical calculations to work out the relative quadrant sizes so that objects appear to be farther away then in reality (as a monitor is only 2D), or closer.
Yes. Drawing pixel by pixel with FillRectangle will be very inefficient and slow things down a huge amount. As you say, you should use a graphics rendering system such as DirectX or OpenGL. The choice of which is up to you. If you do a simple search on the web you will find many tutorials on how to get started with 3d graphics.
OpenGL focuses on "Draw me this object in space", and it will take care of rendering it, taking advantage of your graphics card if possible. You do not worry about the pixels, you specify dimensions, camera angles, shaders etc.
You can draw pixels with OpenGL, but that is not the 'correct' way to draw 3d graphics with it.
EDIT in response to Vasa's questions:
I believe OpenGL does what's best based on your graphics card capabilities and drivers. In general OpenGL isn't going to be your best option for drawing direct pixels. BUT remember that
Pixels are different sizes on different machines. Are you expecting to just live with this? Or live with a big display on low-res screens and a tiny one on high-res screens? There may be multiplications involved. If you use literal pixels then once you start multiplying for different screens you are going to get artefacts and inaccuracies.
You want a direct mapping of X to pixels. OpenGL uses float values. They aren't integer 1 to 1 mappings, but they do use a direct proportion. If you choose a scale then OpenGL is not going to suddenly start distorting ratios.
The important thing is proportions not absolute pixels. Although I accept that it's possible for your case to be different.
See this for 2d drawing:
http://basic4gl.wikispaces.com/2D+Drawing+in+OpenGL

C# Create "wireframe"/3D "map"

image http://prod.triplesign.com/map.jpg
How can I produce a similar output in C# window forms in the easiest way?
Is there a good library for this purpose?
I just needs to be pointed in the direction of which graphic library is best for this.
You should just roll your own in a 3d graphics library. You could use directx. If using WPF it is built-in, you can lookup viewport3d. http://msdn.microsoft.com/en-us/magazine/cc163449.aspx
In graphics programming what you are building is a very simple version of a heightmap. I think building your own would give your greater flexibility in the long run.
So a best library doesn't exist. There are plenty of them and some are just for different purposes. Here a small list of possibilities:
Tao: Make anything yourself with OpenGL
OpenTK: The successor of the Tao framework
Dundas: One of the best but quite expensive (lacks in real time performance)
Nevron: Quite good, but much cheaper (also has problems with real time data)
National Instruments: Expensive, not the best looking ones, but damn good in real time data.
... Probably someone else made some other experiences.
Checkout Microsoft Chart Controls library.
Here's how I'd implement this using OpenGL.
First up, you will need a wrapper to import the OpenGL API into C#. A bit of Googling led me to this:
CsGL - OpenGL .NET
There a few example programs available to demonstrate how the OpenGL interface works. Play around with them to get an idea of how the system works.
To implement the 3D map:
Create an array of vectors (that's not the std::vector/List type but x,y,z triplets) where x and y are along the horizontal plane and z is the up amount.
Set the Z compare to less-than-or-equal (so the overlaid line segments are visible).
Create a list of quads where the vertices of the quads are taken from the array in (1)
Calculate the colour of the quad. Use a dot-product of the quad's normal and a light source direction to get a value to shade value, i.e. normal.light of 1 is black and -1 is white.
Create a list of line segments, again from the array in (1).
Calculate the screen position of the various projected axes points.
Set up your camera and world->view transform (use the example programs to get an idea of how to do this).
Render the quads and lines, OpenGL will do the transformation from world co-ordinates (the list in (1)) to screen space. Draw the labels, you might not want to do this using OpenGL as the labels shouldn't scale with distance from camera, otherwise they could get too small to read.
Since the above is quite a lot of stuff, there isn't really the space (and time on my part) to post working code (but someone else might add something if you're lucky). You could break the task down and ask questions on the parts you don't quite understand.
Have you tried this... gigasoft data visualization tools (Its not free)
And you can checkout the online wireframe demo here

Moving from Wiimote to camera?

I've been doing some Johnny Chung Lee-style Wiimote programming, and am running into problems with the Wiimote's relatively narrow field-of-view and limit of four points. I've bought a Creative Live! camera with an 85-degree field of view and a high resolution.
My prototype application is written in C#, and I'd like to stay there.
So, my question: I'd like to find a C#.Net camera / vision library that lets me track points - probably LEDs - in the camera's field of view. In the future, I'd like to move to R/G/B point tracking so as to allow more points to be tracked and distinguished more easily. Any suggestions?
You could check out the Emgu.CV library which is a .NET (C#) wrapper for OpenCV. OpenCV is considered by many, including myself, to be the best (free) computer vision library.
Check out AForge.Net.. It seems to be a powerful library.
With a normal camera, the task of identifying and tracking leds is quite more challanging, because of all the other objects which are visibile.
I suggest that you try to maximize the contrast by reducing the exposure (thus turning of auto-exposure), if that's possible in the driver: you should aim for a value where your leds have still an high intensity in the image (>200) while not being overexposed (<255). You should then be able to threshold your image correctly and get higher quality results.
If the image is still too cluttered to be analyzed easily and efficiently, you may use infrared leds, remove the IR-block filter on the camera (if your camera has it), and maybe add an "Infrared Pass / Visible Light blocking" filter: you should then have bright spots only where the leds are, but you will not bee able to use color. There may be issues with the image quality though.
When tracking things like lights, especially if they are a special color, I recommend you apply a blur filter to the footage first. This blends out colors nicely, a while less accurate, will use less CPU and there's less threshold adjustments you have to do.

Categories