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.

I have in memory a representation of my 2d GameMap (think of a Scorched Earth like landscape).

The map is made up of MapElements, a MapElement is made up of 64 bits defined like

struct MapElement {
 uint Color;  // RGBA Color
 uint Info;   // info flags (collision, material etc)
}

MapElement Map[Height * Width];

Now I'm thinking of doing some effects in HLSL, for example lighting, that need per-pixel collision information. Is there any way I can just upload the mapdata as I have it in memory, and use it in HLSL ?

So is there a way to in HLSL to sample Uploaded Map to see if (map[y*Height+Width] & CollisionFlag) != 0 ?

share|improve this question

2 Answers 2

You could try creating a Texture2D (or Texture1D) with DXGI_FORMAT_R32G32_UINT, or a generic Buffer and updating that with data from your map array when changes occur.

Then you should be able to do uint2 mapElement = texture.Load(...) or uint2 mapElement = buffer.Load(y*Height+Width);

Load(...) might work better for you than the regular Sample(...), since it will not perform any sort of filtering or interpolation, and allows you to access the elements by index/offset rather than UV coordinates.

share|improve this answer

Storing this type of data in a texture is pretty common, and not that difficult.

I'd keep a couple of things in mind:

Your texture sampler (which is used to read data from the texture) is going to return floats, not ints. This has the potential to introduce some precision issues.

For instance, in my raycaster, I'm storing an octree in a texture, using a single texel per tree node. Each texel has the format:

   a = 0.2 == inner node
   r - texel x of first child
   g - texel y of first child
   b - reserved

   a = 0.5 == leaf node
   rgb == color

   a = 0.9 == empty node
   rgb = reserved

When checking the node type in the shader, I read the texel value from the sampler, then check the node type by range, not via an exact match.

if (a <= 0.3) node_type = INNER
else if (a <= 6) node_type = LEAF
else node_type = EMPTY;

Since 0.3 might be read as, for example, 0.299999, just checking if it's equal to the flag value of 0.3 isn't guaranteed to work, so I spaced the flag values (inner, leaf, empty) far enough apart to allow me to check a range without worrying about precision errors.

When you're calculating the address of the texel where your flags and color are stored, you're using

if ((map[y*width+x] & CollisionFlag) != 0)...

Since youre texel coordinates are normalized (0.0--0.999), you'll need to do this a bit differently:

texelX = (pixelX+0.3)/width;
texelY = (pixelY+0.3)/height;

... where pixelX and pixelY are the familiar int coordinates, and texelX/texelY are the normalized values you'll use when sampling in the shader.

The 0.3 offset is so that you read the texture from the middle of a texel, not from the edge which produces different behavior on different hardware. We use 0.3 instead of, say, 0.5, so that this doesn't accidentally round up to the next coordinate.

There are a lot of good explanations on this process available on AppHub and elsewhere if it's not clear.

HLSL, as of SM 3, doesn't support bitwise operators in shaders. You can perform a shift via normal arithemetic operations such as,

// check bit 3 (0-based, fourth bit)
if ((flags / 8.0)  > 0 && (flags / 8.0) < 1.5) /// bit is set

// check bit 5
if ((flags / 32.0) > 0 && (flags/32.0 < 1.5)) /// bit is set

However, you may have to perform some magic here since the bits in the float you read from the texture don't necessarily match what you put in the int to start with. You might be better off using float ranges similar to what I described above, and using each of the RGB components separately.

Good luck!

share|improve this answer
    
can't you use texture.Load() though to read out integer values form an integer texture? –  melak47 May 11 '12 at 19:13
    
Hadn't seen that one, but I don't think it's supported under DX9. msdn.microsoft.com/en-us/library/… –  David Lively May 11 '12 at 19:52
    
sorry, I keep forgetting that XNA is dx9 only –  melak47 May 12 '12 at 0:22

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.