views:

127

answers:

3

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;

I'm wondering if I'm doing it right, or if I have areas killing the cpu. Because right now it takes ~ 1sec to render this and I want to be able to have it redraw itself very quickly. Thanks

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

A: 

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.

peachykeen
No it seems to be g->FillPolygon( (times 250) If I reduce to 30 iterations its lightening fast, but Ill need more than 30 shapes :-p
Milo
Use a variable for the loop, don't always draw 250 shapes, draw as many as you need. There will be some slowdown as you draw more, that's natural. Try to avoid drawing identical shapes twice, too (unless you have transparency to worry about).
peachykeen
What do I do when it needs to redraw the whole window (ie: everything...) ?
Milo
A: 

I asked a related question some time ago. Maybe this can give you a few pointers:

http://stackoverflow.com/questions/957573/winforms-how-to-speed-up-invalidate

Pedery
A: 

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.

JustJeff
on second examination, it looks like you're drawing a lot of semi-randomly shaped polygons. the win32 gdi is not really a performance graphics system. it does ok with basic rectangular stuff, but when you start asking arbitrary polygons from it, it will be slower for sure. were it me i'd consider directx or opengl for anything more complex than the real basic stuff.
JustJeff