/*****************************************************
Copyright Notice & Disclaimer
Copyright � Alessandro Falappa
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose is hereby granted without
fee, provided that the above copyright notice, author statement
appear in all copies of this software and related documentation.
If you make enhancement or you discover bugs, please let me
know
THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT
LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A
PARTICULAR PURPOSE.
IN NO EVENT SHALL ALESSANDRO FALAPPA BE LIABLE FOR ANY
SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE,
AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
///////////////////////////////////////////////
History
v 1.0: first version
v 1.1: added CGLDispList helper class
changed previous disp list service in StockDispList
v 1.2: added CGLTesselator helper class
added GLCommands pair
added CGLQuadric wrapper class
******************************************************/
// CGLEnabledView.cpp : implementation file of version 1.2
//
#include "stdafx.h"
/*******************
NOTE ABOUT LIBRARIES INCLUSION:
- Remember to include the appropriate libraries in the link phase
(look at Project Settings under the Link tab)
- If you were lucky enough to get SGI's implementation (at present it's
not availabl nor supported) you can play with it also, just include
that libraries. SGI's version is faster if you have no GL acceleration
and if you own a MMX processor
- These includes below can be moved to stdafx.h to speed up compilation
********************/
//* MS openGL libraries (link with OPENGL32.LIB and GLU32.LIB)
#include "gl\gl.h"
#include "gl\glu.h"
//*/
/* SGI openGL libraries (link with OPENGL.LIB and GLU.LIB)
#include "[path-of-SGI-sdk]\include\gl\gl.h"
#include "[path-of-SGI-sdk]\include\gl\glu.h"
//*/
//#include "afxtempl.h"
#include "GLEnabledView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define MAX_LISTS 20
// used to identify a MCD video driver (partial OGL acceleration)
#define INSTALLABLE_DRIVER_TYPE_MASK (PFD_GENERIC_ACCELERATED|PFD_GENERIC_FORMAT)
/////////////////////////////////////////////////////////////////////////////
// Global Functions/variables
// These functions are used by CGLTesselator class
struct GarbListItem{
GLdouble *pvert;
GarbListItem* next;};
GarbListItem* m_garbagelist=NULL;
void AddGarbage(GLdouble * ptr)
{
ASSERT(ptr!=NULL);
// allocate mem for new list item
GarbListItem* temp=new GarbListItem;
// store pointer
temp->pvert=ptr;
// add at head of list
temp->next=m_garbagelist;
m_garbagelist=temp;
}
void DeleteGarbage()
{
if(m_garbagelist!=NULL)
{
GarbListItem* punt=m_garbagelist;
GarbListItem* temp=m_garbagelist;
// scan the list
while(punt!=NULL)
{
// delete vertex
delete[] punt->pvert;
punt=punt->next;
// delete list item
delete temp;
temp=punt;
};
m_garbagelist=NULL;
};
}
void CALLBACK BeginCallback(GLenum type)
{
// issue corresponding GL call
glBegin(type);
}
void CALLBACK ErrorCallback(GLenum errorCode)
{
const GLubyte *estring;
CString mexstr;
// get the error descritption from OGL
estring = gluErrorString(errorCode);
// prepare and show a message box
mexstr.Format("Tessellation/Quadric Error: %s\n", estring);
AfxMessageBox(mexstr,MB_OK | MB_ICONEXCLAMATION);
// replicate mex to debug trace
TRACE("Tessellation Error: %s\n", estring);
}
void CALLBACK EndCallback()
{
// issue corresponding GL call
glEnd();
}
void CALLBACK VertexCallback(GLvoid *vertex)
{
// issue corresponding GL call (double is used to get max precision)
glVertex3dv( (const double *)vertex );
}
void CALLBACK CombineCallback(GLdouble coords[3], GLdouble *data[4], GLfloat weight[4], GLdouble **dataOut )
{
// allocate memory for a new vertex
GLdouble *vertex;
vertex = new GLdouble[3];
// store reported vertex
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
// return vertex to OGL
*dataOut = vertex;
// add vertex pointer to garbage collection routines
AddGarbage(vertex);
}
/////////////////////////////////////////////////////////////////////////////
// CGLEnabledView
IMPLEMENT_DYNCREATE(CGLEnabledView, CView)
CGLEnabledView::CGLEnabledView():
m_dAspectRatio(1.0),
m_bInsideDispList(FALSE), m_bExternDispListCall(FALSE),
m_bExternGLCall(FALSE)
{
// define a default cursor
m_hMouseCursor=AfxGetApp()->LoadStandardCursor(IDC_SIZEALL);
// set the disp list vector to all zeros
for (int c=0;c<MAX_LISTS;c++) m_DispListVector[c]=0;
}
CGLEnabledView::~CGLEnabledView()
{
}
BEGIN_MESSAGE_MAP(CGLEnabledView, CView)
//{{AFX_MSG_MAP(CGLEnabledView)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_WM_SETCURSOR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGLEnabledView drawing
void CGLEnabledView::OnDraw(CDC* pDC)
{
// prepare a semaphore
static BOOL bBusy = FALSE;
// use the semaphore to enter this critic section
if(bBusy) return;
bBusy = TRUE;
// specify the target DeviceContext of the subsequent OGL calls
wglMakeCurrent(m_pCDC->GetSafeHdc(), m_hRC);
// clear background
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// call the virtual drawing procedure (to be overridden by user)
OnDrawGL();
// execute OGL commands (flush the OGL graphical pipeline)
glFinish();
// if double buffering is used it's time to swap the buffers
SwapBuffers(m_pCDC->GetSafeHdc());
// turn the semaphore "green"
bBusy = FALSE;
// free the target DeviceContext (window)
wglMakeCurrent(NULL,NULL);
}
void CGLEnabledView::OnDrawGL()
{
// draw carthesian axes
glBegin(GL_LINES);
// red x axis
glColor3f(1.f,0.f,0.f);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(1.0f,0.0f,0.0f);
glVertex3f(1.0f,0.0f,0.0f);
glVertex3f(0.9f,0.1f,0.0f);
glVertex3f(1.0f,0.0f,0.0f);
glVertex3f(0.9f,-0.1f,0.0f);
// green y axis
glColor3f(0.f,1.f,0.f);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(0.0f,1.0f,0.0f);
glVertex3f(0.0f,1.0f,0.0f);
glVertex3f(0.1f,0.9f,0.0f);
glVertex3f(0.0f,1.0f,0.0f);
glVertex3f(-0.1f,0.9f,0.0f);
// blue z axis
glColor3f(0.f,0.f,1.f);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(0.0f,0.0f,1.0f);
glVertex3f(0.0f,0.0f,1.0f);
glVertex3f(0.0f,0.1f,0.9f);
glVertex3f(0.0f,0.0f,1.0f);
glVertex3f(0.0f,-0.1f,0.9f);
glEnd();
}
/////////////////////////////////////////////////////////////////////////////
// CGLEnabledView diagnostics
#ifdef _DEBUG
void CGLEnabledView::AssertValid() const
{
CView::AssertValid();
}
void CGLEnabledView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
// dump some infos
CString str;
GetWindowText(str);
afxDump<<"\nView Parameters\n\tClient Rectangle :"<<m_ClientRect<<"\n\tAspect Ratio :"<<m_dAspectRatio<<"\n";
afxDump<<"\nWindowTitle :"<<str<<"\n";
}
#endif //_DEBUG
/////////////////////////////////////////////////////////
// CGLEnabledView Constants
// these are used to construct an equilibrated 256 color palette
static unsigned char _threeto8[8] =
{
0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
};
static unsigned char _twoto8[4] =
{
0, 0x55, 0xaa, 0xff
};
static unsigned char _oneto8[2] =
{
0, 255
};
static int defaultOverride[13] =
{
0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91
};
// Wi