X-Git-Url: http://git.tdb.fi/?p=libs%2Fvr.git;a=blobdiff_plain;f=source%2Fstereocombiner.cpp;h=dbbe81509909fd589b7271d985c10e58fa674505;hp=c24a937484aae3c162de692dee4d143959cc2176;hb=HEAD;hpb=cb460150f6870c172a70237f283c9753250be361 diff --git a/source/stereocombiner.cpp b/source/stereocombiner.cpp index c24a937..dbbe815 100644 --- a/source/stereocombiner.cpp +++ b/source/stereocombiner.cpp @@ -1,5 +1,31 @@ +#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 VR { @@ -7,8 +33,82 @@ StereoCombiner::StereoCombiner(): target_width(0), target_height(0), render_aspect(1.0f), - frustum_skew(0.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) { } +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