//将声明放入一个共同的头文件
#include"declares.h"
//定义向量类
classCVector3
{
public:
CVector3();//构造函数
CVector3(floatx, floaty, floatz);
voidSet(floatx, floaty, floatz);
voidNormalize();
floatLength();
void operator += (CVector3&v);//运算符重载
CVector3 operator - ();
friendCVector3 operator + (constCVector3&v1,
constCVector3&v2);
friendCVector3CrossProduct(constCVector3&v1,
constCVector3&v2);
union
{
};
};
struct { floatm_x, m_y, m_z; };
struct { floatr, g, b; };
//部分成员函数的实现
#include"declares.h"
CVector3::CVector3(floatx, floaty, floatz)
{
m_x = x;
m_y = y;
m_z = z;
}
voidCVector3::Normalize()
{
floatl = 1.0f / Length();
m_x *= l;
m_y *= l;
m_z *= l;
}
CVector3 operator + (constCVector3&v1, constCVector3&v2)
{
returnCVector3(v1.m_x + v2.m_x, v1.m_y + v2.m_y, v1.m_z
+ v2.m_z);
}
CVector3CrossProduct(constCVector3&v1,
constCVector3&v2)//叉积
{
returnCVector3(v1*v2);
}
//定义光线类
classCRay
{
public:
voidSetOrigin(CVector3&origin); //设置光线起点
voidSetDirection(CVector3&direction); //设置光线方向
CVector3&GetOrigin(); //获取起点
CVector3&GetDirection();//获取方向
private:
CVector3m_origin;
CVector3m_direction;
};
//部分成员函数的实现
#include"declares.h"
voidCRay::SetOrigin(CVector3&origin)
{
m_origin = origin;
}
CVector3&CRay::GetOrigin()
{
returnm_origin;
}
//材料类
classCMaterial
{
public:
voidSetColor(CColor&color);
CColorGetColor();
voidSetDiffuse(floatdiffuse); //漫反射光(镜面反射
光,反射光,与之类似)
floatGetDiffuse();
voidSetRefractionIndex(floatrefractionIndex);
floatGetRefractionIndex(); //折射率,折射指数
private:
CColorm_color;
floatm_diffuse;
floatm_refractionIndex;
};
//部分成员函数的实现
#include"declares.h"
CMaterial::CMaterial() :m_color(CColor(0.8f, 0.8f,
0.8f))
{
}
m_reflection = 0.0f;
m_diffuse = 0.6f;
m_specular = 0.0f;
m_refractionIndex = 1.5f;
voidCMaterial::SetDiffuse(floatdiffuse)
{
m_diffuse = diffuse;
}
floatCMaterial::GetDiffuse()
{
returnm_diffuse;
}
voidCMaterial::SetRefractionIndex(floatrefractionIndex)
{
m_refractionIndex = refractionIndex;
}
floatCMaterial::GetRefractionIndex()
{
returnm_refractionIndex;
}
//原始类
classCPrimitive
{
public:
enum{SPHERE = 1, PLANE};
CMaterial* GetMaterial();
voidSetMaterial(CMaterial&material);
//下面是三个纯虚函数
virtualintGetType() = 0;
virtualintIntersect(CRay&ray, float&t) = 0;
virtualCVector3GetNormal(CPoint3&position) = 0;
protected:
CMaterialm_material;
};
//部分成员函数的实现
#include"declares.h"
CMaterial* CPrimitive::GetMaterial()
{
return&m_material;
}
voidCPrimitive::SetMaterial(CMaterial&material)
{
m_material = material;
}
//平面类
classCPlane : publicCPrimitive //公有继承原始类
{
public:
CPlane(CVector3normal, floatd);
CVector3&GetNormal();
intIntersect(CRay&ray, float&t);
private:
CVector3m_normal;
floatm_d;
};
//部分成员函数的实现
#include"declares.h"
CPlane::CPlane(CVector3normal, floatd): m_normal(normal)
{
m_d = d;
};
intCPlane::Intersect(CRay&ray, float&t)
{
floatdot = DotProduct(m_normal, ray.GetDirection());
if(dot == 0) // parallel
returnMISS;
else
{
// t = -(N*O+d)/(N*V);
floatt0 = -(DotProduct(m_normal, ray.GetOrigin()) +
m_d) / dot;
if (t0> 0 &&t0<t)
{
t = t0;
returnHIT;
}
else
returnMISS;
}
}
CVector3CPlane::GetNormal(CPoint3&position)
{
returnm_normal;
}
//定义球类
classCSphere : publicCPrimitive//同样公有继承原始类
{
public:
CSphere(CPoint3¢er, floatradius);
intIntersect(CRay&ray, float&t); //光线和球面求交
CVector3GetNormal(CPoint3&position);
private:
CPoint3m_center;
floatm_radius;
};
//部分成员函数的实现
#include"declares.h"
CSphere::CSphere(CPoint3¢er, floatradius)
{
m_center = center;
m_radius = radius;
}
CVector3CSphere::GetNormal(CPoint3&position)
{
returnCVector3(position - m_center) * (1.0f /
m_radius);
}
intCSphere::Intersect(CRay&ray, float&t)
{
// a*t^2 + b*t + c = 0
// a = V·V
floata = DotProduct(ray.GetDirection(),
ray.GetDirection());
// b = 2*V·(O - C)
floatb = 2 * DotProduct(ray.GetDirection(),
(ray.GetOrigin() - m_center));
// c = ||O - C||^2 - r^2
floatc = (float)pow(CVector3(ray.GetOrigin() -
m_center).Length(), 2) - m_radius * m_radius;
// Δ = b^2 - 4*a*c
floatdelta = b * b - 4 * a * c;
intresult = MISS;
if(delta> 0)
{
floatt1 = (-b - sqrtf(delta)) / (2 * a);
floatt2 = (-b + sqrtf(delta)) / (2 * a);
if (t2> 0)
{
if (t1< 0)
{
if (t2<t)
{
t = t2;
result = INPRIM;
}
}
else
{
if (t1<t)
{
t = t1;
result = HIT;
}
}
}
}
returnresult;
}
//定义场景类
classCScene
{
public:
voidInitScene();
CPrimitive* GetPrimitive(intindex);
private:
CPrimitive** m_primitives;
};
//部分成员函数的实现
#include"declares.h"
CPrimitive* CScene::GetPrimitive(intindex)
{
returnm_primitives[index];
}
voidCScene::InitScene()//场景内的初始化,以底面和球体为
例
{
m_primitives = newCPrimitive*[100];
intindex;
index = 0;
m_primitives[index] = newCPlane(CVector3(0.0f, 1.0f,
0.0f), 0.0f);
m_primitives[index]->SetName("bottom plane");
m_primitives[index]->GetMaterial()->SetReflection(0.
0f);
m_primitives[index]->GetMaterial()->SetSpecular(0.0f
);
m_primitives[index]->GetMaterial()->SetDiffuse(1.0f)
;
m_primitives[index]->GetMaterial()->SetColor(CColor(
0.4f, 0.3f, 0.3f));
index++;
m_primitives[index] = newCSphere(CPoint3(5.0f, 12.0f,
10.0f), 12.0f);
m_primitives[index]->SetName("sphere1");
m_primitives[index]->GetMaterial()->SetReflection(0.
6f);
m_primitives[index]->GetMaterial()->SetSpecular(0.6f
);
;
m_primitives[index]->GetMaterial()->SetDiffuse(0.6f)
m_primitives[index]->GetMaterial()->SetColor(CColor(
1.0f, 1.0f, 1.0f));
index++;
m_primitives[index] = newCSphere(CPoint3(0.0f, 20.0f,
30.0f), 0.5f);
m_primitives[index]->SetName("light source 1");
m_primitives[index]->SetLight(true);
m_primitives[index]->GetMaterial()->SetColor(CColor(
1.0f, 1.0f, 1.0f));
}
//光线跟踪
classCRayTracer
{
Public:
voidSetBuffer(COLOR32 * pColorBuffer, intwidth,
intheight); //色彩缓存
CScene* GetScene(); //
CPrimitive* Raytrace(CRay&ray, CColor&totalColor,
intdepth, floatreflactionIndex, float&t);
voidInitRender(); //初始化渲染器
boolRender();//渲染
private:
floatm_xLeft; //左绘制点
floatm_dy;
//y 方向光线步长
CScene* m_pScene; //场景对象
COLOR32 * m_pColorBuffer; //色彩缓存
intm_width;
intm_height;
intm_currentLine;
};
//部分成员函数的实现
#include"declares.h"
voidCRayTracer::SetBuffer(COLOR32* pColorBuffer,
intwidth, intheight)
{
m_pColorBuffer = pColorBuffer;
m_width = width;
m_height = height;
}
CScene* CRayTracer::GetScene()
{
returnm_pScene;
}
CPrimitive* CRayTracer::Raytrace(CRay&ray,
CColor&totalColor, intdepth, floatreflactionIndex,
float&t)
{
if (depth>TRACE_DEPTH) // 深度大于跟踪深度停止
returnNULL;
t = 1000000.0f;
CPrimitive* primitive = NULL;
intresult;
//获取最近的相交点
intnum = m_pScene->GetPrimitiveNum();
for (inti = 0; i<num; i++)
{
CPrimitive* currentPrimitive =
m_pScene->GetPrimitive(i);
intcurrentResult;
currentResult = currentPrimitive->Intersect(ray,
t);
if(currentResult != MISS)
{
primitive = currentPrimitive;
result = currentResult;
}
}
if (primitive == NULL) //没有交点
return 0;
if (primitive->IsLight()) //光线顺利到达
{
totalColor = primitive->GetMaterial()->GetColor();
}
else
{
CPoint3point; //交点计算
point = ray.GetOrigin() + ray.GetDirection() * t;
intnum = m_pScene->GetPrimitiveNum();
for (inti = 0; i<num; i++)
{
CPrimitive* p = m_pScene->GetPrimitive(i);
if (p->IsLight())
{
CPrimitive * pLight = p;
boolvisible = true;
if (pLight->GetType() == CPrimitive::SPHERE)
{
CVector3direction(((CSphere*)p)->GetCenter() -
point);
floatt = direction.Length();
direction.Normalize();
CRayr = CRay(point+direction*EPSILON,
direction);
// whether it is visible for this light
for (intj = 0;
j<m_pScene->GetPrimitiveNum(); j++)
{
CPrimitive* p1 =
m_pScene->GetPrimitive(j);
if ((p1 != pLight) && (p1->Intersect(r,
t)))
{
visible = false;
break;
}
}
}
if (visible)
{
// 入射光
CVector3L = ((CSphere*)pLight)->GetCenter() - point;
L.Normalize();
// normal
CVector3N = primitive->GetNormal(point);
// 计算漫反射光
if
(primitive->GetMaterial()->GetDiffuse() > 0)
{
// k * I * (N·L)
CColordiffuseColor =
primitive->GetMaterial()->GetDiffuse()pLight->GetMateri
al()->GetColor()
* DotProduct(N, L)*primitive->GetMaterial()->GetColor();
totalColor += diffuseColor;
}
// 计算镜面反射光
if
(primitive->GetMaterial()->GetSpecular() > 0)
{
// 视点光线
CVector3V = -ray.GetDirection();
// 反射光线, R = 2 * N * (N·L) - L
CVector3R = 2.0f * N * DotProduct(N, L) - L;
// I * W(θ) * (cosα)^n
CColorspecularColor=pLight->GetMaterial()->GetColor()
* primitive->GetMaterial()->GetSpecular()*
powf(DotProduct(V, -R), 30)
* primitive->GetMaterial()->GetColor();
totalColor += specularColor;
}
}
}
}
// 计算反射
floatreflection =
primitive->GetMaterial()->GetReflection();
if ((reflection> 0.0f) && (depth<TRACE_DEPTH))
{
CVector3N = primitive->GetNormal(point);
CVector3direction = ray.GetDirection() - 2.0f *
DotProduct(ray.GetDirection(), N) * N;
CRayreflectionRay(point + direction * EPSILON,
direction);
CColorreflectionColor(0.0f, 0.0f, 0.0f);
floatt0;
// 继续跟踪反射光线
Raytrace(reflectionRay, reflectionColor, depth +
1, reflactionIndex, t0);
reflectionColor = reflection * reflectionColor *
primitive->GetMaterial()->GetColor();
totalColor += reflectionColor;
}
}
returnprimitive;
}
voidCRayTracer::InitRender()
{
m_currentLine = 0;
m_xLeft = -40.0f;
m_xRight = 40.0f;
m_yTop = 30.0f;
m_yBottom = -30.0f;
m_dx = (m_xRight - m_xLeft) / m_width;
m_dy = (m_yBottom - m_yTop) / m_height;
}
boolCRayTracer::Render()
{
if(m_currentLine>= m_height)
returntrue;
CPoint3o(0.0f, 3.0f, 80.0f);
for (intx = 0; x<m_width; x++ )
{
CColortotalColor(0.0f, 0.0f, 0.0f);
CVector3direction(CPoint3(m_xLeft+x*m_dx,
m_yTop+m_currentLine*m_dy, 0) - o);
direction.Normalize();
CRayr(o, direction);
floatt;
Raytrace(r, totalColor, 1, 1.0f, t);
intred, green, blue;
red = min((int)(totalColor.r * 256), 255);
green = min((int)(totalColor.g * 256), 255);
blue = min((int)(totalColor.b * 256), 255);
m_pColorBuffer[m_currentLine*m_width+x] = (red<< 16)
+ (green<< 8) + blue;
}
m_currentLine++;
returnfalse;
}
//主函数
#include"declares.h"
HWNDhWnd;//窗口句柄
BITMAPINFObmpInfo;//局部变量
HDChDC;
COLOR32buffer[SCREEN_HEIGHT*SCREEN_WIDTH];
CRayTracer* tracer = 0;
LRESULTCALLBACKWndProc(HWNDhWnd, UINTmessage, WPARAMwParam,
LPARAMlParam);
ATOM MyRegisterClass(HINSTANCEhInstance);
BOOL InitInstance(HINSTANCEhInstance, intnCmdShow);
intAPIENTRYWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstanc
e,LPSTRlpCmdLine,intnCmdShow)
{
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
returnFALSE;
}
ZeroMemory(&bmpInfo, sizeof(bmpInfo));
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biWidth = SCREEN_WIDTH;
bmpInfo.bmiHeader.biHeight = -SCREEN_HEIGHT;
hDC = GetDC(hWnd);
tracer = newCRayTracer();
tracer->GetScene()->InitScene();
tracer->SetBuffer(buffer, SCREEN_WIDTH, SCREEN_HEIGHT);
MSGmessage;
tracer->InitRender();
while(1)
{
if(tracer->Render())
tracer->InitRender();
while(PeekMessage(&message, hWnd, 0, 0, PM_REMOVE))
{
TranslateMessage(&message );
DispatchMessage(&message );
}
StretchDIBits(hDC, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0,
0, SCREEN_WIDTH, SCREEN_HEIGHT, buffer, &bmpInfo,
DIB_RGB_COLORS, SRCCOPY);
}
return 1;
}
//窗口设置
ATOMMyRegisterClass(HINSTANCEhInstance)
{
//LPCWSTR str = L"RayTracing";
WNDCLASSEXwcex;
wcex.cbSize
= sizeof(WNDCLASSEX);
wcex.style
wcex.lpfnWndProc
wcex.cbClsExtra
wcex.cbWndExtra
wcex.hInstance
wcex.hIcon
wcex.hCursor
wcex.hCursor
= CS_HREDRAW | CS_VREDRAW;
= (WNDPROC)WndProc;
= 0;
= 0;
= hInstance;
= NULL;
= NULL;
= LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = LPCWSTR("Raytracing");
wcex.hIconSm
= NULL;
returnRegisterClassEx(&wcex);
}
//初始化窗口
BOOLInitInstance(HINSTANCEhInstance, intnCmdShow)
{
// hInst = hInstance;
// make the window show at the center of the screen, and the
client area size is 800*600
RECTrect;
rect.left = 0;
rect.top = 0;
rect.right = SCREEN_WIDTH;
rect.bottom = SCREEN_HEIGHT;
AdjustWindowRect(&rect, WS_POPUP | WS_SYSMENU | WS_CAPTION,
NULL);
intwindowWidth = rect.right - rect.left;
intwindowHeight = rect.bottom - rect.top;
intscreenWidth = GetSystemMetrics(SM_CXSCREEN);
intscreenHeight = GetSystemMetrics(SM_CYSCREEN);
intwindowLeft = (screenWidth - windowWidth) / 2;
intwindowTop = (screenHeight - windowHeight) / 2;
hWnd = CreateWindow(LPCWSTR("Raytracing"), //
class name
LPCWSTR("Raytracing"), // title name
of the window WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, // style
of the window
windowLeft, // initial horizontal
position of the window windowTop,
// initial vertical position of the window
windowWidth, // width of the window
windowHeight, / eight of the window
NULL, // the parent or owner of
the window
NULL, // handle to a menu
hInstance, // handle to the instance
NULL); // parameter
if(!hWnd)
{
returnFALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
returnTRUE;
}
//窗口消息函数
LRESULTCALLBACKWndProc(HWNDhWnd, UINTmessage, WPARAMwParam,
LPARAMlParam)
{
switch(message)
{
caseWM_PAINT:
StretchDIBits(hDC, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0,
0, SCREEN_WIDTH, SCREEN_HEIGHT, buffer, &bmpInfo,
DIB_RGB_COLORS, SRCCOPY);
ValidateRect(hWnd, NULL);
break;
caseWM_CLOSE:
ReleaseDC(hWnd, hDC);
DestroyWindow(hWnd);
ExitProcess(0);
break;
default:
returnDefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
} 帮我修改完善这个代码
最新发布