soildworks模型導入MFC對話框

最近項目需要把solidworks創建的設備模型導入MFC對話框中顯示,並且能鼠標控制移動、縮放。

軟件平臺包括 solidworks 2008 、3DS-Max 7.0 、 vs 2008 sp1;

openGL配置

提供最全的openGL庫,支持鼠標滾輪,配置方法


將下載的壓縮包解開,將得到5個文件(glut.dll, glut32.dll, glut.lib, glut32.lib,glut.h)
(1)把glut.h複製到x:\Program Files\Microsoft\Visual Studio 10.0\VC\include\gl文件夾中,如果沒有gl這個文件夾則可以自己新建一個。(x是你安裝VS的盤符號)
(2)把解壓得到的glut.lib和glut32.lib放到靜態函數庫所在文件夾(即與include並排的lib文件夾下)。
(3)把解壓得到的glut.dll和glut32.dll放到操作系統目錄下面的system32文件夾內。(典型的位置爲:C:\Windows\System32)
(注:如在開發應用程序時用到OpenGL輔助庫函數,則還需下載相應動態鏈接庫,包含glaux.dll, glaux.lib, glaux.h,相應步驟同上)


在Visual C++中先右擊項目,選擇屬性,找到連接器標籤,最後在輸入中的附加依賴庫加上opengl32.lib glut32.lib glu32.lib.

3 #include<gl/glut.h>
 4 
 5 //#include<gl/glu.h>  //glut.h自動包含了glu.h 和 gl.h
 6 
 7 //#include<gl/gl.h>


點擊打開鏈接

1.在solildworks中創建設備模型,編輯好紋理,這裏爲了方便直接爲模型上的顏色,沒有進行貼圖(關於soildworks的使用可另外參考教程)

2.保存模型文件爲 .wtl格式

3.在3DS-Max 7.0中導入上面的.wtl文件,然後導出文件爲.OBJ格式,同時導出素材庫即.mtl格式文件。


4.導入模型到MFC對話框

創建一個MFC對話框在OnInitDialog()中設置RC;

	hrenderDC=::GetDC(this->m_hWnd);
	if(SetWindowPixelFormat(hrenderDC)==FALSE)// 設置像素格式
		return ;

	if(CreateViewGLContext(hrenderDC)==FALSE)//創建RC並選爲所用
		return ;
SetWindowPixelFormat( HDC hDC )
{
PIXELFORMATDESCRIPTOR pixelDesc;

	pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
	pixelDesc.nVersion = 1;

	pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | 
		PFD_SUPPORT_OPENGL |
		PFD_DOUBLEBUFFER |
		PFD_TYPE_RGBA;

	pixelDesc.iPixelType = PFD_TYPE_RGBA;
	pixelDesc.cColorBits = 32;
	pixelDesc.cRedBits = 0;
	pixelDesc.cRedShift = 0;
	pixelDesc.cGreenBits = 0;
	pixelDesc.cGreenShift = 0;
	pixelDesc.cBlueBits = 0;
	pixelDesc.cBlueShift = 0;
	pixelDesc.cAlphaBits = 0;
	pixelDesc.cAlphaShift = 0;
	pixelDesc.cAccumBits = 0;
	pixelDesc.cAccumRedBits = 0;
	pixelDesc.cAccumGreenBits = 0;
	pixelDesc.cAccumBlueBits = 0;
	pixelDesc.cAccumAlphaBits = 0;
	pixelDesc.cDepthBits = 0;
	pixelDesc.cStencilBits = 1;
	pixelDesc.cAuxBuffers = 0;
	pixelDesc.iLayerType = PFD_MAIN_PLANE;
	pixelDesc.bReserved = 0;
	pixelDesc.dwLayerMask = 0;
	pixelDesc.dwVisibleMask = 0;
	pixelDesc.dwDamageMask = 0;

	PixelFormat = ChoosePixelFormat(hDC,&pixelDesc);
	if(PixelFormat==0) // Choose default
	{
		PixelFormat = 1;
		if(DescribePixelFormat(hDC,PixelFormat,
			sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
		{
			return FALSE;
		}
	}

	if(SetPixelFormat(hDC,PixelFormat,&pixelDesc)==FALSE)

	{ 
		return FALSE;
	}

	return TRUE;
}

	hrenderRC = wglCreateContext(hDC);

	if(hrenderRC==NULL)
		return FALSE;

	if(wglMakeCurrent(hDC,hrenderRC)==FALSE)
		return FALSE;



	
隨後初始化openGL配置

	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);

	CRect clirc;
	GetClientRect(&clirc);

	window_width = clirc.Width();
	window_height = clirc.Height();

	glPolygonMode(GL_FRONT,GL_FILL);
	glPolygonMode(GL_BACK,GL_FILL);

	glClearColor(0.0, 0.0, 0.0, 0.0);

	//設置當前操作的矩陣爲“模型”視圖矩陣
	glMatrixMode(GL_PROJECTION);

	//把當前矩陣設置爲單位矩陣
	glLoadIdentity();

	//將當前控件設置爲透視投影空間
	gluPerspective(45.0f, (float)window_width/(float)window_height, 0.1f, 100.0f);

 	glMatrixMode(GL_MODELVIEW);

	glClearColor(0, 0, 0, 1);
	glClearDepth(1.0f); 
	//把屏幕上的顏色清空
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	//啓動深度測試
	glEnable(GL_DEPTH_TEST);

	glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do 用於指定深度緩衝比較值。

	//
	glEnable(GL_NORMALIZE);

	//啓動剔除功能
	glEnable(GL_CULL_FACE);

	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	// Setup other misc features.

	//打開光照功能
	glEnable( GL_LIGHTING );
	glEnable( GL_NORMALIZE );

	//設置顏色填充方式:GL_SMOOTH:平滑方式   GL_FLAT:單色方式
	glShadeModel( GL_SMOOTH );


	//glViewport(0,0,clirc.Width(),clirc.Height());

	// Setup lighting model.
	GLfloat light_model_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
	GLfloat light0_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
	GLfloat light0_direction[] = {0.0f, 0.0f, 10.0f, 0.0f};
	GLfloat light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};

	//	GL_LIGHT0  0號光源,以此類推


	// 光源位置由四個值表示(X,Y,Z,W)如果第四個值W爲零,則表示該光源位於無限遠處,
	//前三個值表示了它所在的方向。這種光源稱爲方向性光源,通常,太陽可以近似的被認爲是方向性光源。
	//如果第四個值W不爲零,則X/W, Y/W, Z/W表示了光源的位置。這種光源稱爲位置性光源。對於位置性光源,
	//設置其位置與設置多邊形頂點的方式相似,各種矩陣變換函數例如:glTranslate*、glRotate*等在這裏也同樣有效。
	//方向性光源在計算時比位置性光源快了不少,因此,在視覺效果允許的情況下,應該儘可能的使用方向性光源。
	glLightfv(GL_LIGHT0, GL_POSITION, light0_direction);


	//GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR屬性。這三個屬性表示了光源所發出的光的反射特性(以及顏色)。
	//每個屬性由四個值表示,分別代表了顏色的R, G, B, A值。GL_AMBIENT表示該光源所發出的光,經過非常多次的反射後,最終遺留在整個光照環境中的強度(顏色)。
	//GL_DIFFUSE表示該光源所發出的光,照射到粗糙表面時經過漫反射,所得到的光的強度(顏色)。
	//GL_SPECULAR表示該光源所發出的光,照射到光滑表面時經過鏡面反射,所得到的光的強度(顏色)。
	glLightfv(GL_LIGHT0, GL_AMBIENT, light_model_ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
	glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
	glEnable( GL_LIGHT0 );
然後讀取模型文件

	// Center of the model
	float modelCenter[] = {0.0f, 0.0f, 0.0f};

	if ( pModel )
	{
		glmDelete( pModel );
		pModel = NULL;
	}

	CString FileName;
	FileName = CommonFunction::GetApplicationPath() + _T("ESR.obj");


	//聲明標識符   
	USES_CONVERSION ;
	char * pFileName = T2A(FileName); 


	// Load the new obj model
	pModel = glmReadOBJ( pFileName);

	// Generate normal for the model
	glmFacetNormals( pModel );

	// Scale the model to fit the screen
	glmUnitize( pModel, modelCenter );

	// Init the modelview matrix as an identity matrix
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glGetDoublev( GL_MODELVIEW_MATRIX, pModelViewMatrix );	

繪製場景及模型

	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glTranslated( 0.0, 0.0, -5.0 );
	glMultMatrixd( pModelViewMatrix );

	if ( pModel )
	{
		glmDraw( pModel, GLM_FLAT|GLM_MATERIAL );
	}

窗口改變大小時候重繪模型
OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);

	window_width  = cx;
	window_height = cy;

	// Reset the viewport
	//把像素繪製到窗口的哪個區域,前兩個參數定義了視口的左下腳(0,0表示最左下方),後兩個參數分別是寬度和高度
	glViewport(0, 0, window_width, window_height);

	//使用glMatrixMode來指定當前操作的究竟是模型視圖矩陣還是投影矩陣。
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	//爲了得到透視效果,我們使用gluPerspective來設置可視空間。假定可視角爲60度(如果調試時發現該角度不合適,可修改之。我在最後選擇的數值是75。),
	//高寬比爲1.0。最近可視距離爲1.0,最遠可視距離爲200000000*2=400000000。即:gluPerspective(60, 1, 1, 400000000);
	gluPerspective(45.0f, (float)window_width/(float)window_height, 0.01f, 200.0f);
}
鼠標操作

OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	OldX = point.x;
	OldY = point.y;
	bLeftBntDown = true;
	CDialog::OnLButtonDown(nFlags, point);
}
OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	bLeftBntDown = false;
	CDialog::OnLButtonUp(nFlags, point);
}
OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值

	if ( bLeftBntDown && pModel )
	{
		float fOldX =  2.0f*OldX/(float)window_width  - 1.0f;
		float fOldY = -2.0f*OldY/(float)window_height + 1.0f;
		float fNewX =  2.0f*point.x/(float)window_width  - 1.0f;
		float fNewY = -2.0f*point.y/(float)window_height + 1.0f;

		double pMatrix[16];
		trackball_opengl_matrix( pMatrix, fOldX, fOldY, fNewX, fNewY);

		glMatrixMode( GL_MODELVIEW );
		glLoadIdentity();
		glLoadMatrixd( pMatrix );
		glMultMatrixd( pModelViewMatrix );
		glGetDoublev( GL_MODELVIEW_MATRIX, pModelViewMatrix );

		OldX = point.x;
		OldY = point.y;
	}
	CDialog::OnMouseMove(nFlags, point);
}

滾輪操作

OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值

	if (zDelta > 0)
	{
		glMatrixMode( GL_MODELVIEW );
		glLoadIdentity();
		glLoadMatrixd( pModelViewMatrix );
		glScaled( 1.05, 1.05, 1.05 );
		glGetDoublev( GL_MODELVIEW_MATRIX, pModelViewMatrix );
	}
	if (zDelta < 0)
	{
		glMatrixMode( GL_MODELVIEW );
		glLoadIdentity();
		glLoadMatrixd( pModelViewMatrix );
		glScaled( 0.95, 0.95, 0.95 );
		glGetDoublev( GL_MODELVIEW_MATRIX, pModelViewMatrix );
	}
	return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}

源碼源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章