DrawGeometry slow - c#

I have a set of Coordinates that is drawn on my override method OnRender using DrawGeometry. One of the Polygons im trying to draw is 121000 points which is a lot. This slows down my map control.
Also when this OnRender happens the points are already in memory I'm just passing the points to DrawGeomerty
here is an example what happens OnRender
MapProjection pa = new MapProjection();
if (this.mapCommunication.MapLayers == null)
{
return;
}
foreach (KeyValuePair<Guid, MapLayerHelper> coordinatePointsLayer in this.mapCommunication.MapLayers)
{
if (!coordinatePointsLayer.Value.IsVisible)
{
continue;
}
if (coordinatePointsLayer.Value.State != LayerEnum.Visible)
{
continue;
}
foreach (CoordinateHelper coordinatePoints in coordinatePointsLayer.Value.Coordinates)
{
foreach (StreamGeometry item in coordinatePoints.GeomertyPoints)
{
drawingContext.DrawGeometry(null, penDrawing, item);
}
}
}
My Question is what direction should i take from here should i optimize, or should i try and incorporate DirectX would this help or what approach should i take?
Thanks for help i pretty new to render this much data.

What i eventually figured out was help me out if I'm wrong :) WPF is already build upon Direct X so would not help me much if i tried accessing through something like SharpDX, because i was going for dubble buffering and that is already implemented.
So what i implemented was instead of reading the point in the OnRender is used a Canvas with a fixed size and added System.Windows.Shapes.Path adding my Geometry that way.
This caused WPF to better manage dubble buffering and the Points rendered much faster.

Related

Fade out parallax layer in unity

I made a fade out effect on a parallax layer and I've done this:
if(currentBackgroundPhase == BackgroundPhase.Night)
{
foreach(SpriteRenderer sprite in GetComponentsInChildren<SpriteRenderer>())
{
if (sprite.name.Contains("Cloud"))
{
sprite.color = new Color(opaqueCloud.r, opaqueCloud.g, opaqueCloud.b, transitionTimeElapsed / TRANSITION_TIME);
}
}
}
The parallax keeps repositioning cloud sprites and this is the only way I can think to do this.
I've looked profiler and didn't see a drop on performance when the if is called.
Is this too expensive / unefficient because the GetComponensInChildren? If so, is there other way to do this?
I looked on profiler's scripts graphic to see if this is too much but didn't notice anything strange.
I can't test on a bad device because I don't have one, and I want this to work on every android device...
The maximum amount of spriterenderers that can be in children is 20 or so.
Well there are some tips that could be helpful to you
Use object pooling if needed as you don't have to destroy and instantiate clouds again and again.
Try Avoiding Foreach loop its not noticeable right now but it does have an impact over for loop.
If a for each loop used for collection or array of object (i.e. array of all elements other than primitive datatype), GC (Garbage Collector) is called to free space of reference variable at the end of a for each loop.
foreach (Gameobject obj in Collection)
{
//Code Do Task
}
Whereas for loop is used to iterate over the elements using an index and so primitive datatype will not affect performance compared to a non-primitive datatype.
for (int i = 0; i < Collection.length; i++){
//Get reference using index i;
//Code Do Task
}
You can try pooling Gameobjects. Just activating deactivating them.
If one cloud is 100% transparent you can deactivate it and reuse somewhere else. If you are moving the clouds it should be possible.

Object Collision C#

I have Been Developing a game, I am having problems with the collision part of this game, and I'm not sure how to fix it
private void timer1_Tick(object sender, EventArgs e)
{
List<Obstacle> removed = new List<Obstacle>();
foreach (Obstacle o in obstacles_)
{
Rectangle bounds = o.Bounds;
if (players_[0].Bounds.IntersectsWith(bounds))
removed.Add(o);
}
foreach (Obstacle ob in removed)
obstacles_.Remove(ob);
}
Basically what I need it to do is if the player runs into an object, then it will remove itself from the list and stop being drawn on the form.
EDIT - Realised I haven't really said what the problem is, When the object collides, it doesn't remove itself, and continues to be drawn
Edit - 2 FIXED - See comment below!
My first guess would be that you're using a different list of objects in the draw step than in the collision step. If you're removing the objects from obstacles_ but in the draw step you iterate through objects_, for example, the objects would still be drawn.
Another problem could be if the obstacles_ list is rebuilt every step. I would suggest stepping through this block, make sure the objects are actually removed, then checking the draw step and see if the list is up to date (the object is gone). If you can, start with one obstacle to make it easy on yourself.
Okay guys, thanks for all the help, I have managed to figure it out, I was creating the bounds in the obstacle class at the start of the code, but then as it updated its position the bounds didnt update...
Seem sorta foolish but I think ive got it all sorted now.
Thanks for everyone that tried to help!

How to make a line drawn by graphics selectable in .NET

A simple code for drawing a line.
using (Graphics g = this.CreateGraphics())
{
g.DrawLine(Pens.Black, new Point(50, 50), new Point(100, 100));
}
This will draw a typical line. However i want to this line to be selectable so that user can manipulate it further(streching, resizing etc) at run time. Initially i attempted to use controls that can be manipulated at runtime with the line as background however that could not work due to overlapping controls issue.
My question is how can i select this line at runtime ?
You need to write it yourself.
Write a class that wraps Line
Add all needed additional behavior to the class (what happens when the line is selected, what happens when the line is stretched, deleted, changed color ...)
Write a class that manages either object was was picked by mouse or not (RayTracer)
etc...
Or simply use: piccolo2d framework
Structured 2D Graphics Framework
I think what you're looking to do is make the Graphics object to be selectable?
If so, you could put your logic into the MouseOver and MouseButton events.
Check this out, it may give you some insight.
Selectable Graphics Object
You must create it yourself. Declare interfaces that your graphics objects implement. Suggestion:
public interface IObject
{
bool HitTest(Point mouseLocation);
void Paint(Graphics g);
List<IAdorner> Adorners { get; }
}
public interface IAdorner
{
bool HitTest(Point mouseLocation);
void Paint(Graphics g);
void StartMoving(Point mouseLocation);
void Move(Point mouseLocation);
}
The adorners are the selectable end points of a line object for instance.
Your main paint routine will look something like this:
private void drawingSurface_Paintobject sender, PaintEventArgs e)
{
foreach (IObject o in _objects) {
o.Paint(e.Graphics);
if (o == _selectedObject) {
foreach (IAdorner a in o.Adorners) {
a.Paint(e.Graphics);
}
}
}
}
And of cause you need all the mouse event handling.
These interfaces are abstract enough in order to allow the implementation of any shapes. For instance they don't include any coordinates, as different types of objects need different numbers and kinds of coordinates and parameters.
Maybe It's a little too late, since you already accepted an answer, but you should really consider WPF for this.
https://stackoverflow.com/a/15469477/643085
That's an exact sample of what you're after, in WPF + MVVM. With a real whole LOT of advantages over any winforms approach (such as NO flicker due to hardware acceleration).
Please at least give it a try. Full CSProj project Source available.
You're REALLY reiventing the wheel implementing all this yourself in GDI. And in the end it will be unusable due to flickering and stuff like that.

Memory leak when setting texture = new Texture2D(...)

I have the following code as part of a game:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin();
terrainSprite.Draw(spriteBatch);
if (resourceMap.pixels.IsDisposed == false)
{
resources.Draw(spriteBatch, spriteFont);
}
spriteBatch.End();
base.Draw(gameTime);
//Disposes the texture here:
resources.pixels.Dispose();
}
//In the resources class
public void Update()
{
//gD = graphics device
pixels = new Texture2D(gD, 800, 353);
//big update method
//manipulate the pixels texture
}
When I open task manager and look at the resource monitor, the memory usage for 'myGame.exe' is constantly going up by about 8 KB (I realize this is small, but my game holds a LOT of data, so saving every bit I can is important, and it builds up fairly quickly). This is after all other code is commented out except for what is shown here. Then, when I comment out the code: "pixels = new Texture2D(gD, 800, 353);", the memory usage stays constant. I also tried GC.Collect(), but no dice.
Is there anything else I can do to try and stop it? (Sorry, getting rid of the code is not an option :p, renewing the texture is much faster than any other method I've come across to make the texture go blank)
Depending on your Game configuration and really, many other factors, such as how slow everything is running, etc., Update and Draw are not perfectly synchronous with each other and are not guaranteed to be run in the following fashion:
Update
Draw
Update
Draw
Update
Draw
Update
Draw
....
Therefore, since you're Disposeing in one and creating a brand new one in the other, something like this can definitely happen:
Update: create new
Update: create new //PREVIOUS ONE LEAKED!
Draw: disposes only current
Update: create new
Update: create new //AGAIN LEAK
Draw: disposes only current
...
Thus, do not Dispose separately in this fashion; Dispose one time for each new one created, no matter what.
I should also add on that textures, along with some other XNA classes (sound and music, and Effects, to name a few) are unmanaged resources, meaning the GC does not see them at all. You must call Dispose on these.
As Andrew points out in his comment, the best way to avoid these pitfalls is not to recreate textures so often - simply reuse the same one and modify it as you see fit.
It appears that Texture2D are not fully handled by the garbage collector.
So when you stop using it (when reusing a variable referencing it, like here, or during the OnDestroy callback), you have to manually destroy the texture. Here :
if(pixels != null) {
Destroy(pixels);
}
pixels = new Texture2D(gD, 800, 353);

Passing 2 parameters to a single class through map[x][y]

Goal:
I’m currently working on an addition to an already existing library (a maze generator). What I’m trying to do is define a new way of storing the maze (partially in memory and partially on the hard disk).
-Skip to the Problem paragraph if you just want to see the question. I added some extra information since you might suggest a completely other approach.
Current situation:
The current way the maze generator stores mazes (in memory) is with a Map. The Map contains a bunch of InnerMapArrays which each contain a line of pixels in the maze. Points can be read/written in the maze like this:
… //Code that creates maze map
map[x][y] = true;
In the Map class there’s a method to return the correct array (x)
public override InnerMapArray this[int x]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return innerData[x];
}
}
Then it will call [y] on the innerData which also contains a similar method to ultimately return the right pixel.
Problem:
Going back to what I want to do is create a new Map type that saves parts of the maze in memory and parts of the maze on the disk. I want to load areas of the maze in sets of 100x100 pixels for example, not by line. (In the image below the red part should be loaded when pixel x=50,y=50 is changed for example)
The current implementation of the Map/InnerMapArray structure does not allow for this. What I want is a way to actually get the X and Y that are passed in one method.
What I thought that could possibly work is the following (not working code):
public override InnerMapArray this[int x][int y]
{
get
{
//load a certain 100x100 part of the maze in memory and set it as current
//so while generating the maze pixels near the currently generated/read pixel
//can be read really fast while others far away won't use any memory
}
}
Sadly the C# compiler doesn’t allow this. Does anyone have a clue that could help me solve this issue in a ‘nice’ way.
The way to achieve what you want is:
public overrride InnerMapArray this[int x, int y] { ... }
This code works only if you have a "double" indexer like this to be overriden in de base class of course. Hope this helps :)

Categories