Click to See Complete Forum and Search --> : Improve the drawing speed


tangzibo
April 13th, 1999, 03:47 AM
Hi
My application needs to draw thousands of lines with different width, how
to improve the drawing speed?
thanks

Harvey Hawes
April 13th, 1999, 07:04 AM
Hi,

Are you drawing to a memory device context and using BitBlt to transfer it to the screen? If not, see
the articles on this site dealing with it (spp. CMemDC).

HTH,



Harvey Hawes

Software Engineer
BioScience Analysis Software Ltd.

Masters Candidate
Cardiovascular/Respiratory Sciences
Faculty of Medicine
University of Calgary
Calgary, Alberta, Canada

mdbuck
April 13th, 1999, 07:50 AM
One thing that I do is to use the API GDI routines directly. CDC::MoveTo(...) is very inefficient because it always returns the previous pen position which 9 times out of 10 nobody cares about. The other thing that I do is check if any of the points matches the last point drawn. If their is a match then I can skip the ::MoveToEx(...) function altogether. For example:

DrawLine(int x1, int y1, int x2, int y2)
////////////////////////////////////////////////////////////////////////////////////////////////
// Sample to speed up drawing. A member function of a display class much like the MFC CDC class
// m_pDC, m_LastX and m_LastY are members of that class as well.
////////////////////////////////////////////////////////////////////////////////////////////////
{

// variables
HDC hDC = m_pDC->m_hDC;

if (x1 == m_LastX && y1 == m_LastY)
{
::LineTo(hDC, x2, y2);
m_LastX = x2;
m_LastY = y2;
}
else if (x2 == m_LastX && y2 == m_LastY)
{
::LineTo(hDC, x1, y1);
m_LastX = x1;
m_LastY = y1;
}
else
{
::MoveToEx(hDC, x1, y1, NULL);
::LineTo(hDC, x2, y2);
m_LastX = x2;
m_LastY = y2;
}

}

One other thing that I do is keep track of the current pen settings. This avoids having to query the device context for the LOGPEN, set the appropriate fields, then set the pen again:

SetPen(UINT style, POINT width, COLORREF color)
{

BOOL bchanged = FALSE;

if (style != m_pLogPen->lopnStyle)
m_pLogPen->lopnStyle = style;
bChanged = TRUE;
}

if (width != m_pLogPen->lopnWidth)
m_pLogPen->lopnWidth = width
bChanged = TRUE;
}

if (color != m_pLogPen->lopnColor)
m_pLogPen->lopnColor = color;
bChanged = TRUE;
}

if (bChanged)
{
// create new pen and replace current pen
}

}

It's a lot of work and it may seem like all the conditionals would slow it down but it is much faster than relying on the API for information.

Gomez Addams
April 13th, 1999, 12:43 PM
Have a look at PolyLine and PolyPolyLine. One of the big causes of slowdowns
with multiple lines is the context switch from a user process to a kernel level library
and these functions will draw as many lines as you want with one call.
One thing to be aware of is that these draw lines using the current pen so if your
lines change colors and widths there will need to be one call for each of these.
You could possibly group together the lines that use the same pen into one call.