Returning the Pixel color of a x,y position using DirectX

EFileTahi-A

Well-known member
Joined
Aug 8, 2004
Messages
539
Location
Portugal / Barreiro
I know I have to GetBackBuffer... but, thats all I know... Can someone give me a hand on this matter? A need simply to pick the color from a pixel located at a certain x,y position. but from the backbuffers itself, not from texutures. I already made it work in GDI+, and it works marvelous, but now I need to do it in DirectX. The whole idea is to create pixel precision collision.
 
Last edited by a moderator:
Im just throwing this out there, but shouldnt there be a way to get the surface for the back buffer and examine the pixel data? I couldnt really tell you where to begin and pixel formats could probably vary, but its a thought.

What is the collision testing for? It sounds like an odd way to implement collision testing.
 
For per-pixel collision detection I would think the approach should be examining texel data for the sprite textures to identify overlapping opaque texels. I dont understand how examining the backbuffer should help in collision detection except in uncommon and very simple situations (such as a monochromatic graphics or solid-color backgrounds). But since I dont know the nature of of the application I thought Id ask.
 
Thank you for the replies.

Well the concept is very simple, if I can access the DirectXs backbuffer where everything has been rendered I can probe for any pixel in it for any color match and thus create collision.

When I make a laser ray traveling through the map I should just check for each pixel in front of the rays path in advancement and check if it matches a specific color. Its really simple to do in GDI+:

Code:
Color c = f_shootRoom.pBufferGfx.GetPixel(Convert.ToInt16(ptfRayStart.X + ptfDirection.X * i), Convert.ToInt16(ptfRayStart.Y + ptfDirection.Y * i));

I just would like to know how can I recreate the same effect in DX :(
 
Could you post a piece of code demonstrating this?

Code:
Surface s = dxDevice.GetBackBuffer(0, 0, BackBufferType.Mono);
s.LockRectangle(new Rectangle(0, 0, 1, 1), LockFlags.ReadOnly);

After this what should I do next?


Thanks for the help so far, Ill keep googling anyway
 
Could you post a piece of code demonstrating this?
The problem is Ive never done it before. I understand the concept and I hoped it would point you in the right direction, but I dont know the individual steps. Im guessing you have to seek through the GraphicsStream or Array returned by LockRectangle and examine the raw pixel data to do your collision detection.
 
I would imagine there could be an associated performance hit with using the GetBackBuffer, could you not perform the collision detection yourself rather than relying on the internal state of DirectX for this check.

If you are rendering sprites then you should know where they are located and what texture is being used - could you not check against the texture pixels. Ideally I would give the sprite a bounding box and check that, only if the box / line intersect would I bother checking the actual pixels.
 
Its a line which acts as laser ray that needs to be checked for collision. I know I could use boxes and detect intersections bewteen them but that would not be precise with irregular surfaces, not precise at all. I want it to detect collision whenever the the rays head passes over a non-black pixel.

I made this with GDI+ and it worked like a charm, even in ZX-Spectrums basic it worked like a charm, I cant believe that using DX it will be slow.
 
Using a bounding rectangle would be a quick check, if the ray intersects the rectangle then you would check the actual pixel data - you wouldnt rely on just the bounding rectangle for pixel perfect accuracy.

If the line intersects the rectangle you would simply need to check the pixels of the sprite at the co-ordinates the line goes through.
 
Its a line which acts as laser ray that needs to be checked for collision. I know I could use boxes and detect intersections bewteen them but that would not be precise, not precise at all. I want it to detect collision whenever the the rays head passes over a non-black pixel.

I made this with GDI+ and it worked like a charm, even in ZX-Spectrums basic it worked like a charm, I cant believe that using DX it will be slow.
 
You got it right, its a line which acts as laser ray that needs to be checked for collision. I know I could use boxes and detect intersections bewteen them but that would not be precise, not precise at all. I want it to detect collision whenever the the rays head passes over a non-black pixel.

I made this with GDI+ and it worked like a charm, even in ZX-Spectrums basic it worked like a charm, I cant believe that using DX it will be slow.

I didnt say use only bounding boxes, I said a bounding box and line intersection is the first step as it is quick and easy and will eliminate any definite misses.

If the line intersects the rectangle then you know you have a potential intersection and then you would need to check on a pixel by pixel basis. If you know your sprites location and you know the texture it is using then you should be able to map the co-ordinates of the line to pixels in the texture.
 
I didnt say use only bounding boxes, I said a bounding box and line intersection is the first step as it is quick and easy and will eliminate any definite misses.

If the line intersects the rectangle then you know you have a potential intersection and then you would need to check on a pixel by pixel basis. If you know your sprites location and you know the texture it is using then you should be able to map the co-ordinates of the line to pixels in the texture.

Sorry for the double post,

Anyway, I see what you mean, unfortunately I dont know how to do it, not even a clue how to bound a box to the ray, plus how afterwards to perform the pixel by pixel collision, and worst, cant find anything on web related to this, except my very own posts...

Thanks again for the post.
 
Are you using MDX or the XNA studio stuff for this? Ive been meaning to have a play with XNA since Ive installed it and this could be a good excuse ;)
 
lol! Im using MDX Visual Studio 2008.

Oh man, Im 1 week long trying yo find for a cure for my problem, my development is alted until I discover it. I really hope you can help me. Your name will be in my credit list for sure. Here is a screeny btw, so you can understand better what Im trying to do.

Notice the blue ray, it was fired from the left-top robot. Now, when you enter fire mode everything is black and only collidible objects are shown (this is not shown bellow), units are represented as circles and the bigger the unit the better the chances of being hit. What I did in GDI+ was to scan ahead from the rays path, each frame. so if the ray is moving 25px per second it should scan for the next 25 pixels so the ray stop at the right moment and does not passes through a collidible object.
 
Last edited by a moderator:
Hey a friend of mine gave me this piece of code:

Code:
Surface s = dxDevice.GetBackBuffer(0, 0, BackBufferType.Mono);
uint[,] data = (uint[,])s.LockRectangle(new Rectangle(0, 0, 32, 32), LockFlags.ReadOnly);

for (int n = 0; n < 100; i++)
{
    for (int j = 0; j < 100; j++)
    {
        data[n, j] = (uint)Color.White.ToArgb();
    }
}

but it gives me error on the second line... you know the Error-in-application one.
 
Ive decided to convert the backbuffer directly to a BMP and use GDI+ to locate the pixels and retrieve their colors:

Code:
Surface s = dxDevice.GetBackBuffer(0, 0, BackBufferType.Mono);
Stream stream = SurfaceLoader.SaveToStream(ImageFileFormat.Bmp, s, new Rectangle(int locationX, int locationY, 1, 1));
Bitmap bmp = new Bitmap(stream);
stream.Dispose();

Color c = bmp.GetPixel(0, 0);
if (c.R == 255 && c.G == 0 && c.B == 0)
{
    // do something
    break;
}

It works perfectly well and very fast has I collect only about 20 pixels.
 
Last edited by a moderator:
Back
Top