0

Lately I got low level graphics programming job to do (implementing raster graphics algorithms). That's why I started to look for tools (classes) which would be helpful to draw primitives (lines, rectangles, ellipses etc.) on the low level of abstraction (even using unsafe code).

I consider if I should implement my algorithms in WPF, WindowsForms, WinAPI or other environment. For now I'm going to give a try to WPF. I found some examples how to draw pixels on bitmap but unfortunately I have problem with understanding this code (source code from MSDN):

    // The DrawPixel method updates the WriteableBitmap by using 
    // unsafe code to write a pixel into the back buffer. 
    static void DrawPixel(MouseEventArgs e)
    {
        int column = (int)e.GetPosition(i).X;
        int row = (int)e.GetPosition(i).Y;

        // Reserve the back buffer for updates.
        writeableBitmap.Lock();

        unsafe
        {
            // Get a pointer to the back buffer. 
            int pBackBuffer = (int)writeableBitmap.BackBuffer;

            // Find the address of the pixel to draw.
            pBackBuffer += row * writeableBitmap.BackBufferStride;
            pBackBuffer += column * 4;//??

            // Compute the pixel's color. 
            int color_data = 255 << 16; // R
            color_data |= 128 << 8;   // G
            color_data |= 255 << 0;   // B 

            // Assign the color data to the pixel.
            *((int*)pBackBuffer) = color_data;//??
        }

        // Specify the area of the bitmap that changed.
        writeableBitmap.AddDirtyRect(new Int32Rect(column, row, 1, 1));

        // Release the back buffer and make it available for display.
        writeableBitmap.Unlock();
    }
  1. What is this pBackBuffer += column * 4; line for? Why 4?
  2. What does it *((int*)pBackBuffer) = color_data; mean? I know pointers from C/C++ but in C# there is IntPtr, int* and this line int pBackBuffer = (int)writeableBitmap.BackBuffer; suggests that we can treat equally int and IntPtr which is also not clear for me.
  3. Which programming environment should I use? WinAPI, WPF or other?

I would be very thankful if someone could explain me this unsafe code.

patryk.beza
  • 4,876
  • 5
  • 37
  • 56

2 Answers2

3

1: What is this pBackBuffer += column * 4; line for? Why 4?

Assuming that pixel is ARGB, it is 4 bytes per pixel. Since column is X coordinate, it must be multiplied by 4.

2: What does it ((int)pBackBuffer) = color_data; mean?

(int*)pBackBuffer - treat value of int pBackBuffer as pointer to an int

and

*((int*)pBackBuffer) = color_data - store color_data to that pointer

IntPtr and int are not quite the same. IntPtr is 32-bit when running on 32-bit OS and 64-bit when running on 64-bit OS. int is always 32-bit.

Mark Hall
  • 53,938
  • 9
  • 94
  • 111
0

Per the previous comment, if you want the code to work for both x64 and x86, the use of int instead of IntPtr to point to the BackBuffer is an error. The line should read...

IntPtr pBackBuffer = (IntPtr)writeableBitmap.BackBuffer;

since BackBuffer is a pointer which will change size depending on whether your x64 or x86. 'int' will always be 32-bit, and so it would probably cause an overflow exception when compiled x64