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.
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.