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