row0: RGBRGBRGB......
row1: RGBRGBRGB......
row2: RGBRGBRGB......
......
Now, I have two kinds of method to paint this *raw data* to a window.
I will demonstrate them in pseudo code:
First method, I will call SetDIBitsToDevice() directly.
/////////////////////////////////////////////////////////
int nSize = Rows * Columns * 3;
pBuffer = new char[nSize]; //allocate a buffer
BITMAPINFO bmi;
Fill bmi......
while(bRunning){
ReceiveFromDevice(pBuffer);
SetDIBitsToDevice(
targetDC,
....,
pBuffer,
&bmi,
DIB_RGB_COLORS );
}
////////////////////////////////////////////////////////
Second method, I use a Dibsection
///////////////////////////////////////////////////////
hBitmap = ::CreateDIBSection(...);
BITMAP = GetObject(hBitmap,...);
pBuffer = BITMAP.bmBits; // Get the pointer to buffer
while(bRunning){
ReceiveFromDevice(pBuffer);
CDC dcMem;
dcMem.CreateCompatibleDC(pdc);
dcMem.SelectObject(hBitmap);
pDC->Bitblt(...,&dcMem...);
......
}
//////////////////////////////////////////////////////
I don't know which method is the best, and runs faster?
I do find a web link talk about this issue:
http://msdn.microsoft.com/en-us/library/ms532354(VS.85).aspx
It suggest that bitblt is faster.
"......For example, a multimedia application that combines animated
graphics with sound would benefit from calling the BitBlt function
because it executes faster than SetDIBitsToDevice...."
But I don't know why? Thanks for any suggestions!
I would like to suggest also to try DirectDraw. DirectDraw can blit 2D
surfaces very fast, e.g. using IDirectDrawSurface::BltFast() method.
Giovanni
"asm23" <asmwa...@gmail.com> ha scritto nel messaggio
news:gb0bik$o1j$1...@aioe.org...
Look at ::QueryPerformanceCounter and ::QueryPerformanceFrequency.
Why depend on secondary sources when you can get the raw data on your own?
joe
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
> Why depend on secondary sources when you can get the raw data on your own?
Sorry, Joe, I can't understand this sentence above. Do you mean that I
should depend on the source code supplied by the device manufacture?
Actually, they have some sample code that use the "second method of
painting the raw data", But sometimes I think the "first method" is more
simple way.
Thanks, Giovanni, But I don't know whether learning DirectDraw is as
easy as learning GDI. But I do agree with you that DirectDraw can do it
in a more effective and fast way.
> Thanks, Giovanni, But I don't know whether learning DirectDraw is as easy
> as learning GDI. But I do agree with you that DirectDraw can do it in a
> more effective and fast way.
DirectDraw has a medium-level learning curve, neither trivial nor very
steep.
You should be familiar with COM *basic* concepts (i.e. what a COM interface
is, IUknown, reference counting using AddRef/Release, QueryInterface...);
you don't need to be a COM guru to be able to use DirectDraw in your C++
Win32/MFC apps.
Moreover, I recall that, with DirectX SDK 6, Microsoft provided some helpful
easy-to-use C++ helper classes (CDisplay and CSurface, IIRC), that wrapped
some of COM and DirectDraw lower level aspects, making the C++ development
process easier. Those classes were not adequate for every need, but they
sure were a good start.
However, I would suggest you to measure your performance with your existing
code (as Joe suggested, too): IMHO, if you are satisfied with your GDI code,
then you don't need to try the (harder) DirectDraw path.
Giovanni
LARGE_INTEGER start;
::QueryPerformanceCounter(&start);
... do computation
::QueryPerformanceCounter(&end);
LONGLONG delta = end.QuadPart - start.QuadPart;
do this for two different algorithms (you said you had already written them, so
instrumenting them requires the four lines above!) Look at the results. Make several
measurements and average them, of course.
You can convert the delta from relative information to absolute time by using the value
from QueryPerformanceFrequency.
It has nothing to do with source code or the device manufacturer. It has to do with
actually MEASURING the information you want to get, instead of trying to depend on
"secondary sources" such as Microsoft documentation or "opinions" not backed by actual
measurement information.
joe
LARGE_INTEGER m_base;
LARGE_INTEGER m_temp;
float m_resolution;
public:
CTimer::CTimer()
{
LARGE_INTEGER t_freq;
QueryPerformanceFrequency(&t_freq);
m_resolution = (float) (1.0f / (double) t_freq.QuadPart);
reset();
}
void CTimer::reset()
{
QueryPerformanceCounter(&m_base);
}
inline float time() {
QueryPerformanceCounter(&m_temp);
return (m_temp.QuadPart - m_base.QuadPart) * m_resolution * 1000.0f;
}
};
////////////////////////////////////////////////////////
This is the result on my system:
method 1 (using SetDIBitsToDevice())
the average of painting a 656*490 24bit image is : 1.63ms
method 2 (using bitblt()
the average painting time is : 1.64ms
So, I think they are just in the same speed.^_^.
Thank you, Giovanni. Now, I have finished testing with the measuring
method Joe suggested. I think it is enough to use the GDI specific
code.(I post the result after joe' message)
So I don't decide to start learning DirectDraw. But I'm very appreciate
with your explanation on DirectDraw. I also gain a lot from your reply.
Thanks again!
I spent 15 years doing performance measurement, and learned that if you ask a programmer
where the performance bottleneck is in the program, you will get the wrong answer. Always.
(In fact, there were never any exceptions to this the whole time I was doing performance
measurement). But once you've measured, you have facts. Then you can make informed
decisions.
Curious: why were you using float? double doesn't cost that much more...and floating
point arithmetic is about the same performance as integer arithmetic on modern processors
(you can measure this, also...except for floating divide, which like integer divide,
always sucks in performance, which is why high-performance floating point algorithms never
divide if they can help it...)
joe
Thanks Joe.
Your suggestion is constructive. I should use "double" instead of
"float". As I have learned some X86 assemble language, I recalled that
many floating point arithmetic instruction take one or two cycles.
Except the fdiv..(They take about 10 cycles and more)