Sign in to follow this  

[.net] How do I manipulate a texture's pixels?

This topic is 3675 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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


Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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:


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 ;-)

Share this post


Link to post
Share on other sites
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);

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
What about Tom Miller's example in "Managed DirectX 9 Kick Start"?:


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

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites

This topic is 3675 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this