⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 raytraceview.cpp

📁 蒙特卡罗方法可以有效地解决复杂的工程问题
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// RayTraceView.cpp : implementation of the CRayTraceView class
//

#include "stdafx.h"
#include "RayTrace.h"

#include "RayTraceDoc.h"
#include "RayTraceView.h"
#include "MainFrm.h"

#include "SetDlg.h"

#include <windowsx.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define ONE  //绘制一次场景
//#define MANY //绘制多次场景

/////////////////////////////////////////////////////////////////////////////
// CRayTraceView

IMPLEMENT_DYNCREATE(CRayTraceView, CView)

BEGIN_MESSAGE_MAP(CRayTraceView, CView)
	//{{AFX_MSG_MAP(CRayTraceView)
	ON_COMMAND(ID_RT_RAYTRACING, OnRtRaytracing)
	ON_COMMAND(ID_RT_SET, OnRtSet)
	ON_WM_SIZE()
	ON_COMMAND(ID_RT_CARTOON, OnRtCartoon)
	ON_UPDATE_COMMAND_UI(ID_RT_RAYTRACING, OnUpdateRtRaytracing)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CRayTraceView construction/destruction

CRayTraceView::CRayTraceView()
{
	// TODO: add construction code here

	//获得程序存放路径
	GetModuleFileName( NULL, m_strPath.GetBuffer(MAX_PATH), MAX_PATH );
	m_strPath.ReleaseBuffer();
	int n = m_strPath.ReverseFind('\\');
	m_strPath.Delete( n, m_strPath.GetLength() - n );
	m_strPath += '\\';

	m_pDrawThread = 0 ;
	m_bDrawing = false;
	m_nScene = 0;
}

CRayTraceView::~CRayTraceView()
{
}

/////////////////////////////////////////////////////////////////////////////
// CRayTraceView drawing

void CRayTraceView::OnDraw(CDC* pDC)
{
	CRayTraceDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CRayTraceView diagnostics

#ifdef _DEBUG
void CRayTraceView::AssertValid() const
{
	CView::AssertValid();
}

void CRayTraceView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CRayTraceDoc* CRayTraceView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CRayTraceDoc)));
	return (CRayTraceDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CRayTraceView message handlers

// 光线跟踪计算线程
UINT RayTracingThread(LPVOID param)
{
	//获得视图类指针
	CRayTraceView *pView = (CRayTraceView*)param;

	//选择场景跟踪
	switch( pView->m_nScene )
	{
	case 0:
		{
			pView->RayTracing();
			break;
		}
	case 1:
		{
			pView->RayTracing2();
			break;
		}
	default :
		break;
	}

	return 0;
}

void CRayTraceView::StartThread()
{
	//清空客户区
	Invalidate(TRUE);

	//生成光线跟踪计算线程
	m_pDrawThread = AfxBeginThread(RayTracingThread,LPVOID(this),THREAD_PRIORITY_BELOW_NORMAL,0,CREATE_SUSPENDED );
	m_pDrawThread->m_bAutoDelete = FALSE ;
	m_pDrawThread->ResumeThread();
}

void CRayTraceView::OnRtRaytracing() 
{
	// TODO: Add your command handler code here
	if( m_pDrawThread )
	{
		DWORD endcode;
		::GetExitCodeThread(m_pDrawThread->m_hThread,&endcode);
		if( 0 == endcode )	
		{
			delete m_pDrawThread;
			m_bDrawing = TRUE ;
			StartThread();
		}
		else
		{
			if(	TRUE == m_bDrawing )
			{
				m_bDrawing = FALSE ;
				m_pDrawThread->SuspendThread();
			}
			else
			{
				m_bDrawing = TRUE ;
				m_pDrawThread->ResumeThread();
			}
		}
	}
	else
	{
		m_bDrawing = TRUE ;
		StartThread();	
	}
}

void CRayTraceView::OnUpdateRtRaytracing(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->SetText( m_bDrawing ? "暂停绘制(&D)\tCtrl+D" : "绘制场景(&D)\tCtrl+D" );
}

void CRayTraceView::OnRtSet() 
{
	// TODO: Add your command handler code here
	CSetDlg dlg(this);
	
	//引入场景当前数据,初始化对话框
	dlg.m_dObservePosX = scene.ObservePosition.GetX();
	dlg.m_dObservePosY = scene.ObservePosition.GetY();
	dlg.m_dObservePosZ = scene.ObservePosition.GetZ();
	
	dlg.m_dLookAtX = scene.LookAt.GetX();
	dlg.m_dLookAtY = scene.LookAt.GetY();
	dlg.m_dLookAtZ = scene.LookAt.GetZ();
	
	dlg.m_dFocalLength = scene.dFocalLength;
	dlg.m_nScene = m_nScene;

	if( IDOK == dlg.DoModal() )
	{
		//保存参数
		scene.ObservePosition = CVector( dlg.m_dObservePosX, dlg.m_dObservePosY, dlg.m_dObservePosZ );
		scene.LookAt = CVector( dlg.m_dLookAtX, dlg.m_dLookAtY, dlg.m_dLookAtZ );
		scene.dFocalLength = dlg.m_dFocalLength;
		m_nScene = dlg.m_nScene;
	}
}

void CRayTraceView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here

	//获取程序窗口初始大小
	scene.nXRes = cx;
	scene.nYRes = cy;
}

//拷贝当前窗口客户区所绘制的图片至文件
void CRayTraceView::SavePicture(CString strPath)
{
	CClientDC clientdc(this);
	CBitmap bm;
	bm.CreateCompatibleBitmap(&clientdc,scene.nXRes,scene.nYRes);

	CDC tdc;
	tdc.CreateCompatibleDC(&clientdc);
	CBitmap *pOld = tdc.SelectObject(&bm);
	tdc.BitBlt(0,0,scene.nXRes,scene.nYRes,&clientdc,0,0,SRCCOPY);
	tdc.SelectObject(pOld);

	BITMAP btm;
	bm.GetBitmap(&btm);
	DWORD size = btm.bmWidthBytes*btm.bmHeight;
	LPSTR lpData = (LPSTR)GlobalAllocPtr(GPTR,size);

	BITMAPINFOHEADER bih;
	bih.biBitCount = btm.bmBitsPixel;
	bih.biClrImportant = 0;
	bih.biClrUsed = 0;
	bih.biCompression = 0;
	bih.biHeight = btm.bmHeight;
	bih.biPlanes = 1;
	bih.biSize = sizeof(BITMAPINFOHEADER);
	bih.biSizeImage = size;
	bih.biWidth = btm.bmWidth;
	bih.biXPelsPerMeter = 0;
	bih.biYPelsPerMeter = 0;

	GetDIBits(clientdc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);


	BITMAPFILEHEADER bfh;
	bfh.bfReserved1=bfh.bfReserved2=0;
	bfh.bfType=((WORD)('M'<< 8)|'B');
	bfh.bfSize=54+size;
	bfh.bfOffBits=54;

	CFile bf;
	if(bf.Open(strPath,CFile::modeCreate|CFile::modeWrite))
	{
		bf.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER));
		bf.WriteHuge(&bih,sizeof(BITMAPINFOHEADER));
		bf.WriteHuge(lpData,size);
		bf.Close();
	}
	GlobalFreePtr(lpData);
}

void CRayTraceView::OnRtCartoon() 
{
	// TODO: Add your command handler code here
	//获得框架类指针
	CMainFrame* pFrame = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
	
	CClientDC dc(this);
	CDC *mdc = new CDC ;
	mdc->CreateCompatibleDC( &dc );  //建立与操作窗口兼容的 DC
	CBitmap bitmap;
	CString str;
	
	switch( m_nScene )
	{
	case 0:
		{
			for( int i = 0; i < 100; i++ )
			{
				str.Format("场景1_%d",i);
				str += ".bmp";
				bitmap.m_hObject = (HBITMAP)::LoadImage(NULL, m_strPath + str,IMAGE_BITMAP,scene.nXRes,scene.nYRes,LR_LOADFROMFILE); //载入图文件
				mdc->SelectObject(bitmap);  //选择位图
				dc.BitBlt( 0 , 0 , scene.nXRes, scene.nYRes, mdc , 0 , 0 , SRCCOPY );
				pFrame->SendMessage(WM_SET_STATUS_TEXT, i+1, 100 );
				::DeleteObject(bitmap.m_hObject);
			}
			break;

		}
	case 1:
		{
			int loop[] = {0,25,41,50,54,57,58,59};	//8个数据
			int j = 0;
			while( j <= 7 )
			{
				for( int i = loop[j++]; i <= 59; i++ )
				{
					str.Format("场景2_%d",i);
					str += ".bmp";
					bitmap.m_hObject = (HBITMAP)::LoadImage(NULL, m_strPath + str,IMAGE_BITMAP,scene.nXRes,scene.nYRes,LR_LOADFROMFILE); //载入图文件
					mdc->SelectObject(bitmap);  //选择位图
					dc.BitBlt( 0 , 0 , scene.nXRes, scene.nYRes, mdc , 0 , 0 , SRCCOPY );
					pFrame->SendMessage(WM_SET_STATUS_TEXT, i+1, 60 );
					::DeleteObject(bitmap.m_hObject);
				}
				for( i = 59; i >= loop[j]; i-- )
				{
					str.Format("场景2_%d",i);
					str += ".bmp";
					bitmap.m_hObject = (HBITMAP)::LoadImage(NULL, m_strPath + str,IMAGE_BITMAP,scene.nXRes,scene.nYRes,LR_LOADFROMFILE); //载入图文件
					mdc->SelectObject(bitmap);  //选择位图
					dc.BitBlt( 0 , 0 , scene.nXRes, scene.nYRes, mdc , 0 , 0 , SRCCOPY );
					pFrame->SendMessage(WM_SET_STATUS_TEXT, i+1, 60 );
					::DeleteObject(bitmap.m_hObject);
				}
			}
			
			break;
			
		}
	default:
		break;
	}
	
	delete mdc;
}

#ifdef MANY
void CRayTraceView::RayTracing()
{
	//获得框架类指针
	CMainFrame* pFrame = (CMainFrame*)(AfxGetApp()->m_pMainWnd);
	for( int ii = 0; ii < 200; )
	{
		pFrame->SendMessage(WM_SET_STATUS_TEXT, ii/2+1, 200 / 2 );	
		
		//初始化材料
		CMaterial* def = new CMaterial(CVector(0.5,0.5,0.5),
			CVector(0.85,0.85,0.85),//(0.15,0.35,0.65),
			CVector(0.05,0.05,0.05),//0.6
			CVector(0.,0.,0.),
			211,1.,FALSE,FALSE);
		
		CMaterial* def2 = new CMaterial(CVector(0.5,0.5,0.5),
			CVector(0.85,0.85,0.85),//(0.15,0.35,0.65),
			CVector(0.05,0.05,0.05),//0.6
			CVector(0.,0.,0.),
			211,1.,FALSE,TRUE);
		
		CMaterial* gold = new CMaterial(CVector(0.1,0.1,0.1),
			CVector(0.8, 0.498039, 0.196078),//(0.25,0.45,0.95),//(0.65,0.65,0.65),
			CVector(0.8,0.5,0.2),//0.6
			CVector(0.,0.,0.),
			1511,1.,FALSE,FALSE);
		
		//初始化纹理
		CImage* map = new CImage( m_strPath + "ashwood.bmp" );
		CImage* map2 = new CImage( m_strPath + "cloud2.bmp" );
		
		//景物1,地面
		CGround* grnd = new CGround;
		grnd->nObjectIndex = 1;
		grnd->SetMaterial( def );
		
		//景物2,长方体,由六个面Face1,Face2,Face3,Face4,Face5,Face6组成
		CQuadra* Face1 = new CQuadra(
			CVector(-50.,0.,50.),
			CVector(50.,0.,50.),
			CVector(50.,50.,50.),
			CVector(-50.,50.,50.)
			);
		
		CQuadra* Face2 = new CQuadra(
			CVector(-50.,0.,0.),
			CVector(50.,0.,0.),
			CVector(50.,50.,0.),
			CVector(-50.,50.,0.)
			);
		
		CQuadra* Face3 = new CQuadra(
			CVector(-50.,0.,0.),
			CVector(-50.,0.,50.),
			CVector(-50.,50.,50.),
			CVector(-50.,50.,0.)
			);
		
		CQuadra* Face4 = new CQuadra(
			CVector(-50.,50.,50.),
			CVector(50.,50.,50.),
			CVector(50.,50.,0.),
			CVector(-50.,50.,0.)
			);
		
		CQuadra* Face5 = new CQuadra(
			CVector(-50.,0.,0.),
			CVector(50.,0.,0.),
			CVector(50.,0.,50.),
			CVector(-50.,0.,50.)
			);
		
		CQuadra* Face6 = new CQuadra(
			CVector(50.,0.,50.),
			CVector(50.,0.,0.),
			CVector(50.,50.,0.),
			CVector(50.,50.,50.)
			);
		
		CVector vecOffset(0,0.,0.),vecRotate(0.,0.,ii);
		Face1->nObjectIndex = 2;
		Face1->Transform( vecOffset,vecRotate );
		Face1->SetMaterial(gold);
		Face1->SetTexture(map);
		
		Face2->nObjectIndex = 3;
		Face2->Transform( vecOffset,vecRotate );
		Face2->SetMaterial(gold);
		Face2->SetTexture(map);
		
		Face3->nObjectIndex = 4;
		Face3->Transform( vecOffset,vecRotate );
		Face3->SetMaterial(gold);
		Face3->SetTexture(map);
		
		Face4->nObjectIndex = 5;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -