www.pudn.com > renliandesanweichongjian.rar > OpenGL.cpp


// OpenGL.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "Face.h" 
#include "OpenGL.h" 
#include  
#include  
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
extern CFaceApp theApp; 
///////////////////////////////////////////////////////////////////////////// 
// COpenGL 
 
COpenGL::COpenGL():m_bInit(FALSE),m_bFullScreen(FALSE), 
		m_hDC(NULL),m_hRC(NULL),m_parent(NULL) 
{ 
} 
 
COpenGL::~COpenGL() 
{ 
	KillGLWindow();	// Shutdown 
} 
 
 
BEGIN_MESSAGE_MAP(COpenGL, CWnd) 
	//{{AFX_MSG_MAP(COpenGL) 
	ON_WM_CREATE() 
	ON_WM_PAINT() 
	ON_WM_SIZE() 
	ON_WM_KEYDOWN() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// COpenGL message handlers 
 
void COpenGL::Create(CRect rect, CWnd *parent) 
{ 
	if (m_bInit) return; 
	ASSERT(rect); 
	ASSERT(parent); 
	m_rect = rect; 
	m_parent = parent; 
 
	CString className = AfxRegisterWndClass( 
		CS_HREDRAW | CS_VREDRAW | CS_OWNDC, 
		NULL, 
		(HBRUSH)GetStockObject(BLACK_BRUSH), 
		NULL); 
	 
	CreateEx( 
		0, 
		className, 
		"OpenGL", 
		WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 
		rect, 
		parent, 
		0); 
} 
 
int COpenGL::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CWnd::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &m_DMsaved); 
 
 
	GLuint	PixelFormat;												// Holds The Results After Searching For A Match 
	static	PIXELFORMATDESCRIPTOR pfd=									// pfd Tells Windows How We Want Things To Be 
	{																		 
		sizeof(PIXELFORMATDESCRIPTOR),									// Size Of This Pixel Format Descriptor 
			1,																// Version Number 
			PFD_DRAW_TO_WINDOW |											// Format Must Support Window 
			PFD_SUPPORT_OPENGL |											// Format Must Support OpenGL 
			PFD_DOUBLEBUFFER,												// Must Support Double Buffering 
			PFD_TYPE_RGBA,													// Request An RGBA Format 
			m_DMsaved.dmBitsPerPel,												// Select Our 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,														// Accumulation Bits Ignored 
			16,																// 16Bit Z-Buffer (Depth Buffer)   
			0,																// No Stencil Buffer 
			0,																// No Auxiliary Buffer 
			PFD_MAIN_PLANE,													// Main Drawing Layer 
			0,																// Reserved 
			0, 0, 0															// Layer Masks Ignored 
	};																		 
	 
	 
	if ( !( m_hDC = ::GetDC ( m_hWnd ) ) )	{							// Did We Get A Device Context?																	 
		KillGLWindow ();													// Reset The Display 
		TRACE ( "Can't Create A GL Device Context." ); 
		return FALSE;												 
	} 
	 
	if ( !( PixelFormat = ChoosePixelFormat ( m_hDC, &pfd ) ) )	{		// Did Windows Find A Matching Pixel Format?																		 
		KillGLWindow ();												// Reset The Display 
		TRACE ( "Can't Find A Suitable PixelFormat." ); 
		return FALSE;												 
	} 
	 
	if ( !SetPixelFormat ( m_hDC, PixelFormat, &pfd ) ){				// Are We Able To Set The Pixel Format?																		 
		KillGLWindow ();												// Reset The Display 
		TRACE ( "Can't Set The PixelFormat." ); 
		return FALSE;												 
	} 
	 
	if ( !( m_hRC = wglCreateContext ( m_hDC ) ) ) {					// Are We Able To Get A Rendering Context?																	 
		KillGLWindow ();												// Reset The Display 
		TRACE( " Can't Create A GL Rendering Context." ); 
		return FALSE;													 
	} 
	 
	if ( !wglMakeCurrent ( m_hDC, m_hRC ) )	{							// Try To Activate The Rendering Context																		 
		KillGLWindow ();												// Reset The Display 
		TRACE ( "Can't Activate The GL Rendering Context." ); 
		return FALSE;													 
	} 
	 
	if ( !InitGL () ) {													// Initialize Our Newly Created GL Window																		 
		KillGLWindow ();												// Reset The Display 
		TRACE ( "Initialization Failed." ); 
		return FALSE;													 
	} 
	m_bInit = TRUE; 
	 
	return 0; 
} 
 
void COpenGL::KillGLWindow() 
{ 
	if (m_bFullScreen)															// Are We In Fullscreen Mode? 
	{ 
		if (!ChangeDisplaySettings(NULL,CDS_TEST)) {						// if the shortcut doesn't work 
			ChangeDisplaySettings(NULL,CDS_RESET);							// Do it anyway (to get the values out of the registry) 
			ChangeDisplaySettings(&m_DMsaved,CDS_RESET);						// change it to the saved settings 
		} else { 
			ChangeDisplaySettings(NULL,CDS_RESET); 
		} 
		 
		ShowCursor(TRUE);													// Show Mouse Pointer 
	}																		 
	 
	if ( m_hRC ) {															// Do We Have A Rendering Context?																		 
		if ( !wglMakeCurrent ( NULL, NULL ) )	{							// Are We Able To Release The DC And RC Contexts? 
			TRACE ( "Release Of DC And RC Failed." ); 
		} 
		 
		if ( !wglDeleteContext ( m_hRC ) ) {								// Are We Able To Delete The RC? 
			TRACE ( "Release Rendering Context Failed." ); 
		} 
		m_hRC = NULL;														// Set RC To NULL 
	} 
	 
	if ( m_hDC && !::ReleaseDC ( m_hWnd, m_hDC ) ) {						// Are We Able To Release The DC 
		TRACE ( "Release Device Context Failed." ); 
		m_hDC = NULL;														// Set DC To NULL 
	} 
	 
	if ( m_hWnd && !::DestroyWindow ( m_hWnd ) )	{							// Are We Able To Destroy The Window? 
		TRACE( "Could Not Release m_hWnd." ); 
		m_hWnd = NULL;														// Set m_hWnd To NULL 
	} 
} 
 
int COpenGL::InitGL() 
{ 
	glShadeModel(GL_SMOOTH);												// Enable Smooth Shading 
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);									// Black Background 
	glClearDepth(1.0f);														// Depth Buffer Setup 
	glEnable(GL_DEPTH_TEST);												// Enables Depth Testing 
	glDepthFunc(GL_LEQUAL);													// The Type Of Depth Testing To Do 
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);						// Really Nice Perspective Calculations 
	glEnable(GL_TEXTURE_2D);												// Enable Texture Mapping 
	float x, y, z; 
	int loop; 
	FILE *filein; 
	char oneline[255]; 
 
	//ÖØÖ÷¾¶ lkliang 051104 
	CString strpath; 
	strpath  = theApp.strPathInit+"//"; 
	strpath += "data/candide.txt"; 
	filein = fopen(strpath, "rt");				// File To Load World Data From 
 
	readstr(filein,oneline); 
	sscanf(oneline, "VERTEXLIST %d\n", &numtriangles); 
 
	 
	for (loop = 0; loop < numtriangles; loop++) 
	{ 
 
			readstr(filein,oneline); 
			sscanf(oneline, "%f %f %f", &x, &y, &z); 
			vertex[loop][0]=x; 
			vertex[loop][1]=y; 
			vertex[loop][2]=z; 
	} 
 
	readstr(filein,oneline); 
	sscanf(oneline, "FACELIST %d\n", &numface); 
	for (loop = 0; loop < numface; loop++) 
	{ 
		readstr(filein,oneline); 
		sscanf(oneline, "%f %f %f", &x, &y, &z); 
			face[loop][0]=x; 
			face[loop][1]=y; 
			face[loop][2]=z; 
	} 
 
	fclose(filein); 
	return TRUE;															// Initialization Went OK	 
} 
 
void COpenGL::RenderGLScene() 
{ 
	if(!m_bInit) return; 
 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			// Clear Screen And Depth Buffer 
	glLoadIdentity(); 
	 
	 
	// EXAMPLE OPENGL CODE START //////////////////////////////////////////////////////// 
	////////////////////////////////////////////////////////////////////////////// 
	static GLfloat	xrot;													// X Rotation  
	static GLfloat	yrot;													// Y Rotation  
	static GLfloat	zrot;													// Z Rotation  
	 
	glPushMatrix();															// Push Matrix Onto Stack (Copy The Current Matrix) 
	glLoadIdentity();													// Reset The Current Modelview Matrix 
	glTranslatef(0.0f,0.0f,-6.0f);										// Move Left 1.5 Units And Into The Screen 6.0 
	 
	glRotatef(xrot,1.0f,0.0f,0.0f); 
	glRotatef(yrot,0.0f,1.0f,0.0f); 
	glRotatef(zrot,0.0f,0.0f,1.0f); 
	 
/*	glBegin(GL_QUADS); 
	// Front Face 
	glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f,  1.0f); 
	glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, -1.0f,  1.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); 
	// Back Face 
	glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, -1.0f); 
	glColor3f(0.0f,1.0f,0.0f);glVertex3f(-1.0f,  1.0f, -1.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); 
	// Top Face 
	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(0.0f,1.0f,0.0f);glVertex3f( 1.0f,  1.0f,  1.0f); 
	glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f,  1.0f, -1.0f); 
	// Bottom Face 
	glColor3f(1.0f,0.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(0.0f,1.0f,0.0f);glVertex3f( 1.0f, -1.0f,  1.0f); 
	glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f,  1.0f); 
	// Right face 
	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(0.0f,1.0f,0.0f);glVertex3f( 1.0f,  1.0f,  1.0f); 
	glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, -1.0f,  1.0f); 
	// Left Face 
	glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, -1.0f); 
	glColor3f(1.0f,0.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(0.0f,1.0f,0.0f);glVertex3f(-1.0f,  1.0f, -1.0f); 
				 
	glEnd();*/ 
	for (int loop=0; loop < numface; loop++)  
	{ 
		glBegin(GL_TRIANGLES);								// Drawing Using Triangles 
		    glVertex3f(vertex[face[loop][0]][0],vertex[face[loop][0]][1],vertex[face[loop][0]][2]);					// Top 
		    glVertex3f(vertex[face[loop][1]][0],vertex[face[loop][1]][1],vertex[face[loop][1]][2]);					// Bottom Left 
		    glVertex3f(vertex[face[loop][2]][0],vertex[face[loop][2]][1],vertex[face[loop][2]][2]);					// Bottom Right 
	    glEnd(); 
	} 
	glPopMatrix();														// Pop Matrix Off The Stack 
	 
	xrot+=1.3f; 
	yrot+=1.2f; 
	zrot+=1.4f;																// Decrease The Rotation Variable For The Quad 
	////////////////////////////////////////////////////////////////////////////// 
	// EXAMPLE OPENGL CODE END ////////////////////////////////////////////////////////// 
	 
	// Swap our scene to the front 
	 
	SwapBuffers(m_hDC); 
	 
	Invalidate(FALSE); 
} 
 
void COpenGL::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
	 
	// TODO: Add your message handler code here 
	::ValidateRect ( m_hWnd, NULL ); 
	 
	// Do not call CWnd::OnPaint() for painting messages 
} 
 
 
void COpenGL::OnSize(UINT nType, int cx, int cy)  
{ 
	CWnd::OnSize(nType, cx, cy); 
	 
	// TODO: Add your message handler code here 
	if ( cy==0) {														// Prevent A Divide By Zero By																	 
		cy=1;															// Making Height Equal One 
	}																		 
	 
	glViewport(0,0,cx,cy);											// Reset The Current Viewport 
	 
	glMatrixMode(GL_PROJECTION);											// Select The Projection Matrix 
	glLoadIdentity();														// Reset The Projection Matrix 
	 
	gluPerspective(45.0f,(GLfloat)cx/(GLfloat)cy,0.1f,100.0f);		// Calculate The Aspect Ratio Of The Window 
	 
	glMatrixMode(GL_MODELVIEW);												// Select The Modelview Matrix 
	glLoadIdentity();														// Reset The Modelview Matrix	 
	 
} 
 
BOOL COpenGL::SetFullScreen(int width, int height, int depth) 
{ 
	if(!m_bInit) return FALSE; 
	if (m_bFullScreen) return TRUE; 
	 
	DEVMODE dmScreenSettings;												// Device Mode 
	memset(&dmScreenSettings,0,sizeof(dmScreenSettings));					// Makes Sure Memory's Cleared 
	dmScreenSettings.dmSize=sizeof(dmScreenSettings);						// Size Of The Devmode Structure 
	dmScreenSettings.dmPelsWidth	= width;								// Selected Screen Width 
	dmScreenSettings.dmPelsHeight	= height;							// Selected Screen Height 
	dmScreenSettings.dmBitsPerPel	= depth;								// Selected Bits Per Pixel 
	dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; 
	 
	// Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. 
	 
	if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) 
	{ 
		return m_bFullScreen = FALSE; 
	} 
 
	SetParent(NULL); 
	SetWindowPos(&CWnd::wndTop, 
		          0, 0,  
				  GetSystemMetrics(SM_CXSCREEN),  
				  GetSystemMetrics(SM_CYSCREEN),  
				  SWP_SHOWWINDOW); 
 
	ShowCursor(FALSE); 
	SetFocus(); 
	return m_bFullScreen = TRUE; 
} 
 
BOOL COpenGL::SetNormScreen() 
{ 
	if(!m_bInit) return FALSE; 
 
	if (m_bFullScreen)															// Are We In Fullscreen Mode? 
	{ 
		if (!ChangeDisplaySettings(NULL,CDS_TEST)) {						// if the shortcut doesn't work 
			ChangeDisplaySettings(NULL,CDS_RESET);							// Do it anyway (to get the values out of the registry) 
			ChangeDisplaySettings(&m_DMsaved,CDS_RESET);						// change it to the saved settings 
		} else { 
			ChangeDisplaySettings(NULL,CDS_RESET); 
		} 
		SetParent(m_parent); 
		SetWindowPos(&CWnd::wndTop, 
		          m_rect.left, m_rect.top,  
				  m_rect.Width(),  
				  m_rect.Height(),  
				  SWP_SHOWWINDOW);		 
		ShowCursor(TRUE);	// Show Mouse Pointer 
		m_bFullScreen = FALSE; 
	} 
	return TRUE; 
} 
void COpenGL::readstr(FILE *f,char *string) 
{ 
	do 
	{ 
		fgets(string, 255, f); 
	} while ((string[0] == '/') || (string[0] == '\n')); 
	return; 
}