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