]> git.tdb.fi Git - libs/gl.git/blob - source/zsortedscene.cpp
Appease the compiler with some extra copy-ctor's and operator='s
[libs/gl.git] / source / zsortedscene.cpp
1 #include "camera.h"
2 #include "renderer.h"
3 #include "zsortedscene.h"
4
5 using namespace std;
6
7 namespace Msp {
8 namespace GL {
9
10 ZSortedScene::ZSortedScene():
11         order(BACK_TO_FRONT),
12         reference(FURTHEST)
13 { }
14
15 void ZSortedScene::add(Renderable &r)
16 {
17         if(renderables.insert(&r).second && !sorted_cache.empty())
18                 sorted_cache.push_back(&r);
19 }
20
21 void ZSortedScene::remove(Renderable &r)
22 {
23         renderables.erase(&r);
24         sorted_cache.clear();
25 }
26
27 void ZSortedScene::set_order(SortOrder o)
28 {
29         order = o;
30 }
31
32 void ZSortedScene::set_reference(DepthReference r)
33 {
34         reference = r;
35 }
36
37 void ZSortedScene::populate_cache() const
38 {
39         if(sorted_cache.empty() && !renderables.empty())
40         {
41                 sorted_cache.reserve(renderables.size());
42                 sorted_cache.insert(sorted_cache.end(), renderables.begin(), renderables.end());
43         }
44 }
45
46 void ZSortedScene::setup_frame(Renderer &renderer)
47 {
48         populate_cache();
49         for(SortedArray::const_iterator i=sorted_cache.begin(); i!=sorted_cache.end(); ++i)
50                 i->renderable->setup_frame(renderer);
51 }
52
53 void ZSortedScene::finish_frame()
54 {
55         for(SortedArray::const_iterator i=sorted_cache.begin(); i!=sorted_cache.end(); ++i)
56                 i->renderable->finish_frame();
57 }
58
59 void ZSortedScene::render(Renderer &renderer, const Tag &tag) const
60 {
61         if(renderables.empty())
62                 return;
63
64         populate_cache();
65
66         const Camera *camera = renderer.get_camera();
67         if(!camera)
68         {
69                 for(SortedArray::const_iterator i=sorted_cache.begin(); i!=sorted_cache.end(); ++i)
70                         renderer.render(*i->renderable, tag);
71                 return;
72         }
73
74         const Vector3 &camera_pos = camera->get_position();
75         const Vector3 &look_dir = camera->get_look_direction();
76         float radius_factor = reference-1.0f;
77         float sign = 1.0f-order*2.0f;
78
79         bool use_frustum = setup_frustum(renderer);
80         for(SortedArray::iterator i=sorted_cache.begin(); i!=sorted_cache.end(); ++i)
81         {
82                 i->in_frustum = (!use_frustum || !frustum_cull(*i->renderable));
83                 if(!i->in_frustum)
84                         continue;
85
86                 if(const Matrix *matrix = i->renderable->get_matrix())
87                 {
88                         if(const Geometry::BoundingSphere<float, 3> *bsphere = i->renderable->get_bounding_sphere())
89                                 i->depth = dot(*matrix*bsphere->get_center()-camera_pos, look_dir)+bsphere->get_radius()*radius_factor;
90                         else
91                                 i->depth = dot(*matrix*Vector3()-camera_pos, look_dir);
92                         i->depth *= sign;
93                 }
94                 else
95                         i->depth = 0;
96         }
97
98         for(SortedArray::iterator i=sorted_cache.begin(), j=i; i!=sorted_cache.end(); ++i)
99                 if(i->in_frustum)
100                 {
101                         if(i!=j)
102                                 swap(*i, *j);
103
104                         if(j!=sorted_cache.begin() && *j<*(j-1))
105                         {
106                                 SortedRenderable sr = *j;
107                                 SortedArray::iterator k = j-1;
108                                 *j = *k;
109                                 while(k!=sorted_cache.begin() && sr<*(k-1))
110                                 {
111                                         *k = *(k-1);
112                                         --k;
113                                 }
114                                 *k = sr;
115                         }
116
117                         ++j;
118                 }
119
120         for(SortedArray::const_iterator i=sorted_cache.begin(); (i!=sorted_cache.end() && i->in_frustum); ++i)
121                 renderer.render(*i->renderable, tag);
122 }
123
124
125 ZSortedScene::SortedRenderable::SortedRenderable(Renderable *r):
126         renderable(r),
127         in_frustum(false),
128         depth(0.0f)
129 { }
130
131 } // namespace GL
132 } // namespace Msp