www.pudn.com > OPENGL-source-code.rar > 2DFontView.cpp


// 2DFontView.cpp : implementation of the CMy2DFontView class 
// 
 
#include "stdafx.h" 
#include "2DFont.h" 
 
#include "2DFontDoc.h" 
#include "2DFontView.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CMy2DFontView 
 
IMPLEMENT_DYNCREATE(CMy2DFontView, CView) 
 
BEGIN_MESSAGE_MAP(CMy2DFontView, CView) 
	//{{AFX_MSG_MAP(CMy2DFontView) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_ERASEBKGND() 
	ON_WM_SIZE() 
	//}}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() 
 
///////////////////////////////////////////////////////////////////////////// 
// CMy2DFontView construction/destruction 
 
CMy2DFontView::CMy2DFontView() 
{ 
	//add down 
	m_pDC = NULL; 
	m_DefaultFlatTextID=0; 
	//add up 
} 
 
CMy2DFontView::~CMy2DFontView() 
{ 
} 
 
BOOL CMy2DFontView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
	//add down 
	cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; 
	//add up 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMy2DFontView drawing 
 
void CMy2DFontView::OnDraw(CDC* pDC) 
{ 
	CMy2DFontDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	// TODO: add draw code for native data here 
	//add down 
	DrawScene(); 
	//add up 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMy2DFontView printing 
 
BOOL CMy2DFontView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CMy2DFontView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CMy2DFontView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMy2DFontView diagnostics 
 
#ifdef _DEBUG 
void CMy2DFontView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CMy2DFontView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CMy2DFontDoc* CMy2DFontView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy2DFontDoc))); 
	return (CMy2DFontDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CMy2DFontView message handlers 
 
 
int CMy2DFontView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	//add down 
	Init(); // ³õʼ»¯OpenGL 
	//add up 
	 
	return 0; 
} 
 
void CMy2DFontView::OnDestroy()  
{ 
	CView::OnDestroy(); 
	 
	//add down 
	HGLRC   hrc; 
 
	hrc = ::wglGetCurrentContext(); 
 
	::wglMakeCurrent(NULL,  NULL); 
 
	if (hrc) 
		::wglDeleteContext(hrc); 
 
	if (m_pDC) 
		delete m_pDC; 
	//add up	 
} 
 
BOOL CMy2DFontView::OnEraseBkgnd(CDC* pDC)  
{ 
	return TRUE; 
} 
 
void CMy2DFontView::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	 
	//add down 
	int w=cx; int h=cy; 
	GLfloat nRange=10.0f; 
 
	if(h==0) h=1; 
 
	glViewport(0,0,w,h); 
 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
 
	if(w<=h) 
		glOrtho(-nRange,nRange,-nRange*h/w,nRange*h/w,-nRange,nRange); 
	else 
		glOrtho(-nRange*w/h,nRange*w/h,-nRange,nRange,-nRange,nRange); 
	glMatrixMode(GL_MODELVIEW); 
	glLoadIdentity(); 
	//add up	 
} 
 
//add down 
void CMy2DFontView::Init() 
{ 
	PIXELFORMATDESCRIPTOR pfd; 
	int         n; 
	HGLRC       hrc; 
 
	m_pDC = new CClientDC(this); 
 
	ASSERT(m_pDC != NULL); 
 
	if (!bSetupPixelFormat()) 
		return; 
 
	n = ::GetPixelFormat(m_pDC->GetSafeHdc()); 
	::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd); 
 
	hrc = wglCreateContext(m_pDC->GetSafeHdc()); 
	wglMakeCurrent(m_pDC->GetSafeHdc(), hrc); 
 
	SetDefaultFonts(); 
 
	glClearDepth(1.0f); 
	glEnable(GL_DEPTH_TEST); 
 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	glMatrixMode(GL_MODELVIEW); 
} 
 
BOOL CMy2DFontView::bSetupPixelFormat() 
{ 
	static PIXELFORMATDESCRIPTOR pfd = 
	{ 
		sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd 
		1,                              // version number 
		PFD_DRAW_TO_WINDOW |            // support window 
		  PFD_SUPPORT_OPENGL |          // support OpenGL 
		  PFD_DOUBLEBUFFER,             // double buffered 
		PFD_TYPE_RGBA,                  // RGBA type 
		24,                             // 24-bit color depth 
		0, 0, 0, 0, 0, 0,               // color bits ignored 
		0,                              // no alpha buffer 
		0,                              // shift bit ignored 
		0,                              // no accumulation buffer 
		0, 0, 0, 0,                     // accum bits ignored 
		32,                             // 32-bit z-buffer 
		0,                              // no stencil buffer 
		0,                              // no auxiliary buffer 
		PFD_MAIN_PLANE,                 // main layer 
		0,                              // reserved 
		0, 0, 0                         // layer masks ignored 
	}; 
	int pixelformat; 
 
	if ( (pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0 ) 
	{ 
		MessageBox("ChoosePixelFormat failed"); 
		return FALSE; 
	} 
 
	if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE) 
	{ 
		MessageBox("SetPixelFormat failed"); 
		return FALSE; 
	} 
 
	return TRUE; 
} 
 
void CMy2DFontView::DrawScene() 
{ 
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
 
	//ÔÚÆÁÄ»ÉÏд×Ö·ûadd down 
	glColor3f(1.0f, 0.0f, 0.0f); 
	float text_x=-8.0; float text_y=0.0; float text_z=0.0; 
	CString text; 
	::glRasterPos3f(text_x,text_y,text_z); 
	GLTextOut( m_DefaultFlatTextID,"Welcome to the OpenGL world!"); 
	//ÔÚÆÁÄ»ÉÏд×Ö·ûadd up 
 
	glFinish(); 
	SwapBuffers(wglGetCurrentDC()); 
 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// GenerateDefaultFonts 
// Generate the default 3D and flat text disp;ay lists 
void CMy2DFontView::GenerateDefaultFonts( char* font3D, char* fontFlat ) 
{ 
   m_DefaultFlatTextID	= GenerateBitmapListForFont( fontFlat ); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// GLTextOut 
// Output text (either Bitmap or Outline) 
void CMy2DFontView::GLTextOut( GLuint id, const char * const textstring ) 
{ 
	if ( 0 == id || 0 == textstring ) 
		{ 
		return; 
		} 
 
	GLsizei size = strlen( textstring ); 
 
	::glListBase( id ); 
	::glCallLists( size, GL_UNSIGNED_BYTE, (const GLvoid*)textstring );  
 
}  
///////////////////////////////////////////////////////////////////////////// 
// GenerateBitmapListForFont 
// The routines used for generating flat text 
GLuint CMy2DFontView::GenerateBitmapListForFont( char* fontname ) 
{ 
	GLuint id; 
 
	if ( 0 == m_pDC || 
		 (GLuint)0 == (id = GetNewDisplayListIDs(256)) ) 
		{ 
        return 0; 
		} 
 
	CFont newfont; 
	CFont* oldfont; 
	BOOL success; 
 
	if ( NULL != fontname ) 
		{ 
 
		LOGFONT     logfont; 
	 
		logfont.lfHeight		= -30; 
		logfont.lfWidth			= 0; 
		logfont.lfEscapement	= 0; 
		logfont.lfOrientation	= logfont.lfEscapement; 
		logfont.lfWeight		= FW_NORMAL; 
		logfont.lfItalic		= FALSE; 
		logfont.lfUnderline		= FALSE; 
		logfont.lfStrikeOut		= FALSE; 
		logfont.lfCharSet		= ANSI_CHARSET; 
		logfont.lfOutPrecision	= OUT_DEFAULT_PRECIS; 
		logfont.lfClipPrecision	= CLIP_DEFAULT_PRECIS; 
		logfont.lfQuality		= DEFAULT_QUALITY; 
		logfont.lfPitchAndFamily = FF_DONTCARE|DEFAULT_PITCH; 
		lstrcpy ( logfont.lfFaceName, fontname ); 
 
		// returns 0 if it fails 
		success = newfont.CreateFontIndirect( &logfont ); 
		oldfont =	m_pDC->SelectObject( &newfont ); 
		ASSERT( 0 != oldfont ); 
		} 
	else 
		{ 
		// make the system font the device context's selected font 
		oldfont =	(CFont*)m_pDC->SelectStockObject( SYSTEM_FONT ); 
		ASSERT( 0 != oldfont ); 
		} 
	 
    // Create a set of display lists based on the glyphs of the font  
	// notice that we really waste the first 32 spaces.... 
	// if there's a problem delete the display lists 
   if (	0 == success || 
		FALSE == ::wglUseFontBitmaps( m_pDC->m_hDC, 0, 256, id ) ) 
		{ 
		::glDeleteLists( id, 256 ); 
		id  = 0; 
		} 
   else 
		{ 
		m_pDC->SelectObject( oldfont ); 
		} 
 
   return id; 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// GetNewDisplayListIDs 
// This is just a nice wrapper for the glGenLists() function. 
GLuint CMy2DFontView::GetNewDisplayListIDs( GLsizei range ) 
{ 
	ASSERT( 0 < range ); 
 
	return ::glGenLists( range ); 
} 
 
//add up