www.pudn.com > WaterWaveInOpengl.rar > MyOpenGLFrameView.cpp


// MyOpenGLFrameView.cpp : implementation of the CMyOpenGLFrameView class 
// 
 
#include "stdafx.h" 
#include "MyOpenGLFrame.h" 
 
#include "MyOpenGLFrameDoc.h" 
#include "MyOpenGLFrameView.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
CClientDC   *m_pDC; 
CMyOpenGLFrameDoc *m_pDoc; 
//定义调色板的值down 
unsigned char threeto8[8] = 
{ 
	0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377 
}; 
 
unsigned char twoto8[4] = 
{ 
	0, 0x55, 0xaa, 0xff 
}; 
 
unsigned char oneto8[2] = 
{ 
	0, 255 
}; 
 
static int defaultOverride[13] = 
{ 
	0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91 
}; 
 
static PALETTEENTRY defaultPalEntry[20] = 
{ 
	{ 0,   0,   0,    0 }, 
	{ 0x80,0,   0,    0 }, 
	{ 0,   0x80,0,    0 }, 
	{ 0x80,0x80,0,    0 }, 
	{ 0,   0,   0x80, 0 }, 
	{ 0x80,0,   0x80, 0 }, 
	{ 0,   0x80,0x80, 0 }, 
	{ 0xC0,0xC0,0xC0, 0 }, 
	 
	{ 192, 220, 192,  0 }, 
	{ 166, 202, 240,  0 }, 
	{ 255, 251, 240,  0 }, 
	{ 160, 160, 164,  0 }, 
	 
	{ 0x80,0x80,0x80, 0 }, 
	{ 0xFF,0,   0,    0 }, 
	{ 0,   0xFF,0,    0 }, 
	{ 0xFF,0xFF,0,    0 }, 
	{ 0,   0,   0xFF, 0 }, 
	{ 0xFF,0,   0xFF, 0 }, 
	{ 0,   0xFF,0xFF, 0 }, 
	{ 0xFF,0xFF,0xFF, 0 } 
}; 
//定义调色板的值up 
///////////////////////////////////////////////////////////////////////////// 
// CMyOpenGLFrameView 
 
IMPLEMENT_DYNCREATE(CMyOpenGLFrameView, CView) 
 
BEGIN_MESSAGE_MAP(CMyOpenGLFrameView, CView) 
	//{{AFX_MSG_MAP(CMyOpenGLFrameView) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_ERASEBKGND() 
	ON_WM_SIZE() 
	ON_WM_TIMER() 
	ON_WM_KEYDOWN() 
	ON_WM_LBUTTONDOWN() 
	//}}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() 
 
///////////////////////////////////////////////////////////////////////////// 
// CMyOpenGLFrameView construction/destruction 
 
CMyOpenGLFrameView::CMyOpenGLFrameView() 
{ 
	// TODO: add construction code here 
	//add down 
	m_pDC = NULL; 
	m_pOldPalette = NULL; 
	 
	rtri=0;					// 用于三角形的角度 ( 新增 ) 
	rquad=0;					// 用于四边形的角度 ( 新增 ) 
	//add up 
	m_bFullView=FALSE; 
	m_pDoc=NULL; 
} 
 
CMyOpenGLFrameView::~CMyOpenGLFrameView() 
{ 
} 
 
BOOL CMyOpenGLFrameView::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); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMyOpenGLFrameView drawing 
//add down 
void CMyOpenGLFrameView::Init() 
{ 
	PIXELFORMATDESCRIPTOR pfd; 
	int         n; 
	HGLRC       hrc; 
	GLfloat     fMaxObjSize, fAspect; 
	GLfloat     fNearPlane, fFarPlane; 
 
	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); 
 
	CreateRGBPalette(); 
 
	hrc = wglCreateContext(m_pDC->GetSafeHdc()); 
	wglMakeCurrent(m_pDC->GetSafeHdc(), hrc); 
 
	GetClientRect(&m_oldRect); 
	glClearDepth(1.0f); 
	glEnable(GL_DEPTH_TEST); 
 
	//定义初始化时的投影方式 
	if (m_oldRect.bottom) 
		fAspect = (GLfloat)m_oldRect.right/m_oldRect.bottom; 
	else    // don't divide by zero, not that we should ever run into that... 
		fAspect = 1.0f; 
	fNearPlane = 3.0f; 
	fFarPlane = 7.0f; 
	fMaxObjSize = 3.0f; 
	m_fRadius = fNearPlane + fMaxObjSize / 2.0f; 
 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	gluPerspective(45.0f, fAspect, fNearPlane, fFarPlane); 
	glMatrixMode(GL_MODELVIEW); 
} 
 
BOOL CMyOpenGLFrameView::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; 
} 
 
unsigned char CMyOpenGLFrameView::ComponentFromIndex(int i, UINT nbits, UINT shift) 
{ 
	unsigned char val; 
 
	val = (unsigned char) (i >> shift); 
	switch (nbits) 
	{ 
 
	case 1: 
		val &= 0x1; 
		return oneto8[val]; 
	case 2: 
		val &= 0x3; 
		return twoto8[val]; 
	case 3: 
		val &= 0x7; 
		return threeto8[val]; 
 
	default: 
		return 0; 
	} 
} 
 
//创建调色板 
void CMyOpenGLFrameView::CreateRGBPalette() 
{ 
	PIXELFORMATDESCRIPTOR pfd; 
	LOGPALETTE *pPal; 
	int n, i; 
 
	n = ::GetPixelFormat(m_pDC->GetSafeHdc()); 
	::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd); 
 
	if (pfd.dwFlags & PFD_NEED_PALETTE) 
	{ 
		n = 1 << pfd.cColorBits; 
		pPal = (PLOGPALETTE) new char[sizeof(LOGPALETTE) + n * sizeof(PALETTEENTRY)]; 
 
		ASSERT(pPal != NULL); 
 
		pPal->palVersion = 0x300; 
		pPal->palNumEntries = n; 
		for (i=0; ipalPalEntry[i].peRed = 
					ComponentFromIndex(i, pfd.cRedBits, pfd.cRedShift); 
			pPal->palPalEntry[i].peGreen = 
					ComponentFromIndex(i, pfd.cGreenBits, pfd.cGreenShift); 
			pPal->palPalEntry[i].peBlue = 
					ComponentFromIndex(i, pfd.cBlueBits, pfd.cBlueShift); 
			pPal->palPalEntry[i].peFlags = 0; 
		} 
 
		/* fix up the palette to include the default GDI palette */ 
		if ((pfd.cColorBits == 8)                           && 
			(pfd.cRedBits   == 3) && (pfd.cRedShift   == 0) && 
			(pfd.cGreenBits == 3) && (pfd.cGreenShift == 3) && 
			(pfd.cBlueBits  == 2) && (pfd.cBlueShift  == 6) 
		   ) 
		{ 
			for (i = 1 ; i <= 12 ; i++) 
				pPal->palPalEntry[defaultOverride[i]] = defaultPalEntry[i]; 
		} 
 
		m_cPalette.CreatePalette(pPal); 
		delete pPal; 
 
		m_pOldPalette = m_pDC->SelectPalette(&m_cPalette, FALSE); 
		m_pDC->RealizePalette(); 
	} 
} 
 
void CMyOpenGLFrameView::DrawScene(void) 
{ 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// 清除屏幕和深度缓存 
	glLoadIdentity();									// 重置当前的模型观察矩阵 
	glTranslatef(-1.5f,0.0f,-6.0f);						// 左移1.5单位,并移入屏幕6.0 
	glRotatef(rtri,0.0f,1.0f,0.0f);						// 绕Y轴旋转三角形 ( 新增 ) 
 
	glBegin(GL_TRIANGLES);								// 绘制三角形 
		glColor3f(1.0f,0.0f,0.0f);						// 红色 
		glVertex3f( 0.0f, 1.0f, 0.0f);					// 三角形的上顶点 (前侧面) 
		glColor3f(0.0f,1.0f,0.0f);						// 绿色 
		glVertex3f(-1.0f,-1.0f, 1.0f);					//三角形的左下顶点 (前侧面) 
		glColor3f(0.0f,0.0f,1.0f);						// 蓝色 
		glVertex3f( 1.0f,-1.0f, 1.0f);					// 三角形的右下顶点 (前侧面) 
 
		glColor3f(1.0f,0.0f,0.0f);					// 红色 
		glVertex3f( 0.0f, 1.0f, 0.0f);				// 三角形的上顶点 (后侧面) 
		glColor3f(0.0f,1.0f,0.0f);					// 绿色 
		glVertex3f( 1.0f,-1.0f, -1.0f);				// 三角形的左下顶点 (后侧面) 
		glColor3f(0.0f,0.0f,1.0f);					// 蓝色 
		glVertex3f(-1.0f,-1.0f, -1.0f);				// 三角形的右下顶点 (后侧面) 
 
		glColor3f(1.0f,0.0f,0.0f);				// 红色 
		glVertex3f( 0.0f, 1.0f, 0.0f);			// 三角形的上顶点 (左侧面) 
		glColor3f(0.0f,0.0f,1.0f);				// 蓝色 
		glVertex3f(-1.0f,-1.0f,-1.0f);			// 三角形的左下顶点 (左侧面) 
		glColor3f(0.0f,1.0f,0.0f);				// 绿色 
		glVertex3f(-1.0f,-1.0f, 1.0f);			// 三角形的右下顶点 (左侧面) 
 
		glColor3f(1.0f,0.0f,0.0f);				// 红色 
		glVertex3f( 0.0f, 1.0f, 0.0f);			// 三角形的上顶点 (右侧面) 
		glColor3f(0.0f,0.0f,1.0f);				// 蓝色 
		glVertex3f( 1.0f,-1.0f, 1.0f);			// 三角形的左下顶点 (右侧面) 
		glColor3f(0.0f,1.0f,0.0f);				// 绿色 
		glVertex3f( 1.0f,-1.0f, -1.0f);			// 三角形的右下顶点 (右侧面) 
 
	glEnd();											// 三角形绘制结束 
 
 
	glLoadIdentity();									// 重置模型观察矩阵 
	glTranslatef(1.5f,0.0f,-6.0f);						// 右移1.5单位,并移入屏幕 6.0 
	glRotatef(rquad,1.0f,0.0f,0.0f);					// 绕X轴旋转四边形 ( 新增 ) 
	glColor3f(0.5f,0.5f,1.0f);							// 一次性将当前色设置为蓝色 
 
	glBegin(GL_QUADS);									// 绘制正方形 
 
		glColor3f(0.0f,1.0f,0.0f);			// 颜色改为蓝色 
		glVertex3f( 1.0f, 1.0f,-1.0f);		// 四边形的右上顶点 (顶面) 
		glVertex3f(-1.0f, 1.0f,-1.0f);		// 四边形的左上顶点 (顶面) 
		glVertex3f(-1.0f, 1.0f, 1.0f);		// 四边形的左下顶点 (顶面) 
		glVertex3f( 1.0f, 1.0f, 1.0f);		// 四边形的右下顶点 (顶面 
 
		glColor3f(1.0f,0.5f,0.0f);			// 颜色改成橙色 
		glVertex3f( 1.0f,-1.0f, 1.0f);		// 四边形的右上顶点(底面) 
		glVertex3f(-1.0f,-1.0f, 1.0f);		// 四边形的左上顶点(底面) 
		glVertex3f(-1.0f,-1.0f,-1.0f);		// 四边形的左下顶点(底面) 
		glVertex3f( 1.0f,-1.0f,-1.0f);		// 四边形的右下顶点(底面) 
 
		glColor3f(1.0f,0.0f,0.0f);			// 颜色改成红色 
		glVertex3f( 1.0f, 1.0f, 1.0f);		// 四边形的右上顶点(前面) 
		glVertex3f(-1.0f, 1.0f, 1.0f);		// 四边形的左上顶点(前面) 
		glVertex3f(-1.0f,-1.0f, 1.0f);		// 四边形的左下顶点(前面) 
		glVertex3f( 1.0f,-1.0f, 1.0f);		// 四边形的右下顶点(前面) 
 
		glColor3f(1.0f,1.0f,0.0f);			// 颜色改成黄色 
		glVertex3f( 1.0f,-1.0f,-1.0f);		// 四边形的右上顶点(后面) 
		glVertex3f(-1.0f,-1.0f,-1.0f);		// 四边形的左上顶点(后面) 
		glVertex3f(-1.0f, 1.0f,-1.0f);		// 四边形的左下顶点(后面) 
		glVertex3f( 1.0f, 1.0f,-1.0f);		// 四边形的右下顶点(后面) 
 
		glColor3f(0.0f,0.0f,1.0f);			// 颜色改成蓝色 
		glVertex3f(-1.0f, 1.0f, 1.0f);		// 四边形的右上顶点(左面) 
		glVertex3f(-1.0f, 1.0f,-1.0f);		// 四边形的左上顶点(左面) 
		glVertex3f(-1.0f,-1.0f,-1.0f);		// 四边形的左下顶点(左面) 
		glVertex3f(-1.0f,-1.0f, 1.0f);		// 四边形的右下顶点(左面) 
 
		glColor3f(1.0f,0.0f,1.0f);			// 颜色改成紫罗兰色 
		glVertex3f( 1.0f, 1.0f,-1.0f);		// 四边形的右上顶点(右面) 
		glVertex3f( 1.0f, 1.0f, 1.0f);		// 四边形的左上顶点(右面) 
		glVertex3f( 1.0f,-1.0f, 1.0f);		// 四边形的左下顶点(右面) 
		glVertex3f( 1.0f,-1.0f,-1.0f);		// 四边形的右下顶点(右面) 
 
	glEnd();											// 正方形绘制结束 
 
		rtri+=0.5f;										// 增加三角形的旋转变量(新增) 
		rquad-=0.5f;									// 减少四边形的旋转变量(新增) 
 
 
	//	glFinish(); 
    glFlush(); 
	//利用双缓存的机制,实现动画 
	SwapBuffers(wglGetCurrentDC()); 
 
	//bBusy = FALSE; 
 
} 
 
void CMyOpenGLFrameView::OnDraw(CDC* pDC) 
{ 
	CMyOpenGLFrameDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	// TODO: add draw code for native data here 
	DrawScene(); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMyOpenGLFrameView printing 
 
BOOL CMyOpenGLFrameView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CMyOpenGLFrameView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CMyOpenGLFrameView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMyOpenGLFrameView diagnostics 
 
#ifdef _DEBUG 
void CMyOpenGLFrameView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CMyOpenGLFrameView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CMyOpenGLFrameDoc* CMyOpenGLFrameView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyOpenGLFrameDoc))); 
	return (CMyOpenGLFrameDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CMyOpenGLFrameView message handlers 
 
int CMyOpenGLFrameView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
	//add down 
	Init(); //初始化 OpenGL 
	//add up 
 
	SetTimer(1,20,NULL); 
	return 0; 
} 
 
void CMyOpenGLFrameView::OnDestroy()  
{ 
 
	 
	// TODO: Add your message handler code here 
	//add down 
	HGLRC   hrc; 
	 
    KillTimer(1); 
	 
	hrc = ::wglGetCurrentContext(); 
	 
	::wglMakeCurrent(NULL,  NULL); 
	 
	if (hrc) 
		::wglDeleteContext(hrc); 
	 
	if (m_pOldPalette) 
		m_pDC->SelectPalette(m_pOldPalette, FALSE); 
	 
	if (m_pDC) 
		delete m_pDC; 
	//add up 
	CView::OnDestroy(); 
} 
 
BOOL CMyOpenGLFrameView::OnEraseBkgnd(CDC* pDC)  
{ 
	// TODO: Add your message handler code here and/or call default 
	 
	return TRUE; 
} 
 
void CMyOpenGLFrameView::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	 
	// TODO: Add your message handler code here 
	//add down 
	if(cy > 0) 
	{ 
		glViewport(0, 0, cx, cy); 
		 
		if((m_oldRect.right > cx) || (m_oldRect.bottom > cy)) 
			RedrawWindow(); 
		 
		m_oldRect.right = cx; 
		m_oldRect.bottom = cy; 
		 
		glMatrixMode(GL_PROJECTION); 
		glLoadIdentity(); 
		//定义投影方式为透视图 
		gluPerspective(45.0f, (GLdouble)cx/cy, 3.0f, 7.0f); 
		glMatrixMode(GL_MODELVIEW); 
	} 
	//add up	 
} 
 
void CMyOpenGLFrameView::OnTimer(UINT nIDEvent)  
{ 
	// TODO: Add your message handler code here and/or call default 
	Invalidate(FALSE); 
 
	CView::OnTimer(nIDEvent); 
} 
 
void CMyOpenGLFrameView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	// TODO: Add your message handler code here and/or call default 
	if(nChar==VK_ESCAPE)   //如果按的键为Esc键 
	{                    //获取主框架窗口的指针 
		CMainFrame *pFrame=(CMainFrame *)AfxGetApp()->m_pMainWnd; 
		//调用主窗口类的自定义函数 EndFullScreen ,便可退出全屏显示状态 
		pFrame->EndFullScreen(); 
		m_bFullView=FALSE; 
	} 
	if(nChar==VK_F1)   //如果按的键为F1键 
	{                    //获取主框架窗口的指针 
		m_bFullView=!m_bFullView; 
		CMainFrame *pFrame=(CMainFrame *)AfxGetApp()->m_pMainWnd; 
		//调用主窗口类的自定义函数 EndFullScreen ,便可退出全屏显示状态 
		if (m_bFullView)  
		{ 
			pFrame->StartFullScreen(); 
		} 
		else 
		{ 
			pFrame->EndFullScreen(); 
		} 
		 
	} 
	 
	CView::OnKeyDown(nChar, nRepCnt, nFlags); 
} 
 
void CMyOpenGLFrameView::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	 
	CView::OnLButtonDown(nFlags, point); 
}