-
[RESOLVED] Pointers*
I'm trying to rewrite this slow chunk of code...
Code:
dest.SetPixel(xx, yy, source.GetPixel((int)((x / lenX) * source.Width), (int)creepY));
...by using pointers thus...
Code:
*(ptrD + (yy * bmpDdest.Stride) + xx) = *(ptrS + (((int)creepY * bmpDsource.Stride) + (int)((x / lenX) * bmpDsource.Stride)));
Where ptrS and ptrD are pointers to the top left pixels of a source bitmap and a destination bitmap (both images have been locked using LockBits).
When I run the pointer version, I get a NullReferenceException, which probably means my pointers are running wild and free on the open plains of my RAM.
Here's my function in full...
Code:
public struct RGB24
{
public byte Blue;
public byte Green;
public byte Red;
}
private unsafe void BlitQuad(ref Bitmap source, ref Bitmap dest, ref Point[] pts)
{
Trajectory leftEdge = new Trajectory(pts[0], pts[3]);
Trajectory rightEdge = new Trajectory(pts[1], pts[2]);
Trajectory scan = null;
BitmapData bmpDsource = source.LockBits(
new Rectangle(new Point(), source.Size),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
BitmapData bmpDdest = dest.LockBits(
new Rectangle(new Point(), dest.Size),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
RGB24* ptrS = (RGB24*)bmpDsource.Scan0, ptrD = (RGB24*)bmpDdest.Scan0;
uint x, y;
float lenY = leftEdge.Length = rightEdge.Length = Math.Max(leftEdge.Length, rightEdge.Length);
float lenX;
float creepY;
int xx, yy;
for(y = 0 ; y < lenY ; y++)
{
creepY = (int)((y / lenY) * source.Height);
scan = new Trajectory(leftEdge.GetNext(), rightEdge.GetNext());
lenX = scan.Length;
for(x = 0 ; x < lenX ; x++)
{
scan.GetNext(out xx, out yy);
*(ptrD + (yy * bmpDdest.Stride) + xx) = *(ptrS + (((int)creepY * bmpDsource.Stride) + (int)((x / lenX) * bmpDsource.Stride))); //copy the pixel
//dest.SetPixel(xx, yy, source.GetPixel((int)((x / lenX) * source.Width), (int)creepY));
}
}
ptrD = 0;
ptrS = 0;
source.UnlockBits(bmpDsource);
dest.UnlockBits(bmpDdest);
}
}
The code that I am trying to replace works just fine, I can't work out why my pointer math won't work. Is it a bracket in the wrong place or something????
-
1 Attachment(s)
Re: Pointers*
-
Re: Pointers*
So how much of a framerate increase can I take credit for? :D
Actually I changed a lot to make it all understandable to me, and tinkered it to a point were it is working so I'm not really sure where your fault lies. You'll see.
-
Re: Pointers*
Thanks for trying, it does indeed work. Still, I don't think we are going to be able to beat our current rendering code.
Grilkip's code clocked 100 ms compared to a managed version's 500ms. Still at least an order of magnitude too slow :(
Reppage to Gril anyway.
-
Re: Pointers*
Your reps feel like a warm shower Wosser. :D
-
Re: Pointers*
Could eliminating some of the conversions within the loop make a difference?
-
Re: Pointers*
wont help you at all, but in case someone else wants to use it :( :( :(
this just shows how to read and copy every pixel to a destination bitmap.
I just tested it with bitmaps of the same size. Also change "3" to "4" if you're using 32bit pixel format....
PHP Code:
private void copyBits (Bitmap source, Bitmap dest)
{
BitmapData sData = source.LockBits (new Rectangle(new Point(), source.Size),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
BitmapData dData = dest.LockBits (new Rectangle(new Point(), dest.Size),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
byte* ptrS = (byte*)sData.Scan0,
ptrD = (byte*)dData.Scan0;
int width = 3*source.Width,
height = source.Height;
int sOffset = sData.Stride - 3*source.Width,
dOffset = dData.Stride - 3*dest.Width;
for (int y=0; y<height; y++)
{
for (int x=0; x<width; x++)
{
*ptrD = *ptrS;
ptrS++;
ptrD++;
}
ptrS+=sOffset;
ptrD+=dOffset;
}
source.UnlockBits(sData);
dest.UnlockBits(dData);
}
-
1 Attachment(s)
Re: Pointers*
Woo000t!!! It works!! I got my code going at last.
I'll post the code then I'm happy that its as fast as its going to get (i still need to add coordinate safety checks to make sure we don't try to use pointers outside the bitmap area)...
The number on the titlebar is FRAMES PER SECOND!!! (ok its still not as fast as GDI+ but its not bending the texture either!)
This is a pretty slow machine too :D