]> git.tdb.fi Git - libs/vr.git/blob - source/stereocombiner.cpp
Fix memory leaks
[libs/vr.git] / source / stereocombiner.cpp
1 #include <algorithm>
2 #include <msp/gl/meshbuilder.h>
3 #include "stereocombiner.h"
4
5 using namespace std;
6
7 namespace {
8
9 const char mirror_vs_source[] =
10         "uniform vec2 scale;\n"
11         "varying vec2 texcoord;\n"
12         "void main()\n"
13         "{\n"
14         "       gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0);\n"
15         "       texcoord = gl_Vertex.xy*scale*0.5+0.5;\n"
16         "}";
17
18 const char mirror_fs_source[] =
19         "uniform sampler2D texture;\n"
20         "varying vec2 texcoord;\n"
21         "void main()\n"
22         "{\n"
23         "       gl_FragColor = texture2D(texture, texcoord);\n"
24         "}";
25
26 }
27
28
29 namespace Msp {
30 namespace VR {
31
32 StereoCombiner::StereoCombiner():
33         target_width(0),
34         target_height(0),
35         render_aspect(1.0f),
36         frustum_skew(0.0f),
37         mirror(0)
38 { }
39
40 StereoCombiner::~StereoCombiner()
41 {
42         delete mirror;
43 }
44
45 void StereoCombiner::configure_eye_frustums(const Frustum &left_frustum, const Frustum &right_frustum)
46 {
47         float vertical = max(max(left_frustum.top, -left_frustum.bottom), max(right_frustum.top, -right_frustum.bottom));
48         fov = Geometry::atan<float>(vertical)*2.0f;
49
50         float inner = max(left_frustum.right, -right_frustum.left);
51         float outer = max(-left_frustum.left, right_frustum.right);
52         frustum_skew = (inner-outer)/(inner+outer);
53
54         render_aspect = (inner+outer)/(vertical*2);
55 }
56
57 void StereoCombiner::set_mirroring(bool m)
58 {
59         if(m && !is_mirroring_supported())
60                 throw runtime_error("mirroring not supported");
61
62         if(m && !mirror)
63                 mirror = new MirrorView;
64         else if(!m && mirror)
65         {
66                 delete mirror;
67                 mirror = 0;
68         }
69 }
70
71 void StereoCombiner::render_mirror(const GL::Texture2D &tex) const
72 {
73         if(!mirror)
74                 return;
75
76         GL::Bind bind_tex(tex);
77         GL::Bind bind_shprog(mirror->shader);
78         mirror->shdata.apply();
79         mirror->mesh.draw();
80 }
81
82
83 StereoCombiner::Frustum::Frustum():
84         left(-1),
85         right(1),
86         bottom(-1),
87         top(1)
88 { }
89
90 StereoCombiner::Frustum::Frustum(float l, float r, float b, float t):
91         left(l),
92         right(r),
93         bottom(b),
94         top(t)
95 { }
96
97
98 StereoCombiner::MirrorView::MirrorView():
99         mesh(GL::VERTEX2),
100         shader(mirror_vs_source, mirror_fs_source)
101 {
102         GL::MeshBuilder bld(mesh);
103         bld.begin(GL::TRIANGLE_STRIP);
104         bld.vertex(-1, 1);
105         bld.vertex(-1, -1);
106         bld.vertex(1, 1);
107         bld.vertex(1, -1);
108         bld.end();
109
110         shdata.uniform("scale", 0.5f, 0.5f);
111 }
112
113 } // namespace VR
114 } // namespace Msp