diff --git a/modules/ovis/include/opencv2/ovis.hpp b/modules/ovis/include/opencv2/ovis.hpp index 3d55103c1..899042cc3 100644 --- a/modules/ovis/include/opencv2/ovis.hpp +++ b/modules/ovis/include/opencv2/ovis.hpp @@ -161,6 +161,16 @@ public: */ CV_WRAP virtual void getScreenshot(OutputArray frame) = 0; + /** + * read back the texture of an active compositor + * @param compname name of the compositor + * @param texname name of the texture inside the compositor + * @param mrtIndex if texture is a MRT, specifies the attachment + * @param out the texture contents + */ + CV_WRAP virtual void getCompositorTexture(const String& compname, const String& texname, + OutputArray out, int mrtIndex = 0) = 0; + /** * get the depth for the current frame. * diff --git a/modules/ovis/src/ovis.cpp b/modules/ovis/src/ovis.cpp index 6fe372a28..c38d06688 100644 --- a/modules/ovis/src/ovis.cpp +++ b/modules/ovis/src/ovis.cpp @@ -382,6 +382,57 @@ public: } } + void getCompositorTexture(const String& compname, const String& texname, OutputArray out, + int mrtIndex) CV_OVERRIDE + { + CompositorManager& cm = CompositorManager::getSingleton(); + CompositorChain* chain = cm.getCompositorChain(frameSrc->getViewport(0)); + CV_Assert(chain && "no active compositors"); + + CompositorInstance* inst = chain->getCompositor(compname); + if(!inst) + CV_Error_(Error::StsBadArg, ("no active compositor named: %s", compname.c_str())); + + TexturePtr tex = inst->getTextureInstance(texname, mrtIndex); + if(!tex) + CV_Error_(Error::StsBadArg, ("no texture named: %s", texname.c_str())); + + PixelFormat src_type = tex->getFormat(); + int dst_type; + switch(src_type) + { + case PF_BYTE_RGB: + dst_type = CV_8UC3; + break; + case PF_BYTE_RGBA: + dst_type = CV_8UC4; + break; + case PF_FLOAT32_RGB: + dst_type = CV_32FC3; + break; + case PF_FLOAT32_RGBA: + dst_type = CV_32FC4; + break; + case PF_DEPTH16: + dst_type = CV_16U; + break; + default: + CV_Error(Error::StsNotImplemented, "unsupported texture format"); + } + + out.create(tex->getHeight(), tex->getWidth(), dst_type); + + Mat mat = out.getMat(); + PixelBox pb(tex->getWidth(), tex->getHeight(), 1, src_type, mat.ptr()); + tex->getBuffer()->blitToMemory(pb, pb); + + if(CV_MAT_CN(dst_type) < 3) + return; + + // convert to OpenCV channel order + cvtColor(mat, mat, CV_MAT_CN(dst_type) == 3 ? COLOR_RGB2BGR : COLOR_RGBA2BGRA); + } + void setBackground(const Scalar& color) CV_OVERRIDE { // hide background plane