📄 raytraceview.cpp
字号:
// 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 + -