jmasterx
jmasterx

Reputation: 54113

Optimizing GDI+ drawing?

I'm using C++ and GDI+ I'm going to be making a vector drawing application and want to use GDI+ for the drawing.

I'v created a simple test to get familiar with it:

case WM_PAINT:
        GetCursorPos(&mouse);
        GetClientRect(hWnd,&rct);
        
        hdc = BeginPaint(hWnd, &ps);
        MemDC = CreateCompatibleDC(hdc);
        bmp = CreateCompatibleBitmap(hdc, 600, 600);
        SelectObject(MemDC,bmp);
        g = new Graphics(MemDC);

        for(int i = 0; i < 1; ++i)
        {
            SolidBrush sb(Color(255,255,255));
            g->FillRectangle(&sb,rct.top,rct.left,rct.right,rct.bottom);
        }
        
        for(int i = 0; i < 250; ++i)
        {
            pts[0].X = 0;
            pts[0].Y = 0;

            pts[1].X = 10 + mouse.x * i;
            pts[1].Y = 0 + mouse.y * i;

            pts[2].X = 10 * i + mouse.x;
            pts[2].Y = 10 + mouse.y * i;

            pts[3].X = 0 + mouse.x;
            pts[3].Y = (rand() % 600) + mouse.y;

            Point p1, p2;
            p1.X = 0;
            p1.Y = 0;
            p2.X = 300;
            p2.Y = 300;
            
            g->FillPolygon(&b,pts,4);
        }
        
        
        BitBlt(hdc,0,0,900,900,MemDC,0,0,SRCCOPY);
    
        EndPaint(hWnd, &ps);

        DeleteObject(bmp);
        g->ReleaseHDC(MemDC);
        DeleteDC(MemDC);
        delete g;
        break;

It takes ~ 1sec to render this. What can I do, if anything, to improve the performance?

In a real situation, would it be better just to figure out the portion of the screen to redraw and only redraw the elements within those bounds?

Upvotes: 0

Views: 1848

Answers (2)

JustJeff
JustJeff

Reputation: 12980

Instead of creating all the resources and tearing them all down for every WM_PAINT, you could try off-loading this to application setup and cleanup. In other words, shift all the stuff like CreateCompatibleDC, CreateCompatibleBitmap to WM_CREATE, and the corresponding deletes to WM_DESTROY. You can keep references to all the device contexts, brush handles, and the like as class attributes or static variables. That way when it's WM_PAINT time, all the setup is already done, and you only need to handle the actual drawing.

Upvotes: 0

ssube
ssube

Reputation: 48267

The slowest line in your code at the moment is probably BitBlt(hdc,0,0,900,900,MemDC,0,0,SRCCOPY);. Blit functions are usually very slow and hard on the CPU. Using the GPU would be faster, but far more involved (if it's even possible to tie into GDI+). Try to find a way to draw to the surface you'll be using in the end, without copying pixel-by-pixel.

Upvotes: 0

Related Questions