www.pudn.com > Screensaver.rar > ChildView.cpp


// ChildView.cpp : implementation of the CChildView class 
// 
 
#include "stdafx.h" 
#include "SnowWorld.h" 
#include "ChildView.h" 
#include "MainFrm.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
GLfloat LightAmbient  [] = { 0.5f, 0.5f, 0.5f, 1.0f }; 
GLfloat LightDiffuse  [] = { 1.0f, 1.0f, 1.0f, 1.0f }; 
GLfloat LightPosition [] = { 0.0f, 0.0f, 2.0f, 1.0f }; 
 
///////////////////////////////////////////////////////////////////////////// 
// CChildView 
 
CChildView::CChildView() 
{ 
	m_pClientDC = NULL; 
	m_lpThread  = NULL; 
 
	m_nFloorIndex = 0; 
} 
 
CChildView::~CChildView() 
{ 
	if ( m_lpThread != NULL ) 
	{ 
		delete m_lpThread; 
		m_lpThread = NULL; 
	} 
} 
 
 
BEGIN_MESSAGE_MAP(CChildView,CWnd ) 
	//{{AFX_MSG_MAP(CChildView) 
	ON_WM_CREATE() 
	ON_WM_SIZE() 
	ON_WM_ERASEBKGND() 
	ON_WM_PAINT() 
	ON_WM_TIMER() 
	ON_WM_DESTROY() 
	ON_WM_LBUTTONDBLCLK() 
	ON_WM_KEYDOWN() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CChildView message handlers 
 
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)  
{ 
	if ( ! CWnd::PreCreateWindow( cs ) ) 
		return FALSE; 
 
	cs.dwExStyle |= WS_EX_CLIENTEDGE; 
	cs.style &= ~WS_BORDER; 
	cs.lpszClass = AfxRegisterWndClass( CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,  
		::LoadCursor( NULL, IDC_ARROW ), HBRUSH( COLOR_WINDOW + 1 ), NULL ); 
 
	return TRUE; 
} 
 
BOOL CChildView::PreTranslateMessage( MSG* pMsg ) 
{ 
	if ( pMsg->message == WM_KEYDOWN && ( pMsg->wParam == VK_RETURN || pMsg->wParam == VK_SPACE ) ) 
	{ 
		if ( ++m_nFloorIndex >= 3 ) 
			m_nFloorIndex = 0; 
	} 
 
	return CWnd::PreTranslateMessage( pMsg ); 
} 
 
int CChildView::OnCreate( LPCREATESTRUCT lpCreateStruct ) 
{ 
	if ( CWnd::OnCreate( lpCreateStruct ) == -1 ) 
	{ 
		TRACE0( "Failed to create the CChildView" ); 
		return -1; 
	} 
 
	m_lpThread = AfxBeginThread( Thread, NULL, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED ); 
	ASSERT( m_lpThread ); 
 
	InitOpenGL(); 
 
	SetTimer( 1, 50, NULL ); 
 
	m_lpThread->ResumeThread(); 
	return 0; 
} 
 
void CChildView::OnSize( UINT nType, int cx, int cy ) 
{ 
	CWnd::OnSize( nType, cx, cy ); 
 
	if ( cy == 0 ) 
		cy = 1; 
 
	glViewport( 0, 0, cx, cy );		// Reset The Current View-port 
	glMatrixMode( GL_PROJECTION );	// Select The Projection Matrix 
	glLoadIdentity();				// Reset The Projection Matrix		 
 
	// Calculate The Aspect Ratio Of The Window 
	gluPerspective( 45.0f, ( GLfloat ) cx / ( GLfloat ) cy, 0.1f, 400.0f ); 
	glMatrixMode( GL_MODELVIEW );	// Select The Model-view Matrix 
	glLoadIdentity();		 
} 
 
void CChildView::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
	CBitmap bitmap; 
	bitmap.LoadBitmap( IDB_SNOW_FLOOR ); 
 
	// TODO: Add your message handler code here 
	DrawOpenGLScene(); 
	// Do not call CWnd::OnPaint() for painting messages 
} 
 
BOOL CChildView::OnEraseBkgnd( CDC* pDC ) 
{ 
	UNREFERENCED_PARAMETER( pDC ); 
 
	return TRUE; 
} 
 
void CChildView::OnDestroy() 
{ 
	HGLRC hrc = NULL; 
	hrc = ::wglGetCurrentContext(); 
 
	::wglMakeCurrent( NULL, NULL ); 
	if ( hrc != NULL ) 
		::wglDeleteContext( hrc ); 
 
	if ( m_pClientDC != NULL ) 
	{ 
		delete m_pClientDC; 
		m_pClientDC = NULL; 
	} 
	ASSERT( m_pClientDC == NULL ); 
 
	CWnd::OnDestroy(); 
} 
 
// Initialize the OpenGL context device... 
 
VOID CChildView::InitOpenGL() 
{ 
	m_pClientDC = new CClientDC( this ); 
	ASSERT( m_pClientDC != NULL ); 
	ASSERT_VALID( m_pClientDC ); 
 
	if ( ! SetupPixelFormat() ) 
		return; 
 
	PIXELFORMATDESCRIPTOR pfd; 
 
	int n = ::GetPixelFormat( m_pClientDC->GetSafeHdc()); 
	::DescribePixelFormat( m_pClientDC->GetSafeHdc(), n, sizeof( pfd ), & pfd ); 
 
	HGLRC hrc = NULL; 
	hrc = wglCreateContext( m_pClientDC->GetSafeHdc() ); 
	ASSERT( hrc ); 
	wglMakeCurrent( m_pClientDC->GetSafeHdc(), hrc ); 
 
	if ( ! LoadOpenGLTextures() ) 
		return; 
 
	glEnable( GL_TEXTURE_2D ); 
	glShadeModel( GL_SMOOTH );				// Enable Smooth Shading 
	glClearColor( 0.5f, 0.5f, 0.5f, 0.5f );	// Black Background 
	glClearDepth( 1.0f );					// Depth Buffer Setup 
 
	glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );	// Really Nice Perspective Calculations 
 
	glLightfv( GL_LIGHT1, GL_AMBIENT,  LightAmbient  ); 
	glLightfv( GL_LIGHT1, GL_DIFFUSE,  LightDiffuse  ); 
	glLightfv( GL_LIGHT1, GL_POSITION, LightPosition ); 
	glEnable( GL_LIGHT1 ); 
	 
	glBlendFunc( GL_SRC_ALPHA,GL_ONE );		// Set The Blending Function For Translucency 
	glEnable( GL_BLEND );	 
} 
 
// Load the texture from the define file path 
 
BOOL CChildView::LoadOpenGLTextures() 
{ 
	glGenTextures( E_TEXTURECOUNT, & m_textureSnow[ 0 ] ); 
	LoadImageFromResID( IDB_SNOW_LARGE,  m_textureSnow[ 0 ] ); 
	LoadImageFromResID( IDB_SNOW_MIDDLE, m_textureSnow[ 1 ] ); 
	LoadImageFromResID( IDB_SNOW_SMALL,  m_textureSnow[ 2 ] ); 
 
	InitSnow(); 
 
	LoadImageFromResID( IDB_SNOW_MIDDLE, m_textureSnow[ 3 ] ); 
 
	return TRUE; 
} 
 
VOID CChildView::SetDefaultTextureParams() 
{ 
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); 
}  
 
BOOL CChildView::SetupPixelFormat() 
{ 
	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 = 0; 
 
	ASSERT( m_pClientDC != NULL ); 
	if ( ( pixelformat = ChoosePixelFormat( m_pClientDC->GetSafeHdc(), & pfd ) ) == 0 ) 
	{ 
		AfxMessageBox( _T( "ChoosePixelFormat failed" ) ); 
		return FALSE; 
	} 
 
	if ( SetPixelFormat( m_pClientDC->GetSafeHdc(), pixelformat, & pfd ) == FALSE ) 
	{ 
		AfxMessageBox( _T( "SetPixelFormat failed" ) ); 
		return FALSE; 
	} 
 
	return TRUE; 
} 
 
VOID CChildView::DrawOpenGLScene() 
{ 
	static GLfloat wAngleY = 10.0f; 
 
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 
 
	glLoadIdentity(); 
	glTranslatef( 0.0f, -30.0f, -150.0f ); 
	glRotatef( wAngleY, 0.0f, 1.0f, 0.0f ); 
 
	glBindTexture( GL_TEXTURE_2D, m_textureSnow[ m_nFloorIndex ] ); 
 
	glColor4f( 1.0f, 1.0f, 1.0f, 0.5 ); 
 
	glBegin( GL_QUADS ); 
		glNormal3f( 0.0f, 1.0f, 0.0f ); 
		glTexCoord2f( 0.0f, 0.0f ); glVertex3f(  100.0f, 0.0f, -100.0f ); 
		glTexCoord2f( 1.0f, 0.0f ); glVertex3f(  100.0f, 0.0f,  100.0f ); 
		glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -100.0f, 0.0f,  100.0f ); 
		glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -100.0f, 0.0f, -100.0f ); 
	glEnd(); 
 
	for ( int nIndex = 0; nIndex < E_SNOWCOUNT; nIndex++ ) 
	{ 
		glLoadIdentity(); 
		glTranslatef( 0.0f, -30.0f, -150.0f );  
		glRotatef( wAngleY, 0.0f, 1.0f, 0.0f ); 
 
		glBindTexture( GL_TEXTURE_2D, m_textureSnow[ m_snow[ nIndex ].nIndexTexture ] ); 
		glTranslatef( m_snow[ nIndex ].x, m_snow[ nIndex ].y, m_snow[ nIndex ].z ); 
 
		glRotatef( m_snow[ nIndex ].xrot, 1.0f, 0.0f, 0.0f ); 
		glRotatef( m_snow[ nIndex ].yrot, 0.0f, 1.0f, 0.0f ); 
		glRotatef( m_snow[ nIndex ].zrot, 0.0f, 0.0f, 1.0f ); 
 
		glBegin( GL_QUADS ); 
			glNormal3f( 0.0f, 1.0f, 0.0f ); 
			glTexCoord2f( 0.0f, 0.0f ); glVertex3f(  1.0f, 0.0f, -1.0f ); 
			glTexCoord2f( 1.0f, 0.0f ); glVertex3f(  1.0f, 0.0f,  1.0f ); 
			glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -1.0f, 0.0f,  1.0f ); 
			glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.0f, 0.0f, -1.0f ); 
		glEnd(); 
 
		m_snow[ nIndex ].y -= m_snow[ nIndex ].dropSpeed; 
		if( m_snow[ nIndex ].y < -33 ) 
			m_snow[ nIndex ].y = 125.0f; 
 
		m_snow[ nIndex ].xrot += m_snow[ nIndex ].rotSpeed; 
		m_snow[ nIndex ].yrot += m_snow[ nIndex ].rotSpeed; 
		m_snow[ nIndex ].zrot += m_snow[ nIndex ].rotSpeed; 
	} 
 
	wAngleY += 0.2f; 
 
	glFinish(); 
	SwapBuffers( wglGetCurrentDC() ); 
} 
 
BOOL CChildView::LoadImageFromResID( UINT nResID, GLuint& texture ) 
{ 
	ASSERT( nResID > 0 ); 
 
	HBITMAP hBitmap = ( HBITMAP ) LoadImage( \ 
									AfxGetInstanceHandle(), \ 
									MAKEINTRESOURCE( nResID ), \ 
									IMAGE_BITMAP, \ 
									0, 0, \ 
									LR_CREATEDIBSECTION ); 
	ASSERT( hBitmap != NULL ); 
 
	DIBSECTION ds; 
	GetObject( hBitmap, sizeof( DIBSECTION ), ( LPVOID ) & ds ); 
 
	glBindTexture( GL_TEXTURE_2D, texture ); 
	SetDefaultTextureParams(); 
 
	glTexImage2D( GL_TEXTURE_2D, 0, 3, ds.dsBm.bmWidth, ds.dsBm.bmHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, ds.dsBm.bmBits ); 
	DeleteObject( hBitmap ); 
 
	return TRUE; 
} 
 
void CChildView::OnTimer( UINT nIDEvent ) 
{ 
	DrawOpenGLScene(); 
 
	CWnd::OnTimer( nIDEvent ); 
 
	// Eat spurious WM_TIMER message 
	MSG msg; 
	while( ::PeekMessage( & msg, m_hWnd, WM_TIMER, WM_TIMER, PM_REMOVE ) ) 
		; 
} 
 
VOID CChildView::InitSnow() 
{ 
	srand( GetTickCount() ); 
 
	for ( int nIndex = 0; nIndex < E_SNOWCOUNT; nIndex++ ) 
	{ 
		m_snow[ nIndex ].nIndexTexture = rand() % 3; 
 
		m_snow[ nIndex ].x = GLfloat( rand() % 200 - 100 ); 
		m_snow[ nIndex ].y = GLfloat( rand() % 200 - 100 ); 
		m_snow[ nIndex ].z = 100.0f + GLfloat( rand() % 25 ); 
	} 
 
	for ( int i = 0; i < E_SNOWCOUNT; i++ ) 
	{ 
		m_snow[ i ].nIndexTexture = rand() % 3; 
		m_snow[ i ].x             = GLfloat( rand() % 200 - 100 ); 
		m_snow[ i ].z             = GLfloat( rand() % 200 - 100 ); 
		m_snow[ i ].y             = 100.0f + GLfloat( rand() % 25 ); 
 
		m_snow[ i ].xrot          = 0; 
		m_snow[ i ].yrot          = 0; 
		m_snow[ i ].zrot          = 0; 
 
		m_snow[ i ].dropSpeed     = 0.01f * ( rand() % 50 + 2 ); 
		m_snow[ i ].rotSpeed      =  0.1f * ( rand() % 10 + 2 ); 
	} 
} 
 
// The thread which will play the music 
//  for the scene... 
 
UINT CChildView::Thread( LPVOID lParam ) 
{ 
	UNREFERENCED_PARAMETER( lParam ); 
 
	for ( ; ; ) 
	{ 
		HRSRC hResInfo = FindResource( AfxGetInstanceHandle(), MAKEINTRESOURCE( IDR_MUSIC_SNOW ), "WAVE" ); 
		ASSERT( hResInfo ); 
		HRSRC hRes = ( HRSRC ) LoadResource( AfxGetInstanceHandle(), hResInfo ); 
		ASSERT( hRes ); 
		LPSTR lpRes = ( LPSTR ) LockResource(hRes); 
        sndPlaySound(lpRes, SND_MEMORY | SND_SYNC | SND_NODEFAULT );  
		FreeResource( hRes );  
	} 
 
	return 0; 
} 
void CChildView::OnLButtonDblClk(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	CMainFrame* pmainFrm=(CMainFrame*)AfxGetApp()->m_pMainWnd; 
	if(!pmainFrm->m_bFullScreen)pmainFrm->FullScreen(); 
	else pmainFrm->EndFullScreen(); 
	CWnd ::OnLButtonDblClk(nFlags, point); 
} 
 
 
void CChildView::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 ,便可退出全屏显示状态 
		if(pFrame->m_bFullScreen)pFrame->EndFullScreen(); 
	} 
	CWnd ::OnKeyDown(nChar, nRepCnt, nFlags); 
}