-
Notifications
You must be signed in to change notification settings - Fork 0
/
scene.h
136 lines (120 loc) · 4.19 KB
/
scene.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#ifndef SCENE_H_
#define SCENE_H_
#include <list>
#include <png++/png.hpp>
#include "view.h"
#include "object.h"
#include "lights.h"
#include "access.h"
#include "bvh.h"
#include <string>
using namespace objects;
using namespace lights;
using namespace view;
typedef unsigned char UInt8;
namespace scene
{
template<class shader>
class basicScene
{
public:
basicScene() : objectList(std::list<typename objects::object*>()), lightList(std::list<typename lights::light*>()), ambience(ambientLight()), window(nullptr){};
std::list<typename objects::object*> objectList;
std::list<typename lights::light*> lightList; //for direction/point lights only;
inline void addObj(typename objects::object * obj) { objectList.push_back(obj); };
inline void addLight(typename lights::light * l) { lightList.push_back(l); };
inline void remObj(typename objects::object * obj) { objectList.remove(obj); };
inline void remLight(typename lights::light * l) { lightList.remove(l); };
ambientLight ambience;
viewWindow * window;
png::image<png::rgb_pixel> * render()
{
png::image<png::rgb_pixel> * outImage = new png::image<png::rgb_pixel>(window->res.first, window->res.second);
auto rays = this->window->rays();
access_n::linearAccess acc(objectList);
UInt64 pixel = 0;
for(UInt64 x = 0; x < window->res.first; x++)
{
for(UInt64 y = 0; y < window->res.second; y++)
{
rgbColor avg(0,0,0, true);
for (UInt64 r = 0; r < pow(window->subdivisions,2); r++)
{
//first find the intersection point closest to the origin
shader shad;
rgbColor col = shad(ambience,
&lightList,
acc(rays[x][y][r]),
rays[x][y][r],
&acc,
x,
y);
avg = avg + col;
}
avg = avg*(1/pow(window->subdivisions,2));
avg.normalize();
avg.changeMode(false);
outImage->set_pixel(x, outImage->get_height()-1-y, png::rgb_pixel((UInt8)round(avg.r()), (UInt8)round(avg.g()), (UInt8)round(avg.b())));
if(!(pixel%100))
std::cout << (F64)(pixel)/(F64)(window->res.second*window->res.first)*100 << "%" << std::endl;
pixel++;
}
}
return outImage;
}
};
template<class shader>
class BVHScene
{
public:
BVHScene() : objectList(std::list<typename objects::object*>()), lightList(std::list<typename lights::light*>()), ambience(ambientLight()), window(nullptr){};
std::list<typename objects::object*> objectList;
std::list<typename lights::light*> lightList; //for direction/point lights only;
ambientLight ambience;
viewWindow * window;
inline void addObj(typename objects::object * obj) { objectList.push_back(obj); };
inline void addLight(typename lights::light * l) { lightList.push_back(l); };
inline void remObj(typename objects::object * obj) { objectList.remove(obj); };
inline void remLight(typename lights::light * l) { lightList.remove(l); };
png::image<png::rgb_pixel> * render()
{
png::image<png::rgb_pixel> * outImage = new png::image<png::rgb_pixel>(window->res.first, window->res.second);
auto rays = this->window->rays();
bvh_n::bvh heirarchy(objectList, 6);
UInt64 pixel = 0;
for(UInt64 x = 0; x < window->res.first /*/2*/; x++)
{
for(UInt64 y = 0 /*window->res.second /2+window->res.second/4*/; y < window->res.second; y++)
{
rgbColor avg(0,0,0, true);
for (UInt64 r = 0; r < pow(window->subdivisions,2); r++)
{
//first find the intersection point closest to the origin
shader shad;
#ifdef DEBUG_SHAD
std::cout << "Shade begin" << std::endl;
#endif
rgbColor col = shad(ambience,
&lightList,
heirarchy(rays[x][y][r]),
rays[x][y][r],
&heirarchy,
x,
y);
avg = avg + col;
}
avg = avg*(1/pow(window->subdivisions,2));
avg.normalize();
avg.changeMode(false);
outImage->set_pixel(x, outImage->get_height()-1-y, png::rgb_pixel((UInt8)round(avg.r()), (UInt8)round(avg.g()), (UInt8)round(avg.b())));
//debug info
if(!(pixel%100))
std::cout << (F64)(pixel)/(F64)(window->res.second*window->res.first)*100 << "%" << std::endl;
pixel++;
}
}
return outImage;
}
};
}
#endif