Jump to content

  • Log In with Google      Sign In   
  • Create Account

slayemin

Member Since 23 Feb 2001
Offline Last Active Yesterday, 02:18 AM

Topics I've Started

List of generic objects

26 August 2014 - 07:59 PM

I'm trying to implement a list of a generic collection and am really confused on how to actually add values to the list in C#. Here is some code demonstrating what I'm trying to do. I am having trouble adding a generic object to a list of generic objects. I've looked all over online and haven't found anything helpful or something that works.

public class Creature
{

}

public class Goblin : Creature
{
	public int sillyValue = 5;
}

public class Troll : Creature
{
	public string name = "bob";
}


public class Unit<T> where T : Creature
{
	List<T> critters = new List<T>();

	public void Add(T item)
	{
		critters.Add(item);
	}

	public Type Type
	{
		get { return typeof(T); }
	}
}

public class Army
{
	List<Unit<Creature>> units = new List<Unit<Creature>>();

	public void Add<T>(Unit<T> unit) where T : Creature
	{
		units.Add(unit);	//<-- SYNTAX ERROR: The best overloaded method match for 'System.Collections.Generic.List<UnitTester.Unit<UnitTester.Creature>>.Add(UnitTester.Unit<UnitTester.Creature>)' has some invalid arguments
	}
}

class Program
{
	static void Main(string[] args)
	{
		Army army = new Army();

		Unit<Goblin> goblins = new Unit<Goblin>();
		goblins.Add(new Goblin());

		Unit<Troll> trolls = new Unit<Troll>();
		trolls.Add(new Troll());

		army.Add(goblins);
		army.Add(trolls);
	}
}

Everything works, except for that one line in the army.add(). If I change the Army class to this, adding to a list works but now I can't access my creature specific virtual methods because casting a derived object to its base class fails. I can get the specific type of the object, but I don't know how to convert it into its actual class object type.

public class Army
{
	List<object> units = new List<object>();

	public void Add<T>(Unit<T> unit) where T : Creature
	{
		units.Add(unit);
	}
	
	public void DoSomething()
	{
		for(int a=0;a<units.Count;a++)
		{
			Creature c = (Creature)units[a]; //<-- casting fail: Unable to cast object of type 'UnitTester.Unit`1[UnitTester.Goblin]' to type 'UnitTester.Creature'.
			c.print();
		}
	}
}

public class Creature
{
	public virtual void print()
	{
		Console.Write("Hello world");
	}
}

public class Goblin : Creature
{
	public int count = 5;

	public override void print()
	{
		Console.Write("value is: " + count);
	}
}

public class Troll : Creature
{
	public string name = "bob";

	public override void print()
	{
		Console.Write("name is: " + name);
	}
}

I found this article on MSDN which looks very close to what I'm trying to do, but it wasn't very helpful: How to: Examine and Instantiate Generic Types with Reflection

 

Any help or insight would be much appreciated :)


C# Indexer overloading?

25 February 2014 - 07:41 PM

I'm trying to create a class which has three dictionaries, each of which store different types of objects. I want to be able to access those dictionary items by using the dictionary key via an indexer.

/// <summary>
/// This is the asset database for all assets being used in the game.
/// </summary>
public class AssetDB
{
	Dictionary<string, Texture2D> m_textureDB;
	Dictionary<string, Model> m_modelDB;
	Dictionary<string, Effect> m_effectDB;

	public enum AssetType
	{
		Texture,
		Model,
		Effect
	}

	public AssetDB()
	{
		m_textureDB = new Dictionary<string, Texture2D>();
		m_modelDB = new Dictionary<string, Model>();
		m_effectDB = new Dictionary<string, Effect>();
	}

	public Texture2D this[string Name]      //ambiguous overload: differs only by return type!
	{
		get { return m_textureDB[Name]; }
		set { m_textureDB.Add(Name, value); }
	}

	public Model this[string Name]      //ambiguous overload: differs only by return type!
	{
		get { return m_modelDB[Name]; }
		set { m_modelDB.Add(Name, value); }
	}

	public Effect this[string Name]      //ambiguous overload: differs only by return type!
	{
		get { return m_effectDB[Name]; }
		set { m_effectDB.Add(Name, value); }
	}

	public void Clear()
	{
		m_effectDB.Clear();
		m_modelDB.Clear();
		m_textureDB.Clear();
	}
} 

Ideally, I'd like to interact with this class by doing something like this:

 

AssetDB m_db = new AssetDB();

m_db[Texture, "Grass"] = Content.Load<Texture2d>("Textures\\Grass");
m_db[Model, "Sphere"] = Content.Load<Model>("Models\\Sphere");

But, I don't know how to overload my indexer to do this correctly.


Why does Game.Draw() have a GameTime parameter?

20 February 2014 - 12:54 PM

Why would a draw() or render() method for an object care about how much time has elapsed?

I see the Game.Draw(GameTime gameTime) method passing a GameTime parameter, but I can't imagine why a method concerned with drawing would care about how much time has elapsed. In my mind, it's just supposed to do its best faith effort to draw the current state of the object. The Game.Update(GameTime gameTime) method should be the only method which cares about how much time has elapsed, right?

 

I was reading the documentation on MSDN (http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.game.draw.aspx) and it said something about fixed time steps: 

 

Update and Draw are called at different rates depending on whether IsFixedTimeStep is true or false. If IsFixedTimeStep is false, Update and Draw will be called sequentially as often as possible. If IsFixedTimeStep is true, Update will be called at the interval specified in TargetElapsedTime, while Draw will continue to be called as often as possible.

Still, I don't see why this matters? Even if my update function gets called 60 times per second and my draw method gets called 1000 times per second, most of those draw calls will just redraw an object which hasn't been updated by the update method since the last draw call. It still shouldn't care about the elapsed game time, right? So, why is game time included in the draw method?

The only thing I can imagine is the draw method could do some sort of interpolation between update frames. Lets say we have a fast moving object, like a bullet, and on update frame 0, it is at position 0. It's moving at 10 units per update frame, so at update frame 1, it'll be at position 10. Lets pretend the draw method runs 10x faster than the update method, so it can draw the position of the object in an interpolated position between the update frames:

Update 0: position = 0;

Draw 0: position = 0;

Draw 1: position = 1;

....

Draw 9: position = 9;

Update 1: position = 10;

Draw 10: position = 10;

Okay, I could buy that explanation if someone gave it to me, but then that gets kind of into a philosophical discussion about whether a draw method should be trying to represent the actual state of an object according to that objects state variables (ie, position value) or its interpolated state between updates. And that raises another question: What happens if you try to click on an object when its being drawn in its interpolated position rather than its actual position and the collision test fails even though on screen it appears to succeed? Granted, I doubt anyone is going to try to click on bullets or this problem may just not be noticeable enough to warrant concern.

The flip side of the argument (and my leaning) is to just say, "Who cares about interpolation between draw frames and update frames?! That's an extra unnecessary CPU cost, which probably is 99% unnoticable when you're updating 60 times per second." And that just brings us full circle back to the original question: Why does the draw method need game time?


Rendering point sprites / textured quads purely on GPU using HLSL

05 February 2014 - 03:57 AM

I'm trying to let my graphics card process all of my billboards and point sprites by using HLSL. I'm a bit of a newbie at it, so I need a bit of help.

 

Currently, what I'd like to do is send the vertex shader an array of point sprite coordinates (ie, a list of verticies). When the vertex shader gets a vertex, I want it to know that it is the center position of the point sprite and that it needs to create the four corners of the quad based on the viewing position of the camera. First question / area of confusion: How do I create these four new vertices out of one vertex in HLSL? I'm not sure about how to allocate the memory dynamically and pass it to the pixel shader, like I would within an application.

 

Second area of confusion: How do I efficiently invoke the shader within my application? Suppose I have a billboard or point sprite class. Normally, I'd manually create my four verticies in the application and then send them down to the video card by using a "DrawUserPrimitive()" method which has an array which contains the vertex data. Easy peasy... but now, I just have one Vector3 for position information, which is inside the world matrix, so I just send the world matrix to the video card. Now, when I try to activate the shader and render the point sprite, how do I do it?

 

Here is my render code for my billboard. I'm confused on how to trigger the shader if I don't actually send it any vertices. I should just have to call "pass.Apply()", right? But it doesn't seem to work.

public BillBoard(Vector3 position, float size, Texture2D texture)
        {
            m_position = position;
            m_size = size;
            m_mode = Mode.Sphere;
            m_effect = s_effect.Clone();
            m_texture = texture;
 
            Matrix world = Matrix.CreateWorld(m_position, Vector3.UnitX, Vector3.Up);
            m_effect.Parameters["xWorld"].SetValue(world);
            m_effect.Parameters["xTexture"].SetValue(m_texture);
 
        }
 
        public int Render(Camera3D currentCamera)
        {
 
            
            m_effect.Parameters["xProjection"].SetValue(currentCamera.Projection);
            m_effect.Parameters["xView"].SetValue(currentCamera.View);
            
            m_effect.CurrentTechnique = m_effect.Techniques["PointSprites"];
 
            foreach (EffectPass pass in m_effect.CurrentTechnique.Passes)
            {
                pass.Apply();
            }
 
            return 0;
        }

XNA: When does "stuff" go into VRAM?

11 September 2013 - 05:53 PM

I'm going to be generating a lot of primitives and meshes programmatically. For example, a huge terrain object which is based off of a height map. This terrain object will have thousands and thousands of verticies. Let's assume that I've got the height map and it's able to fill a vertex buffer in RAM with all of the pertinent vertex information. Now, I need to draw it. To do that, I'd call something like this:
 

public void Render()
{
     foreach (EffectPass pass in m_effect.CurrentTechnique.Passes)
     {
          pass.Apply();
          m_gd.DrawUserIndexedPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList,
          m_verticies, 0, 4, m_indicies, 0, 2);
     }
}

In this case, all of the verticies are stored inside of a "VertexPositionNormalTexture[] m_verticies" array. By calling the "DrawUserIndexedPrimitives", I'm assuming that in this render frame, it's copying the data from RAM into VRAM and the graphics card takes over the rendering from there. However, if my verticies don't ever change, it seems like it'd be a waste of RAM->VRAM bandwidth to keep copying the same data every frame. It'd be better if I could store the data directly on the graphics card as some sort of object in VRAM and then tell the graphics card when I want to render the stored object. Ideally, if I ever need to update the object in VRAM, I could do it on my own time instead of updating every object every frame. I feel like this is totally possible but none of the XNA documentation gives any hints at how to do it. My initial thought was that I could convert my user created primitive into a mesh object and then store the mesh in VRAM and render it like a mesh object, but I don't know how to do this either (documentation isn't helpful). I'm wondering if its possible or if this is just a limitation of the XNA API?

 


PARTNERS