Click here to Skip to main content
15,885,309 members
Articles / Desktop Programming / MFC

The GLU functions and hit testing using OpenGL and MFC

Rate me:
Please Sign up or sign in to vote.
4.62/5 (11 votes)
1 Oct 2000 136.1K   5.7K   62  
This sample teaches you how to create an OpenGL based 3D Drawing application and demonstrates the GLU functions and hit testing using OpenGL and MFC
// 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 <math.h>

#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();

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Technical Lead Samimi Information Technology
United Arab Emirates United Arab Emirates
My company provides services in the fields of:

LAN/WAN Networking
Data Management and Security
Data Recovery
ERP/CRM Solutions
IT Infrastructure Solutions
Software/Hardware Sales/Service

Comments and Discussions