|
|
@ -2,6 +2,8 @@ |
|
|
|
#include "util.h"
|
|
|
|
#include "Camera.h"
|
|
|
|
#include "Ray.h"
|
|
|
|
#include "Material.h"
|
|
|
|
#include "Object.h"
|
|
|
|
#include "Vector3.h"
|
|
|
|
#include "Sphere.h"
|
|
|
|
#pragma comment(lib, "winmm.lib")
|
|
|
@ -9,6 +11,17 @@ static int sTotalPixelCount = 0; |
|
|
|
static int sViewportWidth = 0, sViewportHeight = 0; |
|
|
|
static Camera* sCamera = nullptr; |
|
|
|
Sphere sphere(Vector3(0.0f, 0.0f, -5.0f), 0.5f); |
|
|
|
static Object* sRootObject = nullptr; |
|
|
|
static Material* lambert = nullptr; |
|
|
|
static int sSampleCount = 64; |
|
|
|
void AddObject(Object* object) { |
|
|
|
if (sRootObject == nullptr) { |
|
|
|
sRootObject = object; |
|
|
|
} |
|
|
|
else { |
|
|
|
//TODO
|
|
|
|
} |
|
|
|
} |
|
|
|
void Init(int width, int height) |
|
|
|
{ |
|
|
|
sTotalPixelCount = width * height; |
|
|
@ -16,6 +29,8 @@ void Init(int width, int height) |
|
|
|
sViewportHeight = height; |
|
|
|
sCamera = new Camera(45.0f, float(width) / float(height)); |
|
|
|
sCamera->LookAt(Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 0.0f, -1.0f), Vector3(0.0f, 1.0f, 0.0f)); |
|
|
|
lambert = new LamberMaterial(Vector3(0.1f, 0.4f, 0.7f)); |
|
|
|
AddObject(new Object(&sphere, lambert)); |
|
|
|
} |
|
|
|
|
|
|
|
float GetEscaptedTime() { |
|
|
@ -35,29 +50,37 @@ Vector3 GetEnviromentColor(const Ray& input_ray) { |
|
|
|
return factor * top_color + (1.0f - factor) * bottom_color; |
|
|
|
} |
|
|
|
|
|
|
|
Vector3 GetColor(const Ray& input_ray) { |
|
|
|
HitPoint hit_point; |
|
|
|
if (sRootObject->HitTest(input_ray, 0.01f, 100.0f, hit_point)) { |
|
|
|
Ray scatter_ray; |
|
|
|
if (hit_point.mMaterial->Scatter(input_ray, hit_point, scatter_ray)) { |
|
|
|
return GetColor(scatter_ray); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return GetEnviromentColor(input_ray); |
|
|
|
} |
|
|
|
|
|
|
|
void RenderOnePixel(int pixel_index) { |
|
|
|
int x = pixel_index % sViewportWidth; |
|
|
|
int y = pixel_index / sViewportWidth; |
|
|
|
float u = float(x) / sViewportWidth; |
|
|
|
float v = float(y) / sViewportHeight; |
|
|
|
Ray ray = sCamera->GetRay(u,v); |
|
|
|
HitPoint hit_point; |
|
|
|
if (sphere.HitTest(ray, 0.0f, 100.0f, hit_point)) { |
|
|
|
float rf = hit_point.mNormal.x * 0.5f + 0.5f; |
|
|
|
float gf = hit_point.mNormal.y * 0.5f + 0.5f; |
|
|
|
float bf = hit_point.mNormal.z * 0.5f + 0.5f; |
|
|
|
AByte r = AByte(rf * 255.0f); |
|
|
|
AByte g = AByte(gf * 255.0f); |
|
|
|
AByte b = AByte(bf * 255.0f); |
|
|
|
SetColor(x, y, r, g, b, 255); |
|
|
|
} |
|
|
|
else { |
|
|
|
Vector3 color = GetEnviromentColor(ray); |
|
|
|
AByte r = AByte(color.x * 255.0f); |
|
|
|
AByte g = AByte(color.y * 255.0f); |
|
|
|
AByte b = AByte(color.z * 255.0f); |
|
|
|
SetColor(x, y, r, g, b, 255); |
|
|
|
|
|
|
|
Vector3 color; |
|
|
|
for (int i = 0; i < sSampleCount; i++) { |
|
|
|
float offset_u = srandf()*0.5; |
|
|
|
float offset_v = srandf()*0.5; |
|
|
|
float u = (float(x) + offset_u) / sViewportWidth; |
|
|
|
float v = (float(y) + offset_v) / sViewportHeight; |
|
|
|
Ray ray = sCamera->GetRay(u, v); |
|
|
|
Vector3 current_color = GetColor(ray); |
|
|
|
color = color + current_color; |
|
|
|
} |
|
|
|
color /= sSampleCount; |
|
|
|
AByte r = AByte(color.x * 255.0f); |
|
|
|
AByte g = AByte(color.y * 255.0f); |
|
|
|
AByte b = AByte(color.z * 255.0f); |
|
|
|
SetColor(x, y, r, g, b, 255); |
|
|
|
} |
|
|
|
|
|
|
|
void Render() |
|
|
@ -67,7 +90,7 @@ void Render() |
|
|
|
while (sCurrentRenderPixel < sTotalPixelCount) { |
|
|
|
RenderOnePixel(sCurrentRenderPixel); |
|
|
|
sCurrentRenderPixel++; |
|
|
|
current_render_time = GetEscaptedTime(); |
|
|
|
current_render_time += GetEscaptedTime(); |
|
|
|
if (current_render_time > 0.016f) { |
|
|
|
break; |
|
|
|
} |
|
|
|
xxxxxxxxxx