Jump to content
Xtreme .Net Talk

Recommended Posts

Posted (edited)
I know I have to GetBackBuffer... but, that's 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 backbuffer's 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. Edited by EFileTahi-A
  • 2 weeks later...
  • Leaders
Posted

I'm just throwing this out there, but shouldn't there be a way to get the surface for the back buffer and examine the pixel data? I couldn't really tell you where to begin and pixel formats could probably vary, but it's a thought.

 

What is the collision testing for? It sounds like an odd way to implement collision testing.

[sIGPIC]e[/sIGPIC]
Posted
Marble Eater, what other method of collision detection would you use for non-rectangular sprites? (Sorry for psudo-hijack)

~Nate�

___________________________________________

Please use the [vb]/[cs] tags on posted code.

Please post solutions you find somewhere else.

Follow me on Twitter here.

  • Leaders
Posted
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 don't 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 don't know the nature of of the application I thought I'd ask.
[sIGPIC]e[/sIGPIC]
Posted

Thank you for the replies.

 

Well the concept is very simple, if I can access the DirectX's 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 ray's path in advancement and check if it matches a specific color. Its really simple to do in GDI+:

 

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 :(

  • Leaders
Posted

Well, if you are using MDX, it looks like the thing to do would be to call Device.GetBackBuffer() on your Direct3D device, which will return the rendering surface. You could then call Surface.LockRectangle to access raw data. It doesn't look like much fun, though. Like I said, raw raster data formats could vary.

 

Info:

http://www.geocities.com/foetsch/d3d8screenshot/d3d8screenshot.htm

http://msdn.microsoft.com/en-us/library/bb153344(VS.85).aspx

[sIGPIC]e[/sIGPIC]
Posted

Could you post a piece of code demonstrating this?

 

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, I'll keep googling anyway

  • Leaders
Posted
Could you post a piece of code demonstrating this?

The problem is I've never done it before. I understand the concept and I hoped it would point you in the right direction, but I don't know the individual steps. I'm guessing you have to seek through the GraphicsStream or Array returned by LockRectangle and examine the raw pixel data to do your collision detection.

[sIGPIC]e[/sIGPIC]
  • Administrators
Posted

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.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

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 ray's head passes over a non-black pixel.

 

I made this with GDI+ and it worked like a charm, even in ZX-Spectrum's basic it worked like a charm, I can't believe that using DX it will be slow.

  • Administrators
Posted

Using a bounding rectangle would be a quick check, if the ray intersects the rectangle then you would check the actual pixel data - you wouldn't 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.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

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 ray's head passes over a non-black pixel.

 

I made this with GDI+ and it worked like a charm, even in ZX-Spectrum's basic it worked like a charm, I can't believe that using DX it will be slow.

  • Administrators
Posted
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 ray's head passes over a non-black pixel.

 

I made this with GDI+ and it worked like a charm, even in ZX-Spectrum's basic it worked like a charm, I can't believe that using DX it will be slow.

 

I didn't 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.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted
I didn't 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 don't 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, can't find anything on web related to this, except my very own posts...

 

Thanks again for the post.

Posted (edited)

lol! I'm using MDX Visual Studio 2008.

 

Oh man, I'm 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 I'm 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 ray's 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.

Edited by EFileTahi-A
Posted

Hey a friend of mine gave me this piece of 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.

Posted (edited)

I've decided to convert the backbuffer directly to a BMP and use GDI+ to locate the pixels and retrieve their colors:

 

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.

Edited by EFileTahi-A

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...