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;
}