A managed DirectDraw / DirectX question
-
I've been porting code to C# while using Managed DirectX 9.0b. To access memory surfaces directly i used the Surface.Lock() method, which should return an Array, but returns a byte[,]. Annoyingly, the size of this array is the size of the surface in pixels, not in bytes. E.g. working with a 100X100 pixels surface with 16bits per pixel, the method returns a byte[100,100] (half the size). Using the array position as a pointer, and navigating it manualy using SurfaceDescription.Pitch didn't help either. If you had the patience to read this, read the code:
int stride = back.SurfaceDescription.Pitch; byte[,] barr = back.Lock (Microsoft.DirectX.DirectDraw.LockFlags.SurfaceMemoryPointer ); unsafe { fixed (byte* pbdata = barr) { for (int j=0; j<100; j++) { for (int i=0; i<100; i++) { *(pbdata+j*stride+2*i+1) = 0xF8; } } } } back.Unlock(barr);
this should paint my surface red, but it only paints half of it red. What am I doing wrong? -
I've been porting code to C# while using Managed DirectX 9.0b. To access memory surfaces directly i used the Surface.Lock() method, which should return an Array, but returns a byte[,]. Annoyingly, the size of this array is the size of the surface in pixels, not in bytes. E.g. working with a 100X100 pixels surface with 16bits per pixel, the method returns a byte[100,100] (half the size). Using the array position as a pointer, and navigating it manualy using SurfaceDescription.Pitch didn't help either. If you had the patience to read this, read the code:
int stride = back.SurfaceDescription.Pitch; byte[,] barr = back.Lock (Microsoft.DirectX.DirectDraw.LockFlags.SurfaceMemoryPointer ); unsafe { fixed (byte* pbdata = barr) { for (int j=0; j<100; j++) { for (int i=0; i<100; i++) { *(pbdata+j*stride+2*i+1) = 0xF8; } } } } back.Unlock(barr);
this should paint my surface red, but it only paints half of it red. What am I doing wrong?There used to be a bug regarding this that didn't actually lock all of the surface memory. Not sure if they've fixed it or not... ok, that said, the Pitch property is the distance *in bytes* to the next line of the raster. So one "line" in the raster is actually Pitch bytes long. Hence, one pixel is (Pitch/width) bytes long. Methinks you're addressing the wrong chunk of memory as a result.
Jeremy Kimball magnae clunes mihi placent, nec possum de hac re mentiri. (Large buttocks are pleasing to me, nor am I able to lie concerning this matter)
-
There used to be a bug regarding this that didn't actually lock all of the surface memory. Not sure if they've fixed it or not... ok, that said, the Pitch property is the distance *in bytes* to the next line of the raster. So one "line" in the raster is actually Pitch bytes long. Hence, one pixel is (Pitch/width) bytes long. Methinks you're addressing the wrong chunk of memory as a result.
Jeremy Kimball magnae clunes mihi placent, nec possum de hac re mentiri. (Large buttocks are pleasing to me, nor am I able to lie concerning this matter)
Thanks, u'r absolutely right about the pitch. sorry that my code is ugly that way (the "j" index came before the "i" somehow). but i think i've tried what you've suggested:
for (int line_no=0; line_no<100; line_no++) for (int column_no=0; column_no<100; column_no++) *(pbdata+line_no*Pitch+2*column_no+1) = 0xF8;
Do I understand what you mean, or am i missing something? You say the bug is not locking the whole surface memory? in desperation i've tried to access bytes seemingly outside my surface (like: line_no = 120); to my surprise nothing crashed (as if i've accessed something legal), but the app seemed to be in a deadlock (so maybe it was not locked)