Печать в OpenGLАвтор: Jongwhan Lee.
ОписаниеИтак, вопрос: как правильно распечатать картинку, нарисованную посредствам OpenGL? Сразу оговорюсь, что само изображение это картинка в формате BMP. Теоретически весь процесс заключается в создании битмаповского изображения из картинки OpenGL, а затем распечатки этой картинки на принтере. Сперва с помощью Class Wizard создаём функцию "OnPrint" в классе CBitmapView. void CBitmapView::OnPrint(CDC* pDC, CPrintInfo* pInfo) ; Если Вы хотите получить качественную распечатанную картинку: double ar=(double)paper.Width()/(double)paper.Height(); CRect gl_paper(0,0,1000*ar,1000); Увеличиваем размер OpenGL-евского bitmap-а. CRect gl_paper(0,0,2000*ar,2000); Если задать ещё больше размер, то соответственно качество изображения будет лучше, но и соответственно процессор не сможет быстро справиться с этой задачей. Следующая команда делает OpenGL-ский экран одинакового размера с размером бумаги на принтере: CRect gl_paper=paper; Размер контекста устройства моего принтера позволяет задать размер 6000*6000, но когда я делаю размер GL экрана 6000 на 6000 , то мой компьютер зависает. void CBitmapView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
CRect paper(0,0,0,0);
// получаем размер бумаги..
if (pInfo->m_bPreview) // превью ..
{
PRINTDLG PrtDlg; // Диалог вывода на печать
if (!AfxGetApp()->GetPrinterDeviceDefaults(&PrtDlg))
{
if (pDC->IsKindOf(RUNTIME_CLASS(CPreviewDC)))
{
CPreviewDC *pPrevDC = (CPreviewDC *)pDC;
//m_hAttribDC содержит print/fax аттрибуты ...
paper.right = GetDeviceCaps(pPrevDC->m_hAttribDC, HORZRES);
paper.bottom = GetDeviceCaps(pPrevDC->m_hAttribDC, VERTRES);
}
}
else
{
CPrintDialog dlg(FALSE);
dlg.m_pd.hDevMode = PrtDlg.hDevMode;
dlg.m_pd.hDevNames = PrtDlg.hDevNames;
HDC hdc = dlg.CreatePrinterDC();
// Получаем размер страницы принтера
paper.right = GetDeviceCaps(hdc, HORZRES);
paper.bottom = GetDeviceCaps(hdc, VERTRES);
// Освобождаем контекст устройства
DeleteDC(hdc);
}
}
else { // печатаем на бумагу
paper.right = GetDeviceCaps(pDC->GetSafeHdc(), HORZRES);
paper.bottom = GetDeviceCaps(pDC->GetSafeHdc(), VERTRES);
}
pDC->RoundRect(0,0, paper.right, paper.bottom, 10, 10);
double ar=(double)paper.Width()/(double)paper.Height();
CRect gl_paper(0,0,1000*ar,1000);
int width=((int)(gl_paper.Width()/4))*4;
int height=gl_paper.Height();
CGLPrintMan print;
print.EnableOpenGL(gl_paper,GetSafeHwnd(), &print.m_hDC, &print.m_hRC);
print.StartUpdate();
print.KeepAspectRatio(width,height);
glViewport(0,0,width,height);
glDrawBuffer(GL_FRONT);
print.SetViewVolume();
glGetIntegerv(GL_VIEWPORT, print.m_nvVP);
// рисуем
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
{
glClearColor(1,1,1,0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);
glDisable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glColor3d(1,0,0);
glutSolidSphere(5, 20,20 );
}
// передаём на принтер
{
HDC hdc;
HBITMAP bitmap;
hdc = CreateCompatibleDC(pDC->GetSafeHdc());
bitmap = CreateDIBitmap(hdc, &(print.m_BitmapInfo.bmiHeader),
CBM_INIT,
(GLubyte*)print.m_pBitmapBuffer,
&print.m_BitmapInfo,
DIB_RGB_COLORS);
HGDIOBJ oldbitmap = SelectObject(hdc, bitmap);
BOOL bRet = StretchBlt(pDC->GetSafeHdc(),
0,0 , // смещение
paper.Width(), paper.Height(),// бумаги
print.m_hDC,
0, 0,
print. m_BitmapInfo.bmiHeader.biWidth,
print.m_BitmapInfo.bmiHeader.biHeight,
SRCCOPY);
if (oldbitmap != NULL)
SelectObject(hdc, oldbitmap);
// освобождаем битмап и контекст устройства битмапа
DeleteObject(bitmap);
DeleteDC(hdc);
}
print.EndUpdate();
print.DisableOpenGL(GetSafeHwnd(), print.m_hDC, print.m_hRC);
CView::OnPrint(pDC, pInfo);
}
DownloadsСкачать исходник демо-проекта
- 130 Kb
|