www.pudn.com > 3DEDITOR.rar > 3DEDITORVIEW.CPP


// 3DEditorView.cpp : implementation of the CMy3DEditorView class 
// 
 
#include "stdafx.h" 
#include "3DEditor.h" 
#include "MainFrm.h" 
 
#include "3DEditorDoc.h" 
#include "3DEditorView.h" 
#include "DlgMapping.h" 
#include "DlgProperties.h" 
#include "DlgMaterial.h" 
#include "DlgRayTrace.h" 
 
#include "mmsystem.h" 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
extern CStatusBar *statbar; 
///////////////////////////////////////////////////////////////////////////// 
// CMy3DEditorView 
 
IMPLEMENT_DYNCREATE(CMy3DEditorView, CView) 
 
BEGIN_MESSAGE_MAP(CMy3DEditorView, CView) 
	//{{AFX_MSG_MAP(CMy3DEditorView) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_SIZE() 
	ON_COMMAND(ID_VIEW_VIEWALL, OnViewViewall) 
	ON_COMMAND(ID_VIEW_CAMERA_NEXT, OnViewCameraNext) 
	ON_UPDATE_COMMAND_UI(ID_VIEW_CAMERA_NEXT, OnUpdateViewCameraNext) 
	ON_COMMAND(ID_VIEW_CAMERA_PREVIOUS, OnViewCameraPrevious) 
	ON_UPDATE_COMMAND_UI(ID_VIEW_CAMERA_PREVIOUS, OnUpdateViewCameraPrevious) 
	ON_UPDATE_COMMAND_UI(ID_VIEW_VIEWALL, OnUpdateViewViewall) 
	ON_COMMAND(ID_EDIT_CAMERA_RESET, OnEditCameraReset) 
	ON_UPDATE_COMMAND_UI(ID_EDIT_CAMERA_RESET, OnUpdateEditCameraReset) 
	ON_COMMAND(IDM_FLAT, OnFlat) 
	ON_UPDATE_COMMAND_UI(IDM_FLAT, OnUpdateFlat) 
	ON_COMMAND(IDM_GOURAUND, OnGouraund) 
	ON_UPDATE_COMMAND_UI(IDM_GOURAUND, OnUpdateGouraund) 
	ON_COMMAND(IDM_POINTS, OnPoints) 
	ON_UPDATE_COMMAND_UI(IDM_POINTS, OnUpdatePoints) 
	ON_COMMAND(IDM_SHADED, OnShaded) 
	ON_UPDATE_COMMAND_UI(IDM_SHADED, OnUpdateShaded) 
	ON_COMMAND(IDM_TEXTURED, OnTextured) 
	ON_UPDATE_COMMAND_UI(IDM_TEXTURED, OnUpdateTextured) 
	ON_COMMAND(IDM_WIREFRAME, OnWireframe) 
	ON_UPDATE_COMMAND_UI(IDM_WIREFRAME, OnUpdateWireframe) 
	ON_WM_LBUTTONDOWN() 
	ON_WM_LBUTTONUP() 
	ON_COMMAND(ID_LOOKAT, OnLookat) 
	ON_WM_MOUSEMOVE() 
	ON_WM_MOUSEWHEEL() 
	ON_COMMAND(ID_PAN, OnPan) 
	ON_WM_RBUTTONDOWN() 
	ON_COMMAND(ID_SELECT, OnSelect) 
	ON_WM_TIMER() 
	ON_UPDATE_COMMAND_UI(ID_DOLLY, OnUpdateDolly) 
	ON_UPDATE_COMMAND_UI(ID_LOOKAT, OnUpdateLookat) 
	ON_UPDATE_COMMAND_UI(ID_PAN, OnUpdatePan) 
	ON_UPDATE_COMMAND_UI(ID_SELECT, OnUpdateSelect) 
	ON_COMMAND(ID_ELEMEMTMODE, OnElememtmode) 
	ON_UPDATE_COMMAND_UI(ID_ELEMEMTMODE, OnUpdateElememtmode) 
	ON_COMMAND(ID_MATERIALMODE, OnMaterialmode) 
	ON_UPDATE_COMMAND_UI(ID_MATERIALMODE, OnUpdateMaterialmode) 
	ON_COMMAND(ID_DOLLY, OnDolly) 
	ON_COMMAND(ID_TILT, OnTilt) 
	ON_UPDATE_COMMAND_UI(ID_TILT, OnUpdateTilt) 
	ON_COMMAND(ID_RAYTRACE, OnRaytrace) 
	ON_UPDATE_COMMAND_UI(ID_RAYTRACE, OnUpdateRaytrace) 
	ON_WM_CHAR() 
	ON_COMMAND(ID_CAPTURE_IMAGE, OnCaptureImage) 
	ON_COMMAND(ID_CAPTURE_MOVIE, OnCaptureMovie) 
	ON_UPDATE_COMMAND_UI(ID_CAPTURE_MOVIE, OnUpdateCaptureMovie) 
	ON_COMMAND(ID_CAPTURE_RECORD, OnCaptureRecord) 
	ON_UPDATE_COMMAND_UI(ID_CAPTURE_RECORD, OnUpdateCaptureRecord) 
	ON_COMMAND(ID_CAPTURE_PAUSE, OnCapturePause) 
	ON_UPDATE_COMMAND_UI(ID_CAPTURE_PAUSE, OnUpdateCapturePause) 
	ON_COMMAND(ID_CAPTURE_STOP, OnCaptureStop) 
	ON_UPDATE_COMMAND_UI(ID_CAPTURE_STOP, OnUpdateCaptureStop) 
	ON_WM_ERASEBKGND() 
	//}}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() 
 
///////////////////////////////////////////////////////////////////////////// 
// CMy3DEditorView construction/destruction 
 
CMy3DEditorView::CMy3DEditorView() 
{ 
	// TODO: add construction code here 
	lbut=0; 
	polymode=3; 
	shademode=1; 
	dtimer=0; 
	cammode=0; 
	cur_cam=-1; 
	lastviewUp.Vec(0,0,1); 
	movieCapture=NULL; 
	recording=false; 
} 
 
CMy3DEditorView::~CMy3DEditorView() 
{ 
} 
 
BOOL CMy3DEditorView::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); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMy3DEditorView drawing 
 
void CMy3DEditorView::OnDraw(CDC* pDC) 
{ 
	CMy3DEditorDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	// TODO: add draw code for native data here 
	if(pDC->IsPrinting()) 
	{ 
		 // 将内存DC中的内容绘制到打印DC  
		 CRect      drawRect; 
		 int        cx, cy; 
		 m_MemImageDC.GetMemorySize(&cx, &cy); 
		 drawRect.SetRect(150, 200, 150 + cx*2 , 200 + cy*2); 
         pDC->DPtoLP(&drawRect); 
		 m_MemImageDC.CopyDataToDC(pDC, drawRect); 
	} 
	else // 在当前的DC中绘制OpenGL图像 
	{ 
		wglMakeCurrent( pDC->m_hDC, m_hRC ); 
		glClearColor( pDoc->background.x, pDoc->background.y, pDoc->background.z, 1.0 ); 
 
		if (pDoc->inuse==0) 
			DrawScene(pDC); 
		else  
		{ 
			glDrawBuffer(GL_FRONT); 
			glClear( GL_COLOR_BUFFER_BIT ); 
			glFinish(); 
		} 
		wglMakeCurrent( 0, 0 ); 
		// 准备内存DC  
		CRect rect; 
		GetClientRect(&rect); 
	    m_MemImageDC.SetMemorySize(rect.Width(), rect.Height()); 
		// 将当前的DC的图像数据拷贝到内存中 
		m_MemImageDC.CopyDataFromDC(pDC, rect); 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMy3DEditorView printing 
 
BOOL CMy3DEditorView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CMy3DEditorView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CMy3DEditorView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CMy3DEditorView diagnostics 
 
#ifdef _DEBUG 
void CMy3DEditorView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CMy3DEditorView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CMy3DEditorDoc* CMy3DEditorView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy3DEditorDoc))); 
	return (CMy3DEditorDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CMy3DEditorView message handlers 
 
int CMy3DEditorView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
	CreateOpenGL();	 
	return 0; 
} 
 
void CMy3DEditorView::OnDestroy()  
{ 
	CView::OnDestroy(); 
	 
	// TODO: Add your message handler code here 
	DestroyOpenGL();	 
} 
 
void CMy3DEditorView::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	 
	// TODO: Add your message handler code here 
    CDC *dc = GetDC(); 
	wglMakeCurrent( dc->m_hDC, m_hRC ); 
 
    glViewport(0, 0, cx, cy); 
 
	wglMakeCurrent( NULL, NULL ); 
	ReleaseDC(dc); 
	if (cy==0) 
	{ 
		cy=1; 
		aspect=1.0; 
	} 
	else aspect=(GLfloat)cx/cy; 
 
} 
 
int CMy3DEditorView::CreateOpenGL() 
{ 
	CDC *dc = GetDC(); 
	HDC hDC = dc->GetSafeHdc(); 
	 
	PIXELFORMATDESCRIPTOR pfd = {  
	    sizeof(PIXELFORMATDESCRIPTOR),    // pfd结构的大小  
	    1,                                // 版本号  
	    PFD_DRAW_TO_WINDOW |              // 支持在窗口中绘图  
	    PFD_SUPPORT_OPENGL |              // 支持 OpenGL  
	    PFD_DOUBLEBUFFER,                 // 双缓存模式  
	    PFD_TYPE_RGBA,                    // RGBA 颜色模式  
	    24,                               // 24 位颜色深度  
	    0, 0, 0, 0, 0, 0,                 // 忽略颜色位  
	    0,                                // 没有非透明度缓存  
	    0,                                // 忽略移位位  
	    0,                                // 无累加缓存  
	    0, 0, 0, 0,                       // 忽略累加位  
	    32,                               // 32 位深度缓存      
	    0,                                // 无模板缓存  
	    0,                                // 无辅助缓存  
	    PFD_MAIN_PLANE,                   // 主层  
	    0,                                // 保留  
	    0, 0, 0                           // 忽略层,可见性和损毁掩模  
	}; 	 
	int pixelformat; 
	pixelformat = ::ChoosePixelFormat(hDC, &pfd);//选择像素格式 
	::SetPixelFormat(hDC, pixelformat, &pfd);	//设置像素格式 
	if(pfd.dwFlags & PFD_NEED_PALETTE) 
	SetLogicalPalette();	//设置逻辑调色板 
 
    m_hRC = wglCreateContext( hDC ); 
    wglMakeCurrent( hDC, m_hRC ); 
 
    glClearDepth( 1.0 ); 
    glDepthFunc(GL_LEQUAL); 
	glPointSize(2.0); 
	glLineWidth(1.0); 
	glCullFace(GL_BACK); 
    glPixelStorei(GL_UNPACK_ALIGNMENT,1); 
	glPixelStorei(GL_PACK_ALIGNMENT,1); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); 
	glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); 
    wglMakeCurrent( 0, 0 ); 
 
	ReleaseDC(dc); 
 
	return 0; 
} 
///////////////////////////////////////////////////////////////////// 
//	                  设置逻辑调色板 
////////////////////////////////////////////////////////////////////// 
void CMy3DEditorView::SetLogicalPalette(void) 
{ 
    struct 
    { 
        WORD Version; 
        WORD NumberOfEntries; 
        PALETTEENTRY aEntries[256]; 
    } logicalPalette = { 0x300, 256 }; 
 
	BYTE reds[] = {0, 36, 72, 109, 145, 182, 218, 255}; 
	BYTE greens[] = {0, 36, 72, 109, 145, 182, 218, 255}; 
	BYTE blues[] = {0, 85, 170, 255}; 
 
    for (int colorNum=0; colorNum<256; ++colorNum) 
    { 
        logicalPalette.aEntries[colorNum].peRed = 
            reds[colorNum & 0x07]; 
        logicalPalette.aEntries[colorNum].peGreen = 
            greens[(colorNum >> 0x03) & 0x07]; 
        logicalPalette.aEntries[colorNum].peBlue = 
            blues[(colorNum >> 0x06) & 0x03]; 
        logicalPalette.aEntries[colorNum].peFlags = 0; 
    } 
 
    m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette); 
} 
 
void CMy3DEditorView::DestroyOpenGL() 
{ 
	wglMakeCurrent(NULL, NULL); 
	if (m_hRC) 
		wglDeleteContext(m_hRC); 
	if (m_hPalette) 
	    DeleteObject(m_hPalette); 
	 
	m_hRC=0; 
} 
 
 
void DrawBBox(object *o) 
{ 
	glBegin(GL_LINES); 
		glVertex3f(o->bbox1.x,o->bbox1.y,o->bbox1.z); 
		glVertex3f(o->bbox1.x,o->bbox1.y,o->bbox2.z); 
		glVertex3f(o->bbox1.x,o->bbox1.y,o->bbox1.z); 
		glVertex3f(o->bbox1.x,o->bbox2.y,o->bbox1.z); 
		glVertex3f(o->bbox1.x,o->bbox1.y,o->bbox1.z); 
		glVertex3f(o->bbox2.x,o->bbox1.y,o->bbox1.z); 
 
		glVertex3f(o->bbox2.x,o->bbox2.y,o->bbox2.z); 
		glVertex3f(o->bbox2.x,o->bbox2.y,o->bbox1.z); 
		glVertex3f(o->bbox2.x,o->bbox2.y,o->bbox2.z); 
		glVertex3f(o->bbox2.x,o->bbox1.y,o->bbox2.z); 
		glVertex3f(o->bbox2.x,o->bbox2.y,o->bbox2.z); 
		glVertex3f(o->bbox1.x,o->bbox2.y,o->bbox2.z); 
 
		glVertex3f(o->bbox1.x,o->bbox1.y,o->bbox2.z); 
		glVertex3f(o->bbox2.x,o->bbox1.y,o->bbox2.z); 
		glVertex3f(o->bbox2.x,o->bbox1.y,o->bbox2.z); 
		glVertex3f(o->bbox2.x,o->bbox1.y,o->bbox1.z); 
		glVertex3f(o->bbox2.x,o->bbox1.y,o->bbox1.z); 
		glVertex3f(o->bbox2.x,o->bbox2.y,o->bbox1.z); 
		glVertex3f(o->bbox2.x,o->bbox2.y,o->bbox1.z); 
		glVertex3f(o->bbox1.x,o->bbox2.y,o->bbox1.z); 
		glVertex3f(o->bbox1.x,o->bbox2.y,o->bbox1.z); 
		glVertex3f(o->bbox1.x,o->bbox2.y,o->bbox2.z); 
		glVertex3f(o->bbox1.x,o->bbox2.y,o->bbox2.z); 
		glVertex3f(o->bbox1.x,o->bbox1.y,o->bbox2.z); 
 
	glEnd(); 
} 
 
void CMy3DEditorView::DrawScene(CDC* cDC) 
{ 
	CMy3DEditorDoc* pDoc = GetDocument(); 
    glDrawBuffer(GL_BACK); 
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 
	float f[4]={0,0,0,1}; 
 
	glDisable(GL_POINT_SMOOTH); 
	glDisable(GL_LINE_SMOOTH); 
	glDisable(GL_BLEND); 
 
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,pDoc->textinterp?GL_LINEAR:GL_NEAREST); 
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,pDoc->textinterp?GL_LINEAR:GL_NEAREST); 
 
	if (pDoc->backface) 
		glEnable(GL_CULL_FACE); 
	else 
		glDisable(GL_CULL_FACE); 
 
	if (shademode) 
		glShadeModel(GL_SMOOTH); 
    else  
		glShadeModel(GL_FLAT); 
 
//    if (dither) 
        glEnable(GL_DITHER); 
//    else glDisable(GL_DITHER); 
    if (polymode) 
        if (polymode==1) 
           glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
        else  
			glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
    else  
		glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); 
 
	if (polymode==3) 
	{ 
		glEnable(GL_TEXTURE_2D); 
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,pDoc->textinterp?GL_LINEAR:GL_NEAREST); 
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,pDoc->textinterp?GL_LINEAR:GL_NEAREST); 
	} 
	else 
		glDisable(GL_TEXTURE_2D); 
 
	glMatrixMode( GL_PROJECTION ); 
	glLoadIdentity(); 
	gluPerspective(cam.theta, aspect, nearplane, farplane); 
 
	glMatrixMode( GL_MODELVIEW ); 
	glLoadIdentity(); 
	glMultMatrixf((float *)&cam.mat_t); 
	glTranslatef(-cam.Vp.x,-cam.Vp.y,-cam.Vp.z); 
 
	glEnable(GL_DEPTH_TEST); 
	if (polymode>1) 
	{ 
		glEnable(GL_LIGHTING); 
		glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,1); 
		int i; 
		f[0]=pDoc->amblight.x; 
		f[1]=pDoc->amblight.y; 
		f[2]=pDoc->amblight.z; 
		glLightModelfv(GL_LIGHT_MODEL_AMBIENT,f); 
		if (pDoc->headlight==1) 
		{ 
			glDisable(GL_LIGHT2); 
			glDisable(GL_LIGHT3); 
			glDisable(GL_LIGHT4); 
			glDisable(GL_LIGHT5); 
			glDisable(GL_LIGHT6); 
			glDisable(GL_LIGHT7); 
			glEnable(GL_LIGHT1); 
			f[0]=(float)cam.Vp.x; 
			f[1]=(float)cam.Vp.y; 
			f[2]=(float)cam.Vp.z; 
			glLightfv(GL_LIGHT1,GL_POSITION,f); 
			f[0]=f[1]=f[2]=1.0; 
			glLightfv(GL_LIGHT1,GL_DIFFUSE,f); 
			glLightfv(GL_LIGHT1,GL_SPECULAR,f); 
			glLightf(GL_LIGHT1,GL_SPOT_CUTOFF,180); 
		} 
		else  
			if (pDoc->headlight==-1) 
		{ 
			glDisable(GL_LIGHTING); 
		} 
		else 
		{ 
			light *l; 
			int ml; 
			glDisable(GL_LIGHT1); 
			glGetIntegerv(GL_MAX_LIGHTS,&ml); 
			if (--ml>pDoc->nlights) 
				ml=pDoc->nlights; 
			for( i=0;ilightlib[i]; 
				glEnable(GL_LIGHT1+i); 
				f[0]=l->pos.x; 
				f[1]=l->pos.y; 
				f[2]=l->pos.z; 
				glLightfv(GL_LIGHT1+i,GL_POSITION,f); 
				f[0]=l->color.x; 
				f[1]=l->color.y; 
				f[2]=l->color.z; 
				glLightfv(GL_LIGHT1+i,GL_DIFFUSE,f); 
				glLightfv(GL_LIGHT1+i,GL_SPECULAR,f); 
				if (l->type==1) 
				{ 
					glLightfv(GL_LIGHT1+i,GL_SPOT_DIRECTION,&l->dir.x); 
					glLightf(GL_LIGHT1+i,GL_SPOT_CUTOFF,(float)(Degrees(acos(l->falloff)))); 
				} 
				else glLightf(GL_LIGHT1+i,GL_SPOT_CUTOFF,180); 
				} 
			} 
		} 
	else 
	{ 
	glColor3f(1-pDoc->background.x,1-pDoc->background.y,1-pDoc->background.z); 
	glDisable(GL_LIGHTING); 
	} 
 
	if (pDoc->fog) 
	{ 
	glEnable(GL_FOG); 
	glFogi( GL_FOG_MODE, GL_LINEAR ); 
	glFogf( GL_FOG_START  , 0); 
	glFogf( GL_FOG_END  , pDoc->bboxdiag/4); 
	f[0]=pDoc->background.x; 
	f[1]=pDoc->background.y; 
	f[2]=pDoc->background.z; 
	glFogfv( GL_FOG_COLOR ,f ); 
	} 
	else glDisable(GL_FOG); 
 
	object *o=pDoc->obj0; 
	while( o ) 
		{ 
		DrawObject(o); 
		glFlush(); 
 
		o=(object *)o->next; 
		} 
 
	glDepthMask(GL_FALSE); 
	if (pDoc->selobj) 
		{ 
		glLineWidth(2.0); 
		glTexImage2D(GL_TEXTURE_2D,0,3,0,0,0,GL_RGB,GL_UNSIGNED_BYTE,0); 
		glDisable(GL_TEXTURE_2D); 
		glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
		glShadeModel(GL_FLAT); 
		glDisable(GL_LIGHTING); 
		glDisable(GL_CULL_FACE); 
		glColor3f(1.0f,1.0f,1.0f); 
		 
		int i; 
		if (pDoc->selface==-1) 
			DrawBBox(pDoc->selobj); 
		else 
			{ 
			for( i=0;iselobj->nf;i++ ) 
				if (pDoc->selobj->ft[i]) 
					pDoc->selobj->ft[i]->flag=1;	 
			ftlist *e=pDoc->selobj->ft[pDoc->selobj->elem[pDoc->selface].elem]; 
			e->flag=0; 
			DrawElement(e); 
			} 
		glLineWidth(1.0); 
		} 
 
	if (pDoc->dlgmap) 
	{ 
		DlgMapping *d=(DlgMapping *)pDoc->dlgmap; 
		if (d->obj && d->vsel!=-1) 
		{ 
		glColor3f(1.0f,0.2f,0.2f); 
		glPointSize(10.0); 
		glBegin(GL_POINTS); 
		if (d->obj->vt[d->vsel]) 
			glVertex3fv((float *)&d->obj->vt[d->vsel]->pos); 
		glEnd(); 
		glPointSize(2.0); 
		}	 
	} 
 
	glDepthMask(GL_TRUE); 
 
	if (movieCapture != NULL && recording) 
	{ 
		movieCapture->captureFrame(); 
		glPushMatrix(); 
        glColor4f(1, 0, 0, 1); 
		RECT rect; 
	    GetClientRect(&rect); 
		int x=(rect.right - MovieSize_X) / 2 - 1; 
		int y =(rect.bottom - MovieSize_Y) / 2 - 1; 
		int w=MovieSize_X + 1; 
		int h=MovieSize_Y + 1; 
		glBegin(GL_LINE_LOOP); 
			glVertex3f(x, y, 0); 
			glVertex3f(x + w, y, 0); 
			glVertex3f(x + w, y + h, 0); 
			glVertex3f(x, y + h, 0); 
        glEnd(); 
  
        glPopMatrix(); 
	} 
 
	glFinish(); 
    SwapBuffers(cDC->m_hDC); 
} 
 
 
void CMy3DEditorView::DrawObject(object *obj) 
{ 
	CMy3DEditorDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	int f=0; 
	pDoc->SelectMaterial(pDoc->matlib,last_mat=0); 
	ftlist **ft=obj->ft; 
 
	switch (polymode) 
	{ 
	case 2: 
		glBegin(GL_TRIANGLES); 
		if (shademode) 
			for( f=0;fnf;f++ ) 
				if (ft[f]) 
					{ 
					if (ft[f]->material!=last_mat) 
						{ 
						glEnd(); 
						pDoc->SelectMaterial(&pDoc->matlib[last_mat=ft[f]->material],polymode==3); 
						glBegin(GL_TRIANGLES); 
						} 
 
					 glNormal3fv((float *)&ft[f]->lv[0]->normal); 
 					 glVertex3fv((float *)&ft[f]->lv[0]->pos); 
 
					 glNormal3fv((float *)&ft[f]->lv[1]->normal); 
 					 glVertex3fv((float *)&ft[f]->lv[1]->pos); 
 
					 glNormal3fv((float *)&ft[f]->lv[2]->normal); 
 					 glVertex3fv((float *)&ft[f]->lv[2]->pos); 
					} 
				else ; 
		else 
			for( f=0;fnf;f++ ) 
				if (ft[f]) 
					{ 
					if (ft[f]->material!=last_mat) 
						{ 
						glEnd(); 
						pDoc->SelectMaterial(&pDoc->matlib[last_mat=ft[f]->material],polymode==3); 
						glBegin(GL_TRIANGLES); 
						} 
 
					glNormal3fv((float *)&ft[f]->normal); 
					glVertex3fv((float *)&ft[f]->lv[0]->pos); 
					glVertex3fv((float *)&ft[f]->lv[1]->pos); 
					glVertex3fv((float *)&ft[f]->lv[2]->pos); 
					} 
		glEnd(); 
		break; 
	case 3: 
		{ 
		 float uv[2]; 
		glBegin(GL_TRIANGLES); 
		if (shademode) 
			for( f=0;fnf;f++ ) 
				if (ft[f]) 
					{ 
					if (ft[f]->material!=last_mat) 
						{ 
						glEnd(); 
						pDoc->SelectMaterial(&pDoc->matlib[last_mat=ft[f]->material],polymode==3); 
						glBegin(GL_TRIANGLES); 
						} 
 
					 uv[0]=ft[f]->lv[0]->tx[0]; 
					 uv[1]=ft[f]->lv[0]->tx[1]; 
 
					 pDoc->calc_uv(uv[0], uv[1], &(pDoc->matlib[last_mat].map_texture1)); 
					 
					 glNormal3fv((float *)&ft[f]->lv[0]->normal); 
					 glTexCoord2fv(uv); 
 					 glVertex3fv((float *)&ft[f]->lv[0]->pos); 
 
					 uv[0]=ft[f]->lv[1]->tx[0]; 
					 uv[1]=ft[f]->lv[1]->tx[1]; 
 
					 pDoc->calc_uv(uv[0], uv[1], &(pDoc->matlib[last_mat].map_texture1)); 
 
					 glNormal3fv((float *)&ft[f]->lv[1]->normal); 
					 glTexCoord2fv(uv); 
 					 glVertex3fv((float *)&ft[f]->lv[1]->pos); 
 
					 uv[0]=ft[f]->lv[2]->tx[0]; 
					 uv[1]=ft[f]->lv[2]->tx[1]; 
 
					 pDoc->calc_uv(uv[0], uv[1], &(pDoc->matlib[last_mat].map_texture1)); 
 
					 glNormal3fv((float *)&ft[f]->lv[2]->normal); 
					 glTexCoord2fv(uv); 
 					 glVertex3fv((float *)&ft[f]->lv[2]->pos); 
					} 
				else ; 
		else 
			for( f=0;fnf;f++ ) 
				if (ft[f]) 
					{ 
					if (ft[f]->material!=last_mat) 
						{ 
						glEnd(); 
						pDoc->SelectMaterial(&pDoc->matlib[last_mat=ft[f]->material],polymode==3); 
						glBegin(GL_TRIANGLES); 
						} 
 
					glNormal3fv((float *)&ft[f]->normal); 
 
					uv[0]=ft[f]->lv[0]->tx[0]; 
					uv[1]=ft[f]->lv[0]->tx[1]; 
 
					pDoc->calc_uv(uv[0], uv[1], &(pDoc->matlib[last_mat].map_texture1)); 
 
					glTexCoord2fv(uv); 
					glVertex3fv((float *)&ft[f]->lv[0]->pos); 
					 
					uv[0]=ft[f]->lv[1]->tx[0]; 
					uv[1]=ft[f]->lv[1]->tx[1]; 
 
					pDoc->calc_uv(uv[0], uv[1], &(pDoc->matlib[last_mat].map_texture1)); 
 
					glTexCoord2fv(uv); 
					glVertex3fv((float *)&ft[f]->lv[1]->pos); 
 
					uv[0]=ft[f]->lv[2]->tx[0]; 
					uv[1]=ft[f]->lv[2]->tx[1]; 
 
					pDoc->calc_uv(uv[0], uv[1], &(pDoc->matlib[last_mat].map_texture1)); 
 
					glTexCoord2fv(uv); 
					glVertex3fv((float *)&ft[f]->lv[2]->pos); 
					} 
			glEnd(); 
		} 
		break; 
 
	case 0: 
		glBegin(GL_POINTS); 
		for( f=0;fnv;f++ ) 
			if (obj->vt[f]) 
				glVertex3fv((float *)&obj->vt[f]->pos); 
		glEnd(); 
		break; 
	case 1: 
		glBegin(GL_TRIANGLES); 
		for( f=0;fnf;f++ ) 
			if (ft[f]) 
			{ 
			glVertex3fv((float *)&ft[f]->lv[0]->pos); 
			glVertex3fv((float *)&ft[f]->lv[1]->pos); 
			glVertex3fv((float *)&ft[f]->lv[2]->pos); 
			} 
		glEnd(); 
		break; 
	} 
} 
 
void CMy3DEditorView::DrawElement(ftlist *node) 
{ 
	unsigned short i; 
 
	glBegin(GL_TRIANGLES); 
	glVertex3fv(&node->lv[0]->pos.x); 
	glVertex3fv(&node->lv[1]->pos.x); 
	glVertex3fv(&node->lv[2]->pos.x); 
	glEnd(); 
	for( i=0;i<3;i++ ) 
		if (node->lf[i]) 
			if (node->lf[i]->flag) 
				{ 
				node->lf[i]->flag=0; 
				DrawElement(node->lf[i]); 
				} 
} 
 
void CMy3DEditorView::LookAt(vector& vp,vector& lp) 
{ 
	CMy3DEditorDoc* pDoc = GetDocument(); 
 
	vector U,N; 
	cam.Vp=vp; 
	cam.Lp=lp; 
	cam.theta=45.0; 
	N=lp-vp; 
	N.Normalize(); 
	U=cam.Up - VecDot(N,cam.Up)*N; 
	U.Normalize(); 
	cam.Up=U; 
	cam.CalcSystemVectors(); 
 
	float d2=(pDoc->bboxC - cam.Vp).Length(); 
	nearplane=d2-pDoc->bboxdiag/2; 
	farplane=pDoc->bboxdiag/2+d2; 
	if (nearplanebboxdiag/1000)  
		nearplane=pDoc->bboxdiag/1000; 
	Invalidate(0); 
} 
 
void CMy3DEditorView::OnViewViewall()  
{ 
	// TODO: Add your command handler code here 
	CMy3DEditorDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	vector vp; 
 
	vp=pDoc->bboxC; 
	vp.x-=pDoc->bboxdiag; 
 
	LookAt(vp,pDoc->bboxC);	 
} 
void CMy3DEditorView::OnUpdateViewViewall(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	CMy3DEditorDoc *pDoc=GetDocument(); 
	pCmdUI->Enable(pDoc->obj0!=0);	 
} 
void CMy3DEditorView::OnViewCameraNext()  
{ 
	// TODO: Add your command handler code here 
	CMy3DEditorDoc *pDoc=GetDocument(); 
	cur_cam=(cur_cam+1)%GetDocument()->ncamlib; 
	LookAt(pDoc->camlib[cur_cam].Vp,pDoc->camlib[cur_cam].Lp);	 
} 
 
void CMy3DEditorView::OnUpdateViewCameraNext(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(GetDocument()->ncamlib>1);	 
} 
 
void CMy3DEditorView::OnViewCameraPrevious()  
{ 
	// TODO: Add your command handler code here 
	CMy3DEditorDoc *pDoc=GetDocument(); 
	if (cur_cam==0) 
		cur_cam=GetDocument()->ncamlib-1; 
	else cur_cam=cur_cam-1; 
	LookAt(pDoc->camlib[cur_cam].Vp,pDoc->camlib[cur_cam].Lp);	 
} 
 
void CMy3DEditorView::OnUpdateViewCameraPrevious(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(GetDocument()->ncamlib>1);	 
} 
 
void CMy3DEditorView::OnEditCameraReset()  
{ 
	// TODO: Add your command handler code here 
	CMy3DEditorDoc *pDoc=GetDocument(); 
	LookAt(pDoc->camlib[cur_cam].Vp,pDoc->camlib[cur_cam].Lp);	 
} 
 
void CMy3DEditorView::OnUpdateEditCameraReset(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(cur_cam!=-1);	 
} 
 
void CMy3DEditorView::OnFlat()  
{ 
	// TODO: Add your command handler code here 
	shademode=0; 
	Invalidate(0);	 
} 
 
void CMy3DEditorView::OnUpdateFlat(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetRadio(shademode==0);	 
} 
 
void CMy3DEditorView::OnGouraund()  
{ 
	// TODO: Add your command handler code here 
	shademode=1; 
	Invalidate(0);	 
} 
 
void CMy3DEditorView::OnUpdateGouraund(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetRadio(shademode==1);	 
} 
 
void CMy3DEditorView::OnPoints()  
{ 
	// TODO: Add your command handler code here 
	polymode=0; 
	Invalidate(0);	 
} 
 
void CMy3DEditorView::OnUpdatePoints(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetRadio(polymode==0);	 
} 
 
void CMy3DEditorView::OnShaded()  
{ 
	// TODO: Add your command handler code here 
	polymode=2; 
	Invalidate(0);	 
} 
 
void CMy3DEditorView::OnUpdateShaded(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetRadio(polymode==2);	 
} 
 
void CMy3DEditorView::OnTextured()  
{ 
	// TODO: Add your command handler code here 
	polymode=3; 
	Invalidate(0);	 
} 
 
void CMy3DEditorView::OnUpdateTextured(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetRadio(polymode==3);	 
} 
 
void CMy3DEditorView::OnWireframe()  
{ 
	// TODO: Add your command handler code here 
	polymode=1; 
	Invalidate(0);	 
} 
 
void CMy3DEditorView::OnUpdateWireframe(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetRadio(polymode==1);	 
} 
 
void CMy3DEditorView::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	CMy3DEditorDoc *pDoc=GetDocument(); 
 
	if ((nFlags&MK_CONTROL) || (nFlags&MK_SHIFT) || 
		(GetAsyncKeyState(VK_MENU)&0x8000) ) 
		{ 
		lbut=1; 
		mousex = point.x;     
		mousey = point.y; 
		SetCapture(); 
		} 
	else if (cammode==0) 
		Select(point,0); 
	else if (cammode==7) 
		Select(point,7); 
	else if (cammode==4) 
		Select(point,5); 
	else if (cammode==8) 
		Select(point,8); 
	else 
		{ 
		lbut=1; 
		mousex = point.x;     
		mousey = point.y; 
		SetCapture(); 
		} 
	 
	CView::OnLButtonDown(nFlags, point); 
} 
 
void CMy3DEditorView::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	if (lbut) 
	   {  
		lbut=0; 
	    ReleaseCapture(); 
	   } 
		 
	CView::OnLButtonUp(nFlags, point); 
} 
 
void CMy3DEditorView::OnLookat()  
{ 
	// TODO: Add your command handler code here 
	if (cammode==4) 
		cammode=0; 
	else cammode=4;	 
} 
 
void CMy3DEditorView::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	CMy3DEditorDoc* pDoc = GetDocument(); 
 
	int cmode; 
	if (nFlags&MK_CONTROL) 
		cmode=2; 
	else if (nFlags&MK_SHIFT) 
		cmode=3; 
	else if (GetAsyncKeyState(VK_MENU)&0x8000) 
		cmode=1; 
	else if (cammode!=0) 
		cmode=cammode; 
	else  
		{ 
		mousex=point.x; 
		mousey=point.y; 
		return; 
		} 
 
	switch(cmode) 
	{ 
	case 1:	SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR1)); 
			break; 
	case 2:	SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR2)); 
			break; 
	case 3:	SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR3)); 
			break; 
	case 4:	SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR4)); 
			break; 
	} 
	if (lbut==1) 
		{ 
		 vector disp; 
 
		 switch(cmode) 
		 { 
		 case 1: 
			disp = ((float)(point.y-mousey)*cam.Y +  
				    (float)(mousex-point.x)*cam.X) * pDoc->bboxdiag/1000.0; 
			break; 
		 case 2: 
			 disp = ((float)(mousey-point.y)*cam.Z) * pDoc->bboxdiag/-1000.0f; 
			 { 
			CDC *dc = GetDC(); 
			wglMakeCurrent( dc->m_hDC, m_hRC ); 
			vector rot; 
			rot.Vec(0,0,(mousex-point.x)/5.0f); 
			cam.rotate(rot); 
			wglMakeCurrent( 0, 0); 
			ReleaseDC(dc); 
			 } 
			 break; 
		 case 3: 
			 { 
			CDC *dc = GetDC(); 
			wglMakeCurrent( dc->m_hDC, m_hRC ); 
			vector rot; 
			rot.Vec((point.y-mousey)/10.0f,-(mousex-point.x)/10.0f,0); 
			cam.rotate(rot); 
			wglMakeCurrent( 0, 0); 
			ReleaseDC(dc); 
			disp.Null(); 
			 } 
			 break; 
		 default: disp.Null(); 
		 } 
 
		 cam.Vp+=disp; 
		 cam.Lp+=disp; 
	float d2=(pDoc->bboxC - cam.Vp).Length(); 
	nearplane=d2-pDoc->bboxdiag/2; 
	farplane=pDoc->bboxdiag/2+d2; 
	if (nearplanebboxdiag/1000)  
		nearplane=pDoc->bboxdiag/1000; 
		  
		 mousex=point.x; 
		 mousey=point.y; 
 
		 Invalidate(0); 
		}	 
	CView::OnMouseMove(nFlags, point); 
} 
 
BOOL CMy3DEditorView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)  
{ 
	// TODO: Add your message handler code here and/or call default 
	CMy3DEditorDoc *pDoc=GetDocument(); 
	if (pDoc->dlgprop) 
		((DlgProperties *)pDoc->dlgprop)->step_slider(zDelta/WHEEL_DELTA); 
	return CView::OnMouseWheel(nFlags, zDelta, pt); 
	 
 
} 
 
void CMy3DEditorView::OnPan()  
{ 
	// TODO: Add your command handler code here 
	if (cammode==1) 
		cammode=0; 
	else cammode=1;	 
} 
 
void CMy3DEditorView::OnRButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	CMy3DEditorDoc *pDoc=GetDocument(); 
	if (cammode==4) 
		Select(point,6);	 
	CView::OnRButtonDown(nFlags, point); 
} 
 
void CMy3DEditorView::OnSelect()  
{ 
	// TODO: Add your command handler code here 
	cammode=0;	 
} 
 
void CMy3DEditorView::OnTimer(UINT nIDEvent)  
{ 
	// TODO: Add your message handler code here and/or call default 
	DWORD t0=timeGetTime(); 
	int t=t0-timer; 
	if (t>dtimer) 
		t=dtimer; 
	dtimer-=t; 
	timer=t0; 
	if (dtimer==0) 
		KillTimer(1); 
 
	LookAt(cam.Vp+dvp*(float)t,cam.Lp+dlp*(float)t);	 
	CView::OnTimer(nIDEvent); 
} 
 
void CMy3DEditorView::OnUpdateDolly(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetRadio(cammode==2);	 
} 
 
void CMy3DEditorView::OnUpdateLookat(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetRadio(cammode==4);	 
} 
 
void CMy3DEditorView::OnUpdatePan(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetRadio(cammode==1);	 
} 
 
void CMy3DEditorView::OnUpdateSelect(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetRadio(cammode==0);	 
} 
 
LRESULT CMy3DEditorView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)  
{ 
	// TODO: Add your specialized code here and/or call the base class 
	if (message==WM_MBUTTONDOWN) 
	{ 
		CMy3DEditorDoc *pDoc=GetDocument(); 
		CPoint p(lParam); 
		if (cammode==4) 
			Select(p,4); 
	} 
	else if(message==WM_DISPLAYCHANGE) 
	{ 
		if (wParam<=8) 
			AfxMessageBox(IDS_DISPLAY_ERROR,MB_OK|MB_ICONEXCLAMATION); 
		else 
		{ 
			DestroyOpenGL(); 
			CreateOpenGL(); 
			Invalidate(1); 
		} 
	}	 
	return CView::WindowProc(message, wParam, lParam); 
} 
 
 
void CMy3DEditorView::Select(CPoint point,int mode) 
{ 
	char str[256]; 
	CMy3DEditorDoc *pDoc=GetDocument(); 
	CDC *pDC=GetDC(); 
	wglMakeCurrent( pDC->m_hDC, m_hRC ); 
	glShadeModel(GL_FLAT); 
	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
	if (pDoc->backface && mode!=7) 
		glEnable(GL_CULL_FACE); 
	else  
		glDisable(GL_CULL_FACE); 
 
	unsigned int intbuf[500]; 
	glSelectBuffer( 500,intbuf ); 
 
	int viewport[4]; 
	glGetIntegerv(GL_VIEWPORT,viewport); 
 
	glRenderMode(GL_SELECT); 
	glInitNames(); 
 
	glMatrixMode( GL_PROJECTION ); 
	glPushMatrix(); 
	glLoadIdentity(); 
	gluPickMatrix(point.x,viewport[3]-point.y,1,1,viewport); 
	gluPerspective(cam.theta, aspect, nearplane, farplane ); 
	glMatrixMode( GL_MODELVIEW ); 
 
	object *o=pDoc->obj0; 
	int f,counto=0; 
	while( o ) 
	{ 
	glPushName(counto); 
	glPushName(-1); 
	for( f=0;fnf;f++ ) 
		if (o->ft[f]) 
		{ 
		glLoadName( f ); 
		glBegin(GL_TRIANGLES); 
		glVertex3fv((float *)&o->ft[f]->lv[0]->pos); 
		glVertex3fv((float *)&o->ft[f]->lv[1]->pos); 
		glVertex3fv((float *)&o->ft[f]->lv[2]->pos); 
		glEnd(); 
		} 
	glPopName(); 
	glPopName(); 
	counto++; 
	o=o->next; 
	} 
 
	glPopMatrix(); 
	glFlush(); 
	counto=glRenderMode(GL_RENDER); 
	if (counto>0) 
		{ 
		int pos=0,selpos=0; 
		unsigned int min=-1; 
		 
		for( f=0;fobj0; 
		for( f=0;f<(int)intbuf[selpos+3];f++ ) 
			o=o->next; 
		f=intbuf[selpos+4]; 
		if (mode==4 || mode==5 || mode==6) 
			{ 
			RECT rect; 
			GetClientRect(&rect); 
			float dist; 
			double ipdist=0.5*rect.bottom/TanD(0.5*cam.theta), 
				angx=atan((point.x-rect.right/2+0.5)/ipdist), 
				angy=-atan((point.y-rect.bottom/2+0.5)/ipdist); 
			vector Ro,Rd,vp,lp; 
			Ro.Vec(-(float)(sin(angx)*cos(angy)),-(float)(sin(angy)*cos(angx)),(float)(cos(angx)*cos(angy))); 
			Rd=Ro*cam.mat; 
			Rd.Normalize(); 
			Rd.Negate(); 
			Ro=cam.Vp; 
			o->ft[f]->ray_intersect(Ro,Rd,lp,dist); 
			Rd=cam.Vp-lp; 
			Ro=o->ft[f]->normal; 
			if (VecDot(Rd,Ro)<0) 
				Ro.Negate(); 
			if (mode==5) 
				vp=lp+dist*Ro/2; 
			else if (mode==6) 
				vp=lp+dist*Ro*2; 
			else vp=lp+dist*Ro; 
 
			dtimer=1000; 
			dvp=(vp-cam.Vp)/(float)dtimer; 
			dlp=(lp-cam.Lp)/(float)dtimer; 
			timer=timeGetTime(); 
			SetTimer(1,30,0); 
			} 
		else if(mode==8) 
			{ 
			if (pDoc->dlgmat==0) 
				{ 
				pDoc->dlgmat=new DlgMaterial; 
				((DlgMaterial *)pDoc->dlgmat)->doc=pDoc; 
				pDoc->dlgmat->Create(IDD_MATERIAL); 
				CString s; 
				s.LoadString(IDS_MATERIAL); 
				sprintf(str,s,pDoc->GetTitle()); 
				pDoc->dlgmat->SetWindowText(str); 
				pDoc->dlgmat->ShowWindow(SW_SHOW); 
				} 
			((DlgMaterial *)pDoc->dlgmat)->m_names.SelectString( -1, pDoc->matlib[o->ft[f]->material].name ); 
			((DlgMaterial *)pDoc->dlgmat)->OnSelchangeName(); 
			} 
		else if (mode==0 || mode==7) 
			{ 
			if (pDoc->dlgprop==0) 
				{ 
				pDoc->dlgprop=new DlgProperties; 
				((DlgProperties *)pDoc->dlgprop)->doc=pDoc; 
				pDoc->dlgprop->Create(IDD_PROPERTIES); 
				CString s; 
				s.LoadString(IDS_DETAIL); 
				sprintf(str,s,pDoc->GetTitle()); 
				pDoc->dlgprop->SetWindowText(str); 
				pDoc->dlgprop->ShowWindow(SW_SHOW); 
				} 
			((DlgProperties *)pDoc->dlgprop)->m_obj.SelectString( -1, o->name ); 
			((DlgProperties *)pDoc->dlgprop)->OnSelchangeObj(); 
			if (mode==7) 
				{ 
				((DlgProperties *)pDoc->dlgprop)->m_elem.SetCurSel( o->ft[f]->group+1 ); 
				((DlgProperties *)pDoc->dlgprop)->OnSelchangeElem(); 
				} 
			} 
		} 
	else if (counto==0 && (mode==0 || mode==7)) 
			{ 
			if (pDoc->dlgprop!=0) 
				{ 
				((DlgProperties *)pDoc->dlgprop)->m_obj.SetCurSel( 0 ); 
				((DlgProperties *)pDoc->dlgprop)->OnSelchangeObj(); 
				} 
			else 
				{ 
				pDoc->selobj=0; 
				pDoc->selface=-1; 
				pDoc->UpdateAllViews(0); 
				} 
			} 
 
	wglMakeCurrent( NULL, NULL ); 
} 
 
 
void CMy3DEditorView::OnElememtmode()  
{ 
	// TODO: Add your command handler code here 
	if (cammode==7) 
		cammode=0; 
	else cammode=7;	 
} 
 
void CMy3DEditorView::OnUpdateElememtmode(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck(cammode==7);	 
} 
 
void CMy3DEditorView::OnMaterialmode()  
{ 
	// TODO: Add your command handler code here 
	if (cammode==8) 
		cammode=0; 
	else cammode=8;	 
} 
 
void CMy3DEditorView::OnUpdateMaterialmode(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetCheck(cammode==8);	 
} 
 
void CMy3DEditorView::OnDolly()  
{ 
	// TODO: Add your command handler code here 
	if (cammode==2) 
		cammode=0; 
	else cammode=2;	 
} 
 
void CMy3DEditorView::OnTilt()  
{ 
	// TODO: Add your command handler code here 
	if (cammode==3) 
		cammode=0; 
	else cammode=3;	 
} 
 
void CMy3DEditorView::OnUpdateTilt(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->SetRadio(cammode==3);	 
} 
 
void CMy3DEditorView::OnRaytrace()  
{ 
	// TODO: Add your command handler code here 
	DlgRayTrace d; 
	CMy3DEditorDoc *pDoc=GetDocument(); 
	if (pDoc->dlgprop) 
		((DlgProperties *)(pDoc->dlgprop))->Close(); 
	if (pDoc->dlgmat) 
		((DlgMaterial *)(pDoc->dlgmat))->Close(); 
	d.m_ray_depth=AfxGetApp()->GetProfileInt("RayTrace","RayDepth",3); 
	d.m_shadows=AfxGetApp()->GetProfileInt("RayTrace","Shadows",1); 
	d.m_antialiase=AfxGetApp()->GetProfileInt("RayTrace","AntiAliase",0); 
	d.m_antialiase_factor=AfxGetApp()->GetProfileInt("RayTrace","AntiAliaseFactor",0); 
	d.view=AfxGetApp()->GetProfileInt("RayTrace","Resolution", 1); 
	GetClientRect(&d.rect); 
	d.doc=GetDocument(); 
	d.cam=&cam; 
	if (d.view) 
		{ 
		d.m_res_x=d.rect.right; 
		d.m_res_y=d.rect.bottom; 
		} 
	else 
		{ 
		d.m_res_x=AfxGetApp()->GetProfileInt("RayTrace","ResX",320); 
		d.m_res_y=AfxGetApp()->GetProfileInt("RayTrace","ResY",240); 
		} 
 
	d.DoModal(); 
 
	AfxGetApp()->WriteProfileInt("RayTrace","ResX",d.m_res_x); 
	AfxGetApp()->WriteProfileInt("RayTrace","ResY",d.m_res_y); 
	AfxGetApp()->WriteProfileInt("RayTrace","RayDepth",d.m_ray_depth); 
	AfxGetApp()->WriteProfileInt("RayTrace","Shadows",d.m_shadows); 
	AfxGetApp()->WriteProfileInt("RayTrace","Resolution",d.view); 
	AfxGetApp()->WriteProfileInt("RayTrace","AntiAliase",d.m_antialiase); 
	AfxGetApp()->WriteProfileInt("RayTrace","AntiAliaseFactor",d.m_antialiase_factor);	 
} 
 
void CMy3DEditorView::OnUpdateRaytrace(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(GetDocument()->obj0!=0);	 
} 
 
void CMy3DEditorView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	// TODO: Add your message handler code here and/or call default 
	if (nChar == VK_ESCAPE) 
	{ 
		CMainFrame* pFrame = (CMainFrame*) AfxGetMainWnd(); 
		if(pFrame->m_bFullScreenMode) pFrame->FullScreenModeOff(); 
	} 
	if (nChar ==115) //"S" 
	{ 
		if (movieCapture != NULL) 
        { 
            if (isRecording()) 
                recordPause(); 
            else 
                recordBegin(); 
        } 
	} 
	if (nChar ==112) //"P" 
	{ 
		if (movieCapture != NULL) 
            recordEnd(); 
	} 
	CView::OnChar(nChar, nRepCnt, nFlags); 
} 
 
void CMy3DEditorView::OnCaptureImage()  
{ 
	// TODO: Add your command handler code here 
	CString s; 
	s.LoadString(IDS_FD_IMAGE); 
	CFileDialog fd(FALSE,"jpg",0,OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST,s); 
 
	CDC *dc=GetDC(); 
 
	wglMakeCurrent( dc->m_hDC, m_hRC ); 
 
	if(fd.DoModal()==IDOK) 
	{ 
		BeginWaitCursor(); 
		int viewport[4]; 
		glGetIntegerv(GL_VIEWPORT,viewport); 
 
        bool success = false; 
 
        DWORD nFileType=0; 
		if(strcmp(fd.GetFileExt(),"jpg")==0) nFileType=1; 
		if(strcmp(fd.GetFileExt(),"png")==0) nFileType=2; 
		if(strcmp(fd.GetFileExt(),"bmp")==0) nFileType=3; 
 
        if (nFileType == 1) 
        { 
			success = m_imagecapture.CaptureGLBufferToJPEG(fd.GetPathName(), 
                                            viewport[0],viewport[1], 
                                            viewport[2],viewport[3]); 
        } 
        else if (nFileType == 2) 
        { 
          success = m_imagecapture.CaptureGLBufferToPNG(fd.GetPathName(), 
                                            viewport[0],viewport[1], 
                                            viewport[2],viewport[3]); 
        } 
        else if(nFileType==3) 
		{ 
 
 
		success=m_imagecapture.CaptureGLBufferToBMP(fd.GetPathName(), 
                                            viewport[0],viewport[1], 
                                            viewport[2],viewport[3]); 
		} 
		else 
        { 
            // Invalid file extension specified. 
            MessageBox("WTF? Unknown file extension specified for screen capture.\n","Error",MB_OK); 
        } 
 
        if (!success) 
        { 
            char errorMsg[64]; 
 
            if(nFileType == 0) 
                sprintf(errorMsg, "Specified file extension is not recognized."); 
            else 
                sprintf(errorMsg, "Could not save image file."); 
 
            MessageBox(errorMsg, "Error", MB_OK | MB_ICONERROR); 
        } 
 
		EndWaitCursor(); 
	} 
		 
	wglMakeCurrent( 0, 0 ); 
	ReleaseDC(dc);	 
} 
 
void CMy3DEditorView::OnCaptureMovie()  
{ 
	// TODO: Add your command handler code here 
 
	CString s; 
	s.LoadString(IDS_FD_MOVIE); 
	CFileDialog fd(FALSE,"avi",0,OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST,s); 
 
	CDC *dc=GetDC(); 
 
	wglMakeCurrent( dc->m_hDC, m_hRC ); 
 
	if(fd.DoModal()==IDOK) 
	{ 
		BeginWaitCursor(); 
        DWORD nFileType=0; 
		if(strcmp(fd.GetFileExt(),"avi")==0) nFileType=1; 
 
		if(m_DlgCaptureMovie.DoModal()==IDOK) 
		{ 
			if(m_DlgCaptureMovie.Index_area==0) 
			{ 
				MovieSize_X=160; 
				MovieSize_Y=120; 
			} 
			if(m_DlgCaptureMovie.Index_area==1) 
			{ 
				MovieSize_X=320; 
				MovieSize_Y=240; 
			} 
			if(m_DlgCaptureMovie.Index_area==2) 
			{ 
				MovieSize_X=640; 
				MovieSize_Y=480; 
			} 
			if(m_DlgCaptureMovie.Index_area==3) 
			{ 
				MovieSize_X=720; 
				MovieSize_Y=480; 
			} 
			if(m_DlgCaptureMovie.Index_framerate==0) 
			{ 
				MovieFramerate=15.0; 
			} 
			if(m_DlgCaptureMovie.Index_framerate==1) 
			{ 
				MovieFramerate=24.0; 
			} 
			if(m_DlgCaptureMovie.Index_framerate==2) 
			{ 
				MovieFramerate=25.0; 
			} 
			if(m_DlgCaptureMovie.Index_framerate==3) 
			{ 
				MovieFramerate=29.97; 
			} 
			if(m_DlgCaptureMovie.Index_framerate==4) 
			{ 
				MovieFramerate=30.0; 
			} 
		} 
        bool success = false; 
 
        if (nFileType == 1) 
        { 
			success = BeginMovieCapture(fd.GetPathName(), 
                                        MovieSize_X, 
                                        MovieSize_Y, 
                                        MovieFramerate); 
        } 
		else 
        { 
            // Invalid file extension specified. 
            MessageBox("WTF? Unknown file extension specified for screen capture.\n","Error",MB_OK); 
        } 
 
        if (!success) 
        { 
            char errorMsg[64]; 
 
            if(nFileType == 0) 
                sprintf(errorMsg, "Specified file extension is not recognized."); 
            else 
                sprintf(errorMsg, "Could not capture movie."); 
 
            MessageBox(errorMsg, "Error", MB_OK | MB_ICONERROR); 
        } 
 
		EndWaitCursor(); 
	} 
		 
	wglMakeCurrent( 0, 0 ); 
	ReleaseDC(dc);		 
} 
 
bool CMy3DEditorView::BeginMovieCapture(CString filename, 
                              int width, int height, 
                              float framerate) 
{ 
    movieCapture = new AVICapture(); 
 
    bool success = movieCapture->start(filename, width, height, framerate); 
    if (success) 
        initMovieCapture(movieCapture); 
 
    else 
        delete movieCapture; 
     
    return success; 
} 
 
void CMy3DEditorView::initMovieCapture(AVICapture* mc) 
{ 
    if (movieCapture == NULL) 
        movieCapture = mc; 
} 
 
void CMy3DEditorView::recordBegin() 
{ 
    if (movieCapture != NULL) 
        recording = true; 
} 
 
void CMy3DEditorView::recordPause() 
{ 
	    recording = false; 
} 
 
void CMy3DEditorView::recordEnd() 
{ 
    if (movieCapture != NULL) 
    { 
        recordPause(); 
        movieCapture->end(); 
        delete movieCapture; 
        movieCapture = NULL; 
    } 
} 
 
bool CMy3DEditorView::isRecording() 
{ 
    return recording; 
} 
 
void CMy3DEditorView::OnUpdateCaptureMovie(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(movieCapture == NULL);	 
} 
 
 
void CMy3DEditorView::OnCaptureRecord()  
{ 
	// TODO: Add your command handler code here 
	recordBegin();	 
} 
 
void CMy3DEditorView::OnUpdateCaptureRecord(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(movieCapture != NULL); 
	pCmdUI->SetCheck(recording==true); 
	 
} 
 
void CMy3DEditorView::OnCapturePause()  
{ 
	// TODO: Add your command handler code here 
	recording=!recording;	 
} 
 
void CMy3DEditorView::OnUpdateCapturePause(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(movieCapture != NULL); 
	pCmdUI->SetCheck(recording==false); 
} 
 
void CMy3DEditorView::OnCaptureStop()  
{ 
	// TODO: Add your command handler code here 
	recordEnd();	 
} 
 
void CMy3DEditorView::OnUpdateCaptureStop(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	pCmdUI->Enable(recording != false);	 
} 
 
BOOL CMy3DEditorView::OnEraseBkgnd(CDC* pDC)  
{ 
	// TODO: Add your message handler code here and/or call default 
	// 禁止Windows刷新窗口背景,直接返回	 
	// return CView::OnEraseBkgnd(pDC); 
	return true; 
}