
Mon, 08/28/2000 - 09:35
Forums:
Hi
I received the sample you sent me, but it doesn't help me at all. Let me refine the subject... I have a 3D View with 3D objects inside it. I can watch this 3D View in a window. In order to do that, I must attach a window to the view, so everything is rendered to this window. But I want to render to a MEMORY bitmap, that is a portion of memory that represents what I see in the view. I don't want to import, or export the view in a .bmp file. I know that OpenGL supports rendering to a MEMORY bitmap, via the flag PFD_DRAW_TO_BITMAP in the PIXELFORMATDESCRIPTOR structure. Is there any way to do the same with OpenCascade?????
Regards: Vladimir
Sat, 10/26/2002 - 18:58
Hi,
I have the same problem as mentioned by Vladimir. I need to render the information of the 3dView to a memory Bitmap (espacially in DIB-Format) to work with this data. Unfortunately there aren't any replies to Vladimirs message and I can't reach him by eMail because his domain doesn't seem to work.
I would be pleased if somebody has some information about that topic or if you Vladimir found a solution in the meantime...
Regards,
Andreas
Mon, 09/22/2003 - 12:11
Hi All,
I found this thread in the forum whilst looking for help on creating a bitmap of an OpenCascade view so that I could send it to the Windows clipboard. I contacted Andreas directly to see if he had come up with a solution since posting his query. He very kindly sent a solution to me which worked perfectly and he also suggested that we post a solution to the forum for future reference.
Here is the solution by Andreas for rendering to a bitmap (with thanks to Zafir Anjum for the conversion to DIB from "Converting DDB to DIB" at http://www.codeguru.com/bitmap/ddb_to_dib.shtml)
Many thanks to Andreas for coming up with this solution.
Best regards,
Neil
How to render to a bitmap:
//get HWND of the View-Window
Handle(Aspect_Window) anAspectWindow = myView->Window();
Handle(WNT_Window) aWNTWindow = Handle(WNT_Window)::DownCast(anAspectWindow);
HWND hWindow = (HWND)aWNTWindow->HWindow();
//get size of client area
RECT WindowClientRect;
::GetClientRect(hWindow,&WindowClientRect);
int BitmapWidth=WindowClientRect.right;
int BitmapHeight=WindowClientRect.bottom;
//get or create DeviceContexts
HDC hDCWindow=::GetDC(hWindow);
HDC hDCMem=CreateCompatibleDC(hDCWindow); //MemoryDC
//create MemoryBitmap for MemoryDC
HBITMAP hMemBmp=CreateCompatibleBitmap(hDCWindow,BitmapWidth,BitmapHeight);
SelectObject(hDCMem,hMemBmp);
SelectObject(hDCWindow,(HBITMAP)aWNTWindow->HPixmap());
//copy Bits from HPixmap() to hMemBmp
BitBlt(hDCMem,0,0,BitmapWidth,BitmapHeight,hDCWindow,0,0,SRCCOPY);
//from now on converting to DIB !!!
//create logical palette if neccesary
CPalette Palette;
if (GetDeviceCaps(hDCWindow,RASTERCAPS) & RC_PALETTE)
{
UINT nSize=sizeof(LOGPALETTE)+(sizeof(PALETTEENTRY)*256);
LOGPALETTE *pLP=(LOGPALETTE*)new BYTE[nSize];
pLP->palVersion=0x300;
pLP->palNumEntries=GetSystemPaletteEntries(hDCWindow,0,255,pLP->palPalEntry);
//create palette
Palette.CreatePalette(pLP);
delete[]pLP;
}
//otherwise use DEFAULT_PALETTE
HPALETTE hPalette;
CPalette* pPalette=&Palette;
hPalette=(HPALETTE)pPalette->GetSafeHandle();
if (hPalette==NULL)
hPalette=(HPALETTE)GetStockObject(DEFAULT_PALETTE);
BITMAP Bmp;
BITMAPINFOHEADER BmInfoHeader;
LPBITMAPINFOHEADER lpBmInfoHeader;
DWORD dwLen;
HANDLE hDIB; // Handle the new DIB
HANDLE handle;
HDC hDC;
//make from HBITMAP hMemBmp a BITMAP Bmp
GetObject(hMemBmp,sizeof(Bmp),(LPSTR)&Bmp);
//define Bitmapinfoheader
BmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
BmInfoHeader.biWidth = Bmp.bmWidth;
BmInfoHeader.biHeight = Bmp.bmHeight;
BmInfoHeader.biPlanes = 1;
BmInfoHeader.biBitCount = Bmp.bmPlanes* Bmp.bmBitsPixel;
BmInfoHeader.biCompression = BI_RGB;
BmInfoHeader.biSizeImage = Bmp.bmHeight*((Bmp.bmWidth+3) & ~3); //0;
BmInfoHeader.biXPelsPerMeter= 0;
BmInfoHeader.biYPelsPerMeter= 0;
BmInfoHeader.biClrUsed = 0;
BmInfoHeader.biClrImportant = 0;
//calculate size of Infoheader and Colortable
int nColors = (1 << BmInfoHeader.biBitCount);
if(nColors>256)
nColors=0;
dwLen=BmInfoHeader.biSize+nColors*sizeof(RGBQUAD);
hDC =::GetDC(NULL);
hPalette=SelectPalette(hDC,hPalette,FALSE);
RealizePalette(hDC);
//allocate memory for BitmapinfoHeader and Colortable
hDIB=GlobalAlloc(GMEM_FIXED,dwLen);
lpBmInfoHeader=(LPBITMAPINFOHEADER)hDIB;
*lpBmInfoHeader=BmInfoHeader;
//Getting size of biSizeImage
GetDIBits(hDC,hMemBmp,0L,(DWORD)BmInfoHeader.biHeight,(LPBYTE)NULL,(LPBITMAPINFO)lpBmInfoHeader,(DWORD)DIB_RGB_COLORS);
BmInfoHeader=*lpBmInfoHeader;
if(BmInfoHeader.biSizeImage==0){
BmInfoHeader.biSizeImage=((((BmInfoHeader.biWidth*BmInfoHeader.biBitCount)+31)&~31)/8)*BmInfoHeader.biHeight;
}
//enlarge buffer
dwLen += BmInfoHeader.biSizeImage;
if(handle=GlobalReAlloc(hDIB,dwLen,GMEM_MOVEABLE))
hDIB=handle;
else{
GlobalFree(hDIB);
SelectPalette(hDC,hPalette,FALSE);
::ReleaseDC(NULL,hDC);
}
lpBmInfoHeader=(LPBITMAPINFOHEADER)hDIB;
//CREATION of the DIB
GetDIBits(hDC,hMemBmp,0L,(DWORD)BmInfoHeader.biHeight,(LPBYTE)lpBmInfoHeader+(BmInfoHeader.biSize+nColors
*sizeof(RGBQUAD)),(LPBITMAPINFO)lpBmInfoHeader,(DWORD)DIB_RGB_COLORS);
SelectPalette(hDC,hPalette,FALSE);
::ReleaseDC(NULL,hDC);
BITMAPINFOHEADER* dib;
dib=(BITMAPINFOHEADER*)hDIB;
Having rendered to a DIB it is very easy to send this to the clipboards with:
// Send the DIB to the clipboard
if (OpenClipboard())
{
BeginWaitCursor();
EmptyClipboard();
SetClipboardData (CF_DIB, hDIB );
CloseClipboard();
EndWaitCursor();
}
Fri, 01/07/2005 - 12:14
Nice. But it has a nasty "feature". Try to capture the view in the way shown there when having a window that overlaps the view (e.g. Task manager window). Ha! Surprise !!! :)
The original question was how to render directly to a bitmap, not to capture what's rendered. Capturing the alredy rendered scene can be dificult and have driver-dependant "features". This is true especially when having ovelaping windows in the screen. In full screen mode usually is ok though.
The solution for the original problem is as folows:
- create a memory DC
- create a bitmap (32bp)
- select the bitmap in the DC
- set the pixel format (32 bpp)
- create a OpenGL context based on the memory DC
- render
- do with the bitmap whatever you want
- (do not forget to clean-up objects in the proper order)
- enjoy
this approach WORKS as I have used it many times
Regards,
Pavele
Tue, 01/11/2005 - 12:53
Pavele,
Could you give us that piece of code ?
Philippe