Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Because I'm using sprite sheets instead of an individual texture per sprite, I need to pass in a Rectangle when calling Texture2D.GetData() in my collision detection for per-pixel tests. Unfortunately, without fail I get an ArgumentException percolated down from an internal method inside the Texture (not Texture2D) class.

My code for getting the texture data looks like this:

    public override Color[] GetPixelData()
    {
        Color[] data = new Color[(int)size.Product()];
        Rectangle rect = new Rectangle(hframe * (int)size.X, vframe * (int)size.Y, (int)size.X, (int)size.Y);

#if DEBUG
        if (sprite.Bounds.Contains(rect) && sprite.Format == SurfaceFormat.Color)
#endif
            sprite.GetData(0, rect, data, 0, 1);

        return data;
    }

Even with the check to ensure I'm grabbing a valid rectangle and that the texture format matches what I'm trying to get, I still get that exception, claiming "The size of the data passed in is too large or too small for this resource." Unfortunately, the debugger won't let me check the locals within the Texture.ValidateTotalSize() method where the exception originates.

Has anyone else had this problem and knows how to fix it? I'm relying on AABB testing only for now, but that doesn't really work for some of my game's entities due to odd shapes, rotation and scaling.

share|improve this question
add comment

2 Answers

up vote 6 down vote accepted

You can use Reflector to look inside Texture.ValidateTotalSize() to get an idea of what might be happening to throw the exception.

But in this case I think it's simply that:

sprite.GetData(0, rect, data, 0, 1);

should be:

sprite.GetData(0, rect, data, 0, data.Length());
share|improve this answer
    
That was exactly it, and I feel like such an idiot for not checking Reflector earlier to discover this. Thanks, Andrew! –  Chris Charabaruk Jan 6 '11 at 6:32
add comment

The code you've posted isn't necessarily enough to figure out what's going wrong. XNA's Texture2D.GetData() method takes a Type, for instance, so you must be using some custom class. I have a guess though.

From the looks of it, the type you're using for size uses floats (or doubles; same thing for purposes of this). It's eminently possible that the problem comes from that: casting a float to an int truncates the result. Assuming size.Product() multiplies the floats together and returns the result, you could easily be getting something like:

size.X = 10.3 size.Y = 20.4

(int)size.X * (int)size.Y = 200 (int)(size.X * size.Y) = 210

Try:

Color[] data = new Color[(int)size.X * (int)size.Y];

and see what happens.

share|improve this answer
    
No custom classes here. Microsoft.Xna.Framework.Graphics.Texture2D, Microsoft.Xna.Framework.Color. And I'm simply using Vector2 out of laziness (no IntVector2, although I suppose Short2 sould be okay); while the values are kept in floats, they're integer values and not large enough to round do different numbers. Changing how data's number of elements is calculated changes nothing. –  Chris Charabaruk Jan 6 '11 at 5:34
    
Also, Type with a capital T is a lot different than a generic type. GetData() doesn't take a Type; it takes in an array of a generic type derived from ValueType (i.e. a struct), where that type matches the surface format's bit size -- as Color does for my texture images (32-bit, ARGB). –  Chris Charabaruk Jan 6 '11 at 5:36
    
Actually Point is what I should be using, and I've switched to that. Still no difference; GetData() continues to toss. –  Chris Charabaruk Jan 6 '11 at 5:54
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.