Click here to Skip to main content
12,445,916 members (61,372 online)
Click here to Skip to main content
Articles » Multimedia » OpenGL » General » Downloads

Stats

80.2K views
2.8K downloads
23 bookmarked
Posted

A Win32 class support OpenGL printing

, 22 Nov 1999
// glprintView.cpp : implementation of the CGlprintView class
//

#include "stdafx.h"
#include "glprint.h"

#include "glprintDoc.h"
#include "glprintView.h"
#include <gl\glaux.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CGlprintView

IMPLEMENT_DYNCREATE(CGlprintView, CView)

BEGIN_MESSAGE_MAP(CGlprintView, CView)
	//{{AFX_MSG_MAP(CGlprintView)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_SIZE()
	ON_COMMAND(ID_FILE_SAVE, OnFileSave)
	ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGlprintView construction/destruction

CGlprintView::CGlprintView()
{
	// TODO: add construction code here

}

CGlprintView::~CGlprintView()
{
}

BOOL CGlprintView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CGlprintView drawing
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);
	}	     
}

/////////////////////////////////////////////////////////////////////////////
// CGlprintView printing

BOOL CGlprintView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CGlprintView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CGlprintView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CGlprintView diagnostics

#ifdef _DEBUG
void CGlprintView::AssertValid() const
{
	CView::AssertValid();
}

void CGlprintView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CGlprintDoc* CGlprintView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGlprintDoc)));
	return (CGlprintDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CGlprintView message handlers

/********************************************************************/
/* Set up the OpenGL display environment                 		    */
/********************************************************************/
int CGlprintView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	PIXELFORMATDESCRIPTOR pfd =
	{
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW|
		PFD_SUPPORT_OPENGL|
		PFD_DOUBLEBUFFER,  
		PFD_TYPE_RGBA,
		24,
		0,0,0,0,0,0,
        0,0,0,0,0,0,0,
		32,
		0,0,
		PFD_MAIN_PLANE,
		0,
		0,0,0
	};
     
    m_pDC = new CClientDC(this);
	int pixelFormat =
		ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);
	BOOL success = 
		SetPixelFormat(m_pDC->GetSafeHdc(), pixelFormat, &pfd);

	DescribePixelFormat(m_pDC->GetSafeHdc(), pixelFormat,
		  sizeof(pfd), &pfd);

	if(pfd.dwFlags & PFD_NEED_PALETTE)
         SetPalette();

	m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
	wglMakeCurrent(m_pDC->m_hDC,m_hRC);

	Initialize();

	wglMakeCurrent(NULL,NULL);

	return 0;
}

/********************************************************************/
/* Celan all memory allocated to OpenGL resource           		    */
/********************************************************************/
void CGlprintView::OnDestroy() 
{
	CView::OnDestroy();
	
	// TODO: Add your message handler code here
	wglDeleteContext(m_hRC);
    m_Palette.DeleteObject();
	ReleaseDC(m_pDC);
}


/********************************************************************/
/* If the window size change, adjust the view point for the correct	*/
/* OpenGL diplay                                                    */
/********************************************************************/
void CGlprintView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
    CClientDC clientDC(this);
	wglMakeCurrent(clientDC.m_hDC, m_hRC);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 7.0);
	glViewport(0, 0, cx, cy);
	wglMakeCurrent(NULL, NULL);

}


/********************************************************************/
/* Set up the palette for OpenGL display DC                        	*/
/********************************************************************/
void CGlprintView::SetPalette(void)
{
	PIXELFORMATDESCRIPTOR pfd;  // Pixel Format Descriptor         
	LOGPALETTE *pPal;			// Pointer to memory for logical palette
	int PixelFormat;			// Pixel format index
    int paletteSize;            // Number of entries in palette 
	BYTE RedMask;               // Range for each color entry (7,7,and 3)
	BYTE GreenMask;
	BYTE BlueMask;
    HDC hDC = GetDC()->GetSafeHdc();  //the context device 								

	// Get the pixel format index and retrieve the pixel format description
    PixelFormat = GetPixelFormat(hDC);
    DescribePixelFormat(hDC, PixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
    
	
	// Check whether the pixel format and the pixel type
	if (!(pfd.dwFlags & PFD_NEED_PALETTE ||
	  pfd.iPixelType == PFD_TYPE_COLORINDEX))
	    return;

	// Get the number of entries in palette. 256 colors for 8 bits 
    paletteSize = 1 << pfd.cColorBits;
    
	// Allocate for the logical palette
	pPal = (LOGPALETTE*)
	malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
    
	
	// Fill the logical palette header information 
	pPal->palVersion = 0x300;            //support Windows3.0
    pPal->palNumEntries = paletteSize;   //number of colors entries

    // Set the 1st entries of logical palette with the current system palette 
    (void) GetSystemPaletteEntries(hDC, 0, paletteSize, &pPal->palPalEntry[0]);

	//Set the RGB mask
	RedMask = (1 << pfd.cRedBits) - 1;
	GreenMask = (1 << pfd.cGreenBits) - 1;
	BlueMask = (1 << pfd.cBlueBits) - 1;

	//Set all entries of the logical palette 
    for (int i=0; i<paletteSize; ++i) 
	{
	    pPal->palPalEntry[i].peRed =
		    (((i >> pfd.cRedShift) & RedMask) * 255) / RedMask;
	    pPal->palPalEntry[i].peGreen =
		    (((i >> pfd.cGreenShift) & GreenMask) * 255) / GreenMask;
	    pPal->palPalEntry[i].peBlue =
		    (((i >> pfd.cBlueShift) & BlueMask) * 255) / BlueMask;
	    pPal->palPalEntry[i].peFlags = 0;
    }

	//Create the palette
    m_Palette.CreatePalette(pPal);

	//Free the memory allocated for the logical palette 
    free(pPal);
}


/********************************************************************/
/* Initialize the light setting                                  	*/
/********************************************************************/
void CGlprintView::Initialize(void)
{
	float fv[4];
	
	fv[0] = 0.3f;
	fv[1] = 0.3f;
	fv[2] = 0.3f;
	fv[3] = 1.0f;
	glLightfv(GL_LIGHT0, GL_AMBIENT, fv);//set light ambient
	

	fv[0] = 0.1f;
	fv[1] = 0.1f;
	fv[2] = 0.1f;
	fv[3] = 1.0f;
	glLightfv(GL_LIGHT0, GL_DIFFUSE, fv);//set light specular

	fv[0] = 0.3f;
	fv[1] = 0.3f;
	fv[2] = 0.1f;
	fv[3] = 1.0f;
	glLightfv(GL_LIGHT0, GL_SPECULAR, fv);//set light specular
	
	fv[0] = 100.0f;
	fv[1] = 0.0f;
	fv[2] = 0.0f;
	fv[3] = 0.0f;
	glLightfv(GL_LIGHT0, GL_POSITION, fv);//set light position

	glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
}


/********************************************************************/
/* Display the OpenGL object                                     	*/
/********************************************************************/
void CGlprintView::DrawObject(void)
{
	float fv[4];
	float shine;

	glShadeModel(GL_SMOOTH);
	glEnable(GL_DEPTH_TEST);
	
	//clear color buffer
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

	glPushMatrix();

	shine = 0.3f;
	glMaterialf(GL_FRONT, GL_SHININESS, shine);//set specular

	fv[0] = 0.4f;
	fv[1] = 0.4f;
	fv[2] = 0.4f;
	fv[3] = 0.1f;
	glMaterialfv(GL_FRONT, GL_SPECULAR, fv);//set specular
	glMaterialfv(GL_FRONT, GL_EMISSION, fv);//set specular
	
//draw the wireframe sphere	
	fv[0] = 0.0f;
	fv[1] = 0.0f;
	fv[2] = 0.4f;
	fv[3] = 1.0f;
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, fv);//set material
	glTranslatef(0.0f, 0.0f, -6.0f);
    glRotated(45, 1.0, 0.0, 0.0);     
    glRotated(-30, 0.0, 1.0, 0.0);     
    glRotated(60, 0.0, 0.0, 1.0);     
    auxWireSphere(1.0);

//draw the solid cylinder	
	fv[0] = 0.1f;
	fv[1] = 0.4f;
	fv[2] = 0.1f;
	fv[3] = 10.0f;
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, fv);//set material
	glTranslatef(0.0f, 0.5f, 0.0f);
	auxSolidCylinder(0.1, 3.0);
	glTranslatef(0.0f, -0.5f, 0.0f);

//draw the solid arrow	
	fv[0] = 0.9f;
	fv[1] = 0.1f;
	fv[2] = 0.1f;
	fv[3] = 10.2f;
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, fv);//set material
	glTranslatef(0.0f, 1.5f, 0.0f);
    glRotated(-90, 1.0, 0.0, 0.0);     
    auxSolidCone(0.4, 0.8);
    glRotated(90, 1.0, 0.0, 0.0);     
	glTranslatef(0.0f, -1.5f, 0.0f);

    glRotated(-60, 0.0, 0.0, 1.0);     
    glRotated(30, 0.0, 1.0, 0.0);     
    glRotated(-45, 1.0, 0.0, 0.0);     
	glTranslatef(0.0f, 0.0f, 6.0f);
   
	glPopMatrix();

	glFlush();

}


/********************************************************************/
/* Save current OpenGL image to DIB file                                     	*/
/********************************************************************/
void CGlprintView::OnFileSave() 
{
	// TODO: Add your command handler code here
	//Set up file dialog setting
	char FileString[] = "DIB File(*.bmp)\0*.bmp\0\0";

	CFileDialog dlg(FALSE,NULL,NULL,OFN_CREATEPROMPT|OFN_OVERWRITEPROMPT,NULL,NULL);
	dlg.m_ofn.lpstrFilter = (LPSTR)FileString;
    dlg.m_ofn.lpstrTitle = "Save DIB File";
	if(dlg.DoModal()==IDOK)
	{
		//Get file name
		CString filename = dlg.GetFileTitle();
		filename += ".";
		CString fileext;
		fileext = dlg.GetFileExt(); 
		if(fileext.IsEmpty())
			filename += "bmp";
		else
			filename += fileext;
		
		//Write image data to disk file
		CFile file;
		CFileException fileexc;
		file.Open(filename,CFile::modeCreate|CFile::modeWrite,&fileexc);
		m_MemImageDC.WriteDataToDIBfile(&file);			
		file.Close();
	}
	
}

/********************************************************************/
/* Save current OpenGL image to DIB file                                     	*/
/********************************************************************/
void CGlprintView::OnFileSaveAs() 
{
	// TODO: Add your command handler code here
	OnFileSave();
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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

Share

About the Author

Zhaohui Xing
United States United States
No Biography provided

You may also be interested in...

Pro
Pro
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160811.3 | Last Updated 23 Nov 1999
Article Copyright 1999 by Zhaohui Xing
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid