All pastes #187426 Raw Edit

Anonymous

public text v1 · immutable
·published 2006-10-01 02:44 UTC
rendered paste body
// ChildView.cpp : implementation of the CChildView class
//

#include "stdafx.h"
#include "Snowman.h"
#include "ChildView.h"
#include "Resource.h"
#include <cmath>
#include ".\childview.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CChildView

CChildView::CChildView()
: m_spinangle(0)
, m_spintimer(0)
{
}

CChildView::~CChildView()
{
}


BEGIN_MESSAGE_MAP(CChildView, COpenGLWnd)
	ON_WM_PAINT()
	ON_COMMAND(ID_LABSTUFF_SPIN, OnLabstuffSpin)
	ON_WM_TIMER()
END_MESSAGE_MAP()



// CChildView message handlers

BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
{
	if (!COpenGLWnd::PreCreateWindow(cs))
		return FALSE;

	cs.dwExStyle |= WS_EX_CLIENTEDGE;
	cs.style &= ~WS_BORDER;
	cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
		::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);

	return TRUE;
}


void CChildView::OnLabstuffSpin(){
	if(m_spintimer){
		KillTimer(m_spintimer);
		m_spintimer = 0;
	}
	else{
		m_spintimer = (UINT)SetTimer(1, 30, NULL);
	}	
}

void CChildView::OnTimer(UINT nIDEvent)
{
	m_spinangle += 2.0;
	Invalidate();
	COpenGLWnd::OnTimer(nIDEvent);
}

void drawAxes(void){
  glBegin(GL_LINES);
  glVertex3d(0.0,0.0,0.0);
  glVertex3d(10.0, 0.0, 0.0);
  glEnd();
  glBegin(GL_LINES);
  glVertex3d(0.0,0.0,0.0);
  glVertex3d(0.0,10.0,0.0);
  glEnd();
  glBegin(GL_LINES);
  glVertex3d(0.0,0.0,0.0);
  glVertex3d(0.0,0.0,10.0);
  glEnd();
}

void DrawSphere( Sphere s )
{
  glMatrixMode( GL_MODELVIEW );
  
  GLUquadricObj *quadric;
  quadric=gluNewQuadric();			
  gluQuadricNormals(quadric, GLU_SMOOTH);
  //gluQuadricDrawStyle( quadric, GLU_SOLID );

  glPushMatrix();
    glTranslated( s.GetX(), s.GetY(), s.GetZ() );
    glColor3d( s.GetRed(), s.GetGreen(), s.GetBlue() );
  	gluSphere(quadric, s.GetRadius(), 16, 16 );
  glPopMatrix();
}

void CChildView::OnGLDraw(CDC* pDC)
{
  int width, height;
  Snowman Frosty;
	
  GetSize(width, height);
  
  // Clear render buffers

  glClearColor(0.0f, 0.0f, 0.0f, 0.0f) ;
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Simple rectangle example
	
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(60.0, 1.0, 1.0, 100.0);
		   
  double a2r=3.1415926/180.0;
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(cos(m_spinangle*a2r)*30, 5.0, sin(m_spinangle*a2r)*30,
			0.0, 0.0, 0.0,
			0.0, 1.0, 0.0);
  glColor3d(0.0, 0.0, 1.0);
  drawAxes();

  // Render our snowman

  Frosty.InitSnowman();
  Frosty.DrawSnowman();

  // Print out the snowman's volume. Format a CString, plugging in the
  // overall volume (from Snowman::GetVolume). Set the background color
  // to black, text color to white, and TextOut() through the device
  // context

  CString sVolume;
  sVolume.Format( "Snowman Volume: %.3lf", Frosty.GetVolume() );

  pDC->SetBkColor( 0 );
  pDC->SetTextColor( RGB( 255, 255, 255 ) );
  pDC->TextOut( 2, 2, sVolume );
	
  // Flush to the screen

  glFlush();
}

// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "SnowmanApp.h"

#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_CREATE()
	ON_WM_SETFOCUS()
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // status line indicator
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};


// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
	// TODO: add member initialization code here
}

CMainFrame::~CMainFrame()
{
}


int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	// create a view to occupy the client area of the frame
	if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
		CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
	{
		TRACE0("Failed to create view window\n");
		return -1;
	}
	
	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
	{
		TRACE0("Failed to create toolbar\n");
		return -1;      // fail to create
	}

	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators,
		  sizeof(indicators)/sizeof(UINT)))
	{
		TRACE0("Failed to create status bar\n");
		return -1;      // fail to create
	}
	// TODO: Delete these three lines if you don't want the toolbar to be dockable
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);

	return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
	cs.lpszClass = AfxRegisterWndClass(0);
	return TRUE;
}


// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG


// CMainFrame message handlers

void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)
{
	// forward focus to the view window
	m_wndView.SetFocus();
}

BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
	// let the view have first crack at the command
	if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
		return TRUE;

	// otherwise, do default handling
	return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
//
// Name :         OpenGLWnd.cpp
// Description :  Implementation for the COpenGLWnd class.  This is a
//                class derived from CWnd that will automatically set up
//                for OpenGL.  You can use this whereever you would use
//                CWnd and you'll automatically have OpenGL in this window.
// Author :       Charles B. Owen
// Version :       1-09-01 1.00 CBO Initial version number.
//                 3-03-03 1.01 CBO Improved error handing.
//                 3-16-03 1.02 CBO Fixed problem with saving image
//


#include "stdafx.h"
#include "OpenGLWnd.h"

#include <cassert>
#include <fstream>
#include <vector>
#include <strstream>

using namespace std;

/////////////////////////////////////////////////////////////////////////////
// COpenGLWnd

COpenGLWnd::COpenGLWnd()
{
	m_pPal = NULL;
  m_created = false;
  
  // Dr. Owen's code had this flag disabled; the flicker almost gave me a
  // stroke so I turned it on. No more flicker! Sweeeet. If there's any
  // run-time problems, this should probably be turned off
  
  m_doublebuffer = false;
}

COpenGLWnd::~COpenGLWnd()
{
}


BEGIN_MESSAGE_MAP(COpenGLWnd, CWnd)
	//{{AFX_MSG_MAP(COpenGLWnd)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// COpenGLWnd message handlers

BOOL COpenGLWnd::PreCreateWindow(CREATESTRUCT& cs) 
{
	if (!CWnd::PreCreateWindow(cs))
		return FALSE;

	// Added for OpenGL
   cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;

	return true;
}

int COpenGLWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
    CClientDC dc(this) ;
    //
    // Fill in the pixel format descriptor.
    //
    PIXELFORMATDESCRIPTOR pfd ;
    memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)) ;
    pfd.nSize      = sizeof(PIXELFORMATDESCRIPTOR); 
    pfd.nVersion   = 1 ; 
    pfd.dwFlags    = PFD_SUPPORT_OPENGL |
                        PFD_DRAW_TO_WINDOW ;

    if(m_doublebuffer)
        pfd.dwFlags |= PFD_DOUBLEBUFFER;

    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24 ;
    pfd.cAlphaBits = 8;
    pfd.cDepthBits = 32 ;
    pfd.iLayerType = PFD_MAIN_PLANE ;
    	
    int nPixelFormat = ChoosePixelFormat(dc.m_hDC, &pfd);
    if (nPixelFormat == 0)
        return FormattedErrorAfxMsgBox("ChoosePixelFormat Failed");

    BOOL bResult = SetPixelFormat (dc.m_hDC, nPixelFormat, &pfd);
    if(!bResult)
        return FormattedErrorAfxMsgBox("SetPixelFormat  Failed");

    //
    // Create a rendering context.
    //
    m_hrc = wglCreateContext(dc.m_hDC);
    if (!m_hrc)
        return FormattedErrorAfxMsgBox("Unable to create an OpenGL rendering context");

    // Create the palette
	CreateRGBPalette(dc.m_hDC) ;

    m_created = true;
	
	return 0;
}


//
// CreateRGBPalette
//
BOOL COpenGLWnd::CreateRGBPalette(HDC hDC)
{
	//
	// Check to see if we need a palette
	//
    PIXELFORMATDESCRIPTOR pfd;
    int n = GetPixelFormat(hDC);
    DescribePixelFormat(hDC, n, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
	if (!(pfd.dwFlags & PFD_NEED_PALETTE)) return FALSE ;

    // allocate a log pal and fill it with the color table info
    LOGPALETTE* pPal = (LOGPALETTE*) malloc(sizeof(LOGPALETTE) 
                     + 256 * sizeof(PALETTEENTRY));
    if (!pPal) 
    {
        AfxMessageBox("Out of memory for pallet", MB_OK | MB_ICONSTOP);
        return FALSE;
    }
    pPal->palVersion = 0x300; // Windows 3.0
    pPal->palNumEntries = 256; // table size

	//
	// Create RGB Palette
	//
	ASSERT( pfd.cColorBits == 8) ;
     n = 1 << pfd.cColorBits;
    for (int i=0; i<n; i++)
    {
        pPal->palPalEntry[i].peRed =
                ComponentFromIndex(i, pfd.cRedBits, pfd.cRedShift);
        pPal->palPalEntry[i].peGreen =
                ComponentFromIndex(i, pfd.cGreenBits, pfd.cGreenShift);
        pPal->palPalEntry[i].peBlue =
                ComponentFromIndex(i, pfd.cBlueBits, pfd.cBlueShift);
        pPal->palPalEntry[i].peFlags = 0;
    }

	//
	// Fix up color table with system colors.
	//
    if ((pfd.cColorBits == 8)                           &&
        (pfd.cRedBits   == 3) && (pfd.cRedShift   == 0) &&
        (pfd.cGreenBits == 3) && (pfd.cGreenShift == 3) &&
        (pfd.cBlueBits  == 2) && (pfd.cBlueShift  == 6)
       )
    {
	    for (int j = 1 ; j <= 12 ; j++)
	          pPal->palPalEntry[m_defaultOverride[j]] = m_defaultPalEntry[j];
	}

    // Delete any existing GDI palette
	if (m_pPal) 
      delete m_pPal ;
	m_pPal = new CPalette ;

    BOOL bResult = m_pPal->CreatePalette(pPal);
    free (pPal);

    return bResult;
}


//////////////////////////////////////////////////////////////////////////////////////
//
// OpenGLpalette
//
unsigned char COpenGLWnd::m_threeto8[8] = {
    0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
};
unsigned char COpenGLWnd::m_twoto8[4] = {
   0, 0x55, 0xaa, 0xff
};
unsigned char COpenGLWnd::m_oneto8[2] = {
    0, 255
};

int COpenGLWnd::m_defaultOverride[13] = {
    0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91
};

PALETTEENTRY COpenGLWnd::m_defaultPalEntry[20] = {
    { 0,   0,   0,    0 }, //0
    { 0x80,0,   0,    0 }, 
    { 0,   0x80,0,    0 }, 
    { 0x80,0x80,0,    0 }, 
    { 0,   0,   0x80, 0 },
    { 0x80,0,   0x80, 0 },
    { 0,   0x80,0x80, 0 },
    { 0xC0,0xC0,0xC0, 0 }, //7

    { 192, 220, 192,  0 }, //8
    { 166, 202, 240,  0 },
    { 255, 251, 240,  0 },
    { 160, 160, 164,  0 }, //11

    { 0x80,0x80,0x80, 0 }, //12
    { 0xFF,0,   0,    0 },
    { 0,   0xFF,0,    0 },
    { 0xFF,0xFF,0,    0 },
    { 0,   0,   0xFF, 0 },
    { 0xFF,0,   0xFF, 0 },
    { 0,   0xFF,0xFF, 0 },
    { 0xFF,0xFF,0xFF, 0 }  //19
  };



//
// ComponentFromIndex
//
unsigned char COpenGLWnd::ComponentFromIndex(int i, UINT nbits, UINT shift)
{
    unsigned char val;

    val = (unsigned char) (i >> shift);
    switch (nbits) {

    case 1:
        val &= 0x1;
        return m_oneto8[val];

    case 2:
        val &= 0x3;
        return m_twoto8[val];

    case 3:
        val &= 0x7;
        return m_threeto8[val];

    default:
        return 0;
    }
}


void COpenGLWnd::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
   // Select the palette.
   CPalette* ppalOld = NULL;
	if (m_pPal)
	{
    	ppalOld = dc.SelectPalette(m_pPal, 0);
    	dc.RealizePalette();
	}
	
	// Make the HGLRC current
   BOOL bResult = wglMakeCurrent(dc.m_hDC, m_hrc);
   if (!bResult)
   {
      FormattedErrorAfxMsgBox("wglMakeCurrent Failed");
   }

   // Set the window:
   int width, height;
   GetSize(width, height);

   // Set the viewport
   glViewport(0, 0, width, height);

   glEnable( GL_DEPTH_TEST );

   //
   // Set up the mapping of 3-space to screen space
   //
   GLdouble gldAspect = GLdouble(width)/ GLdouble(height);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();

   
   gluPerspective(30.0, gldAspect, 1.0, 10.0);

	// Draw	
	OnGLDraw(&dc);

	//Swap Buffers
	if(m_doublebuffer)
      SwapBuffers(dc.m_hDC) ;

   // select old palette if we altered it
   if (ppalOld) 
      dc.SelectPalette(ppalOld, 0); 

	wglMakeCurrent(NULL, NULL) ;
}


void COpenGLWnd::SetDoubleBuffer(bool p_doublebuffer)
{
   // Double buffering must be set before the window is created.
   assert(!m_created);

   m_doublebuffer = p_doublebuffer;
}


//
// Name :         COpenGLWnd::OnGLDraw(CDC *pDC)
// Description :  Default OnGLDraw function.  This function clears the screen to a
//                strange color.
//

void COpenGLWnd::OnGLDraw(CDC *pDC)
{
   glClearColor(0.0f, 1.0f, 1.0f, 0.0f) ;
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glFlush();
}

//
// Name :         COpenGLWnd::GetSize()
// Description :  Convenience function to obtain the window size.
//

void COpenGLWnd::GetSize(int &p_width, int &p_height)
{
   RECT rect;
   GetClientRect(&rect);

   p_width = rect.right;
   p_height = rect.bottom;
}


BOOL COpenGLWnd::OnEraseBkgnd(CDC* pDC) 
{
	return true;
}

#define DIB_HEADER_MARKER   ((WORD) ('M' << 8) | 'B')
const int DIB_PADSIZE = 4;

//
// Name :         COpenGLWnd::OnSaveImage()
// Description :  This is called by a menu option.  It saves the current window image
//                as a DIB file.  It pops up a dialog box asking for the file name.
//

void COpenGLWnd::OnSaveImage()
{
   CWaitCursor wait;

   //
   // Obtain the image pixels
   //

   GLbyte **buffer;
   if(!ObtainPixels(buffer))
      return;

   //
   // Determine the output file
   //

	static char BASED_CODE szFilter[] = "Image Files (*.bmp)|*.bmp|All Files (*.*)|*.*||";

	CFileDialog dlg(FALSE, ".bmp", NULL, 0, szFilter, NULL);
	if(dlg.DoModal() != IDOK)
   {
      delete buffer[0];
      delete buffer;
      return;
   }

   UpdateWindow();

   // Open the file
   std::ofstream file(dlg.GetPathName(), std::ios::binary);

   //
   // Write the image file header
   //

   int width, height;
   GetSize(width, height);

   int usewidth3 = (width * 3 + (DIB_PADSIZE - 1)) / DIB_PADSIZE;     
   usewidth3 *= DIB_PADSIZE;

   BITMAPFILEHEADER bmfHdr;   // Header for Bitmap file

   // Fill in the bitmap file header
	bmfHdr.bfType = DIB_HEADER_MARKER;  // "BM"
   bmfHdr.bfSize = sizeof(BITMAPFILEHEADER) + 
         sizeof(BITMAPINFOHEADER) + height * usewidth3;
   bmfHdr.bfReserved1 = 0;
   bmfHdr.bfReserved2 = 0;
   bmfHdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

   // Fill in a BITMAPINFOHEADER
   BITMAPINFOHEADER bmi;

   bmi.biSize = sizeof(bmi);
   bmi.biWidth = width;
   bmi.biHeight = height;
   bmi.biPlanes = 1;
   bmi.biBitCount = 24;
   bmi.biCompression = BI_RGB;
   bmi.biSizeImage = 0;
   bmi.biXPelsPerMeter = 1;
   bmi.biYPelsPerMeter = 1;
   bmi.biClrUsed = 0;
   bmi.biClrImportant = 0;

   file.write((const char *)&bmfHdr, sizeof(BITMAPFILEHEADER));
   file.write((const char *)&bmi, sizeof(bmi));

   if(!file)
   {
      AfxMessageBox("Unable to write output file file", IDOK);
      delete buffer[0];
      delete buffer;

      return;
   }

   for(int i=0;  i<height;  i++)
   {
      file.write((const char *)&buffer[i][0], usewidth3);
   }

   delete buffer[0];
   delete buffer;

   if(!file)
   {
      AfxMessageBox("Unable to write output file file", IDOK);
      return;
   }

   file.close();

   wait.Restore();
}


//
// Name :         COpenGLWnd::ObtainPixels()
// Description :  Allocates the 2D array for p_pixels and obtains all of the 
//                image pixels into it from OpenGL.
// Returns :      true if successful.
//

bool COpenGLWnd::ObtainPixels(GLbyte **&p_pixels)
{
    // Force window to be up-to-date
    UpdateWindow();

    //
    // Make the OpenGL rendering context current
    //

    CClientDC dc(this) ;
    BOOL bResult = wglMakeCurrent(dc.m_hDC, m_hrc);
	if (!bResult)
	{
      AfxMessageBox("Unable to select OpenGL rendering context, could not obtain pixel data.");
      p_pixels = NULL;
      return false;
	}

   //
   // Allocate space for the image
   //

   int width, height;
   GetSize(width, height);

   int usewidth3 = (width * 3 + (DIB_PADSIZE - 1)) / DIB_PADSIZE;     
   usewidth3 *= DIB_PADSIZE;

   p_pixels = new GLbyte *[height];
   p_pixels[0] = new GLbyte[height * usewidth3];
   for(int j=1;  j<height;  j++)
      p_pixels[j] = p_pixels[0] + j * usewidth3; 

   //
   // Configure OpenGL for obtaining the rows.
   //

   GLint swapbytes, lsbfirst, rowlength;
   GLint skiprows, skippixels, alignment;

   /* Save current modes. */
   glGetIntegerv(GL_PACK_SWAP_BYTES, &swapbytes);
   glGetIntegerv(GL_PACK_LSB_FIRST, &lsbfirst);
   glGetIntegerv(GL_PACK_ROW_LENGTH, &rowlength);
   glGetIntegerv(GL_PACK_SKIP_ROWS, &skiprows);
   glGetIntegerv(GL_PACK_SKIP_PIXELS, &skippixels);
   glGetIntegerv(GL_PACK_ALIGNMENT, &alignment);

   glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
   glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE);
   glPixelStorei(GL_PACK_ROW_LENGTH, 0);
   glPixelStorei(GL_PACK_SKIP_ROWS, 0);
   glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
   glPixelStorei(GL_PACK_ALIGNMENT, DIB_PADSIZE);

   //
   // Actually read the pixels.
   //

   glReadBuffer(GL_FRONT);
   glReadPixels(0, 0, width, height, GL_BGR_EXT,
                GL_UNSIGNED_BYTE, (GLvoid *)&p_pixels[0][0]);

   /* Restore saved modes. */
   glPixelStorei(GL_PACK_SWAP_BYTES, swapbytes);
   glPixelStorei(GL_PACK_LSB_FIRST, lsbfirst);
   glPixelStorei(GL_PACK_ROW_LENGTH, rowlength);
   glPixelStorei(GL_PACK_SKIP_ROWS, skiprows);
   glPixelStorei(GL_PACK_SKIP_PIXELS, skippixels);
   glPixelStorei(GL_PACK_ALIGNMENT, alignment);

   wglMakeCurrent(NULL, NULL) ;

   return true;
}


//
// Name :        COpenGLWnd::FormattedErrorAfxMsgBox()
// Description : Output an error message to a message box based on
//               the GetLastError value.
//

int COpenGLWnd::FormattedErrorAfxMsgBox(const char *p_msg)
{
    LPVOID lpMsgBuf;
    FormatMessage( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetLastError(),
        0, // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL 
        );

    ostrstream str;
    str << p_msg << " " << (char *)lpMsgBuf << ends;
    
    // Free the buffer.
    LocalFree( lpMsgBuf );

    AfxMessageBox(str.str(), MB_OK | MB_ICONSTOP);
    delete str.str();

    return -1;
}



// ChildView.h : interface of the CChildView class
//


#pragma once

#include "OpenGLWnd.h"
#include "Sphere.h"

// CChildView window

void DrawSphere( Sphere );
void drawAxes(void);

class CChildView : public COpenGLWnd
{
// Construction
public:
	CChildView();

// Attributes
public:

// Operations
public:

// Overrides
	protected:
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

// Implementation
public:
	virtual ~CChildView();

	// Generated message map functions
protected:
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnLabstuffSpin();
	double m_spinangle;
	UINT m_spintimer;
	afx_msg void OnTimer(UINT nIDEvent);
	void OnGLDraw(CDC* pdc);
	afx_msg void OnLabstuffNewthing();
};

// MainFrm.h : interface of the CMainFrame class
//


#pragma once

#include "ChildView.h"
class CMainFrame : public CFrameWnd
{
	
public:
	CMainFrame();
protected: 
	DECLARE_DYNAMIC(CMainFrame)

// Attributes
public:

// Operations
public:

// Overrides
public:
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);

// Implementation
public:
	virtual ~CMainFrame();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:  // control bar embedded members
	CStatusBar  m_wndStatusBar;
	CToolBar    m_wndToolBar;
	CChildView    m_wndView;

// Generated message map functions
protected:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnSetFocus(CWnd *pOldWnd);
	DECLARE_MESSAGE_MAP()
};


#if !defined(AFX_OPENGLWND_H__13666F99_C0F9_4AF4_B544_4E9DC57E5FE5__INCLUDED_)
#define AFX_OPENGLWND_H__13666F99_C0F9_4AF4_B544_4E9DC57E5FE5__INCLUDED_

//
// Name :         OpenGLWnd.h
// Description :  Header file for COpenGLWnd OpenGL superclass.
// Documentation : See OpenGLWnd.cpp
// Author :       Charles B. Owen
//


#pragma once

#include <gl/gl.h>
#include <gl/glu.h>

/////////////////////////////////////////////////////////////////////////////
// COpenGLWnd window

class COpenGLWnd : public CWnd
{
// Construction
public:

	COpenGLWnd();

// Attributes
public:

// Operations
public:
   virtual void OnGLDraw(CDC *pDC);

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(COpenGLWnd)
	protected:
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	//}}AFX_VIRTUAL

// Implementation
public:
	void OnSaveImage();
	void GetSize(int &p_width, int &p_height);
	bool ObtainPixels(GLbyte **&p_pixels);
	virtual ~COpenGLWnd();

   HGLRC HGLRc() {return m_hrc;}

	// Generated message map functions
protected:
	 void SetDoubleBuffer(bool p_doublebuffer);
   bool GetDoubleBuffer() const {return m_doublebuffer;}

	//{{AFX_MSG(COpenGLWnd)
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnPaint();
   afx_msg BOOL OnEraseBkgnd(CDC* pDC);
   //}}AFX_MSG
	DECLARE_MESSAGE_MAP()

private:
    int FormattedErrorAfxMsgBox(const char *p_msg);

	bool m_created;
	bool m_doublebuffer;
    BOOL CreateRGBPalette(HDC hDC);

    HGLRC m_hrc;
	CPalette* m_pPal ;		//Palette

   	//
	// Support for generating RGB color palette
	//
	unsigned char ComponentFromIndex(int i, UINT nbits, UINT shift) ;

 	static unsigned char   m_oneto8[2];
    static unsigned char   m_twoto8[4];
    static unsigned char   m_threeto8[8];
    static int             m_defaultOverride[13];
    static PALETTEENTRY    m_defaultPalEntry[20];
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_OPENGLWND_H__13666F99_C0F9_4AF4_B544_4E9DC57E5FE5__INCLUDED_)
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by MyRobot.rc
//
#define IDD_ABOUTBOX                    100
#define IDP_OLE_INIT_FAILED             100
#define IDR_MAINFRAME                   128
#define IDR_SnowmanTYPE                 129
#define ID_LABSTUFF_SPIN                32771
#define ID_LABSTUFF_NEWTHING            32772

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        130
#define _APS_NEXT_COMMAND_VALUE         32773
#define _APS_NEXT_CONTROL_VALUE         1000
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
//===========================================================================
// The Snowman Class
//===========================================================================
#include <iostream>
#include "stdafx.h"
#include "Snowman.h"
#include "Sphere.h"

using namespace std;

/*
rgb colors
grey (211, 211, 211)
black (0,0,0);
*/

//===========================================
// Snowman::InitSnowman
//   Initializes all private member spheres.
//===========================================
void Snowman::InitSnowman()
{
	// draw head
	myHead.SetRadius(1.0);
	myHead.SetBlue(232.0);
	myHead.SetGreen(232.0);
	myHead.SetRed(232.0);
	myHead.SetX(0.0);
	myHead.SetY(7.7);
	myHead.SetZ(0.0);

	//draw torso
	myMiddle.SetRadius(2.0);
	myMiddle.SetBlue(232.0);
	myMiddle.SetGreen(232.0);
	myMiddle.SetRed(232.0);
	myMiddle.SetX(0.0);
	myMiddle.SetY(4.8);
	myMiddle.SetZ(0.0);

	//draw lower body
	myBottom.SetRadius(3.0);
	myBottom.SetBlue(232.0);
	myBottom.SetGreen(232.0);
	myBottom.SetRed(232.0);
	myBottom.SetX(0.0);
	myBottom.SetY(0.0);
	myBottom.SetZ(0.0);
/*
	//draw first eye
	eyeOne.SetRadius(5.0);
	eyeOne.SetBlue(211.0);
	eyeOne.SetGreen(211.0);
	eyeOne.SetRed(211.0);
	eyeOne.SetX(10.0);
	eyeOne.SetY(10.0);
	eyeOne.SetZ(0.0);

	//draw second eye
	eyeTwo.SetRadius(5.0);
	eyeTwo.SetBlue(211.0);
	eyeTwo.SetGreen(211.0);
	eyeTwo.SetRed(211.0);
	eyeTwo.SetX(10.0);
	eyeTwo.SetY(10.0);
	eyeTwo.SetZ(2.0);
*/
}
//==================================================================
// Snowman::DrawSnowman
//   Calls the framework's DrawSphere() function for every sphere to be
//   rendered (that is, all the spheres that comprise the snowman).
//==================================================================
void Snowman::DrawSnowman()
{
	DrawSphere(myHead);
	DrawSphere(myMiddle);
	DrawSphere(myBottom);
	DrawSphere(eyeOne);
	DrawSphere(eyeTwo);
}
double Snowman::GetVolume()
{
	double volume = (myHead.GetVolume() + myMiddle.GetVolume() + myBottom.GetVolume());
	return volume;
}
//end of file//===========================================================================
// The Snowman Class
//===========================================================================
#ifndef _Snowman
#define _Snowman

//includes
#include "stdafx.h"
#include "ChildView.h"
#include "Sphere.h"

class Snowman
{
  private:
    Sphere myHead;
	Sphere myMiddle;
	Sphere myBottom;
	Sphere eyeOne;
	Sphere eyeTwo;

  public:
    void InitSnowman(),
		 DrawSnowman();
	double GetVolume();
};

//===========================================================================
// [Eof]
//===========================================================================

#endif
// Snowman.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "SnowmanApp.h"
#include "MainFrm.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CSnowmanApp

BEGIN_MESSAGE_MAP(CSnowmanApp, CWinApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
END_MESSAGE_MAP()


// CSnowmanApp construction

CSnowmanApp::CSnowmanApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}


// The one and only CSnowmanApp object

CSnowmanApp theApp;

// CSnowmanApp initialization

BOOL CSnowmanApp::InitInstance()
{
	// InitCommonControls() is required on Windows XP if an application
	// manifest specifies use of ComCtl32.dll version 6 or later to enable
	// visual styles.  Otherwise, any window creation will fail.
	InitCommonControls();

	CWinApp::InitInstance();

	// Initialize OLE libraries
	if (!AfxOleInit())
	{
		AfxMessageBox(IDP_OLE_INIT_FAILED);
		return FALSE;
	}
	AfxEnableControlContainer();
	// Standard initialization
	// If you are not using these features and wish to reduce the size
	// of your final executable, you should remove from the following
	// the specific initialization routines you do not need
	// Change the registry key under which our settings are stored
	// TODO: You should modify this string to be something appropriate
	// such as the name of your company or organization
	SetRegistryKey(_T("Local AppWizard-Generated Applications"));
	// To create the main window, this code creates a new frame window
	// object and then sets it as the application's main window object
	CMainFrame* pFrame = new CMainFrame;
	if (!pFrame)
		return FALSE;
	m_pMainWnd = pFrame;
	// create and load the frame with its resources
	pFrame->LoadFrame(IDR_MAINFRAME,
		WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
		NULL);
	// The one and only window has been initialized, so show and update it
	
	pFrame->SetWindowText( "Project 05 / CSE231: Snowmen and Spheres" );
	pFrame->ShowWindow(SW_SHOW);
	pFrame->UpdateWindow();
	// call DragAcceptFiles only if there's a suffix
	//  In an SDI app, this should occur after ProcessShellCommand
	return TRUE;
}


// CSnowmanApp message handlers



// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	enum { IDD = IDD_ABOUTBOX };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()

// App command to run the dialog
void CSnowmanApp::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}


// CSnowmanApp message handlers

// SnowmanApp.h : main header file for the Snowman application
//
#pragma once

#ifndef __AFXWIN_H__
	#error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"       // main symbols


// CSnowmanApp:
// See Snowman.cpp for the implementation of this class
//

class CSnowmanApp : public CWinApp
{
public:
	CSnowmanApp();

// Overrides
public:
	virtual BOOL InitInstance();

// Implementation

public:
	afx_msg void OnAppAbout();
	DECLARE_MESSAGE_MAP()
};

extern CSnowmanApp theApp;#ifndef _Sphere
#define _Sphere

//=========
// Sphere
//=========

class Sphere
{
public:
	Sphere(); //constructor

	double      //all of the get functions return a respective double value
		GetX(),
		GetY(),
		GetZ(),
		GetRed(),
		GetGreen(),
		GetBlue(),
		GetRadius(),
		GetVolume();

	void		// all of the void Set* funtions take a double
		 SetX(double),
		 SetY(double),
		 SetZ(double),
		 SetGreen(double),
		 SetBlue(double),
		 SetRed(double),
		 SetRadius(double);

private:
	double
		x, y, z, r, g, b, radius;
};
//end Sphere header
#endif
#include <iostream>
#include "stdafx.h"
#include "Sphere.h"

using namespace std;


Sphere::Sphere()	//implement default Sphere constructor
{
}
double Sphere::GetX()
{
	return x;
}
double Sphere::GetY()
{
	return y;
}
double Sphere::GetZ()
{
	return z;
}
double Sphere::GetRed()
{
	return r;
}
double Sphere::GetGreen()
{
	return g;
}
double Sphere::GetBlue()
{
	return b;
}
double Sphere::GetRadius()
{
	return radius;
}
double Sphere::GetVolume()
{
	double volume = (4.0 / 3.0) * (3.14) * (radius * radius * radius);
	return volume;
}
void Sphere::SetX(double newX)
{
	x = newX;
}
void Sphere::SetY(double newY)
{
	y = newY;
}
void Sphere::SetZ(double newZ)
{
	z = newZ;
}
void Sphere::SetRed(double newRed)
{
	r = newRed;
}
void Sphere::SetGreen(double newGreen)
{
	g = newGreen;
}
void Sphere::SetBlue(double newBlue)
{
	b = newBlue;
}
void Sphere::SetRadius(double newRadius)
{
	radius = newRadius;
}#ifndef _Sphere
#define _Sphere

//=========
// Sphere
//=========

class Sphere
{
public:
	Sphere(); //constructor

	double      //all of the get functions return a respective double value
		GetX(),
		GetY(),
		GetZ(),
		GetRed(),
		GetGreen(),
		GetBlue(),
		GetRadius(),
		GetVolume();

	void		// all of the void Set* funtions take a double
		 SetX(double),
		 SetY(double),
		 SetZ(double),
		 SetGreen(double),
		 SetBlue(double),
		 SetRed(double),
		 SetRadius(double);

private:
	double
		x, y, z, r, g, b, radius;
};
//end Sphere header
#endif
// stdafx.cpp : source file that includes just the standard includes
// MyRobot.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"


// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently

#pragma once

#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
#endif

// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER				// Allow use of features specific to Windows 95 and Windows NT 4 or later.
#define WINVER 0x0400		// Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif

#ifndef _WIN32_WINNT		// Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT 0x0400		// Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif						

#ifndef _WIN32_WINDOWS		// Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif

#ifndef _WIN32_IE			// Allow use of features specific to IE 4.0 or later.
#define _WIN32_IE 0x0400	// Change this to the appropriate value to target IE 5.0 or later.
#endif

#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS	// some CString constructors will be explicit

// turns off MFC's hiding of some common and often safely ignored warning messages
#define _AFX_ALL_WARNINGS

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdisp.h>        // MFC Automation classes

#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>			// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT