www.pudn.com > 3dSimplifier.zip > ChildView.cpp, change:2000-01-14,size:30030b
// ChildView.cpp : implementation of the CChildView class
//
#include "stdafx.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include "Simplifier.h"
#include "ChildView.h"
#include "MainFrm.h"
#include "InitOpenGL.h"
#include "SimplifyDiag.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CChildView
CChildView::CChildView()
{
m_fViewHeight = 2.0;
m_fViewNear = -2.0;
m_fViewFar = 2.0;
m_nMouseAct = MOUSE_SPIN;
m_bAnimate = FALSE;
m_bAxes = TRUE;
m_spinAngle = 0.0;
m_spinAxes[0] = m_spinAxes[2] = 0.0; m_spinAxes[1] = 1.0;
m_sEye.origin.x = m_sEye.origin.y = m_sEye.origin.z = 0.0;
m_sEye.center.x = m_sEye.center.y = 0.0; m_sEye.center.z = -1.0;
m_sEye.up.x = m_sEye.up.z = 0.0; m_sEye.up.y = 1.0;
m_sEye.axisX.y = m_sEye.axisX.z = 0.0; m_sEye.axisX.x = 1.0;
m_sEye.axisY.x = m_sEye.axisY.z = 0.0; m_sEye.axisY.y = 1.0;
m_sEye.axisZ.x = m_sEye.axisZ.y = 0.0; m_sEye.axisZ.z = -1.0;
m_vProjectCenter[0] = 0.0f;
m_vProjectCenter[1] = 0.0f;
m_vProjectCenter[2] = (m_fViewNear+m_fViewFar)/2;
m_nRenderModel = 1;
m_nRenderMode = 1;
m_pModel = NULL;
m_nFaceNo = 0;
}
CChildView::~CChildView()
{
if (m_pModel)
delete m_pModel;
}
BEGIN_MESSAGE_MAP(CChildView,CWnd )
//{{AFX_MSG_MAP(CChildView)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_CREATE()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP( )
ON_WM_SETCURSOR()
ON_WM_TIMER()
ON_WM_CONTEXTMENU()
ON_COMMAND(ID_MOUSE_SPIN, OnMouseSpin)
ON_UPDATE_COMMAND_UI(ID_MOUSE_SPIN, OnUpdateMouseSpin)
ON_COMMAND(ID_MOUSE_TRANSLATE, OnMouseTranslate)
ON_UPDATE_COMMAND_UI(ID_MOUSE_TRANSLATE, OnUpdateMouseTranslate)
ON_COMMAND(ID_MOUSE_ZOOM, OnMouseZoom)
ON_UPDATE_COMMAND_UI(ID_MOUSE_ZOOM, OnUpdateMouseZoom)
ON_COMMAND(ID_ANIMATE, OnAnimate)
ON_UPDATE_COMMAND_UI(ID_ANIMATE, OnUpdateAnimate)
ON_COMMAND(ID_SPIN_XCCW, OnSpinXccw)
ON_COMMAND(ID_SPIN_XCW, OnSpinXcw)
ON_COMMAND(ID_SPIN_YCCW, OnSpinYccw)
ON_COMMAND(ID_SPIN_YCW, OnSpinYcw)
ON_COMMAND(ID_SPIN_ZCCW, OnSpinZccw)
ON_COMMAND(ID_SPIN_ZCW, OnSpinZcw)
ON_COMMAND(ID_ZOOM_IN, OnZoomIn)
ON_COMMAND(ID_ZOOM_OUT, OnZoomOut)
ON_COMMAND(ID_OPEN_FILE, OnOpenFile)
ON_COMMAND(IDM_ORIGINAL_MODEL, OnOriginalModel)
ON_UPDATE_COMMAND_UI(IDM_ORIGINAL_MODEL, OnUpdateOriginalModel)
ON_COMMAND(IDM_SIMPLIFIED_MODEL, OnSimplifiedModel)
ON_UPDATE_COMMAND_UI(IDM_SIMPLIFIED_MODEL, OnUpdateSimplifiedModel)
ON_COMMAND(IDM_WIREFRAME, OnWireframe)
ON_UPDATE_COMMAND_UI(IDM_WIREFRAME, OnUpdateWireframe)
ON_COMMAND(IDM_FLAT, OnFlat)
ON_UPDATE_COMMAND_UI(IDM_FLAT, OnUpdateFlat)
ON_COMMAND(ID_SIMPLIFY, OnSimplify)
ON_COMMAND(ID_SAVE_FILE, OnSaveFile)
ON_COMMAND(ID_AXES, OnAxes)
ON_UPDATE_COMMAND_UI(ID_AXES, OnUpdateAxes)
ON_COMMAND(IDM_SAVE_PICTURE, OnSavePicture)
ON_UPDATE_COMMAND_UI(ID_SIMPLIFY, OnUpdateSimplify)
ON_UPDATE_COMMAND_UI(ID_SAVE_FILE, OnUpdateSaveFile)
ON_COMMAND(ID_CLOSE_FILE, OnCloseFile)
ON_UPDATE_COMMAND_UI(ID_CLOSE_FILE, OnUpdateCloseFile)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChildView message handlers
int CChildView::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
Init();
return 0;
}
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_OWNDC|CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);
if (!CWnd::PreCreateWindow(cs))
return FALSE;
return TRUE;
}
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
DrawScene();
// Do not call CWnd::OnPaint() for painting messages
}
void CChildView::OnSize( UINT nType, int cx, int cy )
{
CWnd::OnSize(nType, cx, cy);
Project();
}
BOOL CChildView::OnCommand(WPARAM wParam, LPARAM lParam)
{
WORD nID = wParam & 0x0000ffff;
switch (nID)
{
case ID_ZOOM_IN:
OnZoomIn();
break;
case ID_ZOOM_OUT:
OnZoomOut();
break;
case ID_SPIN_XCW:
OnSpinXcw();
break;
case ID_SPIN_XCCW:
OnSpinXccw();
break;
case ID_SPIN_YCW:
OnSpinYcw();
break;
case ID_SPIN_YCCW:
OnSpinYccw();
break;
case ID_SPIN_ZCW:
OnSpinZcw();
break;
case ID_SPIN_ZCCW:
OnSpinZccw();
break;
}
return CWnd ::OnCommand(wParam, lParam);
}
void CChildView::OnTimer( UINT nIDEvent )
{
if (nIDEvent == TIMER_ANIMATE)
{
if (m_bAnimate && (m_spinAngle!=0.0) )
SpinGlobal(m_spinAxes, m_spinAngle);
}
else if (nIDEvent == TIMER_TOOLBAR)
{
CMainFrame *pFrameWnd = (CMainFrame*)AfxGetMainWnd();
int count = (pFrameWnd->m_wndInteractRight).GetToolBarCtrl().GetButtonCount();
int nIndex;
for( nIndex = 0; nIndex count; nIndex++)
{
if( (pFrameWnd->m_wndInteractRight).GetToolBarCtrl().IsButtonPressed( (pFrameWnd->m_wndInteractRight).GetItemID( nIndex)))
{
pFrameWnd->SendMessage( WM_COMMAND,
(pFrameWnd->m_wndInteractRight).GetItemID( nIndex), (LPARAM)m_hWnd);
break;
}
}
}
}
void CChildView::OnContextMenu( CWnd* pWnd, CPoint pos )
{
CMenu menu;
menu.LoadMenu(IDR_CONTEXTMENU);
TRACE("%d %d \n",pos.x,pos.y);
menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,
pos.x,pos.y,this);
}
void CChildView::OnMouseMove( UINT nFlags, CPoint point )
{
if (m_nMouseAct == MOUSE_SPIN)
{
MouseSpinGlobal(nFlags, point.x, point.y, 0);
}
else if (m_nMouseAct == MOUSE_ZOOM)
{
MouseZoom(nFlags, point.x, point.y);
}
else if (m_nMouseAct == MOUSE_TRANSLATE)
{
MouseTranslate(nFlags, point.x, point.y);
}
CWnd::OnMouseMove(nFlags, point);
}
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
m_spinAngle = 0.0f;
if (m_nMouseAct == MOUSE_SPIN)
{
if (m_bAnimate)
SetTimer(TIMER_ANIMATE,ANIMATE_RATE,NULL);
MouseSpinGlobal(nFlags, point.x, point.y, 1);
}
else if (m_nMouseAct == MOUSE_ZOOM)
{
MouseZoom(nFlags, point.x, point.y);
}
else if (m_nMouseAct == MOUSE_TRANSLATE)
{
MouseTranslate(nFlags, point.x, point.y);
}
CWnd::OnLButtonDown(nFlags, point);
MSG msg;
while(::PeekMessage( &msg, m_hWnd,
WM_MOUSEMOVE, WM_MOUSEMOVE,
PM_REMOVE))
;
m_bLButtonDown = TRUE;
}
void CChildView::OnLButtonUp(UINT nFlags, CPoint point)
{
m_bLButtonDown = FALSE;
MSG msg;
while(::PeekMessage( &msg, m_hWnd,
WM_MOUSEMOVE, WM_MOUSEMOVE,
PM_REMOVE))
;
CWnd::OnLButtonUp(nFlags, point);
}
BOOL CChildView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
HCURSOR hCursor;
switch (m_nMouseAct)
{
case MOUSE_SPIN:
hCursor = AfxGetApp()->LoadCursor( IDC_SPIN );
SetCursor( hCursor );
break;
case MOUSE_ZOOM:
hCursor = AfxGetApp()->LoadCursor( IDC_ZOOM );
SetCursor( hCursor );
break;
case MOUSE_TRANSLATE:
hCursor = AfxGetApp()->LoadCursor( IDC_TRANSLATE );
SetCursor( hCursor );
break;
default:
hCursor = AfxGetApp()->LoadCursor( IDC_ARROW );
SetCursor( hCursor );
break;
}
return TRUE;
}
void CChildView::OnOriginalModel()
{
if (m_nRenderModel == 1)
{
m_nRenderModel = 0;
DrawScene();
}
}
void CChildView::OnUpdateOriginalModel(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_nRenderModel == 0);
}
void CChildView::OnSimplifiedModel()
{
if (m_nRenderModel == 0)
{
m_nRenderModel = 1;
DrawScene();
}
}
void CChildView::OnUpdateSimplifiedModel(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_nRenderModel == 1);
}
void CChildView::OnWireframe()
{
if (m_nRenderMode == 1)
{
m_nRenderMode = 0;
DrawScene();
}
}
void CChildView::OnUpdateWireframe(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_nRenderMode == 0);
}
void CChildView::OnFlat()
{
if (m_nRenderMode == 0)
{
m_nRenderMode = 1;
DrawScene();
}
}
void CChildView::OnUpdateFlat(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_nRenderMode == 1);
}
void CChildView::OnOpenFile()
{
CFileDialog loadmesh(TRUE, "tm" , NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "tm文件(*.tm)|*.tm||");
loadmesh.m_ofn.lpstrTitle ="打开模型文件";
//SetCurrentDirectory(".\\");
if (loadmesh.DoModal() == IDOK )
{
CString filename;
CString fileext;
fileext = loadmesh.GetFileExt();
filename = loadmesh.GetPathName();
if (!filename.IsEmpty()) {
FILE *fp;
fp = fopen(filename, "r");
if (!fp) {
AfxMessageBox("Can't open file to load");
return;
}
if (!fileext.CompareNoCase("tm"))
{
if (m_pModel)
delete m_pModel;
m_pModel = new CMesh;
HCURSOR hCursor, hOldCursor;
hCursor = AfxGetApp()->LoadCursor( IDC_MY_WAIT );
hOldCursor = SetCursor( hCursor );
CMainFrame *pFrameWnd = (CMainFrame*)AfxGetMainWnd();
pFrameWnd->m_Progress.SetPos(0);
m_pModel->m_pProgress = &(pFrameWnd->m_Progress);
m_nFaceNo = m_pModel->ReadData(fp);
if (m_bAnimate)
OnAnimate();
m_spinAngle = 0.0;
pFrameWnd->m_Progress.SetPos(0);
m_pModel->m_pProgress = NULL;
SetCursor(hOldCursor);
}
fclose(fp);
CMainFrame *pFrameWnd = (CMainFrame*)AfxGetMainWnd();
char tmps[80];
sprintf(tmps,"原始模型:%d", m_nFaceNo);
pFrameWnd->m_wndStatusBar.SetPaneText(1,tmps);
m_nsFaceNo = m_nFaceNo;
sprintf(tmps,"简化模型:%d", m_nsFaceNo);
pFrameWnd->m_wndStatusBar.SetPaneText(2,tmps);
DrawScene();
}
}
}
void CChildView::OnSaveFile()
{
if (!m_pModel)
return;
CFileDialog savemesh(FALSE, "tm" , NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "tm文件(*.tm)|*.tm||");
savemesh.m_ofn.lpstrTitle ="保存模型文件";
SetCurrentDirectory(".\\Mesh");
if (savemesh.DoModal() == IDOK )
{
CString filename;
CString fileext;
fileext = savemesh.GetFileExt();
filename = savemesh.GetPathName();
if (!filename.IsEmpty()) {
FILE *fp;
fp = fopen(filename, "w");
if (!fp) {
AfxMessageBox("Can't open file to load");
return;
}
if (!fileext.CompareNoCase("tm"))
{
HCURSOR hCursor, hOldCursor;
hCursor = AfxGetApp()->LoadCursor( IDC_MY_WAIT );
hOldCursor = SetCursor( hCursor );
CMainFrame *pFrameWnd = (CMainFrame*)AfxGetMainWnd();
pFrameWnd->m_Progress.SetPos(0);
m_pModel->m_pProgress = &(pFrameWnd->m_Progress);
m_pModel->SaveData(fp);
pFrameWnd->m_Progress.SetPos(0);
m_pModel->m_pProgress = NULL;
SetCursor(hOldCursor);
}
fclose(fp);
}
}
}
void CChildView::OnUpdateSaveFile(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_pModel != NULL);
}
void CChildView::OnSavePicture()
{
CFileDialog savefile(FALSE, ".bmp", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "BMP文件(*.bmp)|*.bmp||");
savefile.m_ofn.lpstrTitle = "存为BMP图象" ;
if ( savefile.DoModal() == IDOK )
{
CString filename;
char temp[80];
filename = savefile.GetPathName();
sprintf(temp,"%s",filename);
SaveAsBMP(temp);
}
}
void CChildView::OnSimplify()
{
if (!m_pModel)
return;
HCURSOR hCursor, hOldCursor;
CSimplifyDiag diag(m_nFaceNo);
if (diag.DoModal() == IDOK)
{
hCursor = AfxGetApp()->LoadCursor( IDC_MY_WAIT );
hOldCursor = SetCursor( hCursor );
CMainFrame *pFrameWnd = (CMainFrame*)AfxGetMainWnd();
pFrameWnd->m_Progress.SetPos(1);
m_pModel->m_pProgress = &(pFrameWnd->m_Progress);
if ((diag.m_nInputMode == 0)&&(diag.m_nFaceNo>0)&&(diag.m_nFaceNo<m_nFaceNo))
m_nsFaceNo = m_pModel->Simplify(diag.m_nFaceNo);
else if (diag.m_nInputMode == 1)
m_nsFaceNo = m_pModel->Simplify(diag.m_fRate/100);
if (m_nRenderModel == 1)
DrawScene();
pFrameWnd->m_Progress.SetPos(0);
m_pModel->m_pProgress = NULL;
char tmps[80];
sprintf(tmps,"简化模型:%d", m_nsFaceNo);
pFrameWnd->m_wndStatusBar.SetPaneText(2,tmps);
SetCursor(hOldCursor);
}
}
void CChildView::OnUpdateSimplify(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_pModel != NULL);
}
void CChildView::OnCloseFile()
{
if (m_pModel)
delete m_pModel;
m_pModel = NULL;
DrawScene();
}
void CChildView::OnUpdateCloseFile(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_pModel != NULL);
}
void CChildView::OnAxes()
{
m_bAxes = !m_bAxes;
DrawScene();
}
void CChildView::OnUpdateAxes(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_bAxes);
}
void CChildView::OnAnimate()
{
if (m_bAnimate)
KillTimer(TIMER_ANIMATE);
else
SetTimer( TIMER_ANIMATE, ANIMATE_RATE, NULL );
m_bAnimate = !m_bAnimate;
}
void CChildView::OnUpdateAnimate(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_bAnimate);
}
void CChildView::OnMouseSpin()
{
m_nMouseAct = MOUSE_SPIN;
}
void CChildView::OnUpdateMouseSpin(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck( m_nMouseAct == MOUSE_SPIN);
}
void CChildView::OnMouseTranslate()
{
m_nMouseAct = MOUSE_TRANSLATE;
}
void CChildView::OnUpdateMouseTranslate(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck( m_nMouseAct == MOUSE_TRANSLATE);
}
void CChildView::OnMouseZoom()
{
m_nMouseAct = MOUSE_ZOOM;
}
void CChildView::OnUpdateMouseZoom(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck( m_nMouseAct == MOUSE_ZOOM);
}
BOOL CChildView::SetThePixelFormat(CDC *pDC)
{
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
};
int pixelformat;
if((pixelformat = ChoosePixelFormat(m_hDc, &pfd)) == 0)
{
MessageBox( "ChoosePixelFormat failed", "Error", MB_OK);
return FALSE;
}
if(SetPixelFormat(m_hDc, pixelformat, &pfd) == FALSE)
{
MessageBox( "SetPixelFormat failed", "Error", MB_OK);
return FALSE;
}
CreateRGBPalette(m_hDc);
return TRUE;
}
void CChildView::MouseSpinGlobal(UINT nFlags, int x, int y, int init)
{
// use mouse to play 3D trackball transformation
// see also Intel 3DR
float centerX, centerY;
float radius;
float w, h; // window
RECT rect;
GetClientRect( &rect);
w =(float)rect.right;
h =(float)rect.bottom;
h = (h == 0.0f) ? 1.0f : h;
centerX = w / 2.0f;
centerY = h / 2.0f;
radius = (w > h) ? centerY : centerX ;
if (init)
{
// And call Trackball() with current center, radius
// and current cursor position (in client coordinates)
// to initialize trackball internal parameters.
// Note that we must stop animation at that time.
Trackball( 0, radius, centerX, centerY, (float)x, (float)(h-y),
m_spinAxes[0], m_spinAxes[1], m_spinAxes[2], m_spinAngle);
}
else if ( nFlags & MK_LBUTTON )
{
Trackball(1, radius, centerX, centerY, (float)x, (float)(h-y),
m_spinAxes[0], m_spinAxes[1], m_spinAxes[2], m_spinAngle);
SpinGlobal(m_spinAxes, m_spinAngle);
}
}
void CChildView::SpinGlobal(float axes[], float angle)
{
EyeRotate(m_vProjectCenter, axes, angle, m_sEye );
DrawScene();
}
void CChildView::MouseZoom(UINT nFlags, int x, int y)
{
float w, h;
float scale;
static float oldY, dy ;
RECT rect;
GetClientRect( &rect);
w =(float)rect.right;
h =(float)rect.bottom;
h = (h == 0.0f) ? 1.0f : h;
if( m_bLButtonDown && (nFlags & MK_LBUTTON))
{
dy=oldY-y;
scale=1.0f+dy/h;
Zoom(scale);
oldY=(float)y;
}
else
{
oldY=(float)y;
}
}
void CChildView::Zoom(float scale)
{
if(scale<0.001) return;
m_fViewHeight/=scale;
Project();
DrawScene();
}
void CChildView::MouseTranslate(UINT nFlags, int x, int y)
{
float w, h;
static float oldX, oldY, dx, dy, d[3] ;
RECT rect;
GetClientRect( &rect);
w =(float)rect.right;
h =(float)rect.bottom;
h = (h == 0.0f) ? 1.0f : h;
if( m_bLButtonDown && (nFlags & MK_LBUTTON))
{
dx=x-oldX;
dy=oldY-y;
d[0]=m_fViewWidth*dx/w*0.8f;
d[1]=m_fViewHeight*dy/h*0.8f;
d[2]=0.0f;
Translate(d);
oldX=(float)x;
oldY=(float)y;
}
else
{
oldX=(float)x;
oldY=(float)y;
}
}
void CChildView::Translate(float d[])
{
EyeTranslate(d, m_sEye);
DrawScene();
}
void CChildView::OnSpinXccw()
{
KillTimer(TIMER_ANIMATE);
glRotatef(ROTATE_RATE, 1.0f, 0.0f, 0.0f);
DrawScene();
}
void CChildView::OnSpinXcw()
{
KillTimer(TIMER_ANIMATE);
MSG msg;
while(::PeekMessage( &msg, m_hWnd,
WM_TIMER, WM_TIMER,
PM_REMOVE));
glRotatef(-ROTATE_RATE, 1.0f, 0.0f, 0.0f);
DrawScene();
}
void CChildView::OnSpinYccw()
{
KillTimer(TIMER_ANIMATE);
MSG msg;
while(::PeekMessage( &msg, m_hWnd,
WM_TIMER, WM_TIMER,
PM_REMOVE));
glRotatef(ROTATE_RATE, 0.0f, 1.0f, 0.0f);
DrawScene();
}
void CChildView::OnSpinYcw()
{
KillTimer(TIMER_ANIMATE);
MSG msg;
while(::PeekMessage( &msg, m_hWnd,
WM_TIMER, WM_TIMER,
PM_REMOVE));
glRotatef(-ROTATE_RATE, 0.0f, 1.0f, 0.0f);
DrawScene();
}
void CChildView::OnSpinZccw()
{
KillTimer(TIMER_ANIMATE);
MSG msg;
while(::PeekMessage( &msg, m_hWnd,
WM_TIMER, WM_TIMER,
PM_REMOVE));
glRotatef(ROTATE_RATE, 0.0f, 0.0f, 1.0f);
DrawScene();
}
void CChildView::OnSpinZcw()
{
KillTimer(TIMER_ANIMATE);
MSG msg;
while(::PeekMessage( &msg, m_hWnd,
WM_TIMER, WM_TIMER,
PM_REMOVE));
glRotatef(-ROTATE_RATE, 0.0f, 0.0f, 1.0f);
DrawScene();
}
void CChildView::OnZoomIn()
{
KillTimer(TIMER_ANIMATE);
MSG msg;
while(::PeekMessage( &msg, m_hWnd,
WM_TIMER, WM_TIMER,
PM_REMOVE));
Zoom(1.0f + ZOOM_RATE );
}
void CChildView::OnZoomOut()
{
KillTimer(TIMER_ANIMATE);
MSG msg;
while(::PeekMessage( &msg, m_hWnd,
WM_TIMER, WM_TIMER,
PM_REMOVE));
Zoom(1.0f - ZOOM_RATE );
}
void CChildView::Init()
{
CDC *pDC = GetDC();
m_hDc = pDC->GetSafeHdc();
SetThePixelFormat(pDC);
m_hRc = wglCreateContext(m_hDc);
wglMakeCurrent(m_hDc,m_hRc);
ReleaseDC(pDC);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_AUTO_NORMAL);
glColor3f(1.0f, 1.0f, 0.0f);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
GLfloat light[] = {1.0f,1.0f,1.0f,1.0f};
glLightfv(GL_LIGHT0,GL_DIFFUSE,light);
float ambient[4] = {0.2f, 0.2f, 0.0f, 1.0f};
float diffuse[4] = {0.95f, 0.95f, 0.0f, 1.0f};
float specular[4] = {0.0f, 0.0f, 0.1f, 1.0f};
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR,specular);
SetTimer( TIMER_TOOLBAR, TOOLBAR_RATE, NULL);
if (m_bAnimate)
SetTimer( TIMER_ANIMATE, ANIMATE_RATE, NULL );
CMainFrame *pFrameWnd = (CMainFrame*)AfxGetMainWnd();
m_nsFaceNo = m_nFaceNo = 0;
}
void CChildView::DrawAxes()
{
glDisable(GL_LIGHTING);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glScalef(1.4f, 1.4f, 1.4f);
glBegin(GL_LINES);
// x axis
glColor3f ( 1.0f, 0.0f, 0.0f);
glVertex3f( 0.0f, 0.0f, 0.0f);
glVertex3f( 1.0f, 0.0f, 0.0f);
// y axis
glColor3f ( 0.0f, 1.0f, 0.0f);
glVertex3f( 0.0f, 0.0f, 0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
// z axis
glColor3f ( 0.0f, 0.0f, 1.0f);
glVertex3f( 0.0f, 0.0f, 0.0f);
glVertex3f( 0.0f, 0.0f, 1.0f);
glEnd();
glBegin(GL_TRIANGLES);
// x axis arrow
glColor3f ( 1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.9f, 0.0f, 0.04f);
glVertex3f(0.9f, 0.028f, 0.028f);
glVertex3f(0.9f, 0.0f, 0.04f);
glVertex3f(0.9f, 0.028f, 0.028f);
glVertex3f(0.9f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.9f, 0.028f, 0.028f);
glVertex3f(0.9f, 0.04f, 0.0f);
glVertex3f(0.9f, 0.028f, 0.028f);
glVertex3f(0.9f, 0.04f, 0.0f);
glVertex3f(0.9f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.9f, 0.04f, 0.0f);
glVertex3f(0.9f, 0.028f, -0.028f);
glVertex3f(0.9f, 0.04f, 0.0f);
glVertex3f(0.9f, 0.028f, -0.028f);
glVertex3f(0.9f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.9f, 0.028f, -0.028f);
glVertex3f(0.9f, 0.0f, -0.04f);
glVertex3f(0.9f, 0.028f, -0.028f);
glVertex3f(0.9f, 0.0f, -0.04f);
glVertex3f(0.9f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.9f, 0.0f, -0.04f);
glVertex3f(0.9f, -0.028f, -0.028f);
glVertex3f(0.9f, 0.0f, -0.04f);
glVertex3f(0.9f, -0.028f, -0.028f);
glVertex3f(0.9f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.9f, -0.028f, -0.028f);
glVertex3f(0.9f, -0.04f, 0.0f);
glVertex3f(0.9f, -0.028f, -0.028f);
glVertex3f(0.9f, -0.04f, 0.0f);
glVertex3f(0.9f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.9f, -0.04f, 0.0f);
glVertex3f(0.9f, -0.028f, 0.028f);
glVertex3f(0.9f, -0.04f, 0.0f);
glVertex3f(0.9f, -0.028f, 0.028f);
glVertex3f(0.9f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.9f, -0.028f, 0.028f);
glVertex3f(0.9f, 0.0f, 0.04f);
glVertex3f(0.9f, -0.028f, 0.028f);
glVertex3f(0.9f, 0.0f, 0.04f);
glVertex3f(0.9f, 0.0f, 0.0f);
// y axis arrow
glColor3f ( 0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.9f, 0.04f);
glVertex3f(0.028f, 0.9f, 0.028f);
glVertex3f(0.0f, 0.9f, 0.04f);
glVertex3f(0.028f, 0.9f, 0.028f);
glVertex3f(0.0f, 0.9f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.028f, 0.9f, 0.028f);
glVertex3f(0.04f, 0.9f, 0.0f);
glVertex3f(0.028f, 0.9f, 0.028f);
glVertex3f(0.04f, 0.9f, 0.0f);
glVertex3f(0.0f, 0.9f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.04f, 0.9f, 0.0f);
glVertex3f(0.028f, 0.9f, -0.028f);
glVertex3f(0.04f, 0.9f, 0.0f);
glVertex3f(0.028f, 0.9f, -0.028f);
glVertex3f(0.0f, 0.9f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.028f, 0.9f, -0.028f);
glVertex3f(0.0f, 0.9f, -0.04f);
glVertex3f(0.028f, 0.9f, -0.028f);
glVertex3f(0.0f, 0.9f, -0.04f);
glVertex3f(0.0f, 0.9f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.9f, -0.04f);
glVertex3f(-0.028f, 0.9f, -0.028f);
glVertex3f(0.0f, 0.9f, -0.04f);
glVertex3f(-0.028f, 0.9f, -0.028f);
glVertex3f(0.0f, 0.9f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(-0.028f, 0.9f, -0.028f);
glVertex3f(-0.04f, 0.9f, 0.0f);
glVertex3f(-0.028f, 0.9f, -0.028f);
glVertex3f(-0.04f, 0.9f, 0.0f);
glVertex3f(0.0f, 0.9f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(-0.04f, 0.9f, 0.0f);
glVertex3f(-0.028f, 0.9f, 0.028f);
glVertex3f(-0.04f, 0.9f, 0.0f);
glVertex3f(-0.028f, 0.9f, 0.028f);
glVertex3f(0.0f, 0.9f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(-0.028f, 0.9f, 0.028f);
glVertex3f(0.0f, 0.9f, 0.04f);
glVertex3f(-0.028f, 0.9f, 0.028f);
glVertex3f(0.0f, 0.9f, 0.04f);
glVertex3f(0.0f, 0.9f, 0.0f);
// z axis arrow
glColor3f ( 0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.04f, 0.9f);
glVertex3f(0.028f, 0.028f, 0.9f);
glVertex3f(0.0f, 0.04f, 0.9f);
glVertex3f(0.028f, 0.028f, 0.9f);
glVertex3f(0.0f, 0.0f, 0.9f);
glVertex3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.028f, 0.028f, 0.9f);
glVertex3f(0.04f, 0.0f, 0.9f);
glVertex3f(0.028f, 0.028f, 0.9f);
glVertex3f(0.04f, 0.0f, 0.9f);
glVertex3f(0.0f, 0.0f, 0.9f);
glVertex3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.04f, 0.0f, 0.9f);
glVertex3f(0.028f, -0.028f, 0.9f);
glVertex3f(0.04f, 0.0f, 0.9f);
glVertex3f(0.028f, -0.028f, 0.9f);
glVertex3f(0.0f, 0.0f, 0.9f);
glVertex3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.028f, -0.028f, 0.9f);
glVertex3f(0.0f, -0.04f, 0.9f);
glVertex3f(0.028f, -0.028f, 0.9f);
glVertex3f(0.0f, -0.04f, 0.9f);
glVertex3f(0.0f, 0.0f, 0.9f);
glVertex3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, -0.04f, 0.9f);
glVertex3f(-0.028f, -0.028f, 0.9f);
glVertex3f(0.0f, -0.04f, 0.9f);
glVertex3f(-0.028f, -0.028f, 0.9f);
glVertex3f(0.0f, 0.0f, 0.9f);
glVertex3f(0.0f, 0.0f, 1.0f);
glVertex3f(-0.028f, -0.028f, 0.9f);
glVertex3f(-0.04f, 0.0f, 0.9f);
glVertex3f(-0.028f, -0.028f, 0.9f);
glVertex3f(-0.04f, 0.0f, 0.9f);
glVertex3f(0.0f, 0.0f, 0.9f);
glVertex3f(0.0f, 0.0f, 1.0f);
glVertex3f(-0.04f, 0.0f, 0.9f);
glVertex3f(-0.028f, 0.028f, 0.9f);
glVertex3f(-0.04f, 0.0f, 0.9f);
glVertex3f(-0.028f, 0.028f, 0.9f);
glVertex3f(0.0f, 0.0f, 0.9f);
glVertex3f(0.0f, 0.0f, 1.0f);
glVertex3f(-0.028f, 0.028f, 0.9f);
glVertex3f(0.0f, 0.04f, 0.9f);
glVertex3f(-0.028f, 0.028f, 0.9f);
glVertex3f(0.0f, 0.04f, 0.9f);
glVertex3f(0.0f, 0.0f, 0.9f);
glEnd();
glPopMatrix();
glEnable(GL_LIGHTING);
glColor3f ( 1.0f, 1.0f, 0.0f);
}
void CChildView::SetupBmpHeader(BITMAPINFOHEADER *pbmih, int sx, int sy, int bpp)
{
pbmih->biSize = sizeof(BITMAPINFOHEADER);
pbmih->biWidth = sx;
pbmih->biHeight = sy;
pbmih->biPlanes = 1;
pbmih->biBitCount = bpp;
pbmih->biCompression = BI_RGB;
pbmih->biSizeImage = sx * sy * (bpp/8);
pbmih->biXPelsPerMeter = 2925;
pbmih->biYPelsPerMeter = 2925;
pbmih->biClrUsed = 0;
pbmih->biClrImportant = 0;
}
BOOL CChildView::SaveAsBMP(char *bmpFileName)
{
GLubyte *lpBits;
RECT rect;
GetClientRect(&rect);
CDC *pDC = GetDC();
ASSERT(pDC->m_hDC);
// Creating Compatible Memory Device Context
CDC *pMemDC = new CDC;
if (!pMemDC->CreateCompatibleDC(pDC))
{
MessageBox("CompatibleDC Error");
return 0;
}
// Preparing bitmap header for DIB section
BITMAPINFO bi;
int bpp, sx, sy;
ZeroMemory(&bi, sizeof(BITMAPINFO));
// Making a DIB image which is half size of GL window and full color(24 bpp)
sx = (rect.right-rect.left) ;
sy = (rect.bottom-rect.top) ;
sx=sx-sx % 4; // BMP 要求扫描线为 4 的倍数
bpp = 24;
long dwSizeImage = sx * sy * bpp / 8; // 8 means 8 bit/byte
SetupBmpHeader(&(bi.bmiHeader), sx, sy, bpp);
// Creating a DIB surface
HBITMAP hBm, hBmOld;
hBm = CreateDIBSection(pDC->GetSafeHdc(), &bi, DIB_RGB_COLORS,
(void **)&lpBits, NULL, (DWORD)0);
if (!hBm)
{
MessageBox("CreateDIBSection Error");
return 0;
}
// Selecting the DIB Surface
hBmOld = (HBITMAP)::SelectObject(pMemDC->GetSafeHdc(), hBm);
if (!hBmOld)
{
MessageBox("Select Object Error");
return 0;
}
glReadBuffer(GL_BACK);
glReadPixels(rect.left,rect.top,sx,//rect.right-rect.left,
rect.bottom-rect.top,GL_BGR_EXT,GL_UNSIGNED_BYTE,lpBits);
// Preparing BMP file header information
BITMAPFILEHEADER bmfh;
bmfh.bfType = 0x4d42; // 'BM'
long nSize = sizeof(BITMAPINFOHEADER) + dwSizeImage;
bmfh.bfSize = nSize + sizeof(BITMAPFILEHEADER);
bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
CFile *pbmpFile;
CFileException fileException;
pbmpFile = new CFile;
if (!pbmpFile->Open(bmpFileName ,
CFile::modeCreate | CFile::modeWrite ) )
{
TRACE( "Unable to open file: %s\n, error = %u\n",
"" ,fileException.m_cause);
}
// Wrinting the DIB image
TRY
{
pbmpFile->Write(&bmfh, sizeof(BITMAPFILEHEADER));
pbmpFile->Write(&(bi.bmiHeader), sizeof(BITMAPINFOHEADER));
pbmpFile->Write(lpBits,dwSizeImage);
pbmpFile->Flush();
}
CATCH (CException, e)
{
AfxMessageBox("write error");
return 0;
}
END_CATCH
// Cleaning
pbmpFile->Close();
delete pbmpFile;
hBm = (HBITMAP)::SelectObject(pMemDC->GetSafeHdc(), hBmOld);
DeleteObject(hBm);
delete pMemDC;
ReleaseDC(pDC);
return 1;
}
void CChildView::Project()
{
RECT rect;
GetClientRect( &rect);
GLsizei nWidth = rect.right;
GLsizei nHeight = rect.bottom;
nHeight = (nHeight == 0) ? 1 : nHeight;
float dAspect = (float)nWidth/(float)nHeight;
m_fViewWidth = m_fViewHeight * dAspect;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-m_fViewWidth,m_fViewWidth,-m_fViewHeight,m_fViewHeight,m_fViewNear,m_fViewFar);
glViewport(0,0,nWidth,nHeight);
glMatrixMode(GL_MODELVIEW);
}
void CChildView::DrawScene()
{
int nTriangles = 0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
if (m_pModel)
m_pModel->DrawModel(m_nRenderMode, m_nRenderModel);
if (m_bAxes)
DrawAxes();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glFlush();
SwapBuffers(m_hDc);
}