www.pudn.com > NavigateTest.rar > Navigate.cpp


// Navigate.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "ctrlactivex.h" 
#include "Navigate.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CNavigate dialog 
 
#define WM_NAVIGATE_CLOSE WM_USER+100 
CNavigate::CNavigate(CWnd* pParent /*=NULL*/) 
	: CDialog(CNavigate::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CNavigate) 
	//}}AFX_DATA_INIT 
	m_pDC =NULL; 
	m_iOperation = -1; 
	m_iButtonFlag = -1; 
	m_fRotateZ = 0.0f; 
	m_OpenGL = new COpenGL; 
} 
CNavigate::CNavigate(HWND pParent):CDialog(CNavigate::IDD,FromHandle(pParent)) 
{ 
	parent = pParent; 
} 
 
void CNavigate::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CNavigate) 
	DDX_Control(pDX, IDC_ZOOMSLIDER, m_ZoomSlider); 
	//}}AFX_DATA_MAP 
} 
 
 
BEGIN_MESSAGE_MAP(CNavigate, CDialog) 
	//{{AFX_MSG_MAP(CNavigate) 
	ON_WM_PAINT() 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_SIZE() 
	ON_WM_ACTIVATE() 
	ON_WM_LBUTTONDOWN() 
	ON_COMMAND(IDC_QUERYCOORRDINATE, OnQuerycoorrdinate) 
	ON_WM_MOUSEMOVE() 
	ON_WM_LBUTTONUP() 
	ON_COMMAND(IDC_ZOOMIN, OnZoomin) 
	ON_COMMAND(IDC_ROTATE, OnRotate) 
	ON_COMMAND(IDC_ZOOMOUT, OnZoomout) 
	ON_WM_CLOSE() 
	ON_WM_VSCROLL() 
	ON_COMMAND(IDC_ROTATERIGHT, OnRotateright) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CNavigate message handlers 
 
BOOL CNavigate::OnInitDialog()  
{ 
	CDialog::OnInitDialog(); 
/*	if (!m_wndToolBar.Create( this ) || 
	!m_wndToolBar.LoadToolBar(IDR_NAVIGATEBAR)) 
	{ 
		return -1;      // fail to create 
	} 
	m_wndToolBar.ShowWindow(SW_SHOW); 
	m_wndToolBar.SetBarStyle(CBRS_ALIGN_TOP | CBRS_TOOLTIPS | CBRS_FLYBY); 
	RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);*/ 
 
//	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); 
//	DockControlBar(&m_wndToolBar); 
/*	CRect rect(10,10,10,10); 
	m_OpenGL->Create( NULL,   //CWnd default 
						NULL,   //has no name 
						WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_VISIBLE, 
						rect, 
						this,   //this is the parent 
						0);    */ 
	return TRUE;  // return TRUE unless you set the focus to a control 
	              // EXCEPTION: OCX Property Pages should return FALSE 
} 
 
void CNavigate::OnPaint()  
{ 
	CPaintDC dc(this); 
	RenderScence(); 
} 
 
int CNavigate::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CDialog::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	Init();//初始化函数 
	return 0; 
} 
 
void CNavigate::OnDestroy()  
{ 
	CDialog::OnDestroy(); 
	 
	HGLRC hrc; 
	hrc=::wglGetCurrentContext(); 
	::wglMakeCurrent(NULL,NULL); 
	if (hrc) ::wglDeleteContext(hrc); 
	if(m_pDC) delete m_pDC; 
} 
 
void CNavigate::OnSize(UINT nType, int cx, int cy)  
{ 
	CDialog::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, 1.0, 100000000000.0); 
 	else 
		gluPerspective(60, (float)h/(float)w, 1.0, 100000000000.0); 
	glMatrixMode(GL_MODELVIEW);/**/ 
	 
} 
 
BOOL CNavigate::bSetupPixelFormat() 
{ 
	int pixelformat; 
	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 
	}; 
	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 CNavigate::Init() 
{ 
	PIXELFORMATDESCRIPTOR pfd; 
	m_pDC = new CClientDC(this); 
	ASSERT(m_pDC != NULL); 
	 
	if (!bSetupPixelFormat()) 
		return; 
	int n = ::GetPixelFormat(m_pDC->GetSafeHdc()); 
	::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd); 
 
	hrc = wglCreateContext(m_pDC->GetSafeHdc()); 
	wglMakeCurrent(m_pDC->GetSafeHdc(), hrc); 
	glEnable(GL_DEPTH_TEST); 
 
	glClearDepth(1000000.0f); 
	glDepthFunc(GL_LEQUAL);								// 深度检测类型 
	glEnable(GL_DEPTH_TEST); 
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// 透视优化 
	DrawNavigateBall(); 
	m_dEyeX = pCtl->m_dEyeX; 
	m_dEyeY = pCtl->m_dEyeY; 
	m_dEyeZ = pCtl->m_dEyeZ; 
	m_dCenX = pCtl->m_dCenX; 
	m_dCenY = pCtl->m_dCenY; 
	m_dCenZ = pCtl->m_dCenZ; 
	meDrawRect(pCtl->m_fStartLB[0]-60.0f,-90.0f,pCtl->m_fStartLB[0]+60.0f,90.0f);//显示位置生成 
} 
void CNavigate::RenderScence() 
{ 
	wglMakeCurrent(m_pDC->GetSafeHdc(),hrc); 
	glClearColor(0.0f,0.6f,1.0f,1.0f); 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除颜色缓冲区和深度缓冲区 
	glMatrixMode(GL_MODELVIEW); 
	glLoadIdentity(); 
	gluLookAt(m_dEyeX,m_dEyeY,m_dEyeZ,m_dCenX,m_dCenY,m_dCenZ,0,0,1); 
	if(m_iOperation == 1) 
		glRotatef(m_fRotateZ,0.0f,0.0f,1.0f); 
	glCallList(m_iBallList);//调用导航球列表 
	glCallList(m_iRectList); 
	glFinish(); 
   SwapBuffers(wglGetCurrentDC()); 
} 
void CNavigate::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)  
{ 
	CDialog::OnActivate(nState, pWndOther, bMinimized); 
} 
void CNavigate::GetRealCoord(CPoint point,double *LB) 
{ 
	GLdouble modelMatrix[16],projMatrix[16],dObjXYZ[3]; 
	GLint viewport[4]; 
	float z; 
	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); 
	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); 
	glGetIntegerv(GL_VIEWPORT, viewport); 
	CRect rect; 
	GetClientRect(&rect); 
	int y = viewport[3] - point.y; 
	glReadBuffer(GL_BACK); 
	glReadPixels(point.x,y,1,1,GL_DEPTH_COMPONENT ,GL_FLOAT, &z); 
	gluUnProject(point.x, y, z,  
					modelMatrix, projMatrix, viewport,  
					&dObjXYZ[0], &dObjXYZ[1], &dObjXYZ[2]);  
	pCtl->GetLBCoordinate(dObjXYZ,LB); 
} 
 
void CNavigate::DrawNavigateBall() 
{ 
	m_iBallList = glGenLists(1); 
	glNewList(m_iBallList,GL_COMPILE); 
	glPushMatrix(); 
	CString strURL = "http://192.168.111.91/beijing/World/Earth.bmp"; 
	if(strURL.Right(4) == _T(".bmp")) 
	{ 
		m_pTextures=LoadGLTextures(strURL);//加载纹理 
		if (m_pTextures==-1)		 
			return ;   
		glBindTexture( GL_TEXTURE_2D, m_pTextures);//绑定纹理 
	} 
	glEnable ( GL_CULL_FACE ); 
	glEnable ( GL_TEXTURE_2D ); 
	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
	glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 ); 
	GLUquadricObj*  q = gluNewQuadric ( ); 
	gluQuadricDrawStyle ( q, GLU_FILL ); 
	gluQuadricNormals ( q, GLU_SMOOTH ); 
	gluQuadricTexture ( q, GL_TRUE    ); 
	gluSphere ( q,63.78140, 36, 36 );//画导航球 
	glDisable(GL_TEXTURE_2D); 
	glDisable(GL_CULL_FACE ); 
	gluDeleteQuadric ( q ); 
	glPopMatrix(); 
	glEndList();//列表结束 
} 
 
//在导航球上画显示地区的范围 
void CNavigate::meDrawRect(float fminL, float fminB, float fmaxL, float fmaxB) 
{ 
	float LBxyz[3],RBxyz[3]; 
	int iCols,iRows,i; 
	iCols = iRows = 50; 
	m_dRectMinLB[0] = fminL; 
	m_dRectMinLB[1] = fminB; 
	m_dRectMaxLB[0] = fmaxL; 
	m_dRectMaxLB[1] = fmaxB; 
	m_dx = m_dRectMaxLB[0] - m_dRectMinLB[0]; 
	m_dy = m_dRectMaxLB[1] - m_dRectMinLB[1]; 
	float dx = (fmaxL - fminL)/iCols; 
	float dy = (fmaxB - fminB)/iRows; 
	wglMakeCurrent(m_pDC->GetSafeHdc(),hrc); 
	glLineWidth(2.0f); 
	m_iRectList = glGenLists(1); 
	glNewList(m_iRectList,GL_COMPILE); 
	glBegin(GL_LINES);//画上面水平线 
	for(i = 0;i < iRows;i++) 
	{ 
		LBtoXYZ(fminL+dx*i,fmaxB,LBxyz); 
		LBtoXYZ(fminL+dx*(1+i),fmaxB,RBxyz); 
		glVertex3fv(LBxyz); 
		glVertex3fv(RBxyz); 
	} 
	glBegin(GL_LINES);//画下面水平线 
		for(i = 0;i < iCols;i++) 
		{ 
			LBtoXYZ(fminL+dx*i,fminB,LBxyz); 
			LBtoXYZ(fminL+dx*(1+i),fminB,RBxyz); 
			glVertex3fv(LBxyz); 
			glVertex3fv(RBxyz); 
		} 
	glEnd(); 
	glBegin(GL_LINES);//画左面垂直线 
		for(i = 0;i < iRows;i++) 
		{ 
			LBtoXYZ(fminL,fminB+dy*i,LBxyz); 
			LBtoXYZ(fminL,fminB+dy*(1+i),RBxyz); 
			glVertex3fv(LBxyz); 
			glVertex3fv(RBxyz); 
		} 
	glEnd(); 
	glBegin(GL_LINES);//画右面垂直线 
		for(i = 0;i < iRows;i++) 
		{ 
			LBtoXYZ(fmaxL,fminB+dy*i,LBxyz); 
			LBtoXYZ(fmaxL,fminB+dy*(1+i),RBxyz); 
			glVertex3fv(LBxyz); 
			glVertex3fv(RBxyz); 
		} 
	glEnd(); 
	glEndList(); 
	glLineWidth(1.0f); 
	CRect rect; 
	GetClientRect(rect); 
	rect.top = rect.top+5; 
	rect.left = rect.left+5; 
	InvalidateRect(rect,FALSE); 
} 
//由L,B转换成高斯坐标X,Y,Z 
void CNavigate::LBtoXYZ(float L, float B, float *XYZ) 
{ 
	float Radius = 63.78140f*(1+0.01); 
	L = L*3.1415926/180.0; 
	B = B*3.1415926/180.0; 
	if( abs((int)B) >1.57f||abs((int)L)>3.1416f) 
	{ 
		TRACE("纬度或者经度输入有误!"); 
		return ; 
	} 
	else 
	{ 
		XYZ[0] = Radius * cos(B) * sin(L); 
		XYZ[1] = -Radius * cos(B) * cos(L); 
		XYZ[2] = Radius * sin(B); 
	} 
} 
//鼠标按下////////////////////////////// 
void CNavigate::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	double LB[2]; 
	CString str; 
	if(m_iOperation == 0)//坐标查询 
	{ 
		GetRealCoord(point,LB);//鼠标点位置的经纬坐标 
		str.Format("经度=%f,纬度=%f",LB[0],LB[1]); 
		::MessageBox(::GetFocus(),str,"数字地球军事版",MB_OK); 
	} 
	GetRealCoord(point,LB); 
	//鼠标点是否在显示区域范围内 
	if(!(LB[0] > m_dRectMaxLB[0]||LB[1] > m_dRectMaxLB[1]||LB[0] < m_dRectMinLB[0]||LB[1] < m_dRectMinLB[1])) 
	{ 
		SetCapture(); 
		::SetCursor(AfxGetApp()->LoadCursor(IDC_MOVE)); 
		m_iButtonFlag = 1; 
	} 
	else 
	{ 
		::ReleaseCapture(); 
		m_iButtonFlag = -1; 
	} 
	 
	CDialog::OnLButtonDown(nFlags, point); 
} 
 
void CNavigate::OnQuerycoorrdinate() //查询点的经纬度 
{ 
	m_iOperation = 0;	 
} 
 
void CNavigate::OnMouseMove(UINT nFlags, CPoint point)  
{ 
 
	CDialog::OnMouseMove(nFlags, point); 
} 
 
void CNavigate::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	double LB[2]; 
	if(m_iButtonFlag) 
	{ 
		GetRealCoord(point,LB); 
		float dx = (pCtl->m_fStartLB[0]-LB[0]);//鼠标弹起时的位置离目标点的距离(经纬度) 
		float dy = (pCtl->m_fStartLB[1]-LB[1]); 
		m_dRectMinLB[0] -= dx; 
		m_dRectMinLB[1] -= dy; 
		m_dRectMaxLB[0] -= dx; 
		m_dRectMaxLB[1] -= dy; 
		meDrawRect(m_dRectMinLB[0],m_dRectMinLB[1],m_dRectMaxLB[0],m_dRectMaxLB[1]); 
		//重置目标中心点的位置 
		pCtl->m_fStartLB[0] = (m_dRectMinLB[0]+m_dRectMaxLB[0])/2.0f; 
		pCtl->m_fStartLB[1] = (m_dRectMinLB[1]+m_dRectMaxLB[1])/2.0f; 
		if(!(pCtl->m_bTextureOn))//显示DEM 
		{ 
			pCtl->meViewMap(); 
		} 
		else//显示影像 
		{ 
			pCtl->m_Image.meViewImage(pCtl->m_fScale,pCtl->m_fStartLB); 
			pCtl->EyeToCen(pCtl->m_fStartLB[0],pCtl->m_fStartLB[1]); 
		} 
		pCtl->SendMessage(WM_PAINT,0,0);//执行控件的OnDraw()函数 
		m_iButtonFlag = -1; 
		::ReleaseCapture(); 
	} 
	CDialog::OnLButtonUp(nFlags, point); 
} 
 
void CNavigate::OnZoomin() //放大显示范围 
{ 
	meZoomIn(); 
} 
 
void CNavigate::OnRotate()//绕z轴向左旋转  
{ 
	m_iOperation = 1; 
	m_fRotateZ += 10.0f; 
} 
 
void CNavigate::OnZoomout() //缩小显示范围 
{ 
	meZoomOut(); 
} 
 
void CNavigate::meZoomIn()//放大 
{ 
	m_dRectMinLB[0] = pCtl->m_fMapMinEx[0]; 
	m_dRectMinLB[1] = pCtl->m_fMapMinEx[1]; 
	m_dRectMaxLB[0] = pCtl->m_fMapMaxEx[0]; 
	m_dRectMaxLB[1] = pCtl->m_fMapMaxEx[1]; 
	meDrawRect(m_dRectMinLB[0],m_dRectMinLB[1],m_dRectMaxLB[0],m_dRectMaxLB[1]); 
	pCtl->meZoomIn(); 
	pCtl->SendMessage(WM_PAINT,0,0); 
} 
 
void CNavigate::meZoomOut()//缩小 
{ 
	m_dRectMinLB[0] = pCtl->m_fMapMinEx[0]; 
	m_dRectMinLB[1] = pCtl->m_fMapMinEx[1]; 
	m_dRectMaxLB[0] = pCtl->m_fMapMaxEx[0]; 
	m_dRectMaxLB[1] = pCtl->m_fMapMaxEx[1]; 
	meDrawRect(m_dRectMinLB[0],m_dRectMinLB[1],m_dRectMaxLB[0],m_dRectMaxLB[1]); 
//	pCtl->m_fStartLB[0] = (m_dRectMinLB[0]+m_dRectMaxLB[0])/2.0f; 
//	pCtl->m_fStartLB[1] = (m_dRectMinLB[1]+m_dRectMaxLB[1])/2.0f; 
	 
	pCtl->ZoomOut(); 
	pCtl->SendMessage(WM_PAINT,0,0); 
} 
 
void CNavigate::meMapZoomIn()//接受控件的信息,进行放大操作 
{ 
	m_dRectMinLB[0] = pCtl->m_fMapMinEx[0]; 
	m_dRectMinLB[1] = pCtl->m_fMapMinEx[1]; 
	m_dRectMaxLB[0] = pCtl->m_fMapMaxEx[0]; 
	m_dRectMaxLB[1] = pCtl->m_fMapMaxEx[1]; 
	meDrawRect(m_dRectMinLB[0],m_dRectMinLB[1],m_dRectMaxLB[0],m_dRectMaxLB[1]); 
	pCtl->PostMessage(WM_PAINT,0,0); 
} 
 
void CNavigate::OnClose()  
{ 
	::SendMessage(parent,WM_NAVIGATE_CLOSE,NULL,NULL);	 
	CDialog::OnClose(); 
} 
 
void CNavigate::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)  
{ 
	switch(nSBCode)	 
	{ 
	case SB_LINEDOWN: 
	case SB_PAGEDOWN: 
		meZoomIn(); 
		break; 
	case SB_LINEUP: 
	case SB_PAGEUP: 
		OnZoomout(); 
		break; 
	default: 
		break; 
	} 
	CDialog::OnVScroll(nSBCode, nPos, pScrollBar); 
} 
 
void CNavigate::OnRotateright() //绕z轴向右旋转 
{ 
	m_iOperation = 1; 
	m_fRotateZ -= 10.0f; 
}