www.pudn.com > MY_LOD.rar > MY_LODView.cpp


// MY_LODView.cpp : implementation of the CMY_LODView class 
// 
 
#include "stdafx.h" 
#include "MY_LOD.h" 
 
#include "MY_LODDoc.h" 
#include "MY_LODView.h" 
 
#include "math.h" 
#include "BMPLoad.h" 
#include "Lod.h" 
#include "LandTex.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
int *y;  //保存地形高程数组 
COLOUR *color_map; //保存地形的颜色值 
CLandTex lt; 
int quadtree[QUAD_MAP*QUAD_MAP]; 
int location[3]; 
int lod_lever=8; 
///////////////////////////////////////////////////////////////////////////// 
// CMY_LODView 
 
IMPLEMENT_DYNCREATE(CMY_LODView, CView) 
 
BEGIN_MESSAGE_MAP(CMY_LODView, CView) 
	//{{AFX_MSG_MAP(CMY_LODView) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_SIZE() 
	ON_WM_TIMER() 
	ON_WM_ERASEBKGND() 
	//}}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() 
 
///////////////////////////////////////////////////////////////////////////// 
// CMY_LODView construction/destruction 
 
CMY_LODView::CMY_LODView() 
{ 
	// TODO: add construction code here 
	speed = 0.0; // 移动速度初始化 
	timer = 0.0; wTimer = 0.0; 
	flying_mode = 1; 
} 
 
CMY_LODView::~CMY_LODView() 
{ 
} 
 
BOOL CMY_LODView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
	//////////////////////////////////////////////////////////////// 
	//设置窗口类型 
	cs.style |=WS_CLIPCHILDREN | WS_CLIPSIBLINGS; 
	//////////////////////////////////////////////////////////////// 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMY_LODView drawing 
 
void CMY_LODView::OnDraw(CDC* pDC) 
{ 
	CMY_LODDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	// TODO: add draw code for native data here 
	RenderScene();	//渲染场景 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMY_LODView printing 
 
BOOL CMY_LODView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CMY_LODView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CMY_LODView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMY_LODView diagnostics 
 
#ifdef _DEBUG 
void CMY_LODView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CMY_LODView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CMY_LODDoc* CMY_LODView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMY_LODDoc))); 
	return (CMY_LODDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CMY_LODView message handlers 
 
int CMY_LODView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
	//初始化OpenGL和设置定时器 
	m_pDC=new CClientDC(this); 
	SetTimer(1,20,NULL); 
	InitializeOpenGL(m_pDC); 
	 
	Init(); 
	return 0; 
} 
 
void CMY_LODView::OnDestroy()  
{                   
	CView::OnDestroy(); 
	 
	// TODO: Add your message handler code here 
	//删除调色板和渲染上下文、定时器 
	::wglMakeCurrent(0,0); 
	::wglDeleteContext(m_hRC); 
	if (m_hPalette)  
		DeleteObject(m_hPalette); 
	if (m_pDC) 
		delete m_pDC; 
	KillTimer(1); 
	delete[] y; 
	delete[] color_map; 
	//##调用删除m_Bmpload 
} 
 
void CMY_LODView::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	 
	// TODO: Add your message handler code here 
	//添加窗口缩放时的图形变换函数 
	glViewport(0,0,cx,cy); 
	winWidth=cx; 
	winHeight=cy; 
} 
 
void CMY_LODView::OnTimer(UINT nIDEvent)  
{ 
	// TODO: Add your 0+message handler code here and/or call default 
	Invalidate(false); 
	update_world(); 
	CView::OnTimer(nIDEvent); 
} 
 
BOOL CMY_LODView::OnEraseBkgnd(CDC* pDC)  
{ 
	// TODO: Add your message handler code here and/or call default 
	 
	return 1;//CView::OnEraseBkgnd(pDC); 
} 
 
BOOL CMY_LODView::InitializeOpenGL(CDC *pDC) 
{ 
	pDC=m_pDC; 
	//设置像素格式 
	PIXELFORMATDESCRIPTOR pfd={ 
		sizeof(PIXELFORMATDESCRIPTOR),   //pfd结构的大小 
		1,                               //版本号 
		PFD_DRAW_TO_WINDOW|              //支持在窗口中绘图 
		PFD_SUPPORT_OPENGL|              //支持 OpenGL 
		PFD_DOUBLEBUFFER,                //双缓存模式 
		PFD_TYPE_RGBA,                   //RGBA颜色模式 
		24,                              //24位颜色深度 
		0,0,0,0,0,0,                     //忽略颜色位 
		0,                               //没有非透明度缓存 
		0,                               //忽略移动位 
		0,                               //无累加缓存 
		0,0,0,0,                         //忽略累加位 
		32,                              //32位深度缓存 
		0,                               //无模板缓存 
		0,                               //无辅助缓存 
		PFD_MAIN_PLANE,                  //主层 
		0,                               //保留 
		0,0,0                            //忽略层,可见性和损毁掩模 	 
	}; 
	int pixelformat; 
	pixelformat=::ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd);//选择像素格式 
	::SetPixelFormat(m_pDC->GetSafeHdc(),pixelformat,&pfd);   //设置像素格式 
	//设置调色板 
	if (pfd.dwFlags & PFD_NEED_PALETTE) { 
		struct  { 
			WORD Version; 
			WORD NumberOfEntries; 
			PALETTEENTRY aEntries[256]; 
		} logicalpalette = {0x300,256}; 
		 
		byte reds[]={0, 36, 72, 109, 145, 182, 218, 255}; 
		byte greens[]={0, 36, 72, 109, 145, 182, 218, 255}; 
		byte blues[]={0, 85, 170, 255}; 
 
		for (int colourNum=0;colourNum<256;colourNum++) { 
			logicalpalette.aEntries[colourNum].peRed= 
				reds[colourNum & 0x07]; 
			logicalpalette.aEntries[colourNum].peGreen= 
				greens[(colourNum >> 0x03) & 0x07]; 
			logicalpalette.aEntries[colourNum].peBlue= 
				blues[(colourNum >> 0x06) & 0x03]; 
			logicalpalette.aEntries[colourNum].peFlags=0; 
		} 
 
		m_hPalette=CreatePalette ((LOGPALETTE *) &logicalpalette); 
	} 
	 
	m_hRC=::wglCreateContext(m_pDC->GetSafeHdc()); //生成绘制描述表 
	::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC);   //置当前绘制描述表 
	return true; 
} 
 
void CMY_LODView::Init() 
{ 
	GLfloat fogColor[]={0.12,0.27,0.7,1.0}; 
	GLfloat lightDiffuse[]={1.0,0.75,0.5,1.0}; 
	 
	glClearColor(0.12,0.27,0.7,1.0); 
//	glClearColor(1,1,1,1); 
	for (int i=0;i<256;i++) { 
		sin_t[i]=sin((i/128.0)*PI); 
		cos_t[i]=cos((i/128.0)*PI); 
	} 
 
	initTerrain();  // 初始化地形数据 
	 
	xpos=0*COMP;//118 
	ypos=10.0; 
	zpos=0*COMP;//125 
 
	lookx=120.0*COMP; 
	looky=0.0*COMP; 
	lookz=120.0*COMP; 
 
	speed=50; 
 
	update_world(); 
 
	glFogi(GL_FOG_MODE,GL_LINEAR); 
	glFogfv(GL_FOG_COLOR,fogColor); 
	glFogf(GL_FOG_DENSITY,1); 
	glFogf(GL_FOG_START,(M_SIZE/2)*0.1*COMP); 
	glFogf(GL_FOG_END,(M_SIZE/2)*0.5*COMP); 
 
	glGenTextures(100,texName); 
 
	srand(1111111); 
	randomTerrain(); 
	 
	srand((unsigned)time(NULL)); 
 
	glShadeModel(GL_SMOOTH); 
	m_Lod.m_bFlag=false; 
	move(ROTATE, 2.6, 0); 
	move(LOOKUP, -0.2, 0); 
} 
 
void CMY_LODView::initTerrain() 
{ 
	y=new int[M_SIZE*M_SIZE]; 
	color_map=new COLOUR[M_SIZE*M_SIZE]; 
} 
 
void CMY_LODView::update_world() 
{ 
	timer+=0.05; 
	wTimer+=0.0005; 
 
	if (wTimer>=1.0) { 
		wTimer=0.0; 
	} 
 
	move(FORWARD,speed,1); 
	 
} 
 
void CMY_LODView::move(int type, GLfloat amount, int update) 
{ 
	GLfloat lightposition[]={-1.0, 0.0, 0.2, 0.0}; 
	GLfloat a; 
	switch(type) { 
	case FORWARD: 
		location[0]=xpos/128; 
		location[2]=zpos/128; 
		xpos+=lookx*amount; 
		zpos+=lookz*amount; 
		break; 
	case ROTATE: 
		lookx=lookx*cos(amount)+lookz*sin(amount); 
		lookz=lookz*cos(amount)-lookx*sin(amount); 
		a=1/sqrt(lookx*lookx+lookz*lookz); 
		lookx*=a; 
		lookz*=a; 
		break; 
	case LOOKUP: 
		looky+=amount; 
	} 
 
	if (update) { 
		check_height(); 
		glMatrixMode(GL_MODELVIEW); 
		glLoadIdentity(); 
		 
		glLightfv(GL_LIGHT0,GL_POSITION,lightposition); 
	} 
} 
 
void CMY_LODView::check_height() 
{ 
	float x0, x1, lx, lz, x, z, midpoint; 
	int fx, fz; 
	 
	x = xpos/(COMP*1.0); 
	z = zpos/(COMP*1.0); 
	fx = (int)(x); 
	fz = (int)(z); 
	lx = x - fx; 
	lz = z - fz; 
	 
	x0 = y[IX(fx,fz)] + (y[IX(fx,fz+1)] - y[IX(fx,fz)])*lz; 
	x1 = y[IX(fx+1,fz)] + (y[IX(fx+1,fz+1)] - y[IX(fx+1,fz)])*lz; 
	midpoint = x0 + (x1 - x0)*lx; 
	 
	if(flying_mode	> 0) { 
		ypos = (midpoint * 8) + 1024.0f; 
	} 
	else { 
		ypos = (midpoint * 8) + 16.0f; 
	} 
	 
	if(x<0) 
		xpos = 0; 
	else if(x>(M_SIZE)) 
		xpos = ((M_SIZE) << SHIFT); 
	if(z<0) 
		zpos = 0; 
	else if(z>(M_SIZE)) 
		zpos = ((M_SIZE) << SHIFT);	 
} 
 
void CMY_LODView::randomTerrain() 
{ 
	int x,z; 
	int i,j; 
	int bsize,csize; 
	int rnd; 
	 
	for(i=0;i0) { 
		for (x=0;x255)  
				h=255; 
			else if (h<0)  
				h=0; 
 
			color_map[IX(x,z)].r=h; 
			color_map[IX(x,z)].g=h; 
			color_map[IX(x,z)].b=h; 
		} 
	} 
	lt.NEW_BITMAP(texName,y); 
} 
 
bool CMY_LODView::RenderScene() 
{ 
	int i; 
	int x, z; 
	int aX, aZ; 
	int r; 
	float v1[3]; 
	float location_f[3]; 
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
	glViewport(0,0,(GLsizei)winWidth,(GLsizei)winHeight); 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	gluPerspective(60.0,(GLfloat)winWidth/(GLfloat)winHeight,1.0,((M_SIZE+4)*2)<GetSafeHdc()); 
	return true; 
}