www.pudn.com > roam.rar > ROAMView.cpp


// ROAMView.cpp : implementation of the CROAMView class 
// 
 
#include "stdafx.h" 
#include "ROAM.h" 
 
#include "ROAMDoc.h" 
#include "ROAMView.h" 
#include "math.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
#define PI 3.1415926 
GLfloat LightAmbient[]=		{ 0.0f, 0.0f, 0.9f, 1.0f };//设置光源参数 
GLfloat LightDiffuse[]=		{ 1.0f,0.0f, 0.0f, 1.0f }; 
GLfloat LightPosition[]=	{ 1000.0f, 600.0f, 1000.0f, 1.0f }; 
GLuint	texture;			// Storage For 6 Textures (MODIFIED) 
 
///////////////////////////////////////////////////////////////////////////// 
// CROAMView 
 
IMPLEMENT_DYNCREATE(CROAMView, CView) 
 
BEGIN_MESSAGE_MAP(CROAMView, CView) 
	//{{AFX_MSG_MAP(CROAMView) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_ERASEBKGND() 
	ON_WM_SIZE() 
	ON_WM_KEYDOWN() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CROAMView construction/destruction 
 
CROAMView::CROAMView() 
{ 
	roamTerrain = new CRoamTerrain; 
	 
	m_pDC = NULL; 
	m_Angle = 180.0; 
	 
	//眼睛初始位置 
	eyePos[0] = 500; 
	eyePos[1] = 512; 
	eyePos[2] = 800; 
	 
	//参考点初始位置 
	double rad =  3.141592653*m_Angle/180.0; 
	cenPos[0] = float(eyePos[0] + 10*cos(rad)); 
	cenPos[1] = float(eyePos[1] + 10*sin(rad)); 
	//cenPos[0] = 250; 
	//cenPos[1] = 50; 
	cenPos[2] = 50;  
	 
	deltaX = 1; 
	deltaY = 1; 
} 
 
CROAMView::~CROAMView() 
{ 
} 
 
BOOL CROAMView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CROAMView drawing 
 
void CROAMView::OnDraw(CDC* pDC) 
{ 
	CROAMDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	DrawScene(); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CROAMView diagnostics 
 
#ifdef _DEBUG 
void CROAMView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CROAMView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CROAMDoc* CROAMView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CROAMDoc))); 
	return (CROAMDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CROAMView message handlers 
 
int CROAMView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
	Init(); 
	return 0; 
} 
 
void CROAMView::OnDestroy()  
{ 
	CView::OnDestroy(); 
	 
	HGLRC	hrc; 
	hrc = ::wglGetCurrentContext(); 
	::wglMakeCurrent(NULL,  NULL); 
    if (hrc) 
        ::wglDeleteContext(hrc); 
	if (m_pDC) 
        delete m_pDC;		 
} 
 
BOOL CROAMView::OnEraseBkgnd(CDC* pDC)  
{ 
	return TRUE; 
} 
 
void CROAMView::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	 
	GLint w = cx; 
	GLint h = cy; 
	if( h == 0 ) h=1; 
	glViewport(0,0,w,h); 
 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	if(w > h) 
		gluPerspective (60, (float)w/(float)h, 10.0, 1000000.0); 
	else 
		gluPerspective (60, (float)h/(float)w, 10.0, 1000000.0); 
	glMatrixMode(GL_MODELVIEW);	 
} 
 
BOOL CROAMView::bSetupPixelFormat() 
{ 
	static PIXELFORMATDESCRIPTOR pfd =  
	{ 
        sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd 
			1,                              // version number 
			PFD_DRAW_TO_WINDOW |            // support window 
			PFD_SUPPORT_OPENGL| 
			PFD_DOUBLEBUFFER,             // double buffered,			// support OpenGL 
			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 CROAMView::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); 
	 
	if (!LoadGLTextures())	//载入纹理			 
	{ 
		return ;								 
	} 
	 
    glClearDepth(1000000.0f); 
	glDepthFunc(GL_LEQUAL);								// 深度检测类型 
	glEnable(GL_DEPTH_TEST); 
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// 透视优化 
	 
	glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);		// 环境光 
	glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);		// 散射光 
	glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);	// 光源位置 
	glEnable(GL_LIGHT1);// 激活光源 
     
	glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE); 
    glEnable(GL_COLOR_MATERIAL); 
	 
	glEnable(GL_AUTO_NORMAL); 
    glEnable(GL_NORMALIZE); 
} 
 
AUX_RGBImageRec* CROAMView::LoadBMP(char *Filename) 
{ 
	FILE *File=NULL;									// File Handle 
	 
	if (!Filename)										// 如果不存在 
	{ 
		return NULL;									//  
	} 
	File=fopen(Filename,"r");							// 判断文件是否存在 
	if (File)											// Does The File Exist? 
	{ 
		fclose(File);									// 关闭 
		return auxDIBImageLoad(Filename);				// 载入图像文件并返回一个指针 
	} 
	return NULL;	 
} 
 
 
int CROAMView::LoadGLTextures() 
{ 
	int Status=FALSE;									// 表示纹理图像载入状态 
	//	memset(TextureImage,0,sizeof(void *));           	// 设置空指针 
	 
	// 载入位图 
	if (TextureImage=LoadBMP(_T("back1.bmp")) ) 
	{ 
		Status=TRUE;									// 设置Status为TRUE 
		glGenTextures(6, &texture);	// 创建三个纹理 
		// 创建最近的纹理 
		glBindTexture(GL_TEXTURE_2D, texture);	// 生成两个纹理 
		gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage->sizeX, TextureImage->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage->data); 
	} 
	 
	if (TextureImage)					// 如果图像存在 
	{ 
		if (TextureImage->data)			// 如果图像存在 
		{ 
			free(TextureImage->data);	// 释放纹理图像内存 
		} 
		free(TextureImage);				// 释放纹理结构 
	} 
	return Status;	 
} 
 
void CROAMView::DrawTerrain() 
{ 
	roamTerrain->RoamDrawScene(eyePos[0],eyePos[1]); 
} 
 
void CROAMView::DrawScene() 
{ 
	glClearColor(0.6f, 0.6f, 0.6f, 1.0f); 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
	//glMatrixMode(GL_MODELVIEW); 
	//glLoadIdentity(); 
	 
    glMatrixMode(GL_PROJECTION);  
    glPushMatrix();  
    glLoadIdentity();  
    glOrtho(0, 1, 0, 1, 0, 1);  
    glMatrixMode(GL_MODELVIEW);  
    glPushMatrix();  
    glLoadIdentity();  
    glDepthMask(0);  
	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
	 
    // 设置贴图  
    glBindTexture(GL_TEXTURE_2D, texture );  
    // 绘制背景  
	glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 ); 
	glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 
	glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); 
	glTexEnvf ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL ); 
	glEnable ( GL_TEXTURE_2D ); 
    glBegin(GL_QUADS);  
    glTexCoord2i(0, 0); glVertex2i(0, 0);  
    glTexCoord2i(1, 0); glVertex2i(1, 0);  
    glTexCoord2i(1, 1); glVertex2i(1, 1);  
    glTexCoord2i(0, 1); glVertex2i(0, 1);  
    glEnd();  
	glDisable(GL_TEXTURE_2D); 
	 
    // 恢复3D视角  
    glDepthMask(1);  
    glPopMatrix();  
    glMatrixMode(GL_PROJECTION);  
    glPopMatrix();  
	 
    glMatrixMode(GL_MODELVIEW);  
	glLoadIdentity(); 
 
 
	gluLookAt(eyePos[0],eyePos[1],eyePos[2],cenPos[0],cenPos[1],cenPos[2],0,0,1); 
	//	glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
	glEdgeFlag(TRUE); 
	 
	DrawTerrain(); 
	glFinish(); 
	SwapBuffers(wglGetCurrentDC()); 
} 
 
void CROAMView::KeyCtrlRoam(UINT lrKey, UINT lrValue, UINT udKey, UINT udValue) 
{ 
	float speed = 5.0f; 
//	float PI=3.14159f; 
	if(lrKey == VK_LEFT) 
	{ 
		m_Angle -= 5.0*lrValue; 
	} 
	if(lrKey == VK_RIGHT) 
	{ 
		m_Angle += 5.0*lrValue; 
	} 
	float rad =  float(PI*m_Angle/180.0f); 
	if(udKey == VK_UP) 
	{ 
		eyePos[0] +=(float)cos(rad)*speed*udValue; 
		eyePos[1] +=(float)sin(rad)*speed*udValue; 
	} 
	if(udKey == VK_DOWN) 
	{ 
		eyePos[0] -=(float)cos(rad)*speed*udValue; 
		eyePos[1] -=(float)sin(rad)*speed*udValue; 
	} 
	// 观察点 
	cenPos[0] = float(eyePos[0] + 10*cos(rad)); 
	cenPos[1] = float(eyePos[1] + 10*sin(rad)); 
	Invalidate(FALSE); 
} 
 
void CROAMView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	KeyCtrlRoam(nChar,1,nChar,1);//调用漫游函数 
}