diff --git a/Utils/MapEdit/GLEnabledView.cpp b/Utils/MapEdit/GLEnabledView.cpp new file mode 100644 index 000000000..4e7e2b706 --- /dev/null +++ b/Utils/MapEdit/GLEnabledView.cpp @@ -0,0 +1,1361 @@ +/***************************************************** +Copyright Notice & Disclaimer + +Copyright ©1998-1999 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 find (and possibly fix) 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 +v 1.3: changed window initialization with creation of a windowclass (this solved little NT bug) + added GLU library information retrieval + introduced GL/GLU Information Structure +v 1.4: introduced GL/GLU error checking in OnDraw message handler after scene drawing + improved GL/GLU library information retrieval and modified GL/GLU Information Structure accordingly (added implementation dependent values retrieval) + added 2D bitmap text and 3D polygonal text routines + +******************************************************/ +// CGLEnabledView.cpp : implementation file +// + +#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" // moved to stdafx.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 +#include +#include +#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 ICD_DRIVER_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 + TRACE0(mexstr); +} + +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_numchars(128), + m_bInsideDispList(FALSE), m_bExternDispListCall(FALSE), + m_bExternGLCall(FALSE), + m_gmfvector(NULL), + m_charsetDListBase(0) +{ +// define a default cursor + m_hMouseCursor=AfxGetApp()->LoadStandardCursor(IDC_SIZEALL); +// set the disp list vector to all zeros + for (int c=0;cGetSafeHdc(), 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(); // useless cause swapbuffers issues an implicit glFinish + +// if double buffering is used it's time to swap the buffers + SwapBuffers(m_pCDC->GetSafeHdc()); + +// check for errors + m_glErrorCode=glGetError(); + if(m_glErrorCode != GL_NO_ERROR) + { + const GLubyte *estring; + CString mexstr; +// get the error descritption from OGL + estring = gluErrorString(m_glErrorCode); +// prepare and show a message box + mexstr.Format("GLEnabledView:\n\tAn OpenGL error occurred: %s\n", estring); + AfxMessageBox(mexstr,MB_OK | MB_ICONEXCLAMATION); +// replicate mex to debug trace + TRACE0(mexstr); +// turn the semaphore "red" to avoid other wrong drawings + bBusy=TRUE; + } + else + { +// 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 :"<>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 +}; + +// Windows Default Palette +static PALETTEENTRY defaultPalEntry[20] = +{ + { 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 }, + + { 192, 220, 192, 0 }, + { 166, 202, 240, 0 }, + { 255, 251, 240, 0 }, + { 160, 160, 164, 0 }, + + { 0x80,0x80,0x80, 0 }, + { 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 } +}; + +///////////////////////////////////////////////////////////////////////////// +// CGLEnabledView initialization and palette helpers + +BOOL CGLEnabledView::bSetupPixelFormat() +{ +// define a default desired video mode (pixel format) + static PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd + 1, // version number + PFD_DRAW_TO_WINDOW | // support window + PFD_SUPPORT_OPENGL | // support OpenGL + PFD_DOUBLEBUFFER , // double buffered + PFD_TYPE_RGBA, // RGBA type + 24, // 24-bit color depth + 0, 0, 0, 0, 0, 0, // color bits ignored + 0, // no alpha buffer + 0, // shift bit ignored + 0, // no accumulation buffer + 0, 0, 0, 0, // accum bits ignored + 16, // 16-bit z-buffer + 0, // no stencil buffer + 0, // no auxiliary buffer + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0 // layer masks ignored + }; +// let the user change some parameters if he wants + BOOL bDoublBuf; + ColorsNumber cnum; + ZAccuracy zdepth; + VideoMode(cnum,zdepth,bDoublBuf); +//set the user changes + if(bDoublBuf) pfd.dwFlags=PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |PFD_DOUBLEBUFFER; + else pfd.dwFlags=PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + switch(cnum) + { + case INDEXED: + pfd.cColorBits=8; + pfd.iPixelType=PFD_TYPE_COLORINDEX; + break; + case THOUSANDS: + pfd.cColorBits=16; + break; + case MILLIONS_WITH_TRANSPARENCY: + pfd.cColorBits=32; + break; + case MILLIONS: + default: + pfd.cColorBits=24; + break; + }; + switch(zdepth) + { + case NORMAL: + pfd.cDepthBits=16; + break; + case ACCURATE: + pfd.cDepthBits=32; + break; + }; + +// ask the system for such video mode + ASSERT(m_pCDC != NULL); + int pixelformat; + if ( (pixelformat = ChoosePixelFormat(m_pCDC->GetSafeHdc(), &pfd)) == 0 ) + { + AfxMessageBox("ChoosePixelFormat failed"); + return FALSE; + } +// try to set this video mode + if (SetPixelFormat(m_pCDC->GetSafeHdc(), pixelformat, &pfd) == FALSE) + { +// the requested video mode is not available so get a default one (the first) + pixelformat = 1; + if (DescribePixelFormat(m_pCDC->GetSafeHdc(), pixelformat, sizeof(PIXELFORMATDESCRIPTOR), &pfd)==0) + { +// neither the requested nor the default are available: fail + AfxMessageBox("SetPixelFormat failed (no OpenGL compatible video mode)"); + return FALSE; + } + } + return TRUE; +} + +void CGLEnabledView::CreateRGBPalette() +{ + PIXELFORMATDESCRIPTOR pfd; + LOGPALETTE *pPal; + int n, i; + +// get the initially choosen video mode + n = ::GetPixelFormat(m_pCDC->GetSafeHdc()); + ::DescribePixelFormat(m_pCDC->GetSafeHdc(), n, sizeof(pfd), &pfd); + +// if is an indexed one... + if (pfd.dwFlags & PFD_NEED_PALETTE) + { +// ... construct an equilibrated palette (3 red bits, 3 green bits, 2 blue bits) +// NOTE: this code has been taken from MFC example Cube + n = 1 << pfd.cColorBits; + pPal = (PLOGPALETTE) new char[sizeof(LOGPALETTE) + n * sizeof(PALETTEENTRY)]; + + ASSERT(pPal != NULL); + + pPal->palVersion = 0x300; + pPal->palNumEntries = unsigned short(n); + for (i=0; ipalPalEntry[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 the palette to include the default Windows palette + if ((pfd.cColorBits == 8) && + (pfd.cRedBits == 3) && (pfd.cRedShift == 0) && + (pfd.cGreenBits == 3) && (pfd.cGreenShift == 3) && + (pfd.cBlueBits == 2) && (pfd.cBlueShift == 6) + ) + { + for (i = 1 ; i <= 12 ; i++) + pPal->palPalEntry[defaultOverride[i]] = defaultPalEntry[i]; + } + + m_CurrentPalette.CreatePalette(pPal); + delete pPal; + +// set the palette + m_pOldPalette=m_pCDC->SelectPalette(&m_CurrentPalette, FALSE); + m_pCDC->RealizePalette(); + } +} + +unsigned char CGLEnabledView::ComponentFromIndex(int i, UINT nbits, UINT shift) +{ + unsigned char val; + + val = (unsigned char) (i >> shift); + switch (nbits) + { + + case 1: + val &= 0x1; + return _oneto8[val]; + case 2: + val &= 0x3; + return _twoto8[val]; + case 3: + val &= 0x7; + return _threeto8[val]; + + default: + return 0; + } +} + +///////////////////////////////////////////////////////////////////////////// +// CGLEnabledView message handlers and overridables + +int CGLEnabledView::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CView::OnCreate(lpCreateStruct) == -1) return -1; + +// OpenGL rendering context creation + PIXELFORMATDESCRIPTOR pfd; + int n; + +// initialize the private member + m_pCDC= new CClientDC(this); + +// choose the requested video mode + if (!bSetupPixelFormat()) return 0; + +// ask the system if the video mode is supported + n=::GetPixelFormat(m_pCDC->GetSafeHdc()); + ::DescribePixelFormat(m_pCDC->GetSafeHdc(),n,sizeof(pfd),&pfd); + +// create a palette if the requested video mode has 256 colors (indexed mode) + CreateRGBPalette(); + +// link the Win Device Context with the OGL Rendering Context + m_hRC = wglCreateContext(m_pCDC->GetSafeHdc()); + +// specify the target DeviceContext (window) of the subsequent OGL calls + wglMakeCurrent(m_pCDC->GetSafeHdc(), m_hRC); + +// performs default setting of rendering mode,etc.. + OnCreateGL(); + +// free the target DeviceContext (window) + wglMakeCurrent(NULL,NULL); + + return 0; +} + +void CGLEnabledView::OnCreateGL() +{ +// perform hidden line/surface removal (enabling Z-Buffer) + glEnable(GL_DEPTH_TEST); + +// set background color to black + glClearColor(0.f,0.f,0.f,1.0f ); + +// set clear Z-Buffer value + glClearDepth(1.0f); +} + +void CGLEnabledView::OnDestroy() +{ +// specify the target DeviceContext (window) of the subsequent OGL calls + wglMakeCurrent(m_pCDC->GetSafeHdc(), m_hRC); + +// remove all display lists + for (int c=0;cSelectPalette(&palDefault, FALSE); + +// destroy Win Device Context + if(m_pCDC) delete m_pCDC; + +// finally call the base function + CView::OnDestroy(); +} + +BOOL CGLEnabledView::PreCreateWindow(CREATESTRUCT& cs) +{ +// these styles are requested by OpenGL + cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + +// call base class PreCreateWindow to get the cs.lpszClass filled in with the MFC default class name + if( !CView::PreCreateWindow(cs) ) + return 0; + +// Register the window class if it has not already been registered. + WNDCLASS wndcls; + HINSTANCE hInst = AfxGetInstanceHandle(); +// this is the new registered window class +#define CUSTOM_CLASSNAME _T("GL_WINDOW_CLASS") +// check if our class has been already registered (typical in MDI environment) + if(!(::GetClassInfo(hInst, CUSTOM_CLASSNAME, &wndcls))) + { +// get default MFC class settings + if(::GetClassInfo(hInst, cs.lpszClass, &wndcls)) + { +// set our class name + wndcls.lpszClassName = CUSTOM_CLASSNAME; +// these styles are set for GL to work in MDI + wndcls.style |= (CS_OWNDC | CS_HREDRAW | CS_VREDRAW); + wndcls.hbrBackground = NULL; +// try to register class (else throw exception) + if (!AfxRegisterClass(&wndcls)) AfxThrowResourceException(); + } +// default MFC class not registered + else AfxThrowResourceException(); + } +// set our class name in CREATESTRUCT + cs.lpszClass = CUSTOM_CLASSNAME; +// we're all set + return 1; +} + + +BOOL CGLEnabledView::OnEraseBkgnd(CDC* pDC) +{ +// OGL has his own background erasing so tell Windows to skip (avoids flicker) + return TRUE; +} + +void CGLEnabledView::OnSize(UINT nType, int cx, int cy) +{ + CView::OnSize(nType, cx, cy); +// when called with a nonzero window: + if ( 0 < cx && 0 < cy ) + { +// update the rect and the aspect ratio + m_ClientRect.right = cx; + m_ClientRect.bottom = cy; + m_dAspectRatio=double(cx)/double(cy); + +// specify the target DeviceContext of the OGL calls below + wglMakeCurrent(m_pCDC->GetSafeHdc(), m_hRC); + +// call the virtual sizing procedure (to be overridden by user) + OnSizeGL(cx,cy); + +// free the target DeviceContext (window) + wglMakeCurrent(NULL,NULL); + +// force redraw + Invalidate(TRUE); + }; +} + +void CGLEnabledView::OnSizeGL(int cx, int cy) +{ +// set correspondence between window and OGL viewport + glViewport(0,0,cx,cy); + +// update the camera + glPushMatrix(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(40.0,m_dAspectRatio,0.1f, 10.0f); + glTranslatef(0.0f,0.0f,-4.f); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + +BOOL CGLEnabledView::OnSetCursor(CWnd* /*pWnd*/, UINT /*nHitTest*/, UINT /*message*/) +{ + ASSERT(m_hMouseCursor!=NULL); + ::SetCursor(m_hMouseCursor); + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CGLEnabledView public members + +void CGLEnabledView::VideoMode(ColorsNumber &c, ZAccuracy &z, BOOL &dbuf) +{ +// set default videomode + c=MILLIONS; + z=NORMAL; + dbuf=TRUE; +} + +void CGLEnabledView::SetMouseCursor(HCURSOR mcursor) +{ +// set the specified cursor (only if it is a valid one) + if(mcursor!=NULL) m_hMouseCursor=mcursor; +} + +GLInfoStruct CGLEnabledView::GetInformation() +{ + PIXELFORMATDESCRIPTOR pfd; + GLInfoStruct str; + HDC curr_dc=m_pCDC->GetSafeHdc(); +// Get information about the DC's current pixel format + ::DescribePixelFormat(curr_dc , ::GetPixelFormat(curr_dc),sizeof(PIXELFORMATDESCRIPTOR), &pfd ); +// specify the target Rendering Context of the subsequent OGL calls + wglMakeCurrent(curr_dc, m_hRC); +// Extract driver information + if( 0==(ICD_DRIVER_MASK & pfd.dwFlags) ) + str.acceleration="Fully Accelerated (ICD)"; // fully in hardware (fastest) + else if (ICD_DRIVER_MASK==(ICD_DRIVER_MASK & pfd.dwFlags) ) + str.acceleration="Partially Accelerated (MCD)"; // partially in hardware (pretty fast, maybe..) + else str.acceleration="Not Accelerated (Software)"; // software +// get the company name responsible for this implementation + str.vendor=(char*)::glGetString(GL_VENDOR); + if ( ::glGetError()!=GL_NO_ERROR) str.vendor.Format("Not Available");// failed! +// get the renderer name; this is specific of an hardware configuration + str.renderer=(char*)::glGetString(GL_RENDERER); + if ( ::glGetError()!=GL_NO_ERROR) str.renderer.Format("Not Available");// failed! +// get the version of the GL library + str.glversion=(char*)::glGetString(GL_VERSION); + if ( ::glGetError()!=GL_NO_ERROR) str.glversion.Format("Not Available");// failed! +// return a space separated list of extensions + str.glextensions=(char*)::glGetString(GL_EXTENSIONS); + if ( ::glGetError()!=GL_NO_ERROR) str.glextensions.Format("Not Available");// failed! +// get the version of the GLU library + str.gluversion=(char*)::gluGetString(GLU_VERSION); + if ( ::glGetError()!=GL_NO_ERROR) str.gluversion.Format("Not Available");// failed! +// as above a space separated list of extensions + str.gluextensions=(char*)::gluGetString(GLU_EXTENSIONS); + if ( ::glGetError()!=GL_NO_ERROR) str.gluextensions.Format("Not Available");// failed! + glGetIntegerv(GL_MAX_LIGHTS,&str.max_lights); + glGetIntegerv(GL_MAX_CLIP_PLANES,&str.max_clip_planes); + glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH,&str.max_model_stack_depth); + glGetIntegerv(GL_MAX_PROJECTION_STACK_DEPTH,&str.max_proj_stack_depth); + glGetIntegerv(GL_MAX_TEXTURE_STACK_DEPTH,&str.max_txtr_stack_depth); + glGetIntegerv(GL_MAX_NAME_STACK_DEPTH,&str.max_name_stack_depth); + glGetIntegerv(GL_MAX_ATTRIB_STACK_DEPTH,&str.max_attrib_stack_depth); + glGetIntegerv(GL_MAX_TEXTURE_SIZE,&str.max_texture_size); + glGetIntegerv(GL_MAX_LIST_NESTING,&str.max_list_nesting); + glGetIntegerv(GL_MAX_EVAL_ORDER,&str.max_eval_order); + int tempint[2]; + glGetIntegerv(GL_MAX_VIEWPORT_DIMS,&tempint[0]); + str.max_viewport_dims.cx=tempint[0]; + str.max_viewport_dims.cy=tempint[1]; + glGetIntegerv(GL_AUX_BUFFERS,&str.auxiliary_buffers); + float tempval[2]; + glGetFloatv(GL_POINT_SIZE_RANGE,&tempval[0]); + str.min_smooth_point_size=int(tempval[0]); + str.max_smooth_point_size=int(tempval[1]); + glGetFloatv(GL_POINT_SIZE_GRANULARITY,&str.smooth_point_granularity); + glGetFloatv(GL_LINE_WIDTH_RANGE,&tempval[0]); + str.min_smooth_line_size=int(tempval[0]); + str.max_smooth_line_size=int(tempval[1]); + glGetFloatv(GL_LINE_WIDTH_GRANULARITY,&str.smooth_line_granularity); + glGetIntegerv(GL_RED_BITS,&str.red_bits); + glGetIntegerv(GL_BLUE_BITS,&str.blue_bits); + glGetIntegerv(GL_GREEN_BITS,&str.green_bits); + glGetIntegerv(GL_ALPHA_BITS,&str.alpha_bits); + glGetIntegerv(GL_DEPTH_BITS,&str.depth_bits); + glGetIntegerv(GL_STENCIL_BITS,&str.stencil_bits); +// free the target DeviceContext (window) and return the result + wglMakeCurrent(NULL,NULL); + return str; +} + +void CGLEnabledView::DrawStockDispLists() +{ +// check if we are already inside a drawing session + if(m_hRC==wglGetCurrentContext() && m_pCDC->GetSafeHdc()==wglGetCurrentDC() ) + { +// draw directly all display lists + for (int c=0;cGetSafeHdc(), m_hRC); +// draw all display lists + for (int c=0;cGetSafeHdc()==wglGetCurrentDC() )) + { +// ...if not specify the target DeviceContext of the subsequent OGL calls + wglMakeCurrent(m_pCDC->GetSafeHdc(), m_hRC); +// set a warning for EndDispList + m_bExternDispListCall=TRUE; + }; +// create a handle to the disp list (actually an integer) + m_DispListVector[c]=glGenLists(1); +// set a semaphore + m_bInsideDispList=TRUE; +// start the disp list: all subsequent OGL calls will be redirected to the list + glNewList(m_DispListVector[c],GL_COMPILE); + }; +} + +void CGLEnabledView::EndStockListDef() +{ +// close the disp list + glEndList(); +// unset the semaphore + m_bInsideDispList=FALSE; +// if beginDispList set the warn free the target DeviceContext + if(m_bExternDispListCall) wglMakeCurrent(NULL,NULL); +} + +void CGLEnabledView::ClearStockDispLists() +{ +// check if we are referring to the right Rendering Context + if(m_hRC==wglGetCurrentContext() && m_pCDC->GetSafeHdc()==wglGetCurrentDC() ) + { +// delete active display lists + for (int c=0;cGetSafeHdc(), m_hRC); +// delete active display lists + for (int c=0;cGetSafeHdc()==wglGetCurrentDC() )) + { +// ...if not specify the target DeviceContext of the subsequent OGL calls + wglMakeCurrent(m_pCDC->GetSafeHdc(), m_hRC); +// set a warning for EndGLCommands + m_bExternGLCall=TRUE; + }; +} + +void CGLEnabledView::EndGLCommands() +{ +// if BeginGLCommands set the warn free the target DeviceContext + if(m_bExternGLCall) wglMakeCurrent(NULL,NULL); +} + +void CGLEnabledView::PrepareCharset3D(CString fontname,float extrusion,BOOL boldface,BOOL italicface,BOOL uselines,float precision) +{ + // debug checks + ASSERT(extrusion>=0.f && precision>=0.f); + ASSERT(!fontname.IsEmpty()); + // variables initialization + int mode=uselines ? WGL_FONT_LINES : WGL_FONT_POLYGONS; + if(m_gmfvector==NULL) m_gmfvector=new GLYPHMETRICSFLOAT[m_numchars]; + // prepare to ask for the requested font + LOGFONT lg; + memset(&lg, 0, sizeof(LOGFONT)); + lg.lfHeight=14;// for 3D text the height doesn't matter since the characters will be always of unit height + lg.lfWidth=0; + lg.lfEscapement=lg.lfOrientation=0; + lg.lfItalic=unsigned char(italicface); + if(boldface)lg.lfWeight=FW_BOLD; + else lg.lfWeight=FW_NORMAL; + lg.lfUnderline=FALSE; + lg.lfStrikeOut=FALSE; + lg.lfCharSet=ANSI_CHARSET; + lg.lfOutPrecision=OUT_DEFAULT_PRECIS; + lg.lfClipPrecision=CLIP_DEFAULT_PRECIS; + lg.lfQuality=DEFAULT_QUALITY; + lg.lfPitchAndFamily=DEFAULT_PITCH |FF_DONTCARE; + strcpy(lg.lfFaceName, fontname); + // ask for the font + CFont fnt; + if(!fnt.CreateFontIndirect(&lg)) + { + TRACE("CGLEnabledView::PrepareCharset3D:\n\tUnable to create the requested font.\n"); + m_charsetDListBase=0; + return; + }; + //select the font into the DC + CFont* def_font = m_pCDC->SelectObject(&fnt); + // create or recreate the display lists + if(m_charsetDListBase>0) + glDeleteLists(m_charsetDListBase,m_numchars); + if (0 == (m_charsetDListBase=glGenLists(m_numchars))) + { + TRACE("CGLEnabledView::PrepareCharset3D:\n\tUnable to create the charset (no memory for display lists).\n"); + goto end; + }; + // build the charset display lists + if(!wglUseFontOutlines(m_pCDC->GetSafeHdc(),0,m_numchars-1,m_charsetDListBase,precision,extrusion,mode,m_gmfvector)) + { + TRACE("CGLEnabledView::PrepareCharset3D:\n\tUnable to create the charset (internal error).\n"); + glDeleteLists(m_charsetDListBase,m_numchars); + m_charsetDListBase=0; + }; + // deselect and dispose of the GDI font +end: + m_pCDC->SelectObject(def_font); + fnt.DeleteObject(); +} + +void CGLEnabledView::PrepareCharset3D(const LOGFONT* pLF,float extrusion,BOOL uselines,float precision) +{ + // debug checks + ASSERT(extrusion>=0.f && precision>=0.f); + ASSERT(pLF!=NULL); + // variables initialization + int mode=uselines ? WGL_FONT_LINES : WGL_FONT_POLYGONS; + if(m_gmfvector==NULL) m_gmfvector=new GLYPHMETRICSFLOAT[m_numchars]; + // ask for the font + CFont fnt; + if(!fnt.CreateFontIndirect(pLF)) + { + TRACE("CGLEnabledView::PrepareCharset3D:\n\tUnable to create a font from the passed logical font descriptor.\n"); + return; + } + //select the font into the DC + CFont* def_font = m_pCDC->SelectObject(&fnt); + // create or recreate the display lists + if(m_charsetDListBase>0) glDeleteLists(m_charsetDListBase,m_numchars); + if (0 == (m_charsetDListBase=glGenLists(m_numchars))) + { + TRACE("CGLEnabledView::PrepareCharset3D:\n\tUnable to create the charset (no memory for display lists).\n"); + goto end; + }; + // build the charset display lists + if(!wglUseFontOutlines(m_pCDC->GetSafeHdc(),0,m_numchars-1,m_charsetDListBase,precision,extrusion,mode,m_gmfvector)) + { + TRACE("CGLEnabledView::PrepareCharset3D:\n\tUnable to create the charset (internal error).\n"); + glDeleteLists(m_charsetDListBase,m_numchars); + m_charsetDListBase=0; + }; + // deselect and dispose of the GDI font +end: + m_pCDC->SelectObject(def_font); + fnt.DeleteObject(); +} + +void CGLEnabledView::PrepareCharset2D(CString fontname,int height,BOOL boldface,BOOL italicface) +{ + // debug checks + ASSERT(!fontname.IsEmpty() && height>0); + // prepare to ask for the requested font + LOGFONT lg; + memset(&lg, 0, sizeof(LOGFONT)); + lg.lfHeight=height;// for 2D text the height is taken into consideration + lg.lfWidth=0; + lg.lfEscapement=lg.lfOrientation=0; + lg.lfItalic=unsigned char(italicface); + if(boldface)lg.lfWeight=FW_BOLD; + else lg.lfWeight=FW_NORMAL; + lg.lfUnderline=FALSE; + lg.lfStrikeOut=FALSE; + lg.lfCharSet=ANSI_CHARSET; + lg.lfOutPrecision=OUT_DEFAULT_PRECIS; + lg.lfClipPrecision=CLIP_DEFAULT_PRECIS; + lg.lfQuality=DEFAULT_QUALITY; + lg.lfPitchAndFamily=DEFAULT_PITCH |FF_DONTCARE; + strcpy(lg.lfFaceName, fontname); + // ask for the font + CFont fnt; + if(!fnt.CreateFontIndirect(&lg)) + { + TRACE("CGLEnabledView::PrepareCharset2D:\n\tUnable to create the requested font.\n"); + m_charsetDListBase=0; + return; + }; + //select the font into the DC + CFont* def_font = m_pCDC->SelectObject(&fnt); + // create or recreate the display lists + if(m_charsetDListBase>0) + glDeleteLists(m_charsetDListBase,m_numchars); + if (0 == (m_charsetDListBase=glGenLists(m_numchars))) + { + TRACE("CGLEnabledView::PrepareCharset2D:\n\tUnable to create the charset (no memory for display lists).\n"); + goto end; + }; + // build the charset display lists + if(!wglUseFontBitmaps(m_pCDC->GetSafeHdc(),0,m_numchars-1,m_charsetDListBase)) + { + TRACE("CGLEnabledView::PrepareCharset2D:\n\tUnable to create the charset (internal error).\n"); + glDeleteLists(m_charsetDListBase,m_numchars); + m_charsetDListBase=0; + }; + // deselect and dispose of the GDI font +end: + m_pCDC->SelectObject(def_font); + fnt.DeleteObject(); +} + +void CGLEnabledView::PrepareCharset2D(const LOGFONT* pLF) +{ + // debug checks + ASSERT(pLF!=NULL); + // ask for the font + CFont fnt; + if(!fnt.CreateFontIndirect(pLF)) + { + TRACE("CGLEnabledView::PrepareCharset2D:\n\tUnable to create a font from the passed logical font descriptor.\n"); + return; + } + //select the font into the DC + CFont* def_font = m_pCDC->SelectObject(&fnt); + // create or recreate the display lists + if(m_charsetDListBase>0) glDeleteLists(m_charsetDListBase,m_numchars); + if (0 == (m_charsetDListBase=glGenLists(m_numchars))) + { + TRACE("CGLEnabledView::PrepareCharset2D:\n\tUnable to create the charset (no memory for display lists).\n"); + goto end; + }; + // build the charset display lists + if(!wglUseFontBitmaps(m_pCDC->GetSafeHdc(),0,m_numchars-1,m_charsetDListBase)) + { + TRACE("CGLEnabledView::PrepareCharset2D:\n\tUnable to create the charset (internal error).\n"); + glDeleteLists(m_charsetDListBase,m_numchars); + m_charsetDListBase=0; + }; + // deselect and dispose of the GDI font +end: + m_pCDC->SelectObject(def_font); + fnt.DeleteObject(); +} + +float CGLEnabledView::Text3D(CString text) +{ + float retlen=0.f; + int textlen=0; + if(m_charsetDListBase!=0) + { + if( (textlen=text.GetLength()) >0) + { + // output the outlines corresponding to the requested text srting + glListBase(m_charsetDListBase); + glCallLists(textlen,GL_UNSIGNED_BYTE,LPCTSTR(text)); + // calculate and return the length of the produced outlines + for(int c=0;c0) + { + // output the outlines corresponding to the requested text srting + glListBase(m_charsetDListBase); + glCallLists(textlen,GL_UNSIGNED_BYTE,LPCTSTR(text)); + } + } + else TRACE("CGLEnabledView::Text2D:\n\tNo charset available. Use PrepareCharset2D routines first.\n"); +} + +////////////////////////////////////////////////////////////////////// +// +// Implementation of CGLEnabledView::CGLDispList class. +// +/*** DESCRIPTION + + This is actually a helper class which wraps the + use of display list in OGL. + It must be used inside an GLEnabledView cause + a display list must refer to a Rendering Context. + At present there is no support for Disp. Lists + Sharing among multiple RCs (that is multiple MDI + child windows). + +****************************************/ + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction + +CGLEnabledView::CGLDispList::CGLDispList(): + m_glListId(0), m_bIsolated(FALSE) +{ +} + +CGLEnabledView::CGLDispList::~CGLDispList() +{ +// remove display list + glDeleteLists(m_glListId,1); +} + +////////////////////////////////////////////////////////////////////// +// Member functions + +void CGLEnabledView::CGLDispList::Draw() +{ +// if the list is not empty... + if(m_glListId) + { + if(m_bIsolated) + { +// save current transformation matrix + glPushMatrix(); +// save current OGL internal state (lighting, shading, and such) + glPushAttrib(GL_ALL_ATTRIB_BITS); + }; +// draw the list + glCallList(m_glListId); + if(m_bIsolated) + { +// restore transformation matrix + glPopMatrix(); +// restore OGL internal state + glPopAttrib(); + }; + }; +} + +void CGLEnabledView::CGLDispList::StartDef(BOOL bImmediateExec) +{ +// check if another list is under construction + int cur; + glGetIntegerv(GL_LIST_INDEX,&cur); + if(cur != 0) + { + TRACE0("CGLEnabledView\n\tError: Nested display list definition!\n"); + ASSERT(FALSE); + }; +// if the list is empty firstly allocate one + if(!m_glListId) m_glListId=glGenLists(1); + +// start or replace a list definition + if (bImmediateExec) glNewList(m_glListId,GL_COMPILE_AND_EXECUTE); + else glNewList(m_glListId,GL_COMPILE); +} + +void CGLEnabledView::CGLDispList::EndDef() +{ +// check the coupling with a preceding call to StartDef() + int cur; + glGetIntegerv(GL_LIST_INDEX,&cur); + if(cur != m_glListId) {TRACE0("CGLDispList:Missing StartDef() before EndDef()\n");return;}; +// close list definition + glEndList(); +} + +////////////////////////////////////////////////////////////////////// +// +// Implementation of CGLEnabledView::CGLTesselator class. +// +/*** DESCRIPTION + + This is actually a helper class which wraps the + use of tessellation objects in OGL (see guide). + It must be used inside an GLEnabledView cause + a tesselator object must refer to a Rendering Context. + +****************************************/ + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction + +CGLEnabledView::CGLTesselator::CGLTesselator() +{ +// create tessellation object + m_tessObj=gluNewTess(); +// set callback functions + gluTessCallback(m_tessObj,GLU_TESS_BEGIN,(void (CALLBACK*)())&BeginCallback); + gluTessCallback(m_tessObj,GLU_TESS_VERTEX,(void (CALLBACK*)())&VertexCallback); + gluTessCallback(m_tessObj,GLU_TESS_END,(void (CALLBACK*)())&EndCallback); + gluTessCallback(m_tessObj,GLU_TESS_COMBINE,(void (CALLBACK*)())&CombineCallback); + gluTessCallback(m_tessObj,GLU_TESS_ERROR,(void (CALLBACK*)())&ErrorCallback); +} + +CGLEnabledView::CGLTesselator::~CGLTesselator() +{ +// remove tessellation object + gluDeleteTess(m_tessObj); +} + +////////////////////////////////////////////////////////////////////// +// Member functions + +void CGLEnabledView::CGLTesselator::SetWindingRule(GLdouble which) +{ +// issue the equivalent GL call + gluTessProperty(m_tessObj,GLU_TESS_WINDING_RULE,which); +} + +GLdouble CGLEnabledView::CGLTesselator::GetWindingRule() +{ +//retrieve attribute + GLdouble temp=-1.0; + gluTessProperty(m_tessObj,GLU_TESS_WINDING_RULE,temp); +// return value + return temp; +} + +void CGLEnabledView::CGLTesselator::SetFilling(BOOL bFill) +{ +// issue the equivalent GL calls + if(bFill) gluTessProperty(m_tessObj,GLU_TESS_BOUNDARY_ONLY,GL_FALSE); + else gluTessProperty(m_tessObj,GLU_TESS_BOUNDARY_ONLY,GL_TRUE); +} + +BOOL CGLEnabledView::CGLTesselator::GetFilling() +{ +//retrieve attribute + GLdouble temp=-1.0; + gluTessProperty(m_tessObj,GLU_TESS_BOUNDARY_ONLY,temp); +// convert to a boolean + return (temp==GL_TRUE); +} + +void CGLEnabledView::CGLTesselator::StartDef() +{ +// start a polygon definition + gluTessBeginPolygon(m_tessObj,NULL); +// start a contour definition + gluTessBeginContour(m_tessObj); +} + +void CGLEnabledView::CGLTesselator::EndDef() +{ +// end contour and polygon definition + gluTessEndContour(m_tessObj); + gluTessEndPolygon(m_tessObj); +// free new vertices created by tessellation + ::DeleteGarbage(); +} + +void CGLEnabledView::CGLTesselator::ContourSeparator() +{ +// insert a contour separation + gluTessEndContour(m_tessObj); + gluTessBeginContour(m_tessObj); +} + +void CGLEnabledView::CGLTesselator::AddVertex(GLdouble vertData[3]) +{ +// IMPORTANT: the 3rd parameter must be given otherwise an access +// violation will occur, moreover every vertex must have it's own memory +// location till the closing of the polygon (that is you can't pass all +// the vertices trough the same variable in a for loop). + gluTessVertex(m_tessObj,vertData,vertData); +} + +void CGLEnabledView::CGLTesselator::AddVertexArray(GLdouble arr[][3], int size) +{ + ASSERT(arr!=NULL); +// pass the vertices to the tessellation object + for(int ct=0;ct= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +///////////////////////////////////////////////////////////////////////////// +// CGLEnabledView.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// Global type definitions + enum ColorsNumber{INDEXED,THOUSANDS,MILLIONS,MILLIONS_WITH_TRANSPARENCY}; + enum ZAccuracy{NORMAL,ACCURATE}; + struct GLInfoStruct + { + CString vendor; + CString renderer; + CString acceleration; + CString glextensions; + CString glversion; + CString gluextensions; + CString gluversion; + int max_lights; + int max_clip_planes; + int max_model_stack_depth; + int max_proj_stack_depth; + int max_txtr_stack_depth; + int max_name_stack_depth; + int max_attrib_stack_depth; + int max_texture_size; + int max_list_nesting; + int max_eval_order; + CSize max_viewport_dims; + int auxiliary_buffers; + int max_smooth_point_size; + int min_smooth_point_size; + float smooth_point_granularity; + int max_smooth_line_size; + int min_smooth_line_size; + float smooth_line_granularity; + int red_bits; + int blue_bits; + int green_bits; + int alpha_bits; + int depth_bits; + int stencil_bits; + }; + +///////////////////////////////////////////////////////////////////////////// +// CGLEnabledView view + +class CGLEnabledView : public CView +{ +protected: + CGLEnabledView();// protected constructor used by dynamic creation + DECLARE_DYNCREATE(CGLEnabledView) +/** CGLDispList +DESC:-this is an helper class which let you create "display list objects", + use these objects to define the key elements in your scene (a disp. + list is faster than the corresponding GL commands). + -Through the class members functions you have total control on a + single display list. + -An isolated display list save OGL parameters before execution + (so it's not affected by preceding transformations or settings). +*******/ + class CGLDispList + { + friend class CGLEnabledView; + private: + BOOL m_bIsolated; + int m_glListId; + public: + CGLDispList(); // constructor + ~CGLDispList(); // destructor + void StartDef(BOOL bImmediateExec=FALSE);// enclose a disp.list def. + void EndDef(); + void Draw();// execute disp list GL commands + void SetIsolation(BOOL bValue) {m_bIsolated=bValue;}; // set isolation property + }; + +/** CGLTesselator +DESC:-this is a wrapper class which let you create "tesselator objects", + use these objects to create concave or self intersecting polygons. + -OGL tessellation objects converts a vertices list describing a convex + or self-intersecting polygon in one or more GL primitives.Read the + docs to understand the callbacks mechanism. + -The callbacks have been defined as a simple and direct mapping to + corresponding GL primitive (no per vertex color or texture information). + -The callbacks have to be global functions. + -A very simple garbage collection list has been implemented to manage new + vertices create by combine callback. + -Elaboration and drawing occur after EndDef(). +*******/ + class CGLTesselator + { + public: + CGLTesselator(); // constructor + ~CGLTesselator(); // destructor +// properties functions + void SetFilling(BOOL bFill=TRUE); + BOOL GetFilling(); + void SetWindingRule(GLdouble which); + GLdouble GetWindingRule(); +// definition functions + void StartDef(); + void AddVertexArray(GLdouble arr[][3],int size); + void AddVertex(GLdouble vertData[3]); + void ContourSeparator(); + void EndDef();// here occur drawing + + private: + GLUtesselator* m_tessObj; + }; + +/** CGLQuadric +DESC:-This is a wrapper class which let you create "quadric objects", + use these objects to create spheres, disks and cylinders. + -All GL commands related to quadrics have been wrapped hiding the + quadric object parameter. +*******/ + class CGLQuadric + { + public: + CGLQuadric(GLenum drwStyle=GLU_FILL, // constructor + GLenum normals=GLU_FLAT, + GLenum side=GLU_OUTSIDE, + BOOL bGenerateTxtrCoords=FALSE); + ~CGLQuadric(); // destructor +// properties functions + void SetDrawStyle(GLenum style); + void SetOrientation(GLenum type); + void SetTextureCoordsGen(BOOL flag); + void SetNormals(GLenum type); +// drawing functions + void DrawPartialDisk(GLdouble innerRadius,GLdouble outerRadius,int slices,int loops,GLdouble startAngle,GLdouble sweepAngle); + void DrawDisk(GLdouble innerRadius,GLdouble outerRadius,int slices,int loops); + void DrawCylinder(GLdouble baseRadius,GLdouble topRadius,GLdouble height,int slices,int stacks); + void DrawSphere(GLdouble radius,int longitudeSubdiv,int latitudeSubdiv); + + private: + GLUquadricObj* m_quadrObj; + }; +// Attributes +public: + +// Operations +public: +/* Stock Display lists functions +DESC.: these display lists are internally organized in a vector (20 max), + you have control on definition and redrawing only. + use them for background elements which are to be drawn everytime + all together. +NOTE: between BeginStockDispList and EndStockDispList should be present OpenGL calls only (see documentation for which are allowed and how are them treated) +*/ + void StartStockDListDef(); // allocates a new stock display list entry and opens a display list definition + void EndStockListDef(); // closes a stock display list definition + void DrawStockDispLists(); // executes all the stock display lists + void ClearStockDispLists(); // deletes all the stock display lists +// Information retrieval function + GLInfoStruct GetInformation(); +// Mouse cursor function + void SetMouseCursor(HCURSOR mcursor=NULL); +// Attribute retrieval function + double GetAspectRatio() {return m_dAspectRatio;}; +// Text functions + void PrepareCharset3D(CString fontname,float extrusion,BOOL boldface=FALSE,BOOL italicface=FALSE,BOOL uselines=false,float precision=0.01f);// prepare a 3D charset to be used by successive Text3D calls + void PrepareCharset3D(const LOGFONT* pLF,float extrusion,BOOL uselines=false,float precision=0.01f);// alternate method to prepare a 3D charset + void PrepareCharset2D(CString fontname,int height=10,BOOL boldface=FALSE,BOOL italicface=FALSE);// prepare a 2D charset to be used by successive Text2D calls + void PrepareCharset2D(const LOGFONT* pLF);// alternate method to prepare a 2D charset + float Text3D(CString text);// draw a 3D text string + void Text2D(CString text);// draw a bitmapped text string at the current raster position +// Rendering Context switching + void BeginGLCommands();// use to issue GL commands outside Overridables + void EndGLCommands();// i.e: in menu event handlers, button events handler etc. +// Overridables + virtual void OnCreateGL(); // override to set bg color, activate z-buffer, and other global settings + virtual void OnSizeGL(int cx, int cy); // override to adapt the viewport to the window + virtual void OnDrawGL(); // override to issue drawing functions + virtual void VideoMode(ColorsNumber &c,ZAccuracy &z,BOOL &dbuf); // override to specify some video mode parameters + +// Overrides +// NOTE: these have been declared private because they shouldn't be +// overridden, use the provided virtual functions instead. +private: + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CGLEnabledView) + public: + virtual void OnDraw(CDC* pDC); // overridden to draw this view + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + protected: + //}}AFX_VIRTUAL + +// Implementation +protected: + int m_glErrorCode; + virtual ~CGLEnabledView(); + CRect m_ClientRect; // client area size + double m_dAspectRatio; // aspect + GLYPHMETRICSFLOAT* m_gmfvector; + const int m_numchars; + + +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +// Generated message map functions +// NOTE: these have been declared private because they shouldn't be +// overridden, use the provided virtual functions instead. +private: + //{{AFX_MSG(CGLEnabledView) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnDestroy(); + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + +// member variables +private: + CDC* m_pCDC; // WinGDI Device Context + HGLRC m_hRC; // OpenGL Rendering Context + HCURSOR m_hMouseCursor; // mouse cursor handle for the view + CPalette m_CurrentPalette; // palettes + CPalette* m_pOldPalette; + int m_DispListVector[20]; // Internal stock display list vector + BOOL m_bInsideDispList; // Disp List definition semaphore + BOOL m_bExternGLCall; + BOOL m_bExternDispListCall; + int m_charsetDListBase; +// initialization helper functions + unsigned char ComponentFromIndex(int i, UINT nbits, UINT shift); + void CreateRGBPalette(); + BOOL bSetupPixelFormat(); + + CDC* GetCDC() {return m_pCDC;}; + +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Developer Studio will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_GLENABLEDVIEW_H__59CED13F_E584_11D1_ACB3_E52ED8AC9002__INCLUDED_) diff --git a/Utils/MapEdit/MapEdit.clw b/Utils/MapEdit/MapEdit.clw index 9f05a967f..d0f16fd6f 100644 --- a/Utils/MapEdit/MapEdit.clw +++ b/Utils/MapEdit/MapEdit.clw @@ -51,7 +51,7 @@ HeaderFile=MapEditView.h ImplementationFile=MapEditView.cpp Filter=W LastObject=CMapEditView -BaseClass=CView +BaseClass=CGLEnabledView VirtualFilter=VWC @@ -70,7 +70,7 @@ Type=0 HeaderFile=ChildFrm.h ImplementationFile=ChildFrm.cpp Filter=M -LastObject=IDC_LAYERBAR_LIST +LastObject=CChildFrame [CLS:CAboutDlg] diff --git a/Utils/MapEdit/MapEdit.cpp b/Utils/MapEdit/MapEdit.cpp index b1b9baebd..b131663b6 100644 --- a/Utils/MapEdit/MapEdit.cpp +++ b/Utils/MapEdit/MapEdit.cpp @@ -1,13 +1,18 @@ // MapEdit.cpp : Defines the class behaviors for the application. // -#include "stdafx.h" -#include "MapEdit.h" +#include "stdafx.h" +#include +#include +#include +#include "GLEnabledView.h" -#include "MainFrm.h" -#include "ChildFrm.h" -#include "MapEditDoc.h" -#include "MapEditView.h" +#include "MapEdit.h" + +#include "MainFrm.h" +#include "ChildFrm.h" +#include "MapEditDoc.h" +#include "MapEditView.h" #ifdef _DEBUG #define new DEBUG_NEW diff --git a/Utils/MapEdit/MapEdit.dsp b/Utils/MapEdit/MapEdit.dsp index 726c0ea11..a1e62c18d 100644 --- a/Utils/MapEdit/MapEdit.dsp +++ b/Utils/MapEdit/MapEdit.dsp @@ -85,6 +85,21 @@ LINK32=link.exe # Name "MapEdit - Win32 Release" # Name "MapEdit - Win32 Debug" +# Begin Group "MapEditor" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Core.cpp +# End Source File +# Begin Source File + +SOURCE=.\Core.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" @@ -94,7 +109,19 @@ SOURCE=.\ChildFrm.cpp # End Source File # Begin Source File -SOURCE=.\Core.cpp +SOURCE=.\gl3d.cpp +# End Source File +# Begin Source File + +SOURCE=.\glcam.cpp +# End Source File +# Begin Source File + +SOURCE=.\GLEnabledView.cpp +# End Source File +# Begin Source File + +SOURCE=.\glfrust.cpp # End Source File # Begin Source File @@ -135,7 +162,19 @@ SOURCE=.\ChildFrm.h # End Source File # Begin Source File -SOURCE=.\Core.h +SOURCE=.\gl3d.h +# End Source File +# Begin Source File + +SOURCE=.\glcam.h +# End Source File +# Begin Source File + +SOURCE=.\GLEnabledView.h +# End Source File +# Begin Source File + +SOURCE=.\glfrust.h # End Source File # Begin Source File @@ -186,9 +225,6 @@ SOURCE=.\res\MapEditDoc.ico SOURCE=.\res\Toolbar.bmp # End Source File # End Group -# Begin Source File - -SOURCE=.\ReadMe.txt -# End Source File +# End Group # End Target # End Project diff --git a/Utils/MapEdit/MapEditView.cpp b/Utils/MapEdit/MapEditView.cpp index c7e0660d7..391bee213 100644 --- a/Utils/MapEdit/MapEditView.cpp +++ b/Utils/MapEdit/MapEditView.cpp @@ -1,11 +1,16 @@ // MapEditView.cpp : implementation of the CMapEditView class // -#include "stdafx.h" -#include "MapEdit.h" +#include "stdafx.h" +#include +#include +#include +#include "GLEnabledView.h" -#include "MapEditDoc.h" -#include "MapEditView.h" +#include "MapEdit.h" + +#include "MapEditDoc.h" +#include "MapEditView.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -16,16 +21,16 @@ static char THIS_FILE[] = __FILE__; ///////////////////////////////////////////////////////////////////////////// // CMapEditView -IMPLEMENT_DYNCREATE(CMapEditView, CView) +IMPLEMENT_DYNCREATE(CMapEditView, CGLEnabledView) -BEGIN_MESSAGE_MAP(CMapEditView, CView) +BEGIN_MESSAGE_MAP(CMapEditView, CGLEnabledView) //{{AFX_MSG_MAP(CMapEditView) ON_WM_SETFOCUS() //}}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) + ON_COMMAND(ID_FILE_PRINT, CGLEnabledView::OnFilePrint) + ON_COMMAND(ID_FILE_PRINT_DIRECT, CGLEnabledView::OnFilePrint) + ON_COMMAND(ID_FILE_PRINT_PREVIEW, CGLEnabledView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// @@ -33,6 +38,7 @@ END_MESSAGE_MAP() CMapEditView::CMapEditView() { + TRACE0("Here"); // TODO: add construction code here } @@ -41,24 +47,6 @@ CMapEditView::~CMapEditView() { } -BOOL CMapEditView::PreCreateWindow(CREATESTRUCT& cs) -{ - // TODO: Modify the Window class or styles here by modifying - // the CREATESTRUCT cs - - return CView::PreCreateWindow(cs); -} - -///////////////////////////////////////////////////////////////////////////// -// CMapEditView drawing - -void CMapEditView::OnDraw(CDC* pDC) -{ - CMapEditDoc* pDoc = GetDocument(); - ASSERT_VALID(pDoc); - // TODO: add draw code for native data here -} - ///////////////////////////////////////////////////////////////////////////// // CMapEditView printing @@ -84,12 +72,12 @@ void CMapEditView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) #ifdef _DEBUG void CMapEditView::AssertValid() const { - CView::AssertValid(); + CGLEnabledView::AssertValid(); } void CMapEditView::Dump(CDumpContext& dc) const { - CView::Dump(dc); + CGLEnabledView::Dump(dc); } CMapEditDoc* CMapEditView::GetDocument() // non-debug version is inline @@ -104,12 +92,10 @@ CMapEditDoc* CMapEditView::GetDocument() // non-debug version is inline void CMapEditView::OnSetFocus(CWnd* pOldWnd) { + CMapEditDoc *CurDoc=GetDocument(); - CView::OnSetFocus(pOldWnd); + CGLEnabledView::OnSetFocus(pOldWnd); theApp.SetCurrent(CurDoc); CurDoc->UpdateAll(); // woohoo, that was easy - - // TODO: Add your message handler code here - } diff --git a/Utils/MapEdit/MapEditView.h b/Utils/MapEdit/MapEditView.h index f7847e9be..09bcb6b10 100644 --- a/Utils/MapEdit/MapEditView.h +++ b/Utils/MapEdit/MapEditView.h @@ -9,8 +9,7 @@ #pragma once #endif // _MSC_VER > 1000 - -class CMapEditView : public CView +class CMapEditView : public CGLEnabledView { protected: // create from serialization only CMapEditView(); @@ -26,9 +25,6 @@ public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMapEditView) - public: - virtual void OnDraw(CDC* pDC); // overridden to draw this view - virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);