added GlArrays class and pointCloudShow function
authorVladislav Vinogradov <no@email>
Wed, 23 Nov 2011 10:05:24 +0000 (10:05 +0000)
committerVladislav Vinogradov <no@email>
Wed, 23 Nov 2011 10:05:24 +0000 (10:05 +0000)
modules/core/include/opencv2/core/gpumat.hpp
modules/core/src/gpumat.cpp
modules/highgui/include/opencv2/highgui/highgui.hpp
modules/highgui/src/window.cpp
modules/highgui/src/window_w32.cpp
samples/cpp/point_cloud.cpp [new file with mode: 0644]

index f9fbced..6682fff 100644 (file)
@@ -241,11 +241,15 @@ namespace cv { namespace gpu
         GlBuffer(Size size, int type, Usage usage);\r
 \r
         //! copy from host/device memory\r
-        GlBuffer(const Mat& mat, Usage usage);\r
+        GlBuffer(InputArray mat, Usage usage);\r
         GlBuffer(const GpuMat& d_mat, Usage usage);\r
 \r
+        GlBuffer(const GlBuffer& other);\r
+\r
         ~GlBuffer();\r
 \r
+        GlBuffer& operator =(const GlBuffer& other);\r
+\r
         void create(int rows, int cols, int type, Usage usage);\r
         inline void create(Size size, int type, Usage usage) { create(size.height, size.width, type, usage); }\r
         inline void create(int rows, int cols, int type) { create(rows, cols, type, usage()); }\r
@@ -254,7 +258,7 @@ namespace cv { namespace gpu
         void release();\r
 \r
         //! copy from host/device memory\r
-        void copyFrom(const Mat& mat);\r
+        void copyFrom(InputArray mat);\r
         void copyFrom(const GpuMat& d_mat);\r
 \r
         void bind() const;\r
@@ -267,11 +271,12 @@ namespace cv { namespace gpu
         //! map to device memory\r
         GpuMat mapDevice();\r
         void unmapDevice();\r
+        \r
+        int rows;\r
+        int cols;\r
 \r
-        inline int rows() const { return rows_; }\r
-        inline int cols() const { return cols_; }\r
-        inline Size size() const { return Size(cols_, rows_); }\r
-        inline bool empty() const { return rows_ == 0 || cols_ == 0; }\r
+        inline Size size() const { return Size(cols, rows); }\r
+        inline bool empty() const { return rows == 0 || cols == 0; }\r
 \r
         inline int type() const { return type_; }\r
         inline int depth() const { return CV_MAT_DEPTH(type_); }\r
@@ -282,8 +287,6 @@ namespace cv { namespace gpu
         inline Usage usage() const { return usage_; }\r
 \r
     private:\r
-        int rows_;\r
-        int cols_;\r
         int type_;\r
         Usage usage_;\r
 \r
@@ -303,26 +306,31 @@ namespace cv { namespace gpu
         GlTexture(Size size, int type);\r
 \r
         //! copy from host/device memory\r
-        explicit GlTexture(const Mat& mat, bool bgra = true);\r
+        explicit GlTexture(InputArray mat, bool bgra = true);\r
         explicit GlTexture(const GlBuffer& buf, bool bgra = true);\r
 \r
+        GlTexture(const GlTexture& other);\r
+\r
         ~GlTexture();\r
 \r
+        GlTexture& operator =(const GlTexture& other);\r
+\r
         void create(int rows, int cols, int type);\r
         inline void create(Size size, int type) { create(size.height, size.width, type); }\r
         void release();\r
 \r
         //! copy from host/device memory\r
-        void copyFrom(const Mat& mat, bool bgra = true);\r
+        void copyFrom(InputArray mat, bool bgra = true);\r
         void copyFrom(const GlBuffer& buf, bool bgra = true);\r
 \r
         void bind() const;\r
         void unbind() const;\r
 \r
-        inline int rows() const { return rows_; }\r
-        inline int cols() const { return cols_; }\r
-        inline Size size() const { return Size(cols_, rows_); }\r
-        inline bool empty() const { return rows_ == 0 || cols_ == 0; }\r
+        int rows;\r
+        int cols;\r
+\r
+        inline Size size() const { return Size(cols, rows); }\r
+        inline bool empty() const { return rows == 0 || cols == 0; }\r
 \r
         inline int type() const { return type_; }\r
         inline int depth() const { return CV_MAT_DEPTH(type_); }\r
@@ -331,22 +339,136 @@ namespace cv { namespace gpu
         inline int elemSize1() const { return CV_ELEM_SIZE1(type_); }\r
 \r
     private:\r
-        int rows_;\r
-        int cols_;\r
         int type_;\r
 \r
         class Impl;\r
         Ptr<Impl> impl_;\r
     };\r
 \r
+    //! OpenGL Arrays\r
+    class CV_EXPORTS GlArrays\r
+    {\r
+    public:\r
+        inline GlArrays() \r
+            : vertex_(GlBuffer::ARRAY_BUFFER), color_(GlBuffer::ARRAY_BUFFER), bgra_(true), normal_(GlBuffer::ARRAY_BUFFER), texCoord_(GlBuffer::ARRAY_BUFFER)\r
+        {\r
+        }\r
+\r
+        void setVertexArray(const GlBuffer& vertex);\r
+        void setVertexArray(const GpuMat& vertex);\r
+        void setVertexArray(InputArray vertex);\r
+        inline void resetVertexArray() { vertex_.release(); }\r
+\r
+        void setColorArray(const GlBuffer& color, bool bgra = true);\r
+        void setColorArray(const GpuMat& color, bool bgra = true);\r
+        void setColorArray(InputArray color, bool bgra = true);\r
+        inline void resetColorArray() { color_.release(); }\r
+        \r
+        void setNormalArray(const GlBuffer& normal);\r
+        void setNormalArray(const GpuMat& normal);\r
+        void setNormalArray(InputArray normal);\r
+        inline void resetNormalArray() { normal_.release(); }\r
+        \r
+        void setTexCoordArray(const GlBuffer& texCoord);\r
+        void setTexCoordArray(const GpuMat& texCoord);\r
+        void setTexCoordArray(InputArray texCoord);\r
+        inline void resetTexCoordArray() { texCoord_.release(); }\r
+\r
+        void bind() const;\r
+        void unbind() const;\r
+\r
+        inline int rows() const { return vertex_.rows; }\r
+        inline int cols() const { return vertex_.cols; }\r
+        inline Size size() const { return vertex_.size(); }\r
+        inline bool empty() const { return vertex_.empty(); }\r
+\r
+    private:\r
+        GlBuffer vertex_;\r
+        GlBuffer color_;\r
+        bool bgra_;\r
+        GlBuffer normal_;\r
+        GlBuffer texCoord_;\r
+    };\r
+\r
     //! render functions\r
-    CV_EXPORTS void render(const GlTexture& tex);\r
+\r
+    //! render texture rectangle in window\r
+    CV_EXPORTS void render(const GlTexture& tex, \r
+        Rect_<double> wndRect = Rect_<double>(0.0, 0.0, 1.0, 1.0), \r
+        Rect_<double> texRect = Rect_<double>(0.0, 0.0, 1.0, 1.0));\r
+\r
+    //! render mode\r
+    namespace RenderMode {\r
+        enum {\r
+            POINTS         = 0x0000,\r
+            LINES          = 0x0001,\r
+            LINE_LOOP      = 0x0002,\r
+            LINE_STRIP     = 0x0003,\r
+            TRIANGLES      = 0x0004,\r
+            TRIANGLE_STRIP = 0x0005,\r
+            TRIANGLE_FAN   = 0x0006,\r
+            QUADS          = 0x0007,\r
+            QUAD_STRIP     = 0x0008,\r
+            POLYGON        = 0x0009\r
+        };\r
+    }\r
+\r
+    //! render OpenGL arrays\r
+    CV_EXPORTS void render(const GlArrays& arr, int mode = RenderMode::POINTS);\r
+\r
+    //! OpenGL camera\r
+    class CV_EXPORTS GlCamera\r
+    {\r
+    public:\r
+        GlCamera();\r
+\r
+        void lookAt(Point3d eye, Point3d center, Point3d up);\r
+        void setCameraPos(Point3d pos, double yaw, double pitch, double roll);\r
+\r
+        void setScale(Point3d scale);\r
+\r
+        void setProjectionMatrix(const Mat& projectionMatrix, bool transpose = true);\r
+        void setPerspectiveProjection(double fov, double aspect, double zNear, double zFar);\r
+        void setOrthoProjection(double left, double right, double bottom, double top, double zNear, double zFar);\r
+\r
+        void setupProjectionMatrix() const;\r
+        void setupModelViewMatrix() const;\r
+\r
+    private:\r
+        Point3d eye_;\r
+        Point3d center_;\r
+        Point3d up_;\r
+\r
+        Point3d pos_;\r
+        double yaw_;\r
+        double pitch_;\r
+        double roll_;\r
+\r
+        bool useLookAtParams_;\r
+\r
+        Point3d scale_;\r
+\r
+        Mat projectionMatrix_;\r
+\r
+        double fov_;\r
+        double aspect_;\r
+\r
+        double left_;\r
+        double right_;\r
+        double bottom_;\r
+        double top_;\r
+\r
+        double zNear_;\r
+        double zFar_;\r
+\r
+        bool perspectiveProjection_;\r
+    };\r
 \r
     //! OpenGL extension table\r
     class CV_EXPORTS GlFuncTab\r
     {\r
     public:\r
-        virtual ~GlFuncTab() {}\r
+        virtual ~GlFuncTab();\r
 \r
         virtual void genBuffers(int n, unsigned int* buffers) const = 0;        \r
         virtual void deleteBuffers(int n, const unsigned int* buffers) const = 0;\r
index 365f050..87b7f60 100644 (file)
@@ -52,6 +52,7 @@
 \r
 #ifdef HAVE_OPENGL\r
     #include <GL/gl.h>\r
+    #include <Gl/glu.h>\r
 \r
     #ifdef HAVE_CUDA\r
         #include <cuda_gl_interop.h>\r
@@ -982,6 +983,12 @@ namespace
     }\r
 }\r
 \r
+cv::gpu::GlFuncTab::~GlFuncTab()\r
+{\r
+    if (g_glFuncTab == this)\r
+        g_glFuncTab = 0;\r
+}\r
+\r
 void cv::gpu::setGlFuncTab(const GlFuncTab* tab)\r
 {\r
     g_glFuncTab = tab;\r
@@ -1327,7 +1334,7 @@ inline void cv::gpu::GlBuffer::Impl::unmapDevice(cudaStream_t stream)
 \r
 #endif // HAVE_OPENGL\r
 \r
-cv::gpu::GlBuffer::GlBuffer(Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage)\r
+cv::gpu::GlBuffer::GlBuffer(Usage usage) : rows(0), cols(0), type_(0), usage_(usage)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
@@ -1336,43 +1343,44 @@ cv::gpu::GlBuffer::GlBuffer(Usage usage) : rows_(0), cols_(0), type_(0), usage_(
 #endif\r
 }\r
 \r
-cv::gpu::GlBuffer::GlBuffer(int rows, int cols, int type, Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage)\r
+cv::gpu::GlBuffer::GlBuffer(int rows_, int cols_, int type, Usage usage) : rows(0), cols(0), type_(0), usage_(usage)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
-    impl_ = new Impl(rows, cols, type, usage);\r
-    rows_ = rows;\r
-    cols_ = cols;\r
+    impl_ = new Impl(rows_, cols_, type, usage);\r
+    rows = rows_;\r
+    cols = cols_;\r
     type_ = type;\r
 #endif\r
 }\r
 \r
-cv::gpu::GlBuffer::GlBuffer(Size size, int type, Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage)\r
+cv::gpu::GlBuffer::GlBuffer(Size size, int type, Usage usage) : rows(0), cols(0), type_(0), usage_(usage)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
     impl_ = new Impl(size.height, size.width, type, usage);\r
-    rows_ = size.height;\r
-    cols_ = size.width;\r
+    rows = size.height;\r
+    cols = size.width;\r
     type_ = type;\r
 #endif\r
 }\r
 \r
-cv::gpu::GlBuffer::GlBuffer(const Mat& mat, Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage)\r
+cv::gpu::GlBuffer::GlBuffer(InputArray mat_, Usage usage) : rows(0), cols(0), type_(0), usage_(usage)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
+    Mat mat = mat_.getMat();\r
     impl_ = new Impl(mat, usage);\r
-    rows_ = mat.rows;\r
-    cols_ = mat.cols;\r
+    rows = mat.rows;\r
+    cols = mat.cols;\r
     type_ = mat.type();\r
 #endif\r
 }\r
 \r
-cv::gpu::GlBuffer::GlBuffer(const GpuMat& d_mat, Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage)\r
+cv::gpu::GlBuffer::GlBuffer(const GpuMat& d_mat, Usage usage) : rows(0), cols(0), type_(0), usage_(usage)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
@@ -1382,27 +1390,42 @@ cv::gpu::GlBuffer::GlBuffer(const GpuMat& d_mat, Usage usage) : rows_(0), cols_(
     #else\r
         impl_ = new Impl(d_mat.rows, d_mat.cols, d_mat.type(), usage);\r
         impl_->copyFrom(d_mat);\r
-        rows_ = d_mat.rows;\r
-        cols_ = d_mat.cols;\r
+        rows = d_mat.rows;\r
+        cols = d_mat.cols;\r
         type_ = d_mat.type();\r
     #endif\r
 #endif\r
 }\r
 \r
+cv::gpu::GlBuffer::GlBuffer(const GlBuffer& other) \r
+    : rows(other.rows), cols(other.cols), type_(other.type_), usage_(other.usage_), impl_(other.impl_)\r
+{\r
+}\r
+\r
 cv::gpu::GlBuffer::~GlBuffer()\r
 {\r
 }\r
 \r
-void cv::gpu::GlBuffer::create(int rows, int cols, int type, Usage usage)\r
+GlBuffer& cv::gpu::GlBuffer::operator =(const GlBuffer& other)\r
+{\r
+    rows = other.rows;\r
+    cols = other.cols;\r
+    type_ = other.type_;\r
+    usage_ = other.usage_;\r
+    impl_ = other.impl_;\r
+    return *this;\r
+}\r
+\r
+void cv::gpu::GlBuffer::create(int rows_, int cols_, int type, Usage usage)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
     if (rows_ != rows || cols_ != cols || type_ != type || usage_ != usage)\r
     {\r
-        impl_ = new Impl(rows, cols, type, usage);\r
-        rows_ = rows;\r
-        cols_ = cols;\r
+        impl_ = new Impl(rows_, cols_, type, usage);\r
+        rows = rows_;\r
+        cols = cols_;\r
         type_ = type;\r
         usage_ = usage;\r
     }\r
@@ -1418,11 +1441,12 @@ void cv::gpu::GlBuffer::release()
 #endif\r
 }\r
 \r
-void cv::gpu::GlBuffer::copyFrom(const Mat& mat)\r
+void cv::gpu::GlBuffer::copyFrom(InputArray mat_)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
+    Mat mat = mat_.getMat();\r
     create(mat.rows, mat.cols, mat.type());\r
     impl_->copyFrom(mat, usage_);\r
 #endif\r
@@ -1466,7 +1490,7 @@ Mat cv::gpu::GlBuffer::mapHost()
     throw_nogl();\r
     return Mat();\r
 #else\r
-    return impl_->mapHost(rows_, cols_, type_, usage_);\r
+    return impl_->mapHost(rows, cols, type_, usage_);\r
 #endif\r
 }\r
 \r
@@ -1489,7 +1513,7 @@ GpuMat cv::gpu::GlBuffer::mapDevice()
         throw_nogpu();\r
         return GpuMat();\r
     #else\r
-        return impl_->mapDevice(rows_, cols_, type_);\r
+        return impl_->mapDevice(rows, cols, type_);\r
     #endif\r
 #endif\r
 }\r
@@ -1643,7 +1667,7 @@ cv::gpu::GlTexture::Impl::Impl(const GlBuffer& buf, bool bgra) : tex_(0)
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);\r
     CV_CheckGlError();\r
 \r
-    glTexImage2D(GL_TEXTURE_2D, 0, cn, buf.cols(), buf.rows(), 0, format, gl_types[depth], 0);\r
+    glTexImage2D(GL_TEXTURE_2D, 0, cn, buf.cols, buf.rows, 0, format, gl_types[depth], 0);\r
     CV_CheckGlError();\r
 \r
     buf.unbind();\r
@@ -1682,7 +1706,7 @@ void cv::gpu::GlTexture::Impl::copyFrom(const GlBuffer& buf, bool bgra)
     int cn = buf.channels();\r
     GLenum format = cn == 1 ? GL_LUMINANCE : (cn == 3 ? (bgra ? GL_BGR : GL_RGB) : (bgra ? GL_BGRA : GL_RGBA));\r
 \r
-    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, buf.cols(), buf.rows(), format, gl_types[buf.depth()], 0);\r
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, buf.cols, buf.rows, format, gl_types[buf.depth()], 0);\r
     CV_CheckGlError();\r
 \r
     buf.unbind();\r
@@ -1708,7 +1732,7 @@ inline void cv::gpu::GlTexture::Impl::unbind() const
 \r
 #endif // HAVE_OPENGL\r
 \r
-cv::gpu::GlTexture::GlTexture() : rows_(0), cols_(0), type_(0)\r
+cv::gpu::GlTexture::GlTexture() : rows(0), cols(0), type_(0)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
@@ -1717,68 +1741,83 @@ cv::gpu::GlTexture::GlTexture() : rows_(0), cols_(0), type_(0)
 #endif\r
 }\r
 \r
-cv::gpu::GlTexture::GlTexture(int rows, int cols, int type) : rows_(0), cols_(0), type_(0)\r
+cv::gpu::GlTexture::GlTexture(int rows_, int cols_, int type) : rows(0), cols(0), type_(0)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
-    impl_ = new Impl(rows, cols, type);\r
-    rows_ = rows;\r
-    cols_ = cols;\r
+    impl_ = new Impl(rows_, cols_, type);\r
+    rows = rows_;\r
+    cols = cols_;\r
     type_ = type;\r
 #endif\r
 }\r
 \r
-cv::gpu::GlTexture::GlTexture(Size size, int type) : rows_(0), cols_(0), type_(0)\r
+cv::gpu::GlTexture::GlTexture(Size size, int type) : rows(0), cols(0), type_(0)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
     impl_ = new Impl(size.height, size.width, type);\r
-    rows_ = size.height;\r
-    cols_ = size.width;\r
+    rows = size.height;\r
+    cols = size.width;\r
     type_ = type;\r
 #endif\r
 }\r
 \r
-cv::gpu::GlTexture::GlTexture(const Mat& mat, bool bgra) : rows_(0), cols_(0), type_(0)\r
+cv::gpu::GlTexture::GlTexture(InputArray mat_, bool bgra) : rows(0), cols(0), type_(0)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
+    Mat mat = mat_.getMat();\r
     impl_ = new Impl(mat, bgra);\r
-    rows_ = mat.rows;\r
-    cols_ = mat.cols;\r
+    rows = mat.rows;\r
+    cols = mat.cols;\r
     type_ = mat.type();\r
 #endif\r
 }\r
 \r
-cv::gpu::GlTexture::GlTexture(const GlBuffer& buf, bool bgra) : rows_(0), cols_(0), type_(0)\r
+cv::gpu::GlTexture::GlTexture(const GlBuffer& buf, bool bgra) : rows(0), cols(0), type_(0)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
     impl_ = new Impl(buf, bgra);\r
-    rows_ = buf.rows();\r
-    cols_ = buf.cols();\r
+    rows = buf.rows;\r
+    cols = buf.cols;\r
     type_ = buf.type();\r
 #endif\r
 }\r
 \r
+cv::gpu::GlTexture::GlTexture(const GlTexture& other) \r
+    : rows(other.rows), cols(other.cols), type_(other.type_), impl_(other.impl_)\r
+{\r
+}\r
+\r
 cv::gpu::GlTexture::~GlTexture()\r
 {\r
 }\r
 \r
-void cv::gpu::GlTexture::create(int rows, int cols, int type)\r
+GlTexture& cv::gpu::GlTexture::operator =(const GlTexture& other)\r
+{\r
+    rows = other.rows;\r
+    cols = other.cols;\r
+    type_ = other.type_;\r
+    impl_ = other.impl_;\r
+    return *this;\r
+}\r
+\r
+void cv::gpu::GlTexture::create(int rows_, int cols_, int type)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
     if (rows_ != rows || cols_ != cols || type_ != type)\r
     {\r
-        impl_ = new Impl(rows, cols, type);\r
-        rows_ = rows;\r
-        cols_ = cols;\r
+        impl_ = new Impl(rows_, cols_, type);\r
+        rows = rows_;\r
+        cols = cols_;\r
         type_ = type;\r
     }\r
 #endif\r
@@ -1793,11 +1832,12 @@ void cv::gpu::GlTexture::release()
 #endif\r
 }\r
 \r
-void cv::gpu::GlTexture::copyFrom(const Mat& mat, bool bgra)\r
+void cv::gpu::GlTexture::copyFrom(InputArray mat_, bool bgra)\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
+    Mat mat = mat_.getMat();\r
     create(mat.rows, mat.cols, mat.type());\r
     impl_->copyFrom(mat, bgra);\r
 #endif\r
@@ -1808,7 +1848,7 @@ void cv::gpu::GlTexture::copyFrom(const GlBuffer& buf, bool bgra)
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
-    create(buf.rows(), buf.cols(), buf.type());\r
+    create(buf.rows, buf.cols, buf.type());\r
     impl_->copyFrom(buf, bgra);\r
 #endif\r
 }\r
@@ -1832,40 +1872,268 @@ void cv::gpu::GlTexture::unbind() const
 }\r
 \r
 ////////////////////////////////////////////////////////////////////////\r
-// Rendering\r
+// GlArrays\r
+\r
+void cv::gpu::GlArrays::setVertexArray(const GlBuffer& vertex) \r
+{ \r
+    CV_Assert(vertex.usage() == GlBuffer::ARRAY_BUFFER);\r
+\r
+    int cn = vertex.channels();\r
+    int depth = vertex.depth();\r
 \r
-void cv::gpu::render(const GlTexture& tex)\r
+    CV_Assert(cn == 2 || cn == 3 || cn == 4);\r
+    CV_Assert(depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F);\r
+\r
+    vertex_ = vertex; \r
+}\r
+\r
+void cv::gpu::GlArrays::setVertexArray(const GpuMat& vertex) \r
+{ \r
+    int cn = vertex.channels();\r
+    int depth = vertex.depth();\r
+\r
+    CV_Assert(cn == 2 || cn == 3 || cn == 4);\r
+    CV_Assert(depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F);\r
+\r
+    vertex_.copyFrom(vertex); \r
+}\r
+\r
+void cv::gpu::GlArrays::setVertexArray(InputArray vertex) \r
+{ \r
+    int cn = vertex.channels();\r
+    int depth = vertex.depth();\r
+\r
+    CV_Assert(cn == 2 || cn == 3 || cn == 4);\r
+    CV_Assert(depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F);\r
+\r
+    vertex_.copyFrom(vertex); \r
+}\r
+\r
+void cv::gpu::GlArrays::setColorArray(const GlBuffer& color, bool bgra) \r
+{ \r
+    CV_Assert(color.usage() == GlBuffer::ARRAY_BUFFER);\r
+\r
+    int cn = color.channels();\r
+\r
+    CV_Assert((cn == 3 && !bgra) || cn == 4);\r
+\r
+    color_ = color; \r
+    bgra_ = bgra; \r
+}\r
+\r
+void cv::gpu::GlArrays::setColorArray(const GpuMat& color, bool bgra) \r
+{ \r
+    int cn = color.channels();\r
+\r
+    CV_Assert((cn == 3 && !bgra) || cn == 4);\r
+\r
+    color_.copyFrom(color); \r
+    bgra_ = bgra; \r
+}\r
+\r
+void cv::gpu::GlArrays::setColorArray(InputArray color, bool bgra) \r
+{ \r
+    int cn = color.channels();\r
+\r
+    CV_Assert((cn == 3 && !bgra) || cn == 4);\r
+\r
+    color_.copyFrom(color); \r
+    bgra_ = bgra; \r
+}\r
+\r
+void cv::gpu::GlArrays::setNormalArray(const GlBuffer& normal) \r
+{ \r
+    CV_Assert(normal.usage() == GlBuffer::ARRAY_BUFFER);\r
+\r
+    int cn = normal.channels();\r
+    int depth = normal.depth();\r
+\r
+    CV_Assert(cn == 3);\r
+    CV_Assert(depth == CV_8S || depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F);\r
+\r
+    normal_ = normal; \r
+}\r
+\r
+void cv::gpu::GlArrays::setNormalArray(const GpuMat& normal) \r
+{ \r
+    int cn = normal.channels();\r
+    int depth = normal.depth();\r
+\r
+    CV_Assert(cn == 3);\r
+    CV_Assert(depth == CV_8S || depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F);\r
+\r
+    normal_.copyFrom(normal); \r
+}\r
+\r
+void cv::gpu::GlArrays::setNormalArray(InputArray normal) \r
+{ \r
+    int cn = normal.channels();\r
+    int depth = normal.depth();\r
+\r
+    CV_Assert(cn == 3);\r
+    CV_Assert(depth == CV_8S || depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F);\r
+\r
+    normal_.copyFrom(normal); \r
+}\r
+\r
+void cv::gpu::GlArrays::setTexCoordArray(const GlBuffer& texCoord) \r
+{ \r
+    CV_Assert(texCoord.usage() == GlBuffer::ARRAY_BUFFER);\r
+\r
+    int cn = texCoord.channels();\r
+    int depth = texCoord.depth();\r
+\r
+    CV_Assert(cn >= 1 && cn <= 4);\r
+    CV_Assert(depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F);\r
+\r
+    texCoord_ = texCoord; \r
+}\r
+\r
+void cv::gpu::GlArrays::setTexCoordArray(const GpuMat& texCoord) \r
+{ \r
+    int cn = texCoord.channels();\r
+    int depth = texCoord.depth();\r
+\r
+    CV_Assert(cn >= 1 && cn <= 4);\r
+    CV_Assert(depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F);\r
+\r
+    texCoord_.copyFrom(texCoord); \r
+}\r
+\r
+void cv::gpu::GlArrays::setTexCoordArray(InputArray texCoord) \r
+{ \r
+    int cn = texCoord.channels();\r
+    int depth = texCoord.depth();\r
+\r
+    CV_Assert(cn >= 1 && cn <= 4);\r
+    CV_Assert(depth == CV_16S || depth == CV_32S || depth == CV_32F || depth == CV_64F);\r
+\r
+    texCoord_.copyFrom(texCoord); \r
+}\r
+\r
+void cv::gpu::GlArrays::bind() const\r
 {\r
 #ifndef HAVE_OPENGL\r
     throw_nogl();\r
 #else\r
-    if (!tex.empty())\r
+    CV_DbgAssert(texCoord_.empty() || texCoord_.size().area() == vertex_.size().area());\r
+    CV_DbgAssert(normal_.empty() || normal_.size().area() == vertex_.size().area());\r
+    CV_DbgAssert(color_.empty() || color_.size().area() == vertex_.size().area());\r
+\r
+    if (!texCoord_.empty())\r
     {\r
-        tex.bind();\r
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);\r
+        CV_CheckGlError();\r
 \r
-        glDisable(GL_DEPTH_TEST);\r
+        texCoord_.bind();\r
 \r
-        glMatrixMode(GL_PROJECTION);\r
-        glLoadIdentity();\r
-        glOrtho(0, 1, 1, 0, -1, 1);\r
+        glTexCoordPointer(texCoord_.channels(), gl_types[texCoord_.depth()], 0, 0);\r
+        CV_CheckGlError();\r
 \r
-        glMatrixMode(GL_MODELVIEW);\r
-        glLoadIdentity();\r
+        texCoord_.unbind();\r
+    }\r
 \r
-        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);\r
+    if (!normal_.empty())\r
+    {\r
+        glEnableClientState(GL_NORMAL_ARRAY);\r
+        CV_CheckGlError();\r
 \r
-        glBegin(GL_QUADS);\r
-            glVertex2d(0.0, 0.0);\r
-            glTexCoord2d(1.0, 0.0);     \r
+        normal_.bind();\r
 \r
-            glVertex2d(1.0, 0.0);\r
-            glTexCoord2d(1.0, 1.0);\r
+        glNormalPointer(gl_types[normal_.depth()], 0, 0);\r
+        CV_CheckGlError();\r
 \r
-            glVertex2d(1.0, 1.0);\r
-            glTexCoord2d(0.0, 1.0);     \r
+        normal_.unbind();\r
+    }\r
+\r
+    if (!color_.empty())\r
+    {\r
+        glEnableClientState(GL_COLOR_ARRAY);\r
+        CV_CheckGlError();\r
+\r
+        color_.bind();\r
+\r
+        int cn = color_.channels();\r
+        int format = cn == 3 ? cn : (bgra_ ? GL_BGRA : 4); \r
+\r
+        glColorPointer(format, gl_types[color_.depth()], 0, 0);\r
+        CV_CheckGlError();\r
+\r
+        color_.unbind();\r
+    }\r
+\r
+    if (!vertex_.empty())\r
+    {\r
+        glEnableClientState(GL_VERTEX_ARRAY);\r
+        CV_CheckGlError();\r
+\r
+        vertex_.bind();\r
+\r
+        glVertexPointer(vertex_.channels(), gl_types[vertex_.depth()], 0, 0);\r
+        CV_CheckGlError();\r
 \r
-            glVertex2d(0.0, 1.0);\r
-            glTexCoord2d(0.0, 0.0);    \r
+        vertex_.unbind();\r
+    }\r
+#endif\r
+}\r
+\r
+void cv::gpu::GlArrays::unbind() const\r
+{\r
+#ifndef HAVE_OPENGL\r
+    throw_nogl();\r
+#else\r
+    if (!texCoord_.empty())\r
+    {\r
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);\r
+        CV_CheckGlError();\r
+    }\r
+\r
+    if (!normal_.empty())\r
+    {\r
+        glDisableClientState(GL_NORMAL_ARRAY);\r
+        CV_CheckGlError();\r
+    }\r
+\r
+    if (!color_.empty())\r
+    {\r
+        glDisableClientState(GL_COLOR_ARRAY);\r
+        CV_CheckGlError();\r
+    }\r
+\r
+    if (!vertex_.empty())\r
+    {\r
+        glDisableClientState(GL_VERTEX_ARRAY);\r
+        CV_CheckGlError();\r
+    }\r
+#endif\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Rendering\r
+\r
+void cv::gpu::render(const GlTexture& tex, Rect_<double> wndRect, Rect_<double> texRect)\r
+{\r
+#ifndef HAVE_OPENGL\r
+    throw_nogl();\r
+#else\r
+    if (!tex.empty())\r
+    {\r
+        tex.bind();\r
+\r
+        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);\r
+\r
+        glBegin(GL_QUADS);\r
+            glTexCoord2d(texRect.x, texRect.y);\r
+            glVertex2d(wndRect.x, wndRect.y);\r
+            \r
+            glTexCoord2d(texRect.x, texRect.y + texRect.height);\r
+            glVertex2d(wndRect.x, (wndRect.y + wndRect.height));\r
+            \r
+            glTexCoord2d(texRect.x + texRect.width, texRect.y + texRect.height);\r
+            glVertex2d(wndRect.x + wndRect.width, (wndRect.y + wndRect.height));\r
+            \r
+            glTexCoord2d(texRect.x + texRect.width, texRect.y);\r
+            glVertex2d(wndRect.x + wndRect.width, wndRect.y);\r
         glEnd();\r
 \r
         CV_CheckGlError();\r
@@ -1875,6 +2143,142 @@ void cv::gpu::render(const GlTexture& tex)
 #endif\r
 }\r
 \r
+void cv::gpu::render(const GlArrays& arr, int mode)\r
+{\r
+#ifndef HAVE_OPENGL\r
+    throw_nogl();\r
+#else\r
+    arr.bind();\r
+\r
+    glDrawArrays(mode, 0, arr.size().area());\r
+\r
+    arr.unbind();\r
+#endif\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// GlCamera\r
+\r
+cv::gpu::GlCamera::GlCamera() : \r
+    eye_(0.0, 0.0, -5.0), center_(0.0, 0.0, 0.0), up_(0.0, 1.0, 0.0),\r
+    pos_(0.0, 0.0, -5.0), yaw_(0.0), pitch_(0.0), roll_(0.0),\r
+    useLookAtParams_(false),\r
+\r
+    scale_(1.0, 1.0, 1.0),\r
+\r
+    projectionMatrix_(),\r
+    fov_(45.0), aspect_(0.0),\r
+    left_(0.0), right_(1.0), bottom_(1.0), top_(0.0),\r
+    zNear_(-1.0), zFar_(1.0),\r
+    perspectiveProjection_(false)\r
+{\r
+}\r
+\r
+void cv::gpu::GlCamera::lookAt(Point3d eye, Point3d center, Point3d up)\r
+{\r
+    eye_ = eye;\r
+    center_ = center;\r
+    up_ = up;\r
+    useLookAtParams_ = true;\r
+}\r
+\r
+void cv::gpu::GlCamera::setCameraPos(Point3d pos, double yaw, double pitch, double roll)\r
+{\r
+    pos_ = pos;\r
+    yaw_ = yaw;\r
+    pitch_ = pitch;\r
+    roll_ = roll;\r
+    useLookAtParams_ = false;\r
+}\r
+\r
+void cv::gpu::GlCamera::setScale(Point3d scale)\r
+{\r
+    scale_ = scale;\r
+}\r
+\r
+void cv::gpu::GlCamera::setProjectionMatrix(const Mat& projectionMatrix, bool transpose)\r
+{\r
+    CV_Assert(projectionMatrix.type() == CV_32F || projectionMatrix.type() == CV_64F);\r
+    CV_Assert(projectionMatrix.cols == 4 && projectionMatrix.rows == 4);\r
+\r
+    projectionMatrix_ = transpose ? projectionMatrix.t() : projectionMatrix;\r
+}\r
+\r
+void cv::gpu::GlCamera::setPerspectiveProjection(double fov, double aspect, double zNear, double zFar)\r
+{\r
+    fov_ = fov;\r
+    aspect_ = aspect;\r
+    zNear_ = zNear;\r
+    zFar_ = zFar;\r
+\r
+    projectionMatrix_.release();\r
+    perspectiveProjection_ = true;\r
+}\r
+\r
+void cv::gpu::GlCamera::setOrthoProjection(double left, double right, double bottom, double top, double zNear, double zFar)\r
+{\r
+    left_ = left;\r
+    right_ = right;\r
+    bottom_ = bottom;\r
+    top_ = top;\r
+    zNear_ = zNear;\r
+    zFar_ = zFar;\r
+\r
+    projectionMatrix_.release();\r
+    perspectiveProjection_ = false;\r
+}\r
+\r
+void cv::gpu::GlCamera::setupProjectionMatrix() const\r
+{\r
+#ifndef HAVE_OPENGL\r
+    throw_nogl();\r
+#else\r
+    glMatrixMode(GL_PROJECTION);\r
+    glLoadIdentity();\r
+\r
+    if (projectionMatrix_.empty())\r
+    {\r
+        if (perspectiveProjection_)\r
+            gluPerspective(fov_, aspect_, zNear_, zFar_);\r
+        else\r
+            glOrtho(left_, right_, bottom_, top_, zNear_, zFar_);\r
+    }\r
+    else\r
+    {\r
+        if (projectionMatrix_.type() == CV_32F)\r
+            glLoadMatrixf(projectionMatrix_.ptr<float>());\r
+        else\r
+            glLoadMatrixd(projectionMatrix_.ptr<double>());\r
+    }\r
+\r
+    CV_CheckGlError();\r
+#endif\r
+}\r
+\r
+void cv::gpu::GlCamera::setupModelViewMatrix() const\r
+{\r
+#ifndef HAVE_OPENGL\r
+    throw_nogl();\r
+#else\r
+    glMatrixMode(GL_MODELVIEW);\r
+    glLoadIdentity();\r
+\r
+    if (useLookAtParams_)\r
+        gluLookAt(eye_.x, eye_.y, eye_.z, center_.x, center_.y, center_.z, up_.x, up_.y, up_.z);\r
+    else\r
+    {\r
+        glRotated(-yaw_, 0.0, 1.0, 0.0);\r
+        glRotated(-pitch_, 1.0, 0.0, 0.0);\r
+        glRotated(-roll_, 0.0, 0.0, 1.0);\r
+        glTranslated(-pos_.x, -pos_.y, -pos_.z);\r
+    }\r
+\r
+    glScaled(scale_.x, scale_.y, scale_.z);\r
+\r
+    CV_CheckGlError();\r
+#endif\r
+}\r
+\r
 ////////////////////////////////////////////////////////////////////////\r
 // Error handling\r
 \r
index 0452e0d..5dbad1b 100644 (file)
@@ -139,12 +139,17 @@ CV_EXPORTS void setOpenGlContext(const string& winname);
 
 CV_EXPORTS void updateWindow(const string& winname);
 
-CV_EXPORTS void imshow(const string& winname, const gpu::GpuMat& d_mat);
-
-CV_EXPORTS void imshow(const string& winname, const gpu::GlBuffer& buf);
-
 CV_EXPORTS void imshow(const string& winname, const gpu::GlTexture& tex);
+CV_EXPORTS void imshow(const string& winname, const gpu::GlBuffer& buf);
+CV_EXPORTS void imshow(const string& winname, const gpu::GpuMat& d_mat);
 
+CV_EXPORTS void pointCloudShow(const string& winname, const gpu::GlCamera& camera, const gpu::GlArrays& arr);
+CV_EXPORTS void pointCloudShow(const string& winname, const gpu::GlCamera& camera, const gpu::GlBuffer& points, 
+                               const gpu::GlBuffer& colors = gpu::GlBuffer(gpu::GlBuffer::ARRAY_BUFFER));
+CV_EXPORTS void pointCloudShow(const string& winname, const gpu::GlCamera& camera, const gpu::GpuMat& points, 
+                               const gpu::GpuMat& colors = gpu::GpuMat());
+CV_EXPORTS void pointCloudShow(const string& winname, const gpu::GlCamera& camera, InputArray points, 
+                               InputArray colors = InputArray());
 
 //Only for Qt
 
index ddf615f..556a7af 100644 (file)
@@ -228,6 +228,7 @@ void cv::updateWindow(const string& windowName)
 namespace
 {
     const int CV_TEXTURE_MAGIC_VAL        = 0x00287653;
+    const int CV_POINT_CLOUD_MAGIC_VAL    = 0x00287654;
 
     struct GlObjBase
     {
@@ -273,19 +274,40 @@ namespace
         delete glObj;
     }
 
-    template <typename T>
-    struct GlObj : GlObjBase
+    struct GlObjTex : GlObjBase
     {
-        T obj;
+        cv::gpu::GlTexture tex;
     };
 
     void CV_CDECL glDrawTextureCallback(void* userdata)
     {
-        GlObj<cv::gpu::GlTexture>* texObj = static_cast<GlObj<cv::gpu::GlTexture>*>(userdata);
+        GlObjTex* texObj = static_cast<GlObjTex*>(userdata);
 
         CV_DbgAssert(texObj->flag == CV_TEXTURE_MAGIC_VAL);
 
-        cv::gpu::render(texObj->obj);
+        static cv::gpu::GlCamera glCamera;
+
+        glCamera.setupProjectionMatrix();
+
+        cv::gpu::render(texObj->tex);
+    }
+
+    struct GlObjPointCloud : GlObjBase
+    {
+        cv::gpu::GlArrays arr;
+        cv::gpu::GlCamera camera;
+    };
+
+    void CV_CDECL glDrawPointCloudCallback(void* userdata)
+    {
+        GlObjPointCloud* pointCloudObj = static_cast<GlObjPointCloud*>(userdata);
+
+        CV_DbgAssert(pointCloudObj->flag == CV_POINT_CLOUD_MAGIC_VAL);
+
+        pointCloudObj->camera.setupProjectionMatrix();
+        pointCloudObj->camera.setupModelViewMatrix();
+
+        cv::gpu::render(pointCloudObj->arr);
     }
 
     void CV_CDECL glCleanCallback(void* userdata)
@@ -297,22 +319,16 @@ namespace
 }
 #endif // HAVE_OPENGL
 
-void cv::imshow( const string& winname, InputArray _img )
-{
-    Mat img = _img.getMat();
+#ifdef HAVE_OPENGL
 
-#ifndef HAVE_OPENGL
-    CvMat c_img = img;
-    cvShowImage(winname.c_str(), &c_img);
-#else
-    double useGl = getWindowProperty(winname, WND_PROP_OPENGL);
-    if (useGl <= 0)
-    {
-        CvMat c_img = img;
-        cvShowImage(winname.c_str(), &c_img);
-    }
-    else
+namespace
+{
+    template <typename T> void imshowImpl(const std::string& winname, const T& img)
     {
+        using namespace cv;
+
+        namedWindow(winname, WINDOW_OPENGL | WINDOW_AUTOSIZE);
+
         double autoSize = getWindowProperty(winname, WND_PROP_AUTOSIZE);
 
         if (autoSize > 0)
@@ -330,13 +346,13 @@ void cv::imshow( const string& winname, InputArray _img )
 
         if (glObj)
         {
-            GlObj<cv::gpu::GlTexture>* texObj = static_cast<GlObj<cv::gpu::GlTexture>*>(glObj);
-            texObj->obj.copyFrom(img);
+            GlObjTex* texObj = static_cast<GlObjTex*>(glObj);
+            texObj->tex.copyFrom(img);
         }
         else
         {
-            GlObj<cv::gpu::GlTexture>* texObj = new GlObj<cv::gpu::GlTexture>;
-            texObj->obj.copyFrom(img);
+            GlObjTex* texObj = new GlObjTex;
+            texObj->tex.copyFrom(img);
 
             glObj = texObj;
             glObj->flag = CV_TEXTURE_MAGIC_VAL;
@@ -351,6 +367,28 @@ void cv::imshow( const string& winname, InputArray _img )
 
         updateWindow(winname);
     }
+} 
+
+#endif // HAVE_OPENGL
+
+void cv::imshow( const string& winname, InputArray _img )
+{
+    Mat img = _img.getMat();
+
+#ifndef HAVE_OPENGL
+    CvMat c_img = img;
+    cvShowImage(winname.c_str(), &c_img);
+#else
+    double useGl = getWindowProperty(winname, WND_PROP_OPENGL);
+    if (useGl <= 0)
+    {
+        CvMat c_img = img;
+        cvShowImage(winname.c_str(), &c_img);
+    }
+    else
+    {
+        imshowImpl(winname, img);
+    }
 #endif
 }
 
@@ -359,14 +397,32 @@ void cv::imshow(const string& winname, const gpu::GlBuffer& buf)
 #ifndef HAVE_OPENGL
     CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); 
 #else
-    CV_Assert(buf.usage() == gpu::GlBuffer::TEXTURE_BUFFER);
+    imshowImpl(winname, buf);
+#endif
+}
 
+void cv::imshow(const string& winname, const gpu::GpuMat& d_mat)
+{
+#ifndef HAVE_OPENGL
+    CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); 
+#else
+    setOpenGlContext(winname);
+    gpu::GlBuffer buf(d_mat, gpu::GlBuffer::TEXTURE_BUFFER);
+    imshow(winname, buf);
+#endif
+}
+
+void cv::imshow(const string& winname, const gpu::GlTexture& tex)
+{
+#ifndef HAVE_OPENGL
+    CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); 
+#else
     namedWindow(winname, WINDOW_OPENGL | WINDOW_AUTOSIZE);
 
     double autoSize = getWindowProperty(winname, WND_PROP_AUTOSIZE);
 
     if (autoSize > 0)
-        resizeWindow(winname, buf.cols(), buf.rows());
+        resizeWindow(winname, tex.cols, tex.rows);
 
     setOpenGlContext(winname);
 
@@ -380,13 +436,13 @@ void cv::imshow(const string& winname, const gpu::GlBuffer& buf)
 
     if (glObj)
     {
-        GlObj<cv::gpu::GlTexture>* texObj = static_cast<GlObj<cv::gpu::GlTexture>*>(glObj);
-        texObj->obj.copyFrom(buf);
+        GlObjTex* texObj = static_cast<GlObjTex*>(glObj);
+        texObj->tex = tex;
     }
     else
     {
-        GlObj<cv::gpu::GlTexture>* texObj = new GlObj<cv::gpu::GlTexture>;
-        texObj->obj.copyFrom(buf);
+        GlObjTex* texObj = new GlObjTex;
+        texObj->tex = tex;
 
         glObj = texObj;
         glObj->flag = CV_TEXTURE_MAGIC_VAL;
@@ -395,7 +451,7 @@ void cv::imshow(const string& winname, const gpu::GlBuffer& buf)
         addGlObj(glObj);
 
         icvSetOpenGlCleanCallback(winname.c_str(), glCleanCallback, glObj);
-    }        
+    }
 
     setOpenGlDrawCallback(winname, glDrawTextureCallback, glObj);
 
@@ -403,34 +459,18 @@ void cv::imshow(const string& winname, const gpu::GlBuffer& buf)
 #endif
 }
 
-void cv::imshow(const string& winname, const gpu::GpuMat& d_mat)
-{
+void cv::pointCloudShow(const string& winname, const gpu::GlCamera& camera, const gpu::GlArrays& arr)
+{    
 #ifndef HAVE_OPENGL
     CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); 
 #else
-    setOpenGlContext(winname);
-    gpu::GlBuffer buf(d_mat, gpu::GlBuffer::TEXTURE_BUFFER);
-    imshow(winname, buf);
-#endif
-}
-
-void cv::imshow(const string& winname, const gpu::GlTexture& tex)
-{
-#ifndef HAVE_OPENGL
-    CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); 
-#else
-    namedWindow(winname, WINDOW_OPENGL | WINDOW_AUTOSIZE);
-
-    double autoSize = getWindowProperty(winname, WND_PROP_AUTOSIZE);
-
-    if (autoSize > 0)
-        resizeWindow(winname, tex.cols(), tex.rows());
+    namedWindow(winname, WINDOW_OPENGL);
 
     setOpenGlContext(winname);
 
     GlObjBase* glObj = findGlObjByName(winname);
 
-    if (glObj && glObj->flag != CV_TEXTURE_MAGIC_VAL)
+    if (glObj && glObj->flag != CV_POINT_CLOUD_MAGIC_VAL)
     {
         icvSetOpenGlCleanCallback(winname.c_str(), 0, 0);
         glObj = 0;
@@ -438,16 +478,18 @@ void cv::imshow(const string& winname, const gpu::GlTexture& tex)
 
     if (glObj)
     {
-        GlObj<cv::gpu::GlTexture>* texObj = static_cast<GlObj<cv::gpu::GlTexture>*>(glObj);
-        texObj->obj = tex;
+        GlObjPointCloud* pointCloudObj = static_cast<GlObjPointCloud*>(glObj);
+        pointCloudObj->arr = arr;
+        pointCloudObj->camera = camera;
     }
     else
     {
-        GlObj<cv::gpu::GlTexture>* texObj = new GlObj<cv::gpu::GlTexture>;
-        texObj->obj = tex;
+        GlObjPointCloud* pointCloudObj = new GlObjPointCloud;
+        pointCloudObj->arr = arr;
+        pointCloudObj->camera = camera;
 
-        glObj = texObj;
-        glObj->flag = CV_TEXTURE_MAGIC_VAL;
+        glObj = pointCloudObj;
+        glObj->flag = CV_POINT_CLOUD_MAGIC_VAL;
         glObj->winname = winname;
 
         addGlObj(glObj);
@@ -455,12 +497,98 @@ void cv::imshow(const string& winname, const gpu::GlTexture& tex)
         icvSetOpenGlCleanCallback(winname.c_str(), glCleanCallback, glObj);
     }
 
-    setOpenGlDrawCallback(winname, glDrawTextureCallback, glObj);
+    setOpenGlDrawCallback(winname, glDrawPointCloudCallback, glObj);
 
     updateWindow(winname);
 #endif
 }
 
+#ifdef HAVE_OPENGL
+
+namespace
+{
+    template <typename T> void pointCloudShowImpl(const std::string& winname, const cv::gpu::GlCamera& camera, const T& points, const T& colors)
+    {
+        using namespace cv;
+
+        namedWindow(winname, WINDOW_OPENGL);
+
+        setOpenGlContext(winname);
+
+        GlObjBase* glObj = findGlObjByName(winname);
+
+        if (glObj && glObj->flag != CV_POINT_CLOUD_MAGIC_VAL)
+        {
+            icvSetOpenGlCleanCallback(winname.c_str(), 0, 0);
+            glObj = 0;
+        }
+
+        if (glObj)
+        {
+            GlObjPointCloud* pointCloudObj = static_cast<GlObjPointCloud*>(glObj);
+
+            pointCloudObj->arr.setVertexArray(points);
+            if (colors.empty())
+                pointCloudObj->arr.resetColorArray();
+            else
+                pointCloudObj->arr.setColorArray(colors);
+
+            pointCloudObj->camera = camera;
+        }
+        else
+        {
+            GlObjPointCloud* pointCloudObj = new GlObjPointCloud;
+
+            pointCloudObj->arr.setVertexArray(points);
+            if (!colors.empty())
+                pointCloudObj->arr.setColorArray(colors);
+
+            pointCloudObj->camera = camera;
+
+            glObj = pointCloudObj;
+            glObj->flag = CV_POINT_CLOUD_MAGIC_VAL;
+            glObj->winname = winname;
+
+            addGlObj(glObj);
+
+            icvSetOpenGlCleanCallback(winname.c_str(), glCleanCallback, glObj);
+        }
+
+        setOpenGlDrawCallback(winname, glDrawPointCloudCallback, glObj);
+
+        updateWindow(winname);
+    }
+}
+
+#endif // HAVE_OPENGL
+
+void cv::pointCloudShow(const string& winname, const gpu::GlCamera& camera, const gpu::GlBuffer& points, const gpu::GlBuffer& colors)
+{    
+#ifndef HAVE_OPENGL
+    CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); 
+#else
+    pointCloudShowImpl(winname, camera, points, colors);
+#endif
+}
+
+void cv::pointCloudShow(const string& winname, const gpu::GlCamera& camera, const gpu::GpuMat& points, const gpu::GpuMat& colors)
+{    
+#ifndef HAVE_OPENGL
+    CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); 
+#else
+    pointCloudShowImpl(winname, camera, points, colors);
+#endif
+}
+
+void cv::pointCloudShow(const string& winname, const gpu::GlCamera& camera, InputArray points, InputArray colors)
+{    
+#ifndef HAVE_OPENGL
+    CV_Error(CV_OpenGlNotSupported, "The library is compiled without OpenGL support"); 
+#else
+    pointCloudShowImpl(winname, camera, points, colors);
+#endif
+}
+
 #ifndef HAVE_OPENGL
 
 CV_IMPL void cvCreateOpenGLCallback(const char*, CvOpenGLCallback, void*, double, double, double)
index e42dd14..57a6a57 100644 (file)
@@ -405,12 +405,12 @@ double cvGetModeWindow_W32(const char* name)//YV
 
     CvWindow* window;
 
-    if(!name)
+    if (!name)
         CV_ERROR( CV_StsNullPtr, "NULL name string" );
 
     window = icvFindWindowByName( name );
-    if( !window )
-        CV_ERROR( CV_StsNullPtr, "NULL window" );
+    if (!window)
+        EXIT; // keep silence here
         
     result = window->status;
         
@@ -503,7 +503,7 @@ double cvGetPropWindowAutoSize_W32(const char* name)
 
     window = icvFindWindowByName( name );
     if (!window)
-        EXIT;
+        EXIT; // keep silence here
 
     result = window->flags & CV_WINDOW_AUTOSIZE;
 
@@ -527,7 +527,7 @@ double cvGetRatioWindow_W32(const char* name)
 
     window = icvFindWindowByName( name );
     if (!window)
-        CV_ERROR( CV_StsNullPtr, "NULL window" );
+        EXIT; // keep silence here
         
     result = static_cast<double>(window->width) / window->height;
         
@@ -552,7 +552,7 @@ double cvGetOpenGlProp_W32(const char* name)
 
     window = icvFindWindowByName( name );
     if (!window)
-        __CV_EXIT__;
+        EXIT; // keep silence here
         
     result = window->useGl;
         
@@ -808,7 +808,7 @@ namespace
             0,                             // Shift Bit Ignored
             0,                             // No Accumulation Buffer
             0, 0, 0, 0,                    // Accumulation Bits Ignored
-            16,                            // 16Bit Z-Buffer (Depth Buffer)  
+            32,                            // 32 Bit Z-Buffer (Depth Buffer)  
             0,                             // No Stencil Buffer
             0,                             // No Auxiliary Buffer
             PFD_MAIN_PLANE,                // Main Drawing Layer
@@ -845,6 +845,8 @@ namespace
 
         __BEGIN__;
 
+        delete window->glFuncTab;
+
         if (window->hGLRC)
         {
             wglDeleteContext(window->hGLRC);
@@ -1177,9 +1179,6 @@ static void icvRemoveWindow( CvWindow* window )
 #ifdef HAVE_OPENGL
     if (window->useGl)
     {
-        delete window->glFuncTab;
-         cv::gpu::setGlFuncTab(0);
-
         wglMakeCurrent(window->dc, window->hGLRC);
 
         if (window->glCleanCallback)
diff --git a/samples/cpp/point_cloud.cpp b/samples/cpp/point_cloud.cpp
new file mode 100644 (file)
index 0000000..27eec1c
--- /dev/null
@@ -0,0 +1,255 @@
+#include <cstring>\r
+#include <cmath>\r
+#include <iostream>\r
+#include "opencv2/core/core.hpp"\r
+#include "opencv2/core/gpumat.hpp"\r
+#include "opencv2/highgui/highgui.hpp"\r
+#include "opencv2/imgproc/imgproc.hpp"\r
+#include "opencv2/calib3d/calib3d.hpp"\r
+\r
+using namespace std;\r
+using namespace cv;\r
+using namespace cv::gpu;\r
+\r
+void mouseCallback(int event, int x, int y, int flags, void* userdata)\r
+{\r
+    int* dx = static_cast<int*>(userdata);\r
+    int* dy = dx + 1;\r
+\r
+    static int oldx = x;\r
+    static int oldy = y;\r
+    static bool moving = false;\r
+\r
+    if (event == EVENT_LBUTTONDOWN)\r
+    {\r
+        oldx = x;\r
+        oldy = y;\r
+        moving = true;\r
+    }\r
+    else if (event == EVENT_LBUTTONUP)\r
+    {\r
+        moving = false;\r
+    }\r
+\r
+    if (moving)\r
+    {\r
+        *dx = oldx - x;\r
+        *dy = oldy - y;\r
+    }\r
+    else\r
+    {\r
+        *dx = 0;\r
+        *dy = 0;\r
+    }\r
+}\r
+\r
+inline int clamp(int val, int minVal, int maxVal)\r
+{\r
+    return max(min(val, maxVal), minVal);\r
+}\r
+\r
+Point3d rotate(Point3d v, double yaw, double pitch)\r
+{\r
+    Point3d t1;\r
+    t1.x = v.x * cos(-yaw / 180.0 * CV_PI) - v.z * sin(-yaw / 180.0 * CV_PI);\r
+    t1.y = v.y;\r
+    t1.z = v.x * sin(-yaw / 180.0 * CV_PI) + v.z * cos(-yaw / 180.0 * CV_PI);\r
+\r
+    Point3d t2;\r
+    t2.x = t1.x;\r
+    t2.y = t1.y * cos(pitch / 180.0 * CV_PI) - t1.z * sin(pitch / 180.0 * CV_PI);\r
+    t2.z = t1.y * sin(pitch / 180.0 * CV_PI) + t1.z * cos(pitch / 180.0 * CV_PI);\r
+\r
+    return t2;\r
+}\r
+\r
+int main(int argc, const char* argv[])\r
+{\r
+    const char* keys =\r
+       "{ l | left      |       | left image file name }"\r
+       "{ r | right     |       | right image file name }"\r
+       "{ i | intrinsic |       | intrinsic camera parameters file name }"\r
+       "{ e | extrinsic |       | extrinsic camera parameters file name }"\r
+       "{ d | ndisp     | 256   | number of disparities }"\r
+       "{ s | scale     | 1.0   | scale factor for point cloud }"\r
+       "{ h | help      | false | print help message }";\r
+\r
+    CommandLineParser cmd(argc, argv, keys);\r
+\r
+    if (cmd.get<bool>("help"))    \r
+    {\r
+        cout << "Avaible options:" << endl;\r
+        cmd.printParams();\r
+        return 0;\r
+    }\r
+\r
+    string left = cmd.get<string>("left");\r
+    string right = cmd.get<string>("right");\r
+    string intrinsic = cmd.get<string>("intrinsic");\r
+    string extrinsic = cmd.get<string>("extrinsic");\r
+    int ndisp = cmd.get<int>("ndisp");\r
+    double scale = cmd.get<double>("scale");\r
+\r
+    if (left.empty() || right.empty())\r
+    {\r
+        cout << "Missed input images" << endl;\r
+        cout << "Avaible options:" << endl;\r
+        cmd.printParams();\r
+        return 0;\r
+    }\r
+\r
+    if (intrinsic.empty() ^ extrinsic.empty())\r
+    {\r
+        cout << "Boss camera parameters must be specified" << endl;\r
+        cout << "Avaible options:" << endl;\r
+        cmd.printParams();\r
+        return 0;\r
+    }\r
+\r
+    Mat imgLeftColor = imread(left, IMREAD_COLOR);\r
+    Mat imgRightColor = imread(right, IMREAD_COLOR);\r
+\r
+    if (imgLeftColor.empty())\r
+    {\r
+        cout << "Can't load image " << left << endl;\r
+        return -1;\r
+    }\r
+\r
+    if (imgRightColor.empty())\r
+    {\r
+        cout << "Can't load image " << right << endl;\r
+        return -1;\r
+    }    \r
+    \r
+    Mat Q = Mat::eye(4, 4, CV_32F);\r
+    if (!intrinsic.empty() && !extrinsic.empty())\r
+    {\r
+        FileStorage fs;\r
+    \r
+        // reading intrinsic parameters\r
+        fs.open(intrinsic, CV_STORAGE_READ);\r
+        if (!fs.isOpened())\r
+        {\r
+            cout << "Failed to open file " << intrinsic << endl;\r
+            return -1;\r
+        }\r
+        \r
+        Mat M1, D1, M2, D2;\r
+        fs["M1"] >> M1;\r
+        fs["D1"] >> D1;\r
+        fs["M2"] >> M2;\r
+        fs["D2"] >> D2;\r
+        \r
+        // reading extrinsic parameters\r
+        fs.open(extrinsic, CV_STORAGE_READ);\r
+        if (!fs.isOpened())\r
+        {\r
+            cout << "Failed to open file " << extrinsic << endl;\r
+            return -1;\r
+        }\r
+        \r
+        Mat R, T, R1, P1, R2, P2;\r
+        fs["R"] >> R;\r
+        fs["T"] >> T;\r
+\r
+        Size img_size = imgLeftColor.size();\r
+\r
+        Rect roi1, roi2;\r
+        stereoRectify(M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, -1, img_size, &roi1, &roi2);\r
+        \r
+        Mat map11, map12, map21, map22;\r
+        initUndistortRectifyMap(M1, D1, R1, P1, img_size, CV_16SC2, map11, map12);\r
+        initUndistortRectifyMap(M2, D2, R2, P2, img_size, CV_16SC2, map21, map22);\r
+        \r
+        Mat img1r, img2r;\r
+        remap(imgLeftColor, img1r, map11, map12, INTER_LINEAR);\r
+        remap(imgRightColor, img2r, map21, map22, INTER_LINEAR);\r
+        \r
+        imgLeftColor = img1r(roi1);\r
+        imgRightColor = img2r(roi2);\r
+    }\r
+\r
+    Mat imgLeftGray, imgRightGray;\r
+    cvtColor(imgLeftColor, imgLeftGray, COLOR_BGR2GRAY);\r
+    cvtColor(imgRightColor, imgRightGray, COLOR_BGR2GRAY);\r
+\r
+    cvtColor(imgLeftColor, imgLeftColor, COLOR_BGR2RGB);\r
+\r
+    Mat disp, points;\r
+\r
+    StereoBM bm(0, ndisp);\r
+\r
+    bm(imgLeftGray, imgRightGray, disp);\r
+    disp.convertTo(disp, CV_8U, 1.0 / 16.0);\r
+\r
+    disp = disp(Range(21, disp.rows - 21), Range(ndisp, disp.cols - 21)).clone();\r
+    imgLeftColor = imgLeftColor(Range(21, imgLeftColor.rows - 21), Range(ndisp, imgLeftColor.cols - 21)).clone();\r
+\r
+    reprojectImageTo3D(disp, points, Q);\r
+\r
+    namedWindow("OpenGL Sample", WINDOW_OPENGL);\r
+\r
+    int fov = 0;\r
+    createTrackbar("Fov", "OpenGL Sample", &fov, 100);\r
+\r
+    int mouse[2] = {0, 0};\r
+    setMouseCallback("OpenGL Sample", mouseCallback, mouse);\r
+    \r
+    GlArrays pointCloud;\r
+\r
+    pointCloud.setVertexArray(points);\r
+    pointCloud.setColorArray(imgLeftColor, false);\r
+\r
+    GlCamera camera;\r
+    camera.setScale(Point3d(scale, scale, scale));\r
+    \r
+    double yaw = 0.0;\r
+    double pitch = 0.0;\r
+\r
+    const Point3d dirVec(0.0, 0.0, -1.0);\r
+    const Point3d upVec(0.0, 1.0, 0.0);\r
+    const Point3d leftVec(-1.0, 0.0, 0.0);\r
+    Point3d pos;\r
+\r
+    while (true)\r
+    {\r
+        int key = waitKey(1);\r
+\r
+        if (key == 27)\r
+            break;        \r
+        \r
+        double aspect = getWindowProperty("OpenGL Sample", WND_PROP_ASPECT_RATIO);\r
+\r
+        const double posStep = 0.1;\r
+        const double mouseStep = 0.001;\r
+        const int mouseClamp = 300;\r
+\r
+        camera.setPerspectiveProjection(30.0 + fov / 100.0 * 40.0, aspect, 0.1, 1000.0); \r
+\r
+        int mouse_dx = clamp(mouse[0], -mouseClamp, mouseClamp);\r
+        int mouse_dy = clamp(mouse[1], -mouseClamp, mouseClamp);\r
+\r
+        yaw += mouse_dx * mouseStep;\r
+        pitch += mouse_dy * mouseStep;\r
+\r
+        key = tolower(key);\r
+        if (key == 'w')\r
+            pos += posStep * rotate(dirVec, yaw, pitch);\r
+        else if (key == 's')\r
+            pos -= posStep * rotate(dirVec, yaw, pitch);\r
+        else if (key == 'a')\r
+            pos += posStep * rotate(leftVec, yaw, pitch);\r
+        else if (key == 'd')\r
+            pos -= posStep * rotate(leftVec, yaw, pitch);\r
+        else if (key == 'q')\r
+            pos += posStep * rotate(upVec, yaw, pitch);\r
+        else if (key == 'e')\r
+            pos -= posStep * rotate(upVec, yaw, pitch);\r
+\r
+        camera.setCameraPos(pos, yaw, pitch, 0.0);\r
+\r
+        pointCloudShow("OpenGL Sample", camera, pointCloud);\r
+    }\r
+\r
+    return 0;\r
+}\r