Hi,
I have ACTIVEX object that generates map, it works like:
map.Output(CDC);
I' d like to use this CDC as background for future painting. So in my InitailUpdate I do this:
// Init OpenGL
sf::WindowSettings st;
st.AntialiasingLevel = 8; // Make smooth drawing
m_pSfmlView = new sf::RenderWindow(GetSafeHwnd(), st);
In OnDraw:
m_map.Output(&m_WorkDC);
BITMAPINFOHEADER bi;
::ZeroMemory(&bi, sizeof(BITMAPINFOHEADER));
bi.biSize = sizeof(BITMAPINFOHEADER);
int ret = GetDIBits(m_WorkDC.m_hDC,
(HBITMAP)m_WorkBmp.GetSafeHandle(),
0,
bi.biHeight,
NULL,
(BITMAPINFO*)&bi,
DIB_RGB_COLORS);
bi.biCompression = BI_RGB;
unsigned char *bmpBuffer = new unsigned char[bi.biSizeImage];
ret = GetDIBits(m_WorkDC.m_hDC,
(HBITMAP)m_WorkBmp.GetSafeHandle(),
0,
bi.biHeight,
(void*)bmpBuffer,
(BITMAPINFO*)&bi,
DIB_RGB_COLORS);
So far I have DIB in bmpBuffer, now I'd like to draw this image, but here is my confusion. I beleivbe it is already in pixel format so I use:
sf::Image backgroundImage;
bool b = backgroundImage.LoadFromPixels(bi.biWidth, bi.biHeight, (const unsigned char*)bmpBuffer);
delete [] bmpBuffer;
sf::Sprite background = sf::Sprite(backgroundImage);
m_pSfmlView->Draw(background);
It doesnt work. I debug it littel bit and looks like this DIB is just part of bitmap without the header, so small function that I grab from SOIL fix the problem:
void CMapView::ConvertToPixels(int img_x, int img_y, unsigned char *out)
{
int target = 4;
int z = 0;
for (int j=0; j < (int) img_y; ++j)
{
for (int i=0; i < (int) img_x; ++i)
{
int a;
char ch = out[z+2];
out[z+2] = out[z];
// out[z+1] = get8();
out[z] = ch;
z += 3;
a = 255;
if (target == 4) out[z++] = a;
}
}
unsigned char t;
for (int j=0; j < (int) img_y>>1; ++j)
{
unsigned char *p1 = out + j * img_x * target;
unsigned char *p2 = out + (img_y-1-j)*img_x*target;
for (int i=0; i < (int) img_x*target; ++i)
{
t = p1[i];
p1[i] = p2[i];
p2[i] = t;
}
}
}
It works, but I am really unhappy with the performance because one copy and 2 conversions (150-200 ms in debug mode). So in ideal case it could be something like
m_map.Output(&m_WorkDC);
// Init OpenGL
sf::WindowSettings st;
st.AntialiasingLevel = 8; // Make smooth drawing
m_pSfmlView = new sf::RenderWindow(m_WorkDC, st);
So it should eliminate needs to copy/convert DIB. If there are better way to do so, please help me.
Thanks
Aleksey