Direct3D.Texture poop = Direct3D.TextureLoader.FromFile(...);
Direct3D.SurfaceDescription TextureDetails = poop.GetLevelDescription(0);
Direct3D.Surface PixelBuffer = poop.GetSurfaceLevel(0);
System.IO.Stream PixelStream = PixelBuffer.LockRectangle(new Rectangle(0, 0, TextureDetails.Width, TextureDetails.Height), Direct3D.LockFlags.ReadOnly);
PixelBuffer.UnlockRectangle();
[.net] How do I manipulate a texture's pixels?
I'm using C# and need to know how to manipulate the pixels of a texture. I've spent the last few weeks reading msdn, the summer 2003 sdk, "Beginning C# Game Programming", and "Managed DirectX 9 Kick Start: Graphics and Game Programming". None have provided an answer (except for C++). My whole project is gridlocked until I can get this working. I think I've gotten close by putting the texture into a surface, but I cant figure out how to get the surface into a stream or array. Here is an example of what I have so far:
I don't know about managed DX or C# but doesn't the surface or texture interface have Lock() and Unlock() methods? These allow you, normally, to get the texture's internals.
Ok; I see now you already have started locking something. I'm not familiar enough with that; my best guess is the stream holds the texture data after this.
Greetz,
Illco
Ok; I see now you already have started locking something. I'm not familiar enough with that; my best guess is the stream holds the texture data after this.
Greetz,
Illco
IIRC, you can load the stream (returned from LockRectangle) into a .Net bitmap. I'm not saying it's the fastest method, but it should work.
To do that, it would be something like this:
The best way would be to use the Stream directly, but I'm not clever enough to know how to get at the pixel data without using a Bitmap object ;-)
To do that, it would be something like this:
System.IO.Stream PixelStream = PixelBuffer.LockRectangle(new Rectangle(0, 0, TextureDetails.Width, TextureDetails.Height), Direct3D.LockFlags.ReadOnly);System.Drawing.Bitmap pBitmap = new System.Drawing.Bitmap(PixelStream);// then you can either use pBitmap.GetPixel(x, y) or use the more optimised pBitmap.Lock()PixelBuffer.UnlockRectangle();
The best way would be to use the Stream directly, but I'm not clever enough to know how to get at the pixel data without using a Bitmap object ;-)
Oh, forgot to mention. I haven't used LockRectangle before, but I've used this method, and I know it returns a stream that can be loaded into a bitmap (just in case the method above doesn't work):
Surface s1 = poop.GetSurfaceLevel(0);GraphicsStream gs = SurfaceLoader.SaveToStream(ImageFileFormat.Png, s1);Bitmap b = new Bitmap(gs);
I was really hoping to not have to convert it to a bitmap. But anyway, Illco what version of directx sdk update do you have? Mine is Summer 2003 and does not have SurfaceLoader.SaveToStream()
Update:
I just tried putting the stream into a bitmap and it throws an exception.
In the first code I put it would also throw an exception on the
System.IO.Stream PixelStream = PixelBuffer.LockRectangle(..
line.
Can anyone help me on this? Absolutely any way to read a texture's pixels or make this code work would be great.
[Edited by - Matt Jones on June 24, 2005 2:37:29 PM]
Update:
I just tried putting the stream into a bitmap and it throws an exception.
In the first code I put it would also throw an exception on the
System.IO.Stream PixelStream = PixelBuffer.LockRectangle(..
line.
Can anyone help me on this? Absolutely any way to read a texture's pixels or make this code work would be great.
[Edited by - Matt Jones on June 24, 2005 2:37:29 PM]
What about Tom Miller's example in "Managed DirectX 9 Kick Start"?:
And here's a safe version.
Seems like this does exactly what you're asking (in this example, it sets the pixels to white).
uint *pData = (uint*)texture.LockRectangle(0, LockFlags.None).InternalData.ToPointer();for (int i=0; i < _size.Width; i++){ for (int j=0; j < _size.Height; j++) { *pData = (uint) Color.White.ToArgb(); pData++; }}
And here's a safe version.
uint[,] data = (uint[,])texture.LockRectangle(0, LockFlags.None, _size.Width, _size.Height);for (int i=0; i < _size.Width; i++){ for (int j=0; j < _size.Height; j++) { data[i,j] = (uint) Color.White.ToArgb(); }}
Seems like this does exactly what you're asking (in this example, it sets the pixels to white).
Interesting. I leafed through the book again and could not find that code. Is that first one C++ or is it the mystical "unsafe C# code" I've only herd whispers about?
Anyway I'll look into that. Thanks a bunch.
I hope this works! Ill try the safe version first.
Update!!!!!!!!!!!
I got it to work using the safe method! And I figured out how to use "unsafe code"!
[Edited by - Matt Jones on June 29, 2005 5:25:32 AM]
Anyway I'll look into that. Thanks a bunch.
I hope this works! Ill try the safe version first.
Update!!!!!!!!!!!
I got it to work using the safe method! And I figured out how to use "unsafe code"!
[Edited by - Matt Jones on June 29, 2005 5:25:32 AM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement