www.pudn.com > OpenGLDemoshow.zip > MFCGLView.cpp


// MFCGLView.cpp : implementation of the CMFCGLView class 
// 
 
/*################################################################## 
 
  Author:	Masoud Samimi 
  Website:	www.geocities.com/samimi73 
  Email:	marcello43@hotmail.com 
 
  Program:	MFC OpenGL 
  History:	Last modified for web on 22.07.2000 (dd.mm.yy) 
   
  Purpose: Please visit my website, it is expalined there. 
   
 
Important Notice: 
 
	No guarantee/warantee is given on this app and I will not be responsible  
	for any damage to you, your property or any other person from using it. 
	USE IT ON YOUR OWN RISK. 
 
	Thankyou and have FUNNE =-) 
 
	Masoud Samimi. 
 
##################################################################*/ 
 
#include "stdafx.h" 
#include "MFCGL.h" 
#include "MainFrm.h" 
#include "MFCGLDoc.h" 
#include "MFCGLView.h" 
 
#include "CoordinateAxis.h" 
#include  
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
GLfloat ambientLight[] = { 0.3f, 0.3f,0.3f, 1.0f }; 
GLfloat diffuseLight[] = { 0.7f, 0.7f,0.7f, 1.0f }; 
GLfloat lightPos[] = {-50.0f, 50.0f,100.0f, 1.0f }; 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CMFCGLView 
 
IMPLEMENT_DYNCREATE(CMFCGLView, CView) 
 
BEGIN_MESSAGE_MAP(CMFCGLView, CView) 
	//{{AFX_MSG_MAP(CMFCGLView) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_SIZE() 
	ON_WM_TIMER() 
	ON_WM_ERASEBKGND() 
	ON_COMMAND(C_PAN, OnCameraPan) 
	ON_UPDATE_COMMAND_UI(C_PAN, OnUpdateCameraPan) 
	ON_COMMAND(SELECTMODE, OnSELECTMODE) 
	ON_UPDATE_COMMAND_UI(SELECTMODE, OnUpdateSELECTMODE) 
	ON_WM_MOUSEMOVE() 
	ON_WM_KEYDOWN() 
	ON_WM_LBUTTONDOWN() 
	ON_WM_RBUTTONDOWN() 
	ON_COMMAND(C_ROTATE, OnSceneRotate) 
	ON_UPDATE_COMMAND_UI(C_ROTATE, OnUpdateSceneRotate) 
	ON_WM_PAINT() 
	ON_COMMAND(ID_ORTHO, OnOrtho) 
	ON_UPDATE_COMMAND_UI(ID_ORTHO, OnUpdateOrtho) 
	ON_COMMAND(ID_PERSPECTIVE, OnPerspective) 
	ON_UPDATE_COMMAND_UI(ID_PERSPECTIVE, OnUpdatePerspective) 
	ON_COMMAND(ID_X_VIEW, OnXView) 
	ON_COMMAND(ID_Y_VIEW, OnYView) 
	ON_COMMAND(ID_Z_VIEW, OnZView) 
	ON_COMMAND(ID_FREE_VIEW, OnFreeView) 
	ON_UPDATE_COMMAND_UI(ID_X_VIEW, OnUpdateXView) 
	ON_UPDATE_COMMAND_UI(ID_Y_VIEW, OnUpdateYView) 
	ON_UPDATE_COMMAND_UI(ID_Z_VIEW, OnUpdateZView) 
	ON_UPDATE_COMMAND_UI(ID_FREE_VIEW, OnUpdateFreeView) 
	ON_COMMAND(ID_SHOW_COORDINATE_AXIS, OnShowCoordinateAxis) 
	ON_UPDATE_COMMAND_UI(ID_SHOW_COORDINATE_AXIS, OnUpdateShowCoordinateAxis) 
	ON_COMMAND(ID_DRAWMODE_SOLID, OnDrawmodeSolid) 
	ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SOLID, OnUpdateDrawmodeSolid) 
	ON_COMMAND(ID_DRAWMODE_WIRE, OnDrawmodeWire) 
	ON_UPDATE_COMMAND_UI(ID_DRAWMODE_WIRE, OnUpdateDrawmodeWire) 
	ON_WM_SETCURSOR() 
	ON_COMMAND(ID_DRAWMODE_POINTS, OnDrawmodePoints) 
	ON_UPDATE_COMMAND_UI(ID_DRAWMODE_POINTS, OnUpdateDrawmodePoints) 
	ON_COMMAND(ID_DRAWMODE_SILHOUETTE, OnDrawmodeSilhouette) 
	ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SILHOUETTE, OnUpdateDrawmodeSilhouette) 
	ON_COMMAND(ID_DRAWMODE_ORIENTATION_INSIDE, OnDrawmodeOrientationInside) 
	ON_UPDATE_COMMAND_UI(ID_DRAWMODE_ORIENTATION_INSIDE, OnUpdateDrawmodeOrientationInside) 
	ON_COMMAND(ID_DRAWMODE_ORIENTATION_OUTSIDE, OnDrawmodeOrientationOutside) 
	ON_UPDATE_COMMAND_UI(ID_DRAWMODE_ORIENTATION_OUTSIDE, OnUpdateDrawmodeOrientationOutside) 
	ON_COMMAND(ID_DRAWMODE_SHADING_FLAT, OnDrawmodeShadingFlat) 
	ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SHADING_FLAT, OnUpdateDrawmodeShadingFlat) 
	ON_COMMAND(ID_DRAWMODE_SHADING_NONE, OnDrawmodeShadingNone) 
	ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SHADING_NONE, OnUpdateDrawmodeShadingNone) 
	ON_COMMAND(ID_DRAWMODE_SHADING_SMOOTH, OnDrawmodeShadingSmooth) 
	ON_UPDATE_COMMAND_UI(ID_DRAWMODE_SHADING_SMOOTH, OnUpdateDrawmodeShadingSmooth) 
	//}}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() 
 
///////////////////////////////////////////////////////////////////////////// 
// CMFCGLView construction/destruction 
 
CMFCGLView::CMFCGLView() 
{ 
	// TODO: add construction code here 
	 
	m_pShape = gluNewQuadric();  
 
	m_fLineWidth	= 0.05; 
 
	m_hGLContext	= NULL; 
	m_GLPixelIndex	= 0; 
    m_Action		= SELECT; 
	m_RotateAxis	= AXIS_Z; 
	m_bBuildList	= FALSE; 
	m_bOrtho		= FALSE; 
	m_ViewMode		= FREE_VIEW; 
	m_bShowAxis		= TRUE; 
	 
	m_bSelection	= FALSE; 
 
	m_nDrawMode		= SOLID; 
	m_nDrawOrient	= OUTSIDE; 
	m_nShading		= SMOOTH; 
 
} 
 
CMFCGLView::~CMFCGLView() 
{ 
	gluDeleteQuadric(m_pShape); 
 
} 
 
BOOL CMFCGLView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
	cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS); 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMFCGLView drawing 
 
void CMFCGLView::OnDraw(CDC* pDC) 
{ 
	CMFCGLDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	// TODO: add draw code for native data here 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMFCGLView printing 
 
BOOL CMFCGLView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CMFCGLView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CMFCGLView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMFCGLView diagnostics 
 
#ifdef _DEBUG 
void CMFCGLView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CMFCGLView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CMFCGLDoc* CMFCGLView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCGLDoc))); 
	return (CMFCGLDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CMFCGLView message handlers 
 
BOOL CMFCGLView::SetWindowPixelFormat(HDC hDC) 
{ 
	PIXELFORMATDESCRIPTOR pixelDesc; 
 
	pixelDesc.nSize		= sizeof(PIXELFORMATDESCRIPTOR); 
	pixelDesc.nVersion	= 1; 
 
	pixelDesc.dwFlags	=PFD_DRAW_TO_WINDOW |  
						 PFD_SUPPORT_OPENGL | 
	     				 PFD_STEREO_DONTCARE| 
		    			 PFD_DOUBLEBUFFER; 
 
	      
 
	pixelDesc.iPixelType		= PFD_TYPE_RGBA; 
	pixelDesc.cColorBits		= 32; 
	pixelDesc.cRedBits		= 8; 
	pixelDesc.cRedShift		= 16; 
	pixelDesc.cGreenBits		=8; 
	pixelDesc.cGreenShift		=8; 
	pixelDesc.cBlueBits		= 8; 
	pixelDesc.cBlueShift		= 0; 
	pixelDesc.cAlphaBits		= 0; 
	pixelDesc.cAlphaShift		= 0; 
	pixelDesc.cAccumBits		= 64;	 
	pixelDesc.cAccumRedBits		= 16; 
	pixelDesc.cAccumGreenBits	= 16; 
	pixelDesc.cAccumBlueBits	= 16; 
	pixelDesc.cAccumAlphaBits	= 0; 
	pixelDesc.cDepthBits		= 32; 
	pixelDesc.cStencilBits		= 8; 
	pixelDesc.cAuxBuffers		= 0; 
	pixelDesc.iLayerType		= PFD_MAIN_PLANE; 
	pixelDesc.bReserved		= 0; 
	pixelDesc.dwLayerMask		= 0; 
	pixelDesc.dwVisibleMask		= 0; 
	pixelDesc.dwDamageMask		= 0; 
 
	m_GLPixelIndex = ChoosePixelFormat( hDC, &pixelDesc); 
	if (m_GLPixelIndex==0) // Let's choose a default index. 
	{ 
		m_GLPixelIndex = 1;	 
		if (DescribePixelFormat(hDC,  
						m_GLPixelIndex,  
						sizeof(PIXELFORMATDESCRIPTOR),  
						&pixelDesc)==0) 
		{ 
			return FALSE; 
		} 
	} 
 
	if (SetPixelFormat( hDC,  
				  m_GLPixelIndex,  
				  &pixelDesc)==FALSE) 
	{ 
		return FALSE; 
	} 
 
	return TRUE; 
} 
 
 
int CMFCGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
 
	HWND hWnd = GetSafeHwnd(); 
	HDC hDC = ::GetDC(hWnd); 
 
	if (SetWindowPixelFormat(hDC)==FALSE) 
		return 0; 
	 
	if (CreateViewGLContext(hDC)==FALSE) 
		return 0; 
	 
	SetTimer(0,100,NULL);   //set the timer to make animation 
	return 0; 
} 
 
BOOL CMFCGLView::CreateViewGLContext(HDC hDC) 
{ 
	m_hGLContext = wglCreateContext(hDC); 
	if (m_hGLContext == NULL) 
	{ 
		return FALSE; 
	} 
 
	if (wglMakeCurrent(hDC, m_hGLContext)==FALSE) 
	{ 
		return FALSE; 
	} 
 
	return TRUE; 
} 
 
void CMFCGLView::OnDestroy()  
{ 
	if(wglGetCurrentContext()!=NULL)  
	{ 
		// make the rendering context not current 
		wglMakeCurrent(NULL, NULL) ; 
	} 
	 
	if (m_hGLContext!=NULL) 
	{ 
		wglDeleteContext(m_hGLContext); 
		m_hGLContext = NULL; 
	} 
 
	// Now the associated DC can be released. 
	CView::OnDestroy();  
} 
 
void CMFCGLView::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	 
	GLsizei width, height; 
	GLdouble aspect; 
     
	width = cx; 
	height = cy; 
 
	if (cy==0) 
		aspect = (GLdouble)width; 
	else 
		aspect = (GLdouble)width/(GLdouble)height; 
     
	m_WHRatio=aspect;    //save it for further use. 
 
	glViewport(0, 0, width, height); 
 
    InitOpenGL();       //initialize the GL environment 
 
} 
 
 
 
void CMFCGLView::OnTimer(UINT nIDEvent)  
{ 
	CView::OnTimer(nIDEvent); 
	 
	 
} 
 
 
//override the  virtual function to prevent the window redraw the window client 
BOOL CMFCGLView::OnEraseBkgnd(CDC* pDC)  
{ 
	return FALSE;   //direct return without call the default action; 
} 
 
void CMFCGLView::OnCameraPan()  
{ 
	  m_Action = CAMERA_PAN;     //when click the CameraPan menu item ,set the current action variable 
	  m_bSelection = FALSE; 
} 
 
//update the menu status 
void CMFCGLView::OnUpdateCameraPan(CCmdUI* pCmdUI)  
{ 
	pCmdUI->SetCheck(m_Action==CAMERA_PAN);       
    pCmdUI->Enable(m_ViewMode==FREE_VIEW); 
 
} 
 
void CMFCGLView::OnSELECTMODE()  
{ 
     m_Action = SELECT; 
	 m_bSelection = TRUE; 
} 
 
void CMFCGLView::OnUpdateSELECTMODE(CCmdUI* pCmdUI)  
{ 
     pCmdUI->SetCheck(m_Action==SELECT); 
     pCmdUI->Enable(m_ViewMode==FREE_VIEW); 
	 
} 
 
//according what is the action now ,we do something  
void CMFCGLView::OnMouseMove(UINT nFlags, CPoint point)  
{    
 
	DisplayWorldCoord(point); 
 
    if(nFlags==MK_LBUTTON) 
	{ 
	  
	int rx = point.x-m_OldPoint.x; 
	int ry = point.y-m_OldPoint.y; 
		 
	 switch(m_Action) 
		{ 
		case CAMERA_PAN: 
		       m_Camera.Offset(rx/100.0,-ry/100.0,0);    //pan the scene 
			   break;         
		   
		case SCENE_ROTATE: 
			   m_Scene.RotateRoundAxis(rx/10,m_RotateAxis);  //rotate round the axis 
			   break; 
		} 
 
		m_OldPoint=point; 
		Invalidate(); 
	} 
 
    if(nFlags==MK_RBUTTON) 
	{ 
		 
		int rx=point.x-m_OldPoint.x; 
		 
		switch(m_Action) 
 
		{  
		case CAMERA_PAN: 
		m_Camera.Offset(0,0,rx/100.0); 
		HCURSOR hCursor = NULL; 
		CWinApp *cWinApp = AfxGetApp (); 
		hCursor = cWinApp->LoadCursor (IDC_CUR_ZOOM); 
		::SetCursor(hCursor); 
		break; 
 
		} 
     m_OldPoint=point; 
	 Invalidate(); 
	} 
	 
	//DisplayWorldCoord(point); 
 
	CView::OnMouseMove(nFlags, point); 
} 
 
void CMFCGLView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	if(nChar == VK_TAB && m_Action == SCENE_ROTATE)       
	 
	m_RotateAxis = (m_RotateAxis+1) %3; //alternate the rotate axis 
 
	CView::OnKeyDown(nChar, nRepCnt, nFlags); 
} 
 
void CMFCGLView::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	m_OldPoint = point; 
	 
	UINT xPos = point.x;// horizontal position of cursor  
	WORD yPos = point.y;// vertical position of cursor  
 
	// Render in selection mode and display results 
	if(m_bSelection == TRUE) 
	{ 
	ProcessSelection(xPos, yPos); 
	} 
 
 
	CView::OnLButtonDown(nFlags, point); 
} 
 
void CMFCGLView::OnRButtonDown(UINT nFlags, CPoint point)  
{ 
	m_OldPoint = point; 
	 
	HCURSOR hCursor = NULL; 
    CWinApp *cWinApp = AfxGetApp (); 
	 
    if(m_Action == CAMERA_PAN){ 
	hCursor = cWinApp->LoadCursor (IDC_CUR_ZOOM); 
	::SetCursor(hCursor); 
	 
	} 
 
		 
	CView::OnRButtonDown(nFlags, point); 
} 
 
void CMFCGLView::OnSceneRotate()  
{   
	m_Action = SCENE_ROTATE; 
	m_bSelection = FALSE; 
} 
 
void CMFCGLView::OnUpdateSceneRotate(CCmdUI* pCmdUI)  
{      
      pCmdUI->SetCheck(m_Action == SCENE_ROTATE); 
      pCmdUI->Enable(m_ViewMode==FREE_VIEW); 
 
} 
 
 
 
void CMFCGLView::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
	 
	glLoadIdentity(); 
     
	glClearColor(0.0,0.0,0.0,1); // Black 
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
	 
	CheckOrtho(); 
    SetViewMode(); 
 
	//drawing the coodinate axis. 
    if(m_bShowAxis) 
	{ 
		glDisable(GL_DEPTH_TEST);        
		CCoordinateAxis(2,2,2).Display(); 
    	glEnable(GL_DEPTH_TEST); 
	} 
    
	RenderScene(); 
 
	SwapBuffers(dc.m_ps.hdc); 
} 
 
//when click the ortho menu item 
void CMFCGLView::OnOrtho()    
{ 
	if(m_bOrtho) 
		return; 
	else 
	{ 
	m_bOrtho=TRUE; 
	Invalidate(); 
	} 
	 
} 
 
void CMFCGLView::OnUpdateOrtho(CCmdUI* pCmdUI)  
{ 
	pCmdUI->SetCheck(m_bOrtho); 
} 
 
void CMFCGLView::OnPerspective()  
{ 
	if(!m_bOrtho) 
		return; 
	else 
	{ 
	m_bOrtho=FALSE; 
	Invalidate(); 
	} 
 
} 
 
void CMFCGLView::OnUpdatePerspective(CCmdUI* pCmdUI)  
{ 
     pCmdUI->SetCheck(!m_bOrtho); 
 
} 
 
//do some initialization for the OpenGL 
void CMFCGLView::InitOpenGL() 
{	 
		 
	glLineWidth(m_fLineWidth); 
	glEnable(GL_LINE_SMOOTH); 
 
	glFrontFace(GL_CW); 
	glEnable(GL_CULL_FACE); 
	glCullFace(GL_FRONT); 
 
	glEnable(GL_LIGHTING); 
	glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); 
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); 
	glLightfv(GL_LIGHT0, GL_POSITION, lightPos); 
	glEnable(GL_LIGHT0); 
 
	glEnable(GL_COLOR_MATERIAL); 
	glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE); 
 
	glDepthFunc(GL_LESS); 
	glEnable(GL_DEPTH_TEST); 
     
	glEnable(GL_NORMALIZE); 
 
} 
 
//X-VIEW Mode 
void CMFCGLView::OnXView()  
{     
	m_ViewMode = X_VIEW; 
	m_bOrtho = TRUE; 
	Invalidate(); 
} 
 
void CMFCGLView::OnYView()  
{ 
	m_ViewMode = Y_VIEW; 
	m_bOrtho = TRUE; 
	Invalidate(); 
	 
} 
 
void CMFCGLView::OnZView()  
{ 
	m_ViewMode = Z_VIEW; 
	m_bOrtho = TRUE; 
    Invalidate(); 
	 
} 
 
void CMFCGLView::OnFreeView()  
{ 
	m_ViewMode = FREE_VIEW; 
	m_bOrtho = FALSE; 
    Invalidate(); 
	 
} 
 
void CMFCGLView::OnUpdateXView(CCmdUI* pCmdUI)  
{ 
	pCmdUI->SetCheck(m_ViewMode == X_VIEW); 
 
} 
 
void CMFCGLView::OnUpdateYView(CCmdUI* pCmdUI)  
{ 
	pCmdUI->SetCheck(m_ViewMode == Y_VIEW); 
	 
} 
 
void CMFCGLView::OnUpdateZView(CCmdUI* pCmdUI)  
{ 
	pCmdUI->SetCheck(m_ViewMode == Z_VIEW); 
	 
} 
 
void CMFCGLView::OnUpdateFreeView(CCmdUI* pCmdUI)  
{ 
	pCmdUI->SetCheck(m_ViewMode == FREE_VIEW); 
	 
} 
 
//set the viewmode in the OpenGL 
void CMFCGLView::SetViewMode() 
{ 
    glMatrixMode(GL_MODELVIEW); 
	 
	switch(m_ViewMode) 
	{ 
	case X_VIEW: 
        gluLookAt(100,0,0,0,0,0,0,0,1); 
		break; 
 
	case Y_VIEW: 
		gluLookAt(0,100,0,0,0,0,0,0,1); 
		break; 
	 
	case Z_VIEW: 
		gluLookAt(0,0,100,0,0,0,0,1,0); 
		break; 
	 
	case FREE_VIEW: 
        m_Camera.Apply();                //set the camera transfer matrix 
        gluLookAt(5,5,2,0,0,0,0,0,1);    //the initial view angle 
        m_Scene.Apply();//set scene transfer matrix ,which I use as coordinate  
		break; 
	} 
} 
 
//set ortho or perspective mode 
void CMFCGLView::CheckOrtho() 
{ 
	if(!m_bOrtho) 
	{ 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	gluPerspective(35,m_WHRatio,1,1000); 
	glMatrixMode(GL_MODELVIEW); 
	} 
	else 
	{ 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
    glOrtho(-3*m_WHRatio,3*m_WHRatio,-3,3,-1000,1000); 
	glMatrixMode(GL_MODELVIEW); 
	} 
} 
 
void CMFCGLView::OnShowCoordinateAxis()  
{ 
	m_bShowAxis =! m_bShowAxis; 
	Invalidate(); 
} 
 
void CMFCGLView::OnUpdateShowCoordinateAxis(CCmdUI* pCmdUI)  
{ 
	pCmdUI->SetCheck(m_bShowAxis); 
} 
 
 
void CMFCGLView::OnDrawmodeSolid()  
{ 
	// TODO: Add your command handler code here 
	m_nDrawMode = SOLID; 
	InvalidateRect(NULL); 
		 
} 
 
void CMFCGLView::OnUpdateDrawmodeSolid(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck (m_nDrawMode == SOLID); 
} 
 
void CMFCGLView::OnDrawmodeWire()  
{ 
	// TODO: Add your command handler code here 
	m_nDrawMode = WIRE; 
	Invalidate(); 
} 
 
void CMFCGLView::OnUpdateDrawmodeWire(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck (m_nDrawMode == WIRE); 
} 
 
 
// Parse the selection buffer to see which planet/moon was selected 
void CMFCGLView::ProcessPlanet(GLuint *pSelectBuff) 
{ 
	int id,count; 
	char cMessage[64]; 
 
	// How many names on the name stack 
	count = pSelectBuff[0]; 
 
	// Bottom of the name stack 
	id = pSelectBuff[3]; 
 
 
	// Select on earth or mars, whichever was picked 
	if(m_Action == SELECT && m_bSelection) 
	 
	{	 
	 
	switch(id) 
	{ 
	 
		case DISK: 
			strcpy(cMessage,"Success: Selected Disk."); 
			break; 
 
		case SPHERE: 
			strcpy(cMessage,"Success: Selected Sphere."); 
 
			break; 
 
		case CONE: 
			strcpy(cMessage,"Success: Selected Cone."); 
 
			break; 
 
		case CYLINDER: 
			strcpy(cMessage,"Success: Selected Cylinder."); 
 
			break; 
 
		case TEAPOT: 
			strcpy(cMessage,"Success: Selected Teapot."); 
	 
			break; 
 
		case TORUS: 
			strcpy(cMessage,"Success: Selected Torus."); 
	 
			break; 
 
		case CUBE: 
			strcpy(cMessage,"Success: Selected Cube."); 
		 
			break; 
 
 
		// If nothing was clicked we shouldn't be here! 
		default: 
			strcpy(cMessage,"Error - Nothing was clicked on!"); 
			break; 
		} 
	} 
 
	 
	// Display the message about planet and moon selection 
	AfxMessageBox(cMessage,0,0); 
	 
} 
 
 
// Process the selection, which is triggered by a right mouse 
// click at (xPos, yPos). 
#define BUFFER_LENGTH 64 
void CMFCGLView::ProcessSelection(int xPos, int yPos) 
{ 
	// Space for selection buffer 
	GLuint selectBuff[BUFFER_LENGTH]; 
 
	// Hit counter and viewport storeage 
	GLint hits, viewport[4]; 
 
	// Setup selection buffer 
	glSelectBuffer(BUFFER_LENGTH, selectBuff); 
	 
	// Get the viewport 
	glGetIntegerv(GL_VIEWPORT, viewport); 
 
	// Switch to projection and save the matrix 
	glMatrixMode(GL_PROJECTION); 
	glPushMatrix(); 
 
	// Change render mode 
	glRenderMode(GL_SELECT); 
 
	// Establish new clipping volume to be unit cube around 
	// mouse cursor point (xPos, yPos) and extending two pixels 
	// in the vertical and horzontal direction 
	glLoadIdentity(); 
 
	// Since OpenGL measures 
	// window coordinates starting at the bottom of the window, and Windows 
	// measures starting at the top, we need to account for this by 
	// subtracting the y coordinate from the height of the window. This has 
	// the effect of reversing the coordinate system (y starts at top) 
	 
	gluPickMatrix(xPos, viewport[3] - yPos, 2,2, viewport); 
 
	// Apply perspective matrix  
	gluPerspective(45.0f, m_WHRatio, 1.0, 425.0); 
 
	// Draw the scene 
	RenderScene(); 
 
	// Collect the hits 
	hits = glRenderMode(GL_RENDER); 
 
	// If a single hit occured, display the info. 
	if(hits == 1) 
		ProcessPlanet(selectBuff); 
 
	// Restore the projection matrix 
	glMatrixMode(GL_PROJECTION); 
	glPopMatrix(); 
 
	// Go back to modelview for normal rendering 
	glMatrixMode(GL_MODELVIEW); 
 
} 
 
void CMFCGLView::RenderScene() 
{ 
	switch(m_nDrawMode) 
	{ 
	case SOLID: 
		gluQuadricDrawStyle(m_pShape, GLU_FILL); 
		break; 
 
	case WIRE: 
		gluQuadricDrawStyle(m_pShape, GLU_LINE); 
		break; 
 
	case POINTS: 
		gluQuadricDrawStyle(m_pShape, GLU_POINT); 
		break; 
 
	case SILHOUETTE: 
		gluQuadricDrawStyle(m_pShape, GLU_SILHOUETTE); 
		break; 
	} 
	 
	switch(m_nDrawOrient) 
	{ 
	case INSIDE: 
		gluQuadricOrientation(m_pShape, GLU_INSIDE); 
		break; 
 
	case OUTSIDE: 
		gluQuadricOrientation(m_pShape, GLU_OUTSIDE); 
		break; 
	} 
 
	switch(m_nShading) 
	{ 
	case NONE: 
		gluQuadricNormals(m_pShape, GLU_NONE); 
		break; 
 
	case FLAT: 
		gluQuadricNormals(m_pShape, GLU_FLAT); 
		break; 
		 
	case SMOOTH: 
		gluQuadricNormals(m_pShape, GLU_SMOOTH); 
		break; 
	} 
 
	 
	glMatrixMode(GL_MODELVIEW); 
	glPushMatrix(); 
 
		 
	glInitNames(); 
	glPushName(0); 
 
	glColor3ub(255,255,255); 
 
	glLoadName(SPHERE); 
	gluSphere( m_pShape, 1, 50, 50 );//radius,slices,stacks 
 
	glPushMatrix(); 
	glColor3ub(255,255,255); 
	glTranslatef(-3.0,0.0,0.0); 
	glLoadName(CONE); 
	gluCylinder( m_pShape, 1, 0, 2, 50, 50 ); 
	CCoordinateAxis(2,2,2).Display(); 
	glPopMatrix(); 
 
	glPushMatrix(); 
	glColor3ub(255,255,255); 
	glTranslatef(0.0,2.0,0.0); 
	glLoadName(CYLINDER); 
	gluCylinder( m_pShape, 0.5, 0.5, 2, 50, 50 ); 
	CCoordinateAxis(2,2,2).Display(); 
	glPopMatrix(); 
 
	glPushMatrix(); 
	glColor3ub(255,255,255); 
	glTranslatef(-2.0,-2.0,0.0); 
	glLoadName(DISK); 
	gluDisk( m_pShape, 0.5, 1, 15, 25 ); 
	CCoordinateAxis(2,2,2).Display(); 
	glPopMatrix(); 
 
	switch(m_nDrawMode) 
	{ 
	case WIRE: 
 
	glPushMatrix(); 
	glColor3ub(255,255,255); 
	glTranslatef(2.0,2.0,0.0); 
	glLoadName(TEAPOT); 
	auxWireTeapot(0.5); 
	CCoordinateAxis(2,2,2).Display(); 
	glPopMatrix(); 
	 
	glPushMatrix(); 
	glColor3ub(255,255,255); 
	glTranslatef(-2.0,-2.0,0.0); 
	glLoadName(TORUS); 
	auxWireTorus(0.3, 0.09); 
	CCoordinateAxis(2,2,2).Display(); 
	glPopMatrix(); 
	 
	glPushMatrix(); 
	glColor3ub(255,255,255); 
	glTranslatef(2.5,0.0,0.0); 
	glLoadName(CUBE); 
	auxWireCube(1.0); 
	CCoordinateAxis(2,2,2).Display(); 
	glPopMatrix(); 
 
	break; 
	 
	case SOLID:	 
 
	glPushMatrix(); 
	glColor3ub(255,255,255); 
	glTranslatef(2.5,0.0,0.0); 
	glLoadName(CUBE); 
	auxSolidCube(1.0); 
	CCoordinateAxis(2,2,2).Display(); 
	glPopMatrix(); 
 
	glPushMatrix(); 
	glColor3ub(255,255,255); 
	glTranslatef(-2.0,-2.0,0.0); 
	glLoadName(TORUS); 
	auxSolidTorus(0.3,0.09); 
	CCoordinateAxis(2,2,2).Display(); 
	glPopMatrix(); 
	 
	glPushMatrix(); 
	glColor3ub(255,255,255); 
	glTranslatef(2.0,2.0,0.0); 
	glLoadName(TEAPOT); 
	auxSolidTeapot(0.5); 
	CCoordinateAxis(2,2,2).Display(); 
	glPopMatrix(); 
	 
	break; 
 
} 
    //we should use this to avoid the flash on the screen. 
	 
	glFlush(); 
 
} 
 
 
BOOL CMFCGLView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)  
{ 
	// TODO: Add your message handler code here and/or call default 
   
  if (nHitTest != HTCLIENT)  
   { 
     return CView::OnSetCursor(pWnd, nHitTest, message); 
   } 
   
	 HCURSOR hCursor = NULL; 
    
	 CWinApp *cWinApp = AfxGetApp (); 
    
	 switch (m_Action) { 
 
	 case SCENE_ROTATE: 
         hCursor = cWinApp->LoadCursor (IDC_CUR_ROTATE); 
         break; 
		  
	 case CAMERA_PAN: 
		hCursor = cWinApp->LoadCursor (IDC_CUR_MOVE); 
		break;	 
		 
     case SELECT: 
        hCursor = cWinApp->LoadCursor (IDC_CUR_SELECT); 
          break; 
 
      default: 
         hCursor = LoadCursor (NULL, IDC_ARROW); 
         break; 
   } 
    
	 if (hCursor) SetCursor (hCursor); 
 
   return TRUE; 
 
 
 
} 
 
void CMFCGLView::OnDrawmodePoints()  
{ 
	// TODO: Add your command handler code here 
	m_nDrawMode = POINTS; 
	Invalidate(); 
 
} 
 
void CMFCGLView::OnUpdateDrawmodePoints(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck (m_nDrawMode == POINTS); 
} 
 
void CMFCGLView::OnDrawmodeSilhouette()  
{ 
	// TODO: Add your command handler code here 
	m_nDrawMode = SILHOUETTE; 
	Invalidate(); 
 
} 
 
void CMFCGLView::OnUpdateDrawmodeSilhouette(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck (m_nDrawMode == SILHOUETTE); 
} 
 
void CMFCGLView::OnDrawmodeOrientationInside()  
{ 
	// TODO: Add your command handler code here 
	m_nDrawOrient = INSIDE; 
	Invalidate(); 
} 
 
void CMFCGLView::OnUpdateDrawmodeOrientationInside(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck(m_nDrawOrient == INSIDE); 
} 
 
void CMFCGLView::OnDrawmodeOrientationOutside()  
{ 
	// TODO: Add your command handler code here 
	m_nDrawOrient = OUTSIDE; 
	Invalidate();	 
} 
 
void CMFCGLView::OnUpdateDrawmodeOrientationOutside(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck(m_nDrawOrient == OUTSIDE); 
} 
 
void CMFCGLView::OnDrawmodeShadingFlat()  
{ 
	// TODO: Add your command handler code here 
	m_nShading = FLAT; 
	Invalidate();	 
} 
 
void CMFCGLView::OnUpdateDrawmodeShadingFlat(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck(m_nShading == FLAT); 
} 
 
void CMFCGLView::OnDrawmodeShadingNone()  
{ 
	// TODO: Add your command handler code here 
	m_nShading = NONE; 
	Invalidate();	 
} 
 
void CMFCGLView::OnUpdateDrawmodeShadingNone(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck(m_nShading == NONE); 
} 
 
void CMFCGLView::OnDrawmodeShadingSmooth()  
{ 
	// TODO: Add your command handler code here 
	m_nShading = SMOOTH; 
	Invalidate();	 
} 
 
void CMFCGLView::OnUpdateDrawmodeShadingSmooth(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck(m_nShading == SMOOTH); 
} 
 
 
void CMFCGLView::DisplayWorldCoord(CPoint point) 
{ 
	// Display the world coordinates on the status bar 
 
	char buf[80]; 
	CPoint x = point.x; 
	CPoint y = point.y;  
		 
	CMainFrame* pFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; 
	ASSERT(pFrame); 
	CStatusBar* pStatus = &pFrame->m_wndStatusBar; 
	ASSERT(pStatus); 
	 
	sprintf(buf, "X = %5.2f , Y= %5.2f \n", x, y); 
	pStatus->SetPaneText(1, buf, TRUE); 
	 
	pStatus->Invalidate(); 
 
}