EFileTahi-A Posted June 14, 2008 Posted June 14, 2008 (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 June 14, 2008 by EFileTahi-A Quote
EFileTahi-A Posted June 23, 2008 Author Posted June 23, 2008 Just wondering, is this possible to do? Or my post kinda confusing? I will gladly explain it better if someone stats this. Quote
Leaders snarfblam Posted June 23, 2008 Leaders Posted June 23, 2008 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. Quote [sIGPIC]e[/sIGPIC]
Nate Bross Posted June 24, 2008 Posted June 24, 2008 Marble Eater, what other method of collision detection would you use for non-rectangular sprites? (Sorry for psudo-hijack) Quote ~Nate� ___________________________________________ Please use the [vb]/[cs] tags on posted code. Please post solutions you find somewhere else. Follow me on Twitter here.
Leaders snarfblam Posted June 24, 2008 Leaders Posted June 24, 2008 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. Quote [sIGPIC]e[/sIGPIC]
EFileTahi-A Posted June 26, 2008 Author Posted June 26, 2008 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 :( Quote
Leaders snarfblam Posted June 26, 2008 Leaders Posted June 26, 2008 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 Quote [sIGPIC]e[/sIGPIC]
EFileTahi-A Posted June 27, 2008 Author Posted June 27, 2008 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 Quote
Leaders snarfblam Posted June 27, 2008 Leaders Posted June 27, 2008 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. Quote [sIGPIC]e[/sIGPIC]
EFileTahi-A Posted June 28, 2008 Author Posted June 28, 2008 Ok, thanks for the help anyway :) I'll try to post a solution, if I found any. Quote
Administrators PlausiblyDamp Posted June 30, 2008 Administrators Posted June 30, 2008 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
EFileTahi-A Posted July 1, 2008 Author Posted July 1, 2008 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. Quote
Administrators PlausiblyDamp Posted July 1, 2008 Administrators Posted July 1, 2008 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
EFileTahi-A Posted July 1, 2008 Author Posted July 1, 2008 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. Quote
Administrators PlausiblyDamp Posted July 1, 2008 Administrators Posted July 1, 2008 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
EFileTahi-A Posted July 1, 2008 Author Posted July 1, 2008 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. Quote
Administrators PlausiblyDamp Posted July 1, 2008 Administrators Posted July 1, 2008 Are you using MDX or the XNA studio stuff for this? I've been meaning to have a play with XNA since I've installed it and this could be a good excuse ;) Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
EFileTahi-A Posted July 1, 2008 Author Posted July 1, 2008 (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 July 1, 2008 by EFileTahi-A Quote
EFileTahi-A Posted July 1, 2008 Author Posted July 1, 2008 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. Quote
EFileTahi-A Posted July 4, 2008 Author Posted July 4, 2008 (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 July 4, 2008 by EFileTahi-A Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.