www.pudn.com > opengl_pick_sample.rar > oglview.cpp


// oglview.cpp : implementation of the OGLView class 
// 
 
#include "stdafx.h" 
#include "OGLApp.h" 
 
#include "ogldoc.h" 
#include "oglview.h" 
#include "stretchdlg.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
OGLView * g_view = 0; 
StretchDLG g_dlg; 
extern CStatusBar * g_status_bar; 
 
///////////////////////////////////////////////////////////////////////////// 
// OGLView 
 
IMPLEMENT_DYNCREATE(OGLView, CView) 
 
BEGIN_MESSAGE_MAP(OGLView, CView) 
	//{{AFX_MSG_MAP(OGLView) 
	ON_WM_SIZE() 
	ON_WM_LBUTTONDOWN() 
	ON_WM_LBUTTONUP() 
	ON_WM_MOUSEMOVE() 
	ON_COMMAND(ID_VIEW_DRAW_LINES, OnDrawLines) 
	ON_UPDATE_COMMAND_UI(ID_VIEW_DRAW_LINES, OnUpdateLines) 
	ON_COMMAND(ID_VIEW_DRAW_SOLID, OnDrawSolid) 
	ON_UPDATE_COMMAND_UI(ID_VIEW_DRAW_SOLID, OnUpdateSolid) 
	ON_UPDATE_COMMAND_UI(ID_VIEW_SCALE, OnUpdateScale) 
	ON_COMMAND(ID_VIEW_SCALE, OnViewScale) 
	ON_UPDATE_COMMAND_UI(ID_VIEW_AXES, OnUpdateAxes) 
	ON_COMMAND(ID_VIEW_AXES, OnViewAxes) 
	ON_UPDATE_COMMAND_UI(ID_VIEW_EARTH, OnUpdateEarth) 
	ON_COMMAND(ID_VIEW_EARTH, OnViewEarth) 
	ON_UPDATE_COMMAND_UI(ID_VIEW_SOLAR, OnUpdateSolarSystem) 
	ON_COMMAND(ID_VIEW_SOLAR, OnViewSolarSystem) 
	ON_WM_RBUTTONDOWN() 
	//}}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() 
 
///////////////////////////////////////////////////////////////////////////// 
// OGLView construction/destruction 
 
OGLView::OGLView() 
{ 
	m_left_down = 0; 
	g_view = this; 
} 
 
OGLView::~OGLView() 
{ 
} 
 
BOOL OGLView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// OGLView drawing 
 
void OGLView::OnDraw(CDC* pDC) 
{ 
	OGLDoc* pDoc = GetDocument(); 
	 
	if (pDC->IsPrinting()) 
	{ 
		if (m_3dview.IsInitialized()) 
		{ 
			UINT32 wpix = pDC->GetDeviceCaps(HORZRES); 
			UINT32 hpix = pDC->GetDeviceCaps(VERTRES); 
			if ((wpix > 0) && (hpix > 0)) 
			{ 
				m_3dview.RebuildModel(); 
				m_3dview.SizeImage(wpix,hpix); 
				  // we really don't want to print with a black 
				  // background...right? 
				m_3dview.SetBackgroundColor(1.0,1.0,1.0); 
 
				m_3dview.RenderImage(); 
				glFlush(); 
 
				DIBSection * dib = m_3dview.GetDIB(); 
				if (dib) 
				{ 
					BeginWaitCursor(); 
					pDC->BitBlt(0,0,wpix,hpix,dib->GetDC(),0,0,SRCCOPY); 
					EndWaitCursor(); 
				} 
			} 
		} 
	} 
	else 
	{ 
		ShowImage(); 
	} 
} 
 
void OGLView::ShowImage(void) 
{ 
	if (m_3dview.IsInitialized()) 
	{ 
		m_3dview.SetBackgroundColor(0.0,0.0,0.0); 
		m_3dview.RenderImage(); 
		m_3dview.DrawImage(this); 
	} 
 
	if (g_status_bar) 
	{ 
		g_status_bar->SetPaneText(0,"Left-mouse-drag to rotate, right-mouse to pick"); 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// OGLView printing 
 
BOOL OGLView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void OGLView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void OGLView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// OGLView diagnostics 
 
#ifdef _DEBUG 
void OGLView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void OGLView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
OGLDoc* OGLView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(OGLDoc))); 
	return (OGLDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// OGLView message handlers 
 
void OGLView::OnInitialUpdate()  
{ 
	CView::OnInitialUpdate(); 
	 
	if (!m_3dview.IsInitialized()) 
	{ 
		CRect r; 
		GetClientRect(&r); 
		m_3dview.CreateImage(r.Width(),r.Height()); 
		m_3dview.RebuildModel(); 
	} 
	 
	g_dlg.Create(IDD_SCALE_DLG, this); 
	g_dlg.ShowWindow(SW_SHOW); 
 
	CFrameWnd * frm = GetParentFrame(); 
	if (frm) 
	{ 
		CRect wr, dr; 
		frm->GetWindowRect(&wr); 
		g_dlg.GetWindowRect(&dr); 
 
		int left = wr.left - dr.Width() - 1; 
		int top = dr.top; 
		if (left < 0) 
			left = wr.right + 1; 
		g_dlg.SetWindowPos(&wndTop,left,top,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_SHOWWINDOW); 
	} 
} 
 
void OGLView::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	 
	if ((cx > 0) && (cy > 0)) 
	{ 
		CRect r; 
		GetClientRect(&r); 
		m_3dview.SizeImage(r.Width(),r.Height()); 
		m_3dview.RebuildModel(); 
		ShowImage(); 
	} 
} 
 
void OGLView::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	m_click_pt = point; 
	m_left_down = 1; 
	m_view_matrix = m_3dview.GetModelState(); 
	 
	CView::OnLButtonDown(nFlags, point); 
} 
 
void OGLView::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	m_left_down = 0; 
	 
	CView::OnLButtonUp(nFlags, point); 
} 
 
void OGLView::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	if (m_left_down) 
	{ 
		int xdiff = point.x - m_click_pt.x; 
		int ydiff = point.y - m_click_pt.y; 
 
		double yrot = xdiff/3.0; 
		double xrot = ydiff/3.0; 
		double zrot = 0.0; 
 
		while (xrot < 0.0) xrot += 360.0; 
		while (xrot > 360.0) xrot -= 360.00000001; 
 
		while (yrot < 0.0) yrot += 360.0; 
		while (yrot > 360.0) yrot -= 360.00000001; 
 
		Matrix3D mat = m_view_matrix; 
		mat.AddRotation(xrot,yrot,zrot); 
 
		m_3dview.SetModelState(mat); 
 
		ShowImage(); 
	} 
	 
	CView::OnMouseMove(nFlags, point); 
} 
 
void OGLView::SetScale(double sf) 
{ 
	Matrix3D mat = m_3dview.GetModelState(); 
	mat.SetScale(sf,sf,sf); 
	m_3dview.SetModelState(mat); 
	ShowImage(); 
} 
 
void OGLView::OnDrawLines()  
{ 
	m_3dview.SetDrawingMode(OGL3D::DrawLines); 
	m_3dview.RebuildModel(); 
	ShowImage(); 
} 
 
void OGLView::OnUpdateLines(CCmdUI* pCmdUI)  
{ 
	pCmdUI->Enable(); 
	pCmdUI->SetCheck( ( m_3dview.GetDrawingMode() == OGL3D::DrawLines ) ? 1 : 0 ); 
} 
 
void OGLView::OnDrawSolid()  
{ 
	m_3dview.SetDrawingMode(OGL3D::DrawTriangles); 
	m_3dview.RebuildModel(); 
	ShowImage(); 
} 
 
void OGLView::OnUpdateSolid(CCmdUI* pCmdUI)  
{ 
	pCmdUI->Enable(); 
	pCmdUI->SetCheck( ( m_3dview.GetDrawingMode() == OGL3D::DrawLines ) ? 0 : 1 ); 
} 
 
void OGLView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)  
{ 
	OGLDoc * doc = GetDocument(); 
	if (doc) 
	{ 
		DIBSection * dib = doc->GetDIB(); 
		if (dib && dib->IsCreated()) 
		{ 
			// debugging purposes only 
			//CClientDC dc(this); 
			//dib->Draw(&dc,0,0); 
 
#ifndef SOLAR 
			m_3dview.SetTexture(*dib); 
#endif 
			m_3dview.RebuildModel(); 
			ShowImage(); 
 
			// more debugging 
			//m_3dview.GetTextureDIB()->Draw(&dc,0,0); 
		} 
	} 
} 
 
void OGLView::OnUpdateScale(CCmdUI* pCmdUI)  
{ 
	pCmdUI->Enable(); 
	pCmdUI->SetCheck(g_dlg.IsWindowVisible()); 
} 
 
void OGLView::OnViewScale()  
{ 
	g_dlg.ShowWindow(!g_dlg.IsWindowVisible()); 
} 
 
void OGLView::OnUpdateAxes(CCmdUI* pCmdUI)  
{ 
	pCmdUI->Enable(); 
} 
 
void OGLView::OnViewAxes()  
{	 
} 
 
void OGLView::OnUpdateEarth(CCmdUI* pCmdUI)  
{ 
	pCmdUI->Enable(); 
} 
 
void OGLView::OnViewEarth()  
{	 
} 
 
void OGLView::OnUpdateSolarSystem(CCmdUI* pCmdUI)  
{ 
	pCmdUI->Enable(); 
} 
 
void OGLView::OnViewSolarSystem()  
{	 
} 
 
void OGLView::OnRButtonDown(UINT nFlags, CPoint point)  
{ 
#ifdef SOLAR 
	CString msg; 
	m_3dview.PickPlanet(point.x,point.y,msg); 
	//m_3dview.DrawImage(this); 
	AfxMessageBox((LPCTSTR)msg,MB_ICONINFORMATION); 
#endif 
 
	CView::OnRButtonDown(nFlags, point); 
}