X-Git-Url: http://git.tdb.fi/?p=libs%2Fvr.git;a=blobdiff_plain;f=source%2Fstereocombiner.cpp;h=dbbe81509909fd589b7271d985c10e58fa674505;hp=be0b01e986a76d99bd1abc25a2bade3b2e45e152;hb=HEAD;hpb=cf1b08401da851dd98cde45d9e4acf6e1d185224 diff --git a/source/stereocombiner.cpp b/source/stereocombiner.cpp index be0b01e..dbbe815 100644 --- a/source/stereocombiner.cpp +++ b/source/stereocombiner.cpp @@ -1,13 +1,114 @@ +#include +#include #include "stereocombiner.h" +using namespace std; + +namespace { + +const char mirror_vs_source[] = + "uniform vec2 scale;\n" + "varying vec2 texcoord;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0);\n" + " texcoord = gl_Vertex.xy*scale*0.5+0.5;\n" + "}"; + +const char mirror_fs_source[] = + "uniform sampler2D texture;\n" + "varying vec2 texcoord;\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(texture, texcoord);\n" + "}"; + +} + + namespace Msp { -namespace GL { +namespace VR { StereoCombiner::StereoCombiner(): - width_div(1), - height_div(1), - keep_aspect(false) + target_width(0), + target_height(0), + render_aspect(1.0f), + frustum_skew(0.0f), + mirror(0) +{ } + +StereoCombiner::~StereoCombiner() +{ + delete mirror; +} + +void StereoCombiner::configure_eye_frustums(const Frustum &left_frustum, const Frustum &right_frustum) +{ + float vertical = max(max(left_frustum.top, -left_frustum.bottom), max(right_frustum.top, -right_frustum.bottom)); + fov = Geometry::atan(vertical)*2.0f; + + float inner = max(left_frustum.right, -right_frustum.left); + float outer = max(-left_frustum.left, right_frustum.right); + frustum_skew = (inner-outer)/(inner+outer); + + render_aspect = (inner+outer)/(vertical*2); +} + +void StereoCombiner::set_mirroring(bool m) +{ + if(m && !is_mirroring_supported()) + throw runtime_error("mirroring not supported"); + + if(m && !mirror) + mirror = new MirrorView; + else if(!m && mirror) + { + delete mirror; + mirror = 0; + } +} + +void StereoCombiner::render_mirror(const GL::Texture2D &tex) const +{ + if(!mirror) + return; + + GL::Bind bind_tex(tex); + GL::Bind bind_shprog(mirror->shader); + mirror->shdata.apply(); + mirror->mesh.draw(); +} + + +StereoCombiner::Frustum::Frustum(): + left(-1), + right(1), + bottom(-1), + top(1) { } -} // namespace GL +StereoCombiner::Frustum::Frustum(float l, float r, float b, float t): + left(l), + right(r), + bottom(b), + top(t) +{ } + + +StereoCombiner::MirrorView::MirrorView(): + mesh(GL::VERTEX2), + shader(mirror_vs_source, mirror_fs_source) +{ + GL::MeshBuilder bld(mesh); + bld.begin(GL::TRIANGLE_STRIP); + bld.vertex(-1, 1); + bld.vertex(-1, -1); + bld.vertex(1, 1); + bld.vertex(1, -1); + bld.end(); + + shdata.uniform("scale", 0.5f, 0.5f); +} + +} // namespace VR } // namespace Msp