在MFC中打印OpenGL
- 格式:docx
- 大小:21.21 KB
- 文档页数:4
在MFC中打印OpenGL
我在很多杂志上看到了OpenGL视的实现,但没有一个是介绍如何打印OpenGL 的。
于是,我猜想你巳经有一个实现了的OpenGL视类,但你不能实现打印。
classCOpenGLView : public CView {
...
protected:
CDC *m_pDC;
HGLRC m_hRC;
...
};
在你的OnCreate函数中,你将创建下面这些:
intCOpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (CView::OnCreate (lpCreateStruct) == -1) return (-1);
m_pDC = new CClientDC (this);
if (m_pDC == NULL) return (-1);
// Set the DC's pixel format...
if (!SetDCPixelFormat (m_pDC)) return (-1);
m_hRC = wglCreateContext (m_pDC->GetSafeHdc ());
if (!wglMakeCurrent (m_pDC->GetSafeHdc (), m_hRC)) return (-1);
glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
glClearDepth (1.0);
return (0);
}
注意:在这里我调用了wglMakeCurrent ()函数。
有些作者在OnDraw()函数的开始调用这个
函数,那可能是因为它们的代码没有它就不工作。
wglMakeCurrent ()函数在当前的OpenGL
窗口创建了一个指定的窗口实例。
在一个MDI程序中,带来两个文档的打开,在绘制它们进入
之前,你需要确认每个视实例创建在它们自己的当前窗口。
因而,在OnCreate()函数中调用wglMakeCurrent ()函数是不够的 -- 另外在第二个视被创
建之后,在第一个视中的所有OpenGL调用将在第二个视中被得到实施。
许多作者在他们的视的OnDraw()函数开始部分调用wglMakeCurrent ()
-- 抵住这种诱惑!这是(粗略)我的OpenGL打印函数COpenGLView::OnPrint():
voidCOpenGLView::OnPrint(CDC* pDC, CPrintInfo* pInfo) {
// Let's not worry for now about print preview...
if (pInfo->m_bPreview) return;
// or print a message to preview
window...
UINT CurPage = pInfo->m_nCurPage;
GLsizeiHRes = pDC->GetDeviceCaps(HORZRES);
GLsizeiVRes = pDC->GetDeviceCaps(VERTRES);
GLsizeiHPixelsPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
GLsizeiVPixelsPerInch = pDC->GetDeviceCaps(LOGPIXELSY);
pDC->SetMapMode (MM_TEXT);
// m_LMargin, etc are margins, in inches...
GLint l = (GLint) (m_LMargin*HPixelsPerInch);
GLint r = (GLint) (m_RMargin*HPixelsPerInch);
GLint t = (GLint) (m_TMargin*VPixelsPerInch);
GLint b = (GLint) (m_BMargin*VPixelsPerInch);
// Image width and height...
GLsizei w = HRes - l - r;
GLsizei h = VRes - t - b;
// Probably don't need this...
intSavedDC = pDC->SaveDC ();
if (CurPage == 1) {
// Save the current OpenGL settings...
HDC hDCOld = wglGetCurrentDC ();
HGLRC hGLRCOld = wglGetCurrentContext ();
// Make the printer the current
// OpenGL rendering device...
HGLRC hGLRCPrinter = wglCreateContext (pDC->GetSafeHdc ());
BOOL bRet = wglMakeCurrent (pDC->GetSafeHdc (), hGLRCPrinter);
ASSERT (bRet);
glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
glClearDepth (1.0);
// This makes a square image...
if (w < h) h = w;
if (h < w) w = h;
// This centers the images...
l = (HRes - w)/2;
b = (VRes - h)/2;
//
glViewport(l, b, w, h);
OnDraw (pDC);
// Go back to the saved OpenGL settings...
wglMakeCurrent (hDCOld, hGLRCOld);
wglDeleteContext(hGLRCPrinter);
}
// Probably don't need this...
if (SavedDC != 0) pDC->RestoreDC (SavedDC);
}
注意:OnPrint ()函数调用OnDraw ()函数。
如果在OnDraw ()函数中你调用了wglMakeCurrent
(),你将不再被打印...你应该重绘这个视!它应当也被注明,在OnBeginPrinting ()
和OnEndPrinting ()函数中能够做到设置和存储当前的OpenGL设备。
为了简单起见,在这里我
巳经放置了所有代码。
于是,现在打印OpenGL是简单的。
让我们加到绘制...
为了确售你绘制到了正确的窗口,你需要调用wglMakeCurrent从SOMEWHERE OTHER THAN OnDraw
()。
But where? 侯选的是OnActivateView () 与 OnUpdate ()函数。
我通常重载两这个函数: OnActivateView ()
和 OnUpdate (),并且在两个函数中我调用 wglMakeCurrent ()。
在OnUpdate ()函数, 我保存和恢复当前设置在函数的开始和结束(就象在 OnPrint ())。
在OnActivateView ()函数中这不是必须的。
voidCOpenGLView::OnActivateView(BOOL bActivate,
CView* pActivateView, CView* pDeactiveView) {
CView::OnActivateView(bActivate, pActivateView, pDeactiveView);
if (bActivate) {
wglMakeCurrent (m_pDC->GetSafeHdc (), m_hRC);
}
}
voidCOpenGLView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) {
// Save the current OpenGL settings...
HDC hDCOld = wglGetCurrentDC ();
HGLRC hGLRCOld = wglGetCurrentContext ();
// Make this view the current OpenGL rendering context...
BOOL bRet = wglMakeCurrent (m_pDC, m_hRC);
// Draw!!!
OnDraw (m_pDC);
// Go back to the saved OpenGL settings...
wglMakeCurrent (hDCOld, hGLRCOld);
wglDeleteContext(hGLRCPrinter);
}
注:在OnUpdate函数中要返回预先设置。