Печать в 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;
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
|