Render multiple layers in XNA - c#

I'm using XNA, and I've run into a little problem. I need to support multiple layers, each with a distinct z order (I call these "viewports"). A picture is worth a thousand words, so here's what it should look like:
http://www.charlesstrahan.com/so_files/viewports.png
There are several things to notice here. Sprites do not render outside of their viewport, as you can see with Sprite B. Also, notice how the viewports are rendered - it's very similar to "layers" in Photoshop. Although Sprite C is has a z order of -1000, C still renders above Sprite A because its viewport's z-order is a greater than A's viewport's z-order.
There's one last detail that I couldn't display very well in the above picture. Each viewport needs to optionally render a color over its region of the screen - you could think of it as a "tinting" affect.
I'm completely at a loss when it comes to doing this the best way in XNA, so I could really use a short snippet of C#/VB.NET code that demonstrates this in action. Any help would be greatly appreciated.

You can easily do this with RenderTargets :-) There are lots of resources on how to use them on the web (example).
If you're just starting yoru project though, consider installing the XNA 4.0 (in CTP right now via the windows phone SDK). It's gotten a lot easier in the new version ... from an article that Shawn Hargreaves put out recently, RenderTarget changes in XNA Game Studio 4.0.
List<Texture2D> textures = new List<Texture2D>();
for (int i = 0; i < 100; i++)
{
RenderTarget2D rt = new RenderTarget2D(...);
GraphicsDevice.SetRenderTarget(rt);
DrawCharacterAnimationFrame(i);
GraphicsDevice.SetRenderTarget(null);
textures.Add(rt);
}
And the "tinting" feature you were asking about is braindead easy with this because you can just call the Clear method when you go to render each render target with whatever color you want.

You can just sort your objects into groups then render each group in order with clipping
device.ClipPlanes[0].Plane = plane;
device.ClipPlanes[0].IsEnabled = true;

Related

C#, display and navigate structural 3D FEM model (helix-toolkit, SharpDX?)

Hello! I am trying to implement a simple way to display the deformed shape of a beam. I found HelixToolkit that offers perfect tools, but I can't find the way to display different tiles of the same mesh with a different colour, or gradient. I found this: https://github.com/helix-toolkit/helix-toolkit/issues/885 that is the adding of the VertColorMaterial property, but it looks like it is for SharpDX library, but I started with HelixToolkit wpf (don't understand if in HelixToolkit is also available).
I can't even find a way to do it with SharpDX: it looks that there is almost no doc in internet.
Additionaly, SharpDX stopped its developement.
So:
do you know any example?
do you suggest me another library, which is fast/offers the ability of navigate the model, and it is compatible/use the wpf framework?
I also would like the ability to refine and subdivide a mesh.
Any kind of advice would be useful, I am new to the world of computer 3d graphic.
Thanks
EDIT 1:
I followed JonasH hint applying a texture, but it apply the texture for each tile. (See image).
I can only dinstict by out materian and in materia (set in the picture as Hue and the arrow Texture).
I need to apply one color for each polygon to give to the mesh a "FEM" style. Do you know how is it possibile with HelixToolkit?
You might consider using Kitware VTK instead of HelixToolkit. It’s extremely powerful library for scientific data visualization, well documented, perfect for finite element pre and post processing. You can take a look on my app, unfortunately it has not been documented yet, but just as an example:
https://github.com/galuszkm/STAN
I assume you have a color per vertex you want to use. I would recommend using wpf or helixToolkit wpf since they are quite easy to use. But as far as I'm aware they do not support vertex coloring.
A workaround would be to use a texture. I would assume you want to visualize some scalar property as a color. You would first need to create your MeshGeometry and assign the TextureCoordinates, simply assign the value you want to visualize to one of the texture coordinates in the 0-1 range. You would also need to create a gradient texture, either a gradientBrush or create an image. You would then assign the brush like:
var brush = new ImageBrush()
{
ImageSource = new BitmapImage(new Uri("gradient.png", UriKind.Relative))
};
var material = new DiffuseMaterial(brush);
GeometryModel3D model = new GeometryModel3D(mesh, material);

WPF 2D in 3D view Animations : Performance issue

I've put a TextBlock in a 3D panel (Planerator) and I used a Storyboard to animate it. (as crawl text)
When the field of view is 1 everything works fine, But if I set the field of view to more than 50 the frame rate will drop sharply and rendering will be choppy.
I used theCompositionTarget.rendering.
Please see the following images:
I need to 2D animations in 3d view with good performance.
Please tell me how can I solve this problem? Should I leave WPF and go to the DirectX?
UPDATE 1 :
I just want to move ONE 2Dtext in 3D space , but the performance is poor.(rendering isn't smooth it is choppy)
This is a sample project.
UPDATE 2:
This is the sample project updated version based on cokeman19's answer. (the performance have been improved ~10 frames, But I need to perfect rendering)
UPDATE 3 :
Finally, I got an acceptable performance with the help of the cokeman19's answer and the contents of this page.
I'm not sure if it's just a byproduct of the sample app, but under Planerator.CreateVisualChild(), it doesn't seem to be necessary to set the GeometryModel3D.BackMaterial. For reference:
VisualBrush vb = new VisualBrush(_logicalChild);
SetCachingForObject(vb); // big perf wins by caching!!
Material backMaterial = new DiffuseMaterial(vb);
...
GeometryModel3D backModel = new GeometryModel3D() { ..., BackMaterial = backMaterial };
The BackMaterial is a VisualBrush wrapper around the logical child, which doesn't belong to the visual tree, so rendering doesn't seem to make sense here. Moreover, the logical child (the LayoutInvalidationCatcher class), is in turn a wrapper around the visual child, which is already rendered (using _logicalChild) in setting frontModel.Visual.
Removing the code for the creation and setting of BackMaterial brings the FPS up to ~55.
In addition, if it's an option, setting the following brings the FPS back up to 60, with no noticeable degradation in quality.
RenderOptions.SetEdgeMode(_viewport3d, EdgeMode.Aliased);
Update:
The only other gain I was able to make was to set the CacheMode to BitmapCache, which may not be appliable for your needs.
frontModel.CacheMode = new BitmapCache(20) { EnableClearType = false };
Even on my slowest machine, this allowed for maximum FPS, but there are some drawbacks. Because the zoom level is so high on the text element, and this technique creates a picture to use in the animation (instead of animating the UIElement itself), I had to set the scale level to 20 before it became almost visually imperceptible. This of course has memory implications, as well.

Draw a graph using arrays of pictureboxes

I am currently writing a program where I need to draw some graph's. I need to have a little bit specific layout in these graphs. For example I have three stages of a length in days defined by the user. a start stage of for example 30 days, a mid stage of 40 and an end stage of 20 days. These stages I want to have all a different backgroundcolor in the graph. I do that by drawing pictureboxes and adapting their widths to the stage lengths. Also for every day in the total length I want to draw a vertical line and for the amount of horizontal lines in the graph I take the maximum of y = f(x).
y = f(x) needs to be plotted on the graph. For I use many pictureboxes on the background I cannot use the graphics.DrawLine for it will be drawn behind the pictureboxes. So I decided to make the line with an array of pictureboxes ;) It works fine, but obviously it takes a lot of time to load the program now.
Is there another way to draw this graph using arrays of controls that require less effort from the computer? Or should I completely stop with the arrays?
(I wanted to post my picture here, but I don't have ten reputation yet because I'm a noobie :( )
Later on I will add more lines to this graph, but since I figured that my program is already slowing down I ceased programming those other lines and went to the all-knowing forum!
Any help will be much appreciated!
Greetz,
Arrie
The common form controls aren't really suitable for this purpose. I'd suggest taking a look at using libraries that give you more power and control over visuals and graphics.
#Kári is right:
If you want to stay with .NET only (no 3rd library dependence) you can use GDI. In .NET you can use by including System.Drawing.dll as an reference.
One simple yet correct approach would be:
create a target control (picturebox for example)
implement the OnPaintDraw Event which gives you an Graphics object
that contains many drawing methods. See MSDN for more information:
MSDN -> Graphics
The methods of Graphics will always draw above the control, so make sure your target control is visible an not behind any other control.
If GDI is not enough you can check out other libraries. (See .NET graph library around?)

Using an Image as for Font in XNA (SpriteFont? Or something else?)

So I've gotten to the portion of a 2D XNA-based top-down hack-and-slash project I'm working on where I need to draw text onto the screen. What I want to use is a SpriteSheet-esque image I found with the characters and symbols I'm going to need for this project.
Now, I've done a little bit of reading on this before asking, and the only two ways of putting a "Font" or something onto the screen is by using Fonts already installed on the computer, or, according to this, I have to create a Custom Content Processor?
My question is, if I have an image (say, in PNG format), that has all the letters/characters I want on it, how do I use those letters in my 2D game? And it doesn't necessarily have to be an XNA-based solution.
Thanks in advance.
You draw it exactly how you would draw any other sprite from a sprite sheet.
You might already know that the SpriteBatch.Draw method has some overloads that can take a Rectangle that represents the source from your sprite-sheet.
you can keep track of your relation from chars to sprite rectangle with a dictionary
Dictionary<char, Rectangle> fontDict = new Dictionary<char,Rectangle>();
fontDict.Add('A', new Rectangle(/*params representing source of A*/);
and you can your word with a for or foreach loop
for(int i = 0; i<str.Count; i++)
{
Rectangle spriterect = fontDict[str[i]];
SpriteBach.Draw(/*params*/);
}
Keep in mind that you also have to manage the spacing of the letters out on your own, but it's possible to do on your own.
It does however Look like the ContentManager supports creating SpriteFonts based off of image formats such as jpg and png, so I'd say you might just be better off exploring that
further googling yields the FontTextureProcessor Class, which might be helpful.

PixelShading in C#

I hope I do not make my first mistake with my first post.
I am writing a library for several graphical effects and filters (for example Sobel or Gauß mask).
Because of the low Speed, doing this on the CPU, I wrote some shaders with the Shazzam tool.
My concret Problem is, that I am not able to use this shader in C#.
In the Internet I found only advice how to apply a pixelshader as a effect in XAML directly to a element, which is not usable for my application, because this makes it impossible to apply several shaders on one Image, which is needed, for example the Canny Edge Detector.
To illustarte this issue a Little pseudo-code, which should Show, what I expect from the method.
PixelShader somePixelShader = new PixelShader(pixelshader.ps);
somePixelShader.Input = Bitmap;
somePixelShader.Height = 200;
somePixelShader.Width = 800;
somePixelShader.Execute();
Bitmap = somePixelShader.Result;
As you see, everything should be done in C#.
Perhaps you can help me with my issue.
You can make a copy of the current effect output as a bitmap with RenderTargetBitmap, then submit this outputted image as the new input for the next effect, rinse, repeat.
Update : after a small (and inconclusive) test, this will not work : Can't render pixel shader to RenderTargetBitmap! Please help!
Check out these white papers for step-by-step instructions + examples on how to compile and use a pixel shader in WPF or SL.
You may also want to check out the WPF Pixel Shader Effects Library here.

Categories