Копируем изображение OpenGL в
ClipBoard.
Автор: Pierre Alliez.
Пример показывает, как можно скапчурить OpenGL
картинку и отправить её в клипборду. После этого
картинку можно вставить в любой графический
редактор. Так же не составит труда сохранить это
изображение как .bmp файл. Предполагается, что
разрешение Вашего экрана установлено в true color.
// Замените CRenderView Вашим
собственным CView-наследованным классом
void CRenderView::SnapClient()
{
BeginWaitCursor();
// Получаем геометрию клиента
CRect rect;
GetClientRect(&rect);
CSize size(rect.Width(),rect.Height());
TRACE(" client zone : (%d;%d)\n",size.cx,size.cy);
// Линии получились с
выравниванием в 32 байта, и 24 бита на пиксель
// Урезаем их
size.cx -= size.cx % 4;
TRACE(" final client zone : (%d;%d)\n",size.cx,size.cy);
// Создаём bitmap и устанавливаем его в
контексте устройства
CBitmap bitmap;
CDC *pDC = GetDC();
CDC MemDC;
ASSERT(MemDC.CreateCompatibleDC(NULL));
ASSERT(bitmap.CreateCompatibleBitmap(pDC,size.cx,size.cy));
MemDC.SelectObject(&bitmap);
// Рассчитываем кол-во
необходимых байт для изображения
int NbBytes = 3 * size.cx * size.cy;
unsigned char
*pPixelData = new unsigned char[NbBytes];
// Копируем из OpenGL
::glReadPixels(0,0,size.cx,size.cy,GL_RGB,GL_UNSIGNED_BYTE,pPixelData);
// Заполняем заголовок
BITMAPINFOHEADER header;
header.biWidth = size.cx;
header.biHeight = size.cy;
header.biSizeImage = NbBytes;
header.biSize = 40;
header.biPlanes = 1;
header.biBitCount = 3 * 8; // RGB
header.biCompression = 0;
header.biXPelsPerMeter = 0;
header.biYPelsPerMeter = 0;
header.biClrUsed = 0;
header.biClrImportant = 0;
// Генерируем handle
HANDLE handle = (HANDLE)::GlobalAlloc (GHND,sizeof(BITMAPINFOHEADER)
+ NbBytes);
if(handle != NULL)
{
// Блокируем handle
char *pData = (char
*) ::GlobalLock((HGLOBAL)handle);
// Копируем заголовок и данные
memcpy(pData,&header,sizeof(BITMAPINFOHEADER));
memcpy(pData+sizeof(BITMAPINFOHEADER),pPixelData,NbBytes);
// Разблокируем
::GlobalUnlock((HGLOBAL)handle);
// Кладём DIB в clipboard
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_DIB,handle);
CloseClipboard();
}
// Освобождаем всё
MemDC.DeleteDC();
bitmap.DeleteObject();
delete [] pPixelData;
EndWaitCursor();
}
|