Commit d94e66c6 authored by Ken Martin's avatar Ken Martin

add support for stereo spherical 3d

ffmpegvideo source recognized stereo video now

vtkSkybox has a mode to properly display it
parent 653fee07
......@@ -26,6 +26,8 @@
extern "C" {
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/stereo3d.h>
#include <libavcodec/avcodec.h>
}
#include <cctype>
......@@ -133,6 +135,8 @@ vtkFFMPEGVideoSource::vtkFFMPEGVideoSource()
this->FrameBufferRowAlignment = 4;
this->Internal = new vtkFFMPEGVideoSourceInternal;
this->Stereo3D = false;
}
//----------------------------------------------------------------------------
......@@ -199,6 +203,24 @@ void vtkFFMPEGVideoSource::Initialize()
this->Internal->VideoDecodeContext->thread_count = this->DecodingThreads;
// this->Internal->VideoDecodeContext->thread_type = FF_THREAD_FRAME;
// examine the video stream side data for additional information
this->Stereo3D = false;
if (this->Internal->VideoStream->nb_side_data > 0)
{
for (int i = 0; i < this->Internal->VideoStream->nb_side_data; ++i)
{
AVPacketSideData sd = this->Internal->VideoStream->side_data[i];
if (sd.type == AV_PKT_DATA_STEREO3D)
{
AVStereo3D *stereo = reinterpret_cast<AVStereo3D *>(sd.data);
if (stereo->type == AV_STEREO3D_TOPBOTTOM)
{
this->Stereo3D = true;
}
}
}
}
avcodec_parameters_to_context(
this->Internal->VideoDecodeContext,
this->Internal->VideoStream->codecpar);
......
......@@ -130,6 +130,9 @@ public:
// Usefull for while loops
vtkGetMacro(EndOfFile,bool);
// Is the video stream stereo 3d
vtkGetMacro(Stereo3D, bool);
// we do not use Invoke Observers here because this callback
// will happen in a different thread that could conflict
// with events from other threads. In this function you should
......@@ -190,6 +193,8 @@ protected:
void ReadFrame();
bool Stereo3D;
private:
vtkFFMPEGVideoSource(const vtkFFMPEGVideoSource&) = delete;
void operator=(const vtkFFMPEGVideoSource&) = delete;
......
......@@ -39,26 +39,34 @@ public:
using Superclass::GetBounds;
double *GetBounds() override;
//@{
/**
* Set/Get the projection to be used
*/
enum Projection
{
Cube,
Sphere,
Floor,
StereoSphere
};
vtkGetMacro(Projection, int);
vtkSetMacro(Projection, int);
void SetProjectionToCube() { this->SetProjection(vtkSkybox::Cube); }
void SetProjectionToSphere() {this->SetProjection(vtkSkybox::Sphere); }
void SetProjectionToStereoSphere() {this->SetProjection(vtkSkybox::StereoSphere); }
void SetProjectionToFloor() {this->SetProjection(vtkSkybox::Floor); }
//@}
//@{
/**
* Set/Get the plane equation for the floor.
*/
vtkSetVector4Macro(FloorPlane, float);
vtkGetVector4Macro(FloorPlane, float);
vtkSetVector3Macro(FloorRight, float);
vtkGetVector3Macro(FloorRight, float);
//@}
protected:
vtkSkybox();
......
......@@ -84,6 +84,7 @@ vtkOpenGLSkybox::vtkOpenGLSkybox()
this->GetProperty()->SetAmbient(1.0);
this->GetProperty()->SetSpecular(0.0);
this->OpenGLActor->SetProperty(this->GetProperty());
this->CurrentRenderer = nullptr;
}
vtkOpenGLSkybox::~vtkOpenGLSkybox() = default;
......@@ -104,6 +105,8 @@ void vtkOpenGLSkybox::UpdateUniforms(vtkObject *, unsigned long, void *calldata)
float front[3];
vtkMath::Cross(plane, this->FloorRight, front);
program->SetUniform3f("floorFront", front);
program->SetUniformf("leftEye",
(this->CurrentRenderer->GetActiveCamera()->GetLeftEye() ? 1.0 : 0.0));
}
// Actual Skybox render method.
......@@ -149,6 +152,29 @@ void vtkOpenGLSkybox::Render(vtkRenderer *ren, vtkMapper *mapper)
"}\n"
);
}
if (this->Projection == vtkSkybox::StereoSphere)
{
// Replace VTK fragment shader
this->CubeMapper->SetFragmentShaderCode(
"//VTK::System::Dec\n" // always start with this line
"//VTK::Output::Dec\n" // always have this line in your FS
"in vec3 TexCoords;\n"
"uniform vec3 cameraPos;\n" // wc camera position
"uniform sampler2D actortexture;\n"
"uniform vec4 floorPlane;\n" // floor plane eqn
"uniform vec3 floorRight;\n" // floor plane right
"uniform vec3 floorFront;\n" // floor plane front
"uniform float leftEye;\n" // 1.0 for left, 0.0 for right
"void main () {\n"
" vec3 diri = normalize(TexCoords - cameraPos);\n"
" vec3 dirv = vec3(dot(diri,floorRight),\n"
" dot(diri,floorPlane.xyz),\n"
" -dot(diri,floorFront));\n"
" float phix = length(vec2(dirv.x, dirv.z));\n"
" gl_FragData[0] = texture(actortexture, vec2(0.5*atan(dirv.z, dirv.x)/3.1415927 + 0.5, 0.5*atan(dirv.y,phix)/3.1415927 + 0.25 + 0.5*leftEye));\n"
"}\n"
);
}
if (this->Projection == vtkSkybox::Floor)
{
// Replace VTK fragment shader
......@@ -189,12 +215,13 @@ void vtkOpenGLSkybox::Render(vtkRenderer *ren, vtkMapper *mapper)
this->LastProjection = this->Projection;
}
double *pos = ren->GetActiveCamera()->GetPosition();
this->LastCameraPosition[0] = pos[0];
this->LastCameraPosition[1] = pos[1];
this->LastCameraPosition[2] = pos[2];
this->CurrentRenderer = ren;
// get opacity
static_cast<vtkOpenGLRenderer*>(ren)->GetState()->vtkglDepthMask(GL_TRUE);
......
......@@ -29,7 +29,6 @@
class vtkOpenGLActor;
class vtkOpenGLPolyDataMapper;
class vtkOpenGLRenderer;
class VTKRENDERINGOPENGL2_EXPORT vtkOpenGLSkybox : public vtkSkybox
{
......@@ -54,6 +53,7 @@ protected:
vtkNew<vtkOpenGLPolyDataMapper> CubeMapper;
vtkNew<vtkOpenGLActor> OpenGLActor;
vtkRenderer *CurrentRenderer;
private:
vtkOpenGLSkybox(const vtkOpenGLSkybox&) = delete;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment