Click here to Skip to main content
15,867,686 members
Articles / Multimedia / OpenGL

A Win32 class support OpenGL printing

Rate me:
Please Sign up or sign in to vote.
4.14/5 (8 votes)
22 Nov 1999 95.3K   3.1K   26   8

The sample

The demo

The sample of the print preview

The print preview

The article gives a class, CGLMemoryDC, which can support OpenGL printing under Win95/NT

CGLMemoryDC stores the DIB data for the printer context device.

//data of DIB
private:
	HBITMAP      m_hBitmap;       //handle of bitmap
	BITMAPINFO   m_DIBInfo;       //infomation about the DIB
	BYTE*        m_hImage;        //DIB color data
	DWORD        m_dwDataSize;    //DIB data size 

 

CGLMemoryDC also gives the functions to get DIB data from selected context device or set DIB data to target context device

/********************************************************************/
/* Scan the image from the device context   					    */
/********************************************************************/
void CGLMemoryDC::CopyDataFromDC(CDC* pDC, CRect& rect)
{
	CDC      dcBuffer;       //the compatible DC 
	CBitmap  bmBitmap;		 //bitmap in memory for retreive data from DC
	CBitmap* pbmBitmapOld;

	//if the orignal bitmap did not set up
	if(!m_hBitmap)
        return;

	//create compatible DC to copy image
	dcBuffer.CreateCompatibleDC(pDC);

	//create memory bitmap 
	bmBitmap.CreateCompatibleBitmap(pDC,
                  m_DIBInfo.bmiHeader.biWidth,
                  m_DIBInfo.bmiHeader.biHeight);
    
	//set memory bitmap to memory DC
	pbmBitmapOld = dcBuffer.SelectObject(&bmBitmap);
    
	//copy source DC image to memory bitmap
	dcBuffer.StretchBlt(0, 0,  
			m_DIBInfo.bmiHeader.biWidth,
			m_DIBInfo.bmiHeader.biHeight,
			pDC, 
			rect.left,
			rect.top,
			rect.Width(),
			rect.Height(),
			SRCCOPY);

	//restore the orginal object in memory DC
    dcBuffer.SelectObject(pbmBitmapOld);

	//copy image data from memory bitmap
	GetDIBits(pDC->m_hDC,
		HBITMAP)bmBitmap, 
		0, 
		m_DIBInfo.bmiHeader.biHeight,
		m_hImage,
		&m_DIBInfo,
		DIB_RGB_COLORS);
}


/********************************************************************/
/* Copy image data to target DC             					    */
/*                                                                  */ 
/* This function just support the color printer setting in Text     */
/* mode																*/
/********************************************************************/
void CGLMemoryDC::CopyDataToDC(CDC* pDC, CRect& rect)
{
    ::StretchDIBits(pDC->m_hDC, 
			rect.left, 
			rect.top, 
			rect.Width(), 
			rect.Height(),
			0, 0, 
			m_DIBInfo.bmiHeader.biWidth, 
			m_DIBInfo.bmiHeader.biHeight,
			m_hImage,  
			&m_DIBInfo, 
			DIB_RGB_COLORS, 
			SRCCOPY);
}


/********************************************************************/
/* Write image data directly to target DC                           */
/*                                                                  */ 
/* This function just support the color printer setting in Photo    */
/* quality mode                                                     */
/********************************************************************/
void CGLMemoryDC::WriteDataToDC(CDC* pDC, int startx, int starty)
{
    ::SetDIBitsToDevice(pDC->m_hDC, 
				startx, 
				starty,
				m_DIBInfo.bmiHeader.biWidth,
				m_DIBInfo.bmiHeader.biHeight,
				0, 0, 0,
				m_DIBInfo.bmiHeader.biHeight,
				m_hImage, 
				&m_DIBInfo, 
				DIB_RGB_COLORS);
           			 
}

 

The function "WriteDataToDIBfile" in CGLMemoryDC allow to store DIB data to disk file

The use of CGLMemoryDC in application program to support printing is like

void CGlprintView::OnDraw(CDC* pDC)
{
	CGlprintDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// TODO: add draw code for native data here
	//if print
	if(pDC->IsPrinting())
	{
		 //draw the image in memory DC to print DC 
		 CRect      drawRect;
		 int        cx, cy;
		 COLORREF	clrOld = pDC->SetTextColor(RGB(250, 10, 10));
		 pDC->TextOut(450,10, "This is a demo of OpenGL print provided by Zhaohui Xing");
		 pDC->SetTextColor(RGB(128, 128, 255));
		 pDC->TextOut(40,80, "Large Size");
		 drawRect.SetRect(40, 160, 2440, 1960);
		 pDC->DPtoLP(&drawRect);
		 m_MemImageDC.CopyDataToDC(pDC, drawRect);
		 pDC->TextOut(40,1960, "Medium Size");
		 drawRect.SetRect(500, 2040, 2100, 3240);
		 pDC->DPtoLP(&drawRect);
		 m_MemImageDC.CopyDataToDC(pDC, drawRect);
		 pDC->TextOut(40,3260, "Orignal Size");
		 m_MemImageDC.GetMemorySize(&cx, &cy);
		 drawRect.SetRect(1000, 3400, 1000 + cx , 3400 + cy);
		 pDC->DPtoLP(&drawRect);
		 m_MemImageDC.CopyDataToDC(pDC, drawRect);
		 pDC->SetTextColor(clrOld);
	}
	else //draw opnGL in current DC
	{
		 CPalette* oldPalette;

		 //Set logic palette
		 oldPalette = m_pDC->SelectPalette(&m_Palette, FALSE);
		 m_pDC->RealizePalette();
	
		 //draw openGL object
		 wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
		 DrawObject();
		 SwapBuffers(m_pDC->GetSafeHdc());
		 wglMakeCurrent(m_pDC->GetSafeHdc(), NULL);
		 
		 //Prepare the memory DC 
		 CRect rect;
		 GetClientRect(&rect);
		 m_MemImageDC.SetMemorySize(rect.Width(), rect.Height());
		 //copy the image data in current DC to memory
		 m_MemImageDC.CopyDataFromDC(m_pDC, rect);

		 m_pDC->SelectPalette(oldPalette, FALSE);
	}	     
}

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalprint ing screen content in a dialog based application in vc++ Pin
12-Jun-02 18:45
suss12-Jun-02 18:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.