Spaces:
Sleeping
Sleeping
3737b3723fd97bb0284fe37da43d665041a758f698eeb86f73a3901fcaeb33dc
Browse files- third-party/DPVO/Pangolin/components/pango_geometry/src/geometry.cpp +50 -0
- third-party/DPVO/Pangolin/components/pango_geometry/src/geometry_obj.cpp +252 -0
- third-party/DPVO/Pangolin/components/pango_geometry/src/geometry_ply.cpp +498 -0
- third-party/DPVO/Pangolin/components/pango_glgeometry/CMakeLists.txt +15 -0
- third-party/DPVO/Pangolin/components/pango_glgeometry/include/pangolin/geometry/glgeometry.h +87 -0
- third-party/DPVO/Pangolin/components/pango_glgeometry/src/glgeometry.cpp +142 -0
- third-party/DPVO/Pangolin/components/pango_image/CMakeLists.txt +112 -0
- third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/copy.h +45 -0
- third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/image.h +428 -0
- third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/image_convert.h +31 -0
- third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/image_io.h +65 -0
- third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/image_utils.h +185 -0
- third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/managed_image.h +174 -0
- third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/memcpy.h +110 -0
- third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/pixel_format.h +69 -0
- third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/shared_image.h +145 -0
- third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/typed_image.h +91 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io.cpp +197 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_bmp.cpp +94 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_exr.cpp +231 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_jpg.cpp +319 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_libraw.cpp +48 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_lz4.cpp +86 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_packed12bit.cpp +87 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_pango.cpp +62 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_png.cpp +234 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_ppm.cpp +104 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_raw.cpp +25 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_tga.cpp +53 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_tiff.cpp +79 -0
- third-party/DPVO/Pangolin/components/pango_image/src/image_io_zstd.cpp +128 -0
- third-party/DPVO/Pangolin/components/pango_image/src/pixel_format.cpp +87 -0
- third-party/DPVO/Pangolin/components/pango_opengl/CMakeLists.txt +50 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/cg.h +283 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/colour.h +178 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/compat/gl2engine.h +316 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/compat/gl_es_compat.h +39 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gl.h +296 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gl.hpp +956 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glchar.h +78 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glcuda.h +259 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gldraw.h +518 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glfont.h +80 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glformattraits.h +232 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glinclude.h +46 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glpangoglu.h +80 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glpixformat.h +110 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glplatform.h +86 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glsl.h +812 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glstate.h +220 -0
third-party/DPVO/Pangolin/components/pango_geometry/src/geometry.cpp
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#include <pangolin/geometry/geometry.h>
|
| 29 |
+
#include <pangolin/geometry/geometry_ply.h>
|
| 30 |
+
#include <pangolin/geometry/geometry_obj.h>
|
| 31 |
+
#include <pangolin/utils/file_extension.h>
|
| 32 |
+
#include <pangolin/utils/file_utils.h>
|
| 33 |
+
|
| 34 |
+
namespace pangolin {
|
| 35 |
+
|
| 36 |
+
// TODO: Replace this with proper factory registry
|
| 37 |
+
pangolin::Geometry LoadGeometry(const std::string& filename)
|
| 38 |
+
{
|
| 39 |
+
const std::string expanded_filename = PathExpand(filename);
|
| 40 |
+
const ImageFileType ft = FileType(expanded_filename);
|
| 41 |
+
if(ft == ImageFileTypePly) {
|
| 42 |
+
return LoadGeometryPly(expanded_filename);
|
| 43 |
+
}else if(ft == ImageFileTypeObj) {
|
| 44 |
+
return LoadGeometryObj(expanded_filename);
|
| 45 |
+
}else{
|
| 46 |
+
throw std::runtime_error("Unsupported geometry file type.");
|
| 47 |
+
}
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
}
|
third-party/DPVO/Pangolin/components/pango_geometry/src/geometry_obj.cpp
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#include <unordered_set>
|
| 29 |
+
|
| 30 |
+
#include <pangolin/geometry/geometry_obj.h>
|
| 31 |
+
#include <tinyobj/tiny_obj_loader.h>
|
| 32 |
+
#include <pangolin/utils/variadic_all.h>
|
| 33 |
+
#include <pangolin/utils/simple_math.h>
|
| 34 |
+
|
| 35 |
+
#include <pangolin/image/image_io.h>
|
| 36 |
+
#include <pangolin/utils/file_utils.h>
|
| 37 |
+
|
| 38 |
+
namespace std {
|
| 39 |
+
|
| 40 |
+
template<>
|
| 41 |
+
struct hash<tinyobj::index_t> {
|
| 42 |
+
|
| 43 |
+
std::size_t operator()(const tinyobj::index_t & t) const noexcept {
|
| 44 |
+
static std::hash<int> h;
|
| 45 |
+
return h(t.vertex_index) ^ h(t.normal_index) ^ h(t.texcoord_index);
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
};
|
| 49 |
+
|
| 50 |
+
} // namespace std
|
| 51 |
+
|
| 52 |
+
namespace tinyobj {
|
| 53 |
+
|
| 54 |
+
bool operator==(const index_t a, const index_t b) {
|
| 55 |
+
return a.vertex_index == b.vertex_index && a.normal_index == b.normal_index && a.texcoord_index == b.texcoord_index;
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
} // namespace tinyobj
|
| 59 |
+
|
| 60 |
+
namespace pangolin {
|
| 61 |
+
|
| 62 |
+
template<typename T>
|
| 63 |
+
Geometry::Element ConvertVectorToGeometryElement(const std::vector<T>& v, size_t count_per_element, const std::string& attribute_name )
|
| 64 |
+
{
|
| 65 |
+
PANGO_ASSERT(v.size() % count_per_element == 0);
|
| 66 |
+
const size_t num_elements = v.size() / count_per_element;
|
| 67 |
+
|
| 68 |
+
// Allocate buffer and copy into it
|
| 69 |
+
Geometry::Element el(sizeof(T) * count_per_element, num_elements);
|
| 70 |
+
el.CopyFrom(Image<T>(v.data(), count_per_element, num_elements));
|
| 71 |
+
el.attributes[attribute_name] = el.template UnsafeReinterpret<T>();
|
| 72 |
+
return el;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
template<typename T>
|
| 76 |
+
Image<T> GetImageWrapper(std::vector<T>& vec, size_t count_per_element)
|
| 77 |
+
{
|
| 78 |
+
PANGO_ASSERT(vec.size() % count_per_element == 0);
|
| 79 |
+
if(vec.size()) {
|
| 80 |
+
return Image<T>(vec.data(), count_per_element, vec.size() / count_per_element, count_per_element * sizeof(T));
|
| 81 |
+
}else{
|
| 82 |
+
return Image<T>();
|
| 83 |
+
}
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
pangolin::Geometry LoadGeometryObj(const std::string& filename)
|
| 88 |
+
{
|
| 89 |
+
pangolin::Geometry geom;
|
| 90 |
+
|
| 91 |
+
tinyobj::attrib_t attrib;
|
| 92 |
+
std::vector<tinyobj::shape_t> shapes;
|
| 93 |
+
std::vector<tinyobj::material_t> materials;
|
| 94 |
+
|
| 95 |
+
std::string warn;
|
| 96 |
+
std::string err;
|
| 97 |
+
if(tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filename.c_str(), PathParent(filename).c_str())) {
|
| 98 |
+
PANGO_ASSERT(attrib.vertices.size() % 3 == 0);
|
| 99 |
+
PANGO_ASSERT(attrib.normals.size() % 3 == 0);
|
| 100 |
+
PANGO_ASSERT(attrib.colors.size() % 3 == 0);
|
| 101 |
+
PANGO_ASSERT(attrib.texcoords.size() % 2 == 0);
|
| 102 |
+
|
| 103 |
+
// Load textures - a bit of a hack for now.
|
| 104 |
+
for(size_t i=0; i < materials.size(); ++i) {
|
| 105 |
+
if(!materials[i].diffuse_texname.empty()) {
|
| 106 |
+
const std::string tex_name = FormatString("texture_%",i);
|
| 107 |
+
try {
|
| 108 |
+
TypedImage& tex_image = geom.textures[tex_name];
|
| 109 |
+
tex_image = LoadImage(PathParent(filename) + "/" + materials[i].diffuse_texname);
|
| 110 |
+
const int row_bytes = tex_image.w * tex_image.fmt.bpp / 8;
|
| 111 |
+
std::vector<unsigned char> tmp_row(row_bytes);
|
| 112 |
+
for (std::size_t y=0; y < (tex_image.h >> 1); ++y) {
|
| 113 |
+
std::memcpy(tmp_row.data(), tex_image.RowPtr(y), row_bytes);
|
| 114 |
+
std::memcpy(tex_image.RowPtr(y), tex_image.RowPtr(tex_image.h - 1 - y), row_bytes);
|
| 115 |
+
std::memcpy(tex_image.RowPtr(tex_image.h - 1 - y), tmp_row.data(), row_bytes);
|
| 116 |
+
}
|
| 117 |
+
} catch(const std::exception& e) {
|
| 118 |
+
pango_print_warn("Unable to read texture '%s'\n", tex_name.c_str());
|
| 119 |
+
geom.textures.erase(tex_name);
|
| 120 |
+
}
|
| 121 |
+
}
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
// PANGO_ASSERT(all_of(
|
| 125 |
+
// [&](const size_t& v){return (v == 0) || (v == num_verts);},
|
| 126 |
+
// attrib.normals.size() / 3,
|
| 127 |
+
// attrib.colors.size() / 3));
|
| 128 |
+
|
| 129 |
+
// Get rid of color buffer if all elements are equal.
|
| 130 |
+
if ( std::adjacent_find( attrib.colors.begin(), attrib.colors.end(), std::not_equal_to<float>() ) == attrib.colors.end() )
|
| 131 |
+
{
|
| 132 |
+
attrib.colors.clear();
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
Image<float> tiny_vs = GetImageWrapper(attrib.vertices, 3);
|
| 136 |
+
Image<float> tiny_ns = GetImageWrapper(attrib.normals, 3);
|
| 137 |
+
Image<float> tiny_cs = GetImageWrapper(attrib.colors, 3);
|
| 138 |
+
Image<float> tiny_ts = GetImageWrapper(attrib.texcoords, 2);
|
| 139 |
+
|
| 140 |
+
// Some vertices are used with multiple texture coordinates or multiple normals, and will need to be split.
|
| 141 |
+
// First, we'll find the number of unique combinations of vertex, texture, and normal indices used, as each
|
| 142 |
+
// will result in a separate vertex in the buffers
|
| 143 |
+
std::unordered_map<tinyobj::index_t, std::size_t> reindex_map;
|
| 144 |
+
|
| 145 |
+
for(auto& shape : shapes) {
|
| 146 |
+
|
| 147 |
+
if(shape.mesh.indices.size() == 0) {
|
| 148 |
+
continue;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
const size_t num_indices = shape.mesh.indices.size() ;
|
| 152 |
+
|
| 153 |
+
for(size_t i=0; i < num_indices; ++i) {
|
| 154 |
+
|
| 155 |
+
const tinyobj::index_t index = shape.mesh.indices[i];
|
| 156 |
+
|
| 157 |
+
if (reindex_map.find(index) == reindex_map.end()) {
|
| 158 |
+
|
| 159 |
+
reindex_map.insert(std::pair<tinyobj::index_t, std::size_t>(index, reindex_map.size()));
|
| 160 |
+
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
const int num_unique_verts = reindex_map.size();
|
| 168 |
+
|
| 169 |
+
// Create unified verts attribute
|
| 170 |
+
auto& verts = geom.buffers["geometry"];
|
| 171 |
+
Image<float> new_vs, new_ns, new_cs, new_ts;
|
| 172 |
+
{
|
| 173 |
+
verts.Reinitialise(sizeof(float)*(tiny_vs.w + tiny_ns.w + tiny_cs.w + tiny_ts.w),num_unique_verts);
|
| 174 |
+
size_t float_offset = 0;
|
| 175 |
+
if(tiny_vs.IsValid()) {
|
| 176 |
+
new_vs = verts.UnsafeReinterpret<float>().SubImage(float_offset,0,3,num_unique_verts);
|
| 177 |
+
verts.attributes["vertex"] = new_vs;
|
| 178 |
+
float_offset += 3;
|
| 179 |
+
for (auto& el : reindex_map) {
|
| 180 |
+
new_vs.Row(el.second).CopyFrom(tiny_vs.Row(el.first.vertex_index));
|
| 181 |
+
}
|
| 182 |
+
}
|
| 183 |
+
if(tiny_ns.IsValid()) {
|
| 184 |
+
new_ns = verts.UnsafeReinterpret<float>().SubImage(float_offset,0,3,num_unique_verts);
|
| 185 |
+
verts.attributes["normal"] = new_ns;
|
| 186 |
+
float_offset += 3;
|
| 187 |
+
for (auto& el : reindex_map) {
|
| 188 |
+
new_ns.Row(el.second).CopyFrom(tiny_ns.Row(el.first.normal_index));
|
| 189 |
+
}
|
| 190 |
+
}
|
| 191 |
+
if(tiny_cs.IsValid()) {
|
| 192 |
+
new_cs = verts.UnsafeReinterpret<float>().SubImage(float_offset,0,3,num_unique_verts);
|
| 193 |
+
verts.attributes["color"] = new_cs;
|
| 194 |
+
float_offset += 3;
|
| 195 |
+
for (auto& el : reindex_map) {
|
| 196 |
+
new_cs.Row(el.second).CopyFrom(tiny_cs.Row(el.first.vertex_index));
|
| 197 |
+
}
|
| 198 |
+
}
|
| 199 |
+
if(tiny_ts.IsValid()) {
|
| 200 |
+
new_ts = verts.UnsafeReinterpret<float>().SubImage(float_offset,0,2,num_unique_verts);
|
| 201 |
+
verts.attributes["uv"] = new_ts;
|
| 202 |
+
float_offset += 2;
|
| 203 |
+
for (auto& el : reindex_map) {
|
| 204 |
+
new_ts.Row(el.second).CopyFrom(tiny_ts.Row(el.first.texcoord_index));
|
| 205 |
+
}
|
| 206 |
+
}
|
| 207 |
+
PANGO_ASSERT(float_offset * sizeof(float) == verts.w);
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
for(auto& shape : shapes) {
|
| 211 |
+
if(shape.mesh.indices.size() == 0) {
|
| 212 |
+
continue;
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
auto faces = geom.objects.emplace(shape.name, Geometry::Element());
|
| 216 |
+
|
| 217 |
+
if(std::all_of( shape.mesh.num_face_vertices.begin(), shape.mesh.num_face_vertices.end(),
|
| 218 |
+
[](unsigned char num){return num==3;}
|
| 219 |
+
)) {
|
| 220 |
+
// tri mesh
|
| 221 |
+
const size_t num_indices = shape.mesh.indices.size() ;
|
| 222 |
+
const size_t num_faces = shape.mesh.indices.size() / 3;
|
| 223 |
+
PANGO_ASSERT(num_indices % 3 == 0);
|
| 224 |
+
|
| 225 |
+
// Use vert_ibo as our new IBO
|
| 226 |
+
faces->second.Reinitialise(3*sizeof(uint32_t), num_faces);
|
| 227 |
+
Image<uint32_t> new_ibo = faces->second.UnsafeReinterpret<uint32_t>().SubImage(0,0,3,num_faces);
|
| 228 |
+
for(size_t f=0; f < num_faces; ++f) {
|
| 229 |
+
for(size_t v=0; v < 3; ++v) {
|
| 230 |
+
new_ibo(v,f) = reindex_map[shape.mesh.indices[3 * f + v]];
|
| 231 |
+
}
|
| 232 |
+
}
|
| 233 |
+
faces->second.attributes["vertex_indices"] = new_ibo;
|
| 234 |
+
|
| 235 |
+
}else if(std::all_of( shape.mesh.num_face_vertices.begin(), shape.mesh.num_face_vertices.end(),
|
| 236 |
+
[](unsigned char num){return num==4;}
|
| 237 |
+
)) {
|
| 238 |
+
// Quad mesh
|
| 239 |
+
throw std::runtime_error("Do not support quad meshes yet.");
|
| 240 |
+
}else{
|
| 241 |
+
// ???
|
| 242 |
+
throw std::runtime_error("Do not support meshes with mixed triangles and quads.");
|
| 243 |
+
}
|
| 244 |
+
}
|
| 245 |
+
}else{
|
| 246 |
+
throw std::runtime_error(FormatString("Unable to load OBJ file '%'. Error: '%'", filename, err));
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
return geom;
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
}
|
third-party/DPVO/Pangolin/components/pango_geometry/src/geometry_ply.cpp
ADDED
|
@@ -0,0 +1,498 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#include <pangolin/geometry/geometry_ply.h>
|
| 29 |
+
|
| 30 |
+
#include <pangolin/utils/file_utils.h>
|
| 31 |
+
#include <pangolin/utils/variadic_all.h>
|
| 32 |
+
#include <pangolin/utils/parse.h>
|
| 33 |
+
#include <pangolin/utils/type_convert.h>
|
| 34 |
+
#include <pangolin/utils/simple_math.h>
|
| 35 |
+
#include <pangolin/image/image_io.h>
|
| 36 |
+
|
| 37 |
+
namespace pangolin {
|
| 38 |
+
|
| 39 |
+
#define FORMAT_STRING_LIST(x) #x,
|
| 40 |
+
|
| 41 |
+
const char* PlyHeaderString[] = {
|
| 42 |
+
PLY_HEADER_LIST(FORMAT_STRING_LIST)
|
| 43 |
+
};
|
| 44 |
+
|
| 45 |
+
const char* PlyFormatString[] = {
|
| 46 |
+
PLY_FORMAT_LIST(FORMAT_STRING_LIST)
|
| 47 |
+
};
|
| 48 |
+
|
| 49 |
+
const char* PlyTypeString[] = {
|
| 50 |
+
PLY_TYPE_LIST(FORMAT_STRING_LIST)
|
| 51 |
+
};
|
| 52 |
+
|
| 53 |
+
#undef FORMAT_STRING_LIST
|
| 54 |
+
|
| 55 |
+
PLY_GROUP_LIST(PANGOLIN_DEFINE_PARSE_TOKEN)
|
| 56 |
+
|
| 57 |
+
void ParsePlyHeader(PlyHeaderDetails& ply, std::istream& is)
|
| 58 |
+
{
|
| 59 |
+
// 'Active' element for property definitions.
|
| 60 |
+
int current_element = -1;
|
| 61 |
+
|
| 62 |
+
// Check header is correct
|
| 63 |
+
PlyHeader token = ParseTokenPlyHeader(is);
|
| 64 |
+
if( token != PlyHeader_ply) {
|
| 65 |
+
throw std::runtime_error("Bad PLY header magic.");
|
| 66 |
+
}
|
| 67 |
+
ConsumeToNewline(is);
|
| 68 |
+
|
| 69 |
+
while(is.good() && token != PlyHeader_end_header) {
|
| 70 |
+
token = ParseTokenPlyHeader(is);
|
| 71 |
+
switch (token) {
|
| 72 |
+
case PlyHeader_format:
|
| 73 |
+
// parse PLY format and version
|
| 74 |
+
ConsumeWhitespace(is);
|
| 75 |
+
ply.format = ParseTokenPlyFormat(is);
|
| 76 |
+
ConsumeWhitespace(is);
|
| 77 |
+
ply.version = ReadToken(is);
|
| 78 |
+
break;
|
| 79 |
+
case PlyHeader_element:
|
| 80 |
+
{
|
| 81 |
+
current_element = ply.elements.size();
|
| 82 |
+
PlyElementDetails el;
|
| 83 |
+
el.stride_bytes = 0;
|
| 84 |
+
ConsumeWhitespace(is);
|
| 85 |
+
el.name = ReadToken(is);
|
| 86 |
+
ConsumeWhitespace(is);
|
| 87 |
+
el.num_items = FromString<int>(ReadToken(is));
|
| 88 |
+
ply.elements.push_back(el);
|
| 89 |
+
break;
|
| 90 |
+
}
|
| 91 |
+
case PlyHeader_property:
|
| 92 |
+
if(current_element >= 0) {
|
| 93 |
+
PlyElementDetails& el = ply.elements[current_element];
|
| 94 |
+
PlyPropertyDetails prop;
|
| 95 |
+
ConsumeWhitespace(is);
|
| 96 |
+
const PlyType t = ParseTokenPlyType(is);
|
| 97 |
+
if( t == PlyType_list) {
|
| 98 |
+
ConsumeWhitespace(is);
|
| 99 |
+
const PlyType idtype = ParseTokenPlyType(is);
|
| 100 |
+
ConsumeWhitespace(is);
|
| 101 |
+
const PlyType itemtype = ParseTokenPlyType(is);
|
| 102 |
+
prop.list_index_type = idtype;
|
| 103 |
+
prop.type = itemtype;
|
| 104 |
+
prop.offset_bytes = el.stride_bytes;
|
| 105 |
+
prop.num_items = -1;
|
| 106 |
+
el.stride_bytes = -1;
|
| 107 |
+
}else{
|
| 108 |
+
prop.list_index_type = PlyType_none;
|
| 109 |
+
prop.type = t;
|
| 110 |
+
prop.offset_bytes = el.stride_bytes;
|
| 111 |
+
prop.num_items = 1;
|
| 112 |
+
const size_t size_bytes = PlyTypeSizeBytes[prop.type];
|
| 113 |
+
if( el.stride_bytes >= 0) {
|
| 114 |
+
el.stride_bytes += size_bytes;
|
| 115 |
+
}
|
| 116 |
+
}
|
| 117 |
+
ConsumeWhitespace(is);
|
| 118 |
+
prop.name = ReadToken(is);
|
| 119 |
+
el.properties.push_back(prop);
|
| 120 |
+
}else{
|
| 121 |
+
pango_print_warn("PLY Parser: property declaration before element. Ignoring line.");
|
| 122 |
+
}
|
| 123 |
+
break;
|
| 124 |
+
case PlyHeader_comment:
|
| 125 |
+
case PlyHeader_end_header:
|
| 126 |
+
break;
|
| 127 |
+
default:
|
| 128 |
+
pango_print_warn("PLY Parser: Unknown token - ignoring line.");
|
| 129 |
+
}
|
| 130 |
+
ConsumeToNewline(is);
|
| 131 |
+
}
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
void ParsePlyAscii(pangolin::Geometry& /*geom*/, const PlyHeaderDetails& /*ply*/, std::istream& /*is*/)
|
| 135 |
+
{
|
| 136 |
+
throw std::runtime_error("ASCII Ply loading not currently supported. Consider converting to binary.");
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
void AddVertexNormals(pangolin::Geometry& geom)
|
| 140 |
+
{
|
| 141 |
+
auto it_geom = geom.buffers.find("geometry");
|
| 142 |
+
auto it_face = geom.objects.find("default");
|
| 143 |
+
|
| 144 |
+
if(it_geom != geom.buffers.end() && it_face != geom.objects.end())
|
| 145 |
+
{
|
| 146 |
+
const auto it_vbo = it_geom->second.attributes.find("vertex");
|
| 147 |
+
const auto it_ibo = it_face->second.attributes.find("vertex_indices");
|
| 148 |
+
|
| 149 |
+
if(it_vbo != it_geom->second.attributes.end() && it_ibo != it_face->second.attributes.end()) {
|
| 150 |
+
const auto& ibo = std::get<Image<uint32_t>>(it_ibo->second);
|
| 151 |
+
const auto& vbo = std::get<Image<float>>(it_vbo->second);
|
| 152 |
+
|
| 153 |
+
// Assume we have triangles.
|
| 154 |
+
PANGO_ASSERT(ibo.w == 3 && vbo.w == 3);
|
| 155 |
+
|
| 156 |
+
ManagedImage<float> vert_normals(3, vbo.h);
|
| 157 |
+
ManagedImage<size_t> vert_face_count(1, vbo.h);
|
| 158 |
+
vert_normals.Fill(0.0f);
|
| 159 |
+
vert_face_count.Fill(0);
|
| 160 |
+
|
| 161 |
+
float ab[3];
|
| 162 |
+
float ac[3];
|
| 163 |
+
float fn[3];
|
| 164 |
+
|
| 165 |
+
for(size_t i=0; i < ibo.h; ++i) {
|
| 166 |
+
uint32_t i0 = ibo(0,i);
|
| 167 |
+
uint32_t i1 = ibo(1,i);
|
| 168 |
+
uint32_t i2 = ibo(2,i);
|
| 169 |
+
MatSub<3,1>(ab, vbo.RowPtr(i1), vbo.RowPtr(i0));
|
| 170 |
+
MatSub<3,1>(ac, vbo.RowPtr(i2), vbo.RowPtr(i0));
|
| 171 |
+
VecCross3(fn, ab, ac);
|
| 172 |
+
Normalise<3>(fn);
|
| 173 |
+
for(size_t v=0; v < 3; ++v) {
|
| 174 |
+
MatAdd<3,1>(vert_normals.RowPtr(ibo(v,i)), vert_normals.RowPtr(ibo(v,i)), fn);
|
| 175 |
+
++vert_face_count(0,ibo(v,i));
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
for(size_t v=0; v < vert_normals.h; ++v) {
|
| 180 |
+
// Compute average
|
| 181 |
+
MatMul<3,1>(vert_normals.RowPtr(v), 1.0f / vert_face_count(0,v));
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
auto& el = geom.buffers["normal"];
|
| 185 |
+
(ManagedImage<float>&)el = std::move(vert_normals);
|
| 186 |
+
auto& attr_norm = el.attributes["normal"];
|
| 187 |
+
attr_norm = Image<float>((float*)el.ptr, 3, el.h, el.pitch);
|
| 188 |
+
}
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
void StandardizeXyzToVertex(pangolin::Geometry& geom)
|
| 194 |
+
{
|
| 195 |
+
auto it_verts = geom.buffers.find("geometry");
|
| 196 |
+
|
| 197 |
+
if(it_verts != geom.buffers.end()) {
|
| 198 |
+
auto& verts = it_verts->second;
|
| 199 |
+
auto it_x = verts.attributes.find("x");
|
| 200 |
+
auto it_y = verts.attributes.find("y");
|
| 201 |
+
auto it_z = verts.attributes.find("z");
|
| 202 |
+
if(all_found(verts.attributes, it_x, it_y, it_z)) {
|
| 203 |
+
if(verts.attributes.find("vertex") == verts.attributes.end()) {
|
| 204 |
+
auto& vertex = verts.attributes["vertex"];
|
| 205 |
+
auto& imx = std::get<Image<float>>(it_x->second);
|
| 206 |
+
auto& imy = std::get<Image<float>>(it_y->second);
|
| 207 |
+
auto& imz = std::get<Image<float>>(it_z->second);
|
| 208 |
+
|
| 209 |
+
if(imx.ptr + 1 == imy.ptr && imy.ptr + 1 == imz.ptr) {
|
| 210 |
+
vertex = Image<float>((float*)imx.ptr, 3, verts.h, imx.pitch);
|
| 211 |
+
}else{
|
| 212 |
+
throw std::runtime_error("Ooops");
|
| 213 |
+
}
|
| 214 |
+
}
|
| 215 |
+
verts.attributes.erase(it_x);
|
| 216 |
+
verts.attributes.erase(it_y);
|
| 217 |
+
verts.attributes.erase(it_z);
|
| 218 |
+
}
|
| 219 |
+
}
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
void StandardizeRgbToColor(pangolin::Geometry& geom)
|
| 223 |
+
{
|
| 224 |
+
auto it_verts = geom.buffers.find("geometry");
|
| 225 |
+
|
| 226 |
+
if(it_verts != geom.buffers.end()) {
|
| 227 |
+
auto& verts = it_verts->second;
|
| 228 |
+
auto it_r = verts.attributes.find("r");
|
| 229 |
+
auto it_g = verts.attributes.find("g");
|
| 230 |
+
auto it_b = verts.attributes.find("b");
|
| 231 |
+
auto it_a = verts.attributes.find("a");
|
| 232 |
+
|
| 233 |
+
if(!all_found(verts.attributes, it_r, it_b, it_g)) {
|
| 234 |
+
it_r = verts.attributes.find("red");
|
| 235 |
+
it_g = verts.attributes.find("green");
|
| 236 |
+
it_b = verts.attributes.find("blue");
|
| 237 |
+
it_a = verts.attributes.find("alpha");
|
| 238 |
+
}
|
| 239 |
+
|
| 240 |
+
if(all_found(verts.attributes, it_r, it_g, it_b)) {
|
| 241 |
+
const bool have_alpha = it_a != verts.attributes.end();
|
| 242 |
+
|
| 243 |
+
if(verts.attributes.find("color") == verts.attributes.end()) {
|
| 244 |
+
Geometry::Element::Attribute& red = it_r->second;
|
| 245 |
+
Geometry::Element::Attribute& color = verts.attributes["color"];
|
| 246 |
+
|
| 247 |
+
// TODO: Check that these really are contiguous in memory...
|
| 248 |
+
if(auto attrib = std::get_if<Image<float>>(&red)) {
|
| 249 |
+
color = Image<float>(attrib->ptr, have_alpha ? 4 : 3, verts.h, verts.pitch);
|
| 250 |
+
}else if(auto attrib = std::get_if<Image<uint8_t>>(&red)) {
|
| 251 |
+
color = Image<uint8_t>(attrib->ptr, have_alpha ? 4 : 3, verts.h, verts.pitch);
|
| 252 |
+
}else if(auto attrib = std::get_if<Image<uint16_t>>(&red)) {
|
| 253 |
+
color = Image<uint16_t>(attrib->ptr, have_alpha ? 4 : 3, verts.h, verts.pitch);
|
| 254 |
+
}else if(auto attrib = std::get_if<Image<uint32_t>>(&red)) {
|
| 255 |
+
color = Image<uint32_t>(attrib->ptr, have_alpha ? 4 : 3, verts.h, verts.pitch);
|
| 256 |
+
}
|
| 257 |
+
}
|
| 258 |
+
verts.attributes.erase(it_r);
|
| 259 |
+
verts.attributes.erase(it_g);
|
| 260 |
+
verts.attributes.erase(it_b);
|
| 261 |
+
if(have_alpha) verts.attributes.erase(it_a);
|
| 262 |
+
}
|
| 263 |
+
}
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
void StandardizeMultiTextureFaceToXyzuv(pangolin::Geometry& geom)
|
| 267 |
+
{
|
| 268 |
+
const auto it_multi_texture_face = geom.buffers.find("multi_texture_face");
|
| 269 |
+
const auto it_multi_texture_vertex = geom.buffers.find("multi_texture_vertex");
|
| 270 |
+
const auto it_geom = geom.buffers.find("geometry");
|
| 271 |
+
const auto it_face = geom.objects.find("default");
|
| 272 |
+
|
| 273 |
+
if(it_geom != geom.buffers.end() && it_face != geom.objects.end())
|
| 274 |
+
{
|
| 275 |
+
const auto it_vbo = it_geom->second.attributes.find("vertex");
|
| 276 |
+
const auto it_ibo = it_face->second.attributes.find("vertex_indices");
|
| 277 |
+
|
| 278 |
+
if(all_found(geom.buffers, it_multi_texture_face, it_multi_texture_vertex) &&
|
| 279 |
+
it_vbo != it_geom->second.attributes.end() &&
|
| 280 |
+
it_ibo != it_face->second.attributes.end()
|
| 281 |
+
) {
|
| 282 |
+
const auto it_uv_ibo = it_multi_texture_face->second.attributes.find("texture_vertex_indices");
|
| 283 |
+
const auto it_tx = it_multi_texture_face->second.attributes.find("tx");
|
| 284 |
+
const auto it_tn = it_multi_texture_face->second.attributes.find("tn");
|
| 285 |
+
|
| 286 |
+
const auto it_u = it_multi_texture_vertex->second.attributes.find("u");
|
| 287 |
+
const auto it_v = it_multi_texture_vertex->second.attributes.find("v");
|
| 288 |
+
|
| 289 |
+
if(all_found(it_multi_texture_vertex->second.attributes, it_u, it_v) &&
|
| 290 |
+
it_uv_ibo != it_multi_texture_face->second.attributes.end()
|
| 291 |
+
) {
|
| 292 |
+
// We're going to create a new vertex buffer to hold uv's too
|
| 293 |
+
auto& orig_ibo = std::get<Image<uint32_t>>(it_ibo->second);
|
| 294 |
+
const auto& orig_xyz = std::get<Image<float>>(it_vbo->second);
|
| 295 |
+
const auto& uv_ibo = std::get<Image<uint32_t>>(it_uv_ibo->second);
|
| 296 |
+
const auto& u = std::get<Image<float>>(it_u->second);
|
| 297 |
+
const auto& v = std::get<Image<float>>(it_v->second);
|
| 298 |
+
const auto& tx = std::get<Image<uint8_t>>(it_tx->second);
|
| 299 |
+
const auto& tn = std::get<Image<uint32_t>>(it_tn->second);
|
| 300 |
+
|
| 301 |
+
PANGO_ASSERT(u.h == v.h);
|
| 302 |
+
PANGO_ASSERT(orig_ibo.w == 3 && uv_ibo.w == 3);
|
| 303 |
+
|
| 304 |
+
pangolin::Geometry::Element new_xyzuv(5*sizeof(float), u.h);
|
| 305 |
+
Image<float> new_xyz = new_xyzuv.UnsafeReinterpret<float>().SubImage(0,0,3,new_xyzuv.h);
|
| 306 |
+
Image<float> new_uv = new_xyzuv.UnsafeReinterpret<float>().SubImage(3,0,2,new_xyzuv.h);
|
| 307 |
+
new_xyzuv.attributes["vertex"] = new_xyz;
|
| 308 |
+
new_xyzuv.attributes["uv"] = new_uv;
|
| 309 |
+
|
| 310 |
+
for(size_t face=0; face < orig_ibo.h; ++face) {
|
| 311 |
+
uint32_t vtn = tn(0,face);
|
| 312 |
+
uint8_t vtx = tx(0,face);
|
| 313 |
+
PANGO_ASSERT(vtx==0, "Haven't implemented multi-texture yet.");
|
| 314 |
+
|
| 315 |
+
for(size_t vert=0; vert < 3; ++vert)
|
| 316 |
+
{
|
| 317 |
+
uint32_t& orig_xyz_index = orig_ibo(vert,vtn);
|
| 318 |
+
const uint32_t uv_index = uv_ibo(vert,face);
|
| 319 |
+
PANGO_ASSERT(uv_index < new_xyzuv.h && orig_xyz_index < orig_xyz.h);
|
| 320 |
+
|
| 321 |
+
for(int el=0; el < 3; ++el) {
|
| 322 |
+
new_xyz(el,uv_index) = orig_xyz(el,orig_xyz_index);
|
| 323 |
+
}
|
| 324 |
+
new_uv(0,uv_index) = u(0,uv_index);
|
| 325 |
+
new_uv(1,uv_index) = v(0,uv_index);
|
| 326 |
+
orig_xyz_index = uv_index;
|
| 327 |
+
}
|
| 328 |
+
}
|
| 329 |
+
|
| 330 |
+
geom.buffers["geometry"] = std::move(new_xyzuv);
|
| 331 |
+
geom.buffers.erase(it_multi_texture_face);
|
| 332 |
+
geom.buffers.erase(it_multi_texture_vertex);
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
+
}
|
| 336 |
+
}
|
| 337 |
+
}
|
| 338 |
+
|
| 339 |
+
void Standardize(pangolin::Geometry& geom)
|
| 340 |
+
{
|
| 341 |
+
StandardizeXyzToVertex(geom);
|
| 342 |
+
StandardizeRgbToColor(geom);
|
| 343 |
+
StandardizeMultiTextureFaceToXyzuv(geom);
|
| 344 |
+
AddVertexNormals(geom);
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
inline int ReadGlIntType(PlyType type, std::istream& is)
|
| 348 |
+
{
|
| 349 |
+
// TODO: This seems really dodgey...
|
| 350 |
+
// int may not be big enough and if the datatype is smaller will it be padded?
|
| 351 |
+
int v = 0;
|
| 352 |
+
is.read( (char*)&v, PlyTypeSizeBytes[type]);
|
| 353 |
+
return v;
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
inline void ReadInto(std::vector<unsigned char>& vec, std::istream& is, size_t num_bytes)
|
| 357 |
+
{
|
| 358 |
+
const size_t current_size = vec.size();
|
| 359 |
+
vec.resize(current_size + num_bytes);
|
| 360 |
+
is.read((char*)vec.data() + current_size, num_bytes);
|
| 361 |
+
}
|
| 362 |
+
|
| 363 |
+
void ParsePlyLE(pangolin::Geometry& geom, PlyHeaderDetails& ply, std::istream& is)
|
| 364 |
+
{
|
| 365 |
+
std::vector<uint8_t> buffer;
|
| 366 |
+
|
| 367 |
+
for(auto& el : ply.elements) {
|
| 368 |
+
pangolin::Geometry::Element geom_el;
|
| 369 |
+
|
| 370 |
+
if(el.stride_bytes > 0) {
|
| 371 |
+
// This will usually be the case for vertex buffers with a known number of attributes
|
| 372 |
+
PANGO_ASSERT(el.num_items > 0);
|
| 373 |
+
geom_el.Reinitialise(el.stride_bytes, el.num_items);
|
| 374 |
+
is.read((char*)geom_el.ptr, geom_el.Area());
|
| 375 |
+
}else {
|
| 376 |
+
// This will generally be the case for face data (containing a list of vertex indices)
|
| 377 |
+
|
| 378 |
+
// Reserve enough space for a list of quads
|
| 379 |
+
buffer.clear();
|
| 380 |
+
buffer.reserve(el.num_items * el.properties.size() * 4);
|
| 381 |
+
|
| 382 |
+
for(int i=0; i< el.num_items; ++i) {
|
| 383 |
+
size_t offset_bytes = 0;
|
| 384 |
+
for(auto& prop : el.properties) {
|
| 385 |
+
if(prop.isList()) {
|
| 386 |
+
const int list_items = ReadGlIntType(prop.list_index_type, is);
|
| 387 |
+
if(prop.num_items == -1) {
|
| 388 |
+
prop.num_items = list_items;
|
| 389 |
+
prop.offset_bytes = offset_bytes;
|
| 390 |
+
}else{
|
| 391 |
+
PANGO_ASSERT(prop.num_items == list_items);
|
| 392 |
+
}
|
| 393 |
+
}
|
| 394 |
+
const size_t num_bytes = prop.num_items * PlyTypeSizeBytes[prop.type];
|
| 395 |
+
ReadInto(buffer, is, num_bytes);
|
| 396 |
+
offset_bytes += num_bytes;
|
| 397 |
+
}
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
// Update element stride now we know
|
| 401 |
+
el.stride_bytes = 0;
|
| 402 |
+
for(auto& prop : el.properties) {
|
| 403 |
+
el.stride_bytes += prop.num_items * PlyTypeSizeBytes[prop.type];
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
geom_el.Reinitialise(el.stride_bytes, el.num_items);
|
| 407 |
+
PANGO_ASSERT(geom_el.SizeBytes() == buffer.size());
|
| 408 |
+
std::memcpy(geom_el.ptr, buffer.data(), buffer.size());
|
| 409 |
+
}
|
| 410 |
+
|
| 411 |
+
for(auto& prop : el.properties) {
|
| 412 |
+
Image<uint8_t> attrib(geom_el.ptr + prop.offset_bytes, prop.num_items, el.num_items, geom_el.pitch);
|
| 413 |
+
switch (prop.type) {
|
| 414 |
+
case PlyType_char:
|
| 415 |
+
case PlyType_uchar:
|
| 416 |
+
geom_el.attributes[prop.name] = attrib.UnsafeReinterpret<uint8_t>();
|
| 417 |
+
break;
|
| 418 |
+
case PlyType_short:
|
| 419 |
+
case PlyType_ushort:
|
| 420 |
+
geom_el.attributes[prop.name] = attrib.UnsafeReinterpret<uint16_t>();
|
| 421 |
+
break;
|
| 422 |
+
case PlyType_int:
|
| 423 |
+
case PlyType_uint:
|
| 424 |
+
geom_el.attributes[prop.name] = attrib.UnsafeReinterpret<uint32_t>();
|
| 425 |
+
break;
|
| 426 |
+
case PlyType_float:
|
| 427 |
+
geom_el.attributes[prop.name] = attrib.UnsafeReinterpret<float>();
|
| 428 |
+
break;
|
| 429 |
+
default:
|
| 430 |
+
throw std::runtime_error("Unsupported PLY data type");
|
| 431 |
+
}
|
| 432 |
+
}
|
| 433 |
+
if(el.name == "vertex") {
|
| 434 |
+
geom.buffers["geometry"] = std::move(geom_el);
|
| 435 |
+
}else if(el.name == "face") {
|
| 436 |
+
geom.objects.emplace("default", std::move(geom_el));
|
| 437 |
+
}else{
|
| 438 |
+
geom.buffers[el.name] = std::move(geom_el);
|
| 439 |
+
}
|
| 440 |
+
}
|
| 441 |
+
|
| 442 |
+
Standardize(geom);
|
| 443 |
+
}
|
| 444 |
+
|
| 445 |
+
void ParsePlyBE(pangolin::Geometry& /*geom*/, const PlyHeaderDetails& /*ply*/, std::istream& /*is*/)
|
| 446 |
+
{
|
| 447 |
+
throw std::runtime_error("Not implemented.");
|
| 448 |
+
}
|
| 449 |
+
|
| 450 |
+
void AttachAssociatedTexturesPly(pangolin::Geometry& geom, const std::string& filename)
|
| 451 |
+
{
|
| 452 |
+
// For PLY, texture names are generally implicit
|
| 453 |
+
auto dot = filename.find_last_of('.');
|
| 454 |
+
if(dot != filename.npos) {
|
| 455 |
+
const std::string base = filename.substr(0, dot);
|
| 456 |
+
for(int i=0; i < 10; ++i) {
|
| 457 |
+
const std::string glob = FormatString("%_%.*", base, i);
|
| 458 |
+
std::vector<std::string> file_vec;
|
| 459 |
+
if(FilesMatchingWildcard(glob, file_vec)) {
|
| 460 |
+
for(const auto& file : file_vec) {
|
| 461 |
+
try {
|
| 462 |
+
geom.textures[FormatString("texture_%",i)] = LoadImage(file);
|
| 463 |
+
break;
|
| 464 |
+
}catch(std::runtime_error&)
|
| 465 |
+
{
|
| 466 |
+
}
|
| 467 |
+
}
|
| 468 |
+
}
|
| 469 |
+
}
|
| 470 |
+
}
|
| 471 |
+
}
|
| 472 |
+
|
| 473 |
+
pangolin::Geometry LoadGeometryPly(const std::string& filename)
|
| 474 |
+
{
|
| 475 |
+
std::ifstream bFile( filename.c_str(), std::ios::in | std::ios::binary );
|
| 476 |
+
if( !bFile.is_open() ) throw std::runtime_error("Unable to open PLY file: " + filename);
|
| 477 |
+
|
| 478 |
+
PlyHeaderDetails ply;
|
| 479 |
+
ParsePlyHeader(ply, bFile);
|
| 480 |
+
|
| 481 |
+
// Initialise geom object
|
| 482 |
+
pangolin::Geometry geom;
|
| 483 |
+
|
| 484 |
+
// Fill in geometry from file.
|
| 485 |
+
if(ply.format == PlyFormat_ascii) {
|
| 486 |
+
ParsePlyAscii(geom, ply, bFile);
|
| 487 |
+
}else if(ply.format == PlyFormat_binary_little_endian) {
|
| 488 |
+
ParsePlyLE(geom, ply, bFile);
|
| 489 |
+
}else if(ply.format == PlyFormat_binary_big_endian) {
|
| 490 |
+
ParsePlyBE(geom, ply, bFile);
|
| 491 |
+
}
|
| 492 |
+
|
| 493 |
+
AttachAssociatedTexturesPly(geom, filename);
|
| 494 |
+
|
| 495 |
+
return geom;
|
| 496 |
+
}
|
| 497 |
+
|
| 498 |
+
}
|
third-party/DPVO/Pangolin/components/pango_glgeometry/CMakeLists.txt
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
get_filename_component(COMPONENT ${CMAKE_CURRENT_LIST_DIR} NAME)
|
| 2 |
+
|
| 3 |
+
target_sources( ${COMPONENT}
|
| 4 |
+
PRIVATE
|
| 5 |
+
${CMAKE_CURRENT_LIST_DIR}/src/glgeometry.cpp
|
| 6 |
+
)
|
| 7 |
+
|
| 8 |
+
target_link_libraries(${COMPONENT} pango_geometry pango_opengl)
|
| 9 |
+
target_include_directories(${COMPONENT} PUBLIC
|
| 10 |
+
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
|
| 11 |
+
$<INSTALL_INTERFACE:include>
|
| 12 |
+
)
|
| 13 |
+
install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/include"
|
| 14 |
+
DESTINATION ${CMAKE_INSTALL_PREFIX}
|
| 15 |
+
)
|
third-party/DPVO/Pangolin/components/pango_glgeometry/include/pangolin/geometry/glgeometry.h
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/geometry/geometry.h>
|
| 31 |
+
#include <pangolin/gl/gl.h>
|
| 32 |
+
#include <pangolin/gl/glsl.h>
|
| 33 |
+
|
| 34 |
+
namespace pangolin {
|
| 35 |
+
|
| 36 |
+
struct GlGeometry
|
| 37 |
+
{
|
| 38 |
+
GlGeometry() = default;
|
| 39 |
+
GlGeometry(GlGeometry&&) = default;
|
| 40 |
+
GlGeometry& operator=(GlGeometry&&) = default;
|
| 41 |
+
|
| 42 |
+
struct Element : public GlBufferData
|
| 43 |
+
{
|
| 44 |
+
Element() = default;
|
| 45 |
+
Element(Element&&) = default;
|
| 46 |
+
Element& operator=(Element&&) = default;
|
| 47 |
+
|
| 48 |
+
Element(GlBufferType buffer_type, size_t size_bytes, GLenum gluse, uint8_t* data)
|
| 49 |
+
: GlBufferData(buffer_type, size_bytes, gluse, data)
|
| 50 |
+
{}
|
| 51 |
+
|
| 52 |
+
inline bool HasAttribute(const std::string& name) const {
|
| 53 |
+
return attributes.find(name) != attributes.end();
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
struct Attribute {
|
| 57 |
+
// Stuff needed by glVertexAttribPointer
|
| 58 |
+
GLenum gltype;
|
| 59 |
+
size_t count_per_element;
|
| 60 |
+
size_t num_elements;
|
| 61 |
+
size_t offset;
|
| 62 |
+
size_t stride_bytes;
|
| 63 |
+
};
|
| 64 |
+
std::map<std::string, Attribute> attributes;
|
| 65 |
+
};
|
| 66 |
+
|
| 67 |
+
inline bool HasAttribute(const std::string& name) const
|
| 68 |
+
{
|
| 69 |
+
for(const auto& b : buffers) if(b.second.HasAttribute(name)) return true;
|
| 70 |
+
return false;
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
// Store vertices and attributes
|
| 74 |
+
std::map<std::string, Element> buffers;
|
| 75 |
+
// Stores index buffers for each sub-object
|
| 76 |
+
std::multimap<std::string, Element> objects;
|
| 77 |
+
// Stores pixmaps
|
| 78 |
+
std::map<std::string, GlTexture> textures;
|
| 79 |
+
};
|
| 80 |
+
|
| 81 |
+
GlGeometry::Element ToGlGeometry(const Geometry::Element& el, GlBufferType buffertype);
|
| 82 |
+
|
| 83 |
+
GlGeometry ToGlGeometry(const Geometry& geom);
|
| 84 |
+
|
| 85 |
+
void GlDraw(GlSlProgram& prog, const GlGeometry& geom, const GlTexture *matcap);
|
| 86 |
+
|
| 87 |
+
}
|
third-party/DPVO/Pangolin/components/pango_glgeometry/src/glgeometry.cpp
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#include <pangolin/geometry/glgeometry.h>
|
| 29 |
+
|
| 30 |
+
#include <pangolin/gl/glformattraits.h>
|
| 31 |
+
|
| 32 |
+
namespace pangolin {
|
| 33 |
+
|
| 34 |
+
GlGeometry::Element ToGlGeometryElement(const Geometry::Element& el, GlBufferType buffertype)
|
| 35 |
+
{
|
| 36 |
+
GlGeometry::Element glel(buffertype, el.SizeBytes(), GL_STATIC_DRAW, el.ptr );
|
| 37 |
+
for(const auto& attrib_variant : el.attributes) {
|
| 38 |
+
visit([&](auto&& attrib){
|
| 39 |
+
using T = std::decay_t<decltype(attrib)>;
|
| 40 |
+
auto& glattrib = glel.attributes[attrib_variant.first];
|
| 41 |
+
glattrib.gltype = GlFormatTraits<typename T::PixelType>::gltype;
|
| 42 |
+
glattrib.count_per_element = attrib.w;
|
| 43 |
+
glattrib.num_elements = attrib.h;
|
| 44 |
+
glattrib.offset = (uint8_t*)attrib.ptr - el.ptr;
|
| 45 |
+
glattrib.stride_bytes = attrib.pitch;
|
| 46 |
+
}, attrib_variant.second);
|
| 47 |
+
}
|
| 48 |
+
return glel;
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
GlGeometry ToGlGeometry(const Geometry& geom)
|
| 52 |
+
{
|
| 53 |
+
GlGeometry gl;
|
| 54 |
+
for(const auto& b : geom.buffers)
|
| 55 |
+
gl.buffers[b.first] = ToGlGeometryElement(b.second, GlArrayBuffer);
|
| 56 |
+
|
| 57 |
+
for(const auto& b : geom.objects)
|
| 58 |
+
gl.objects.emplace(b.first, ToGlGeometryElement(b.second, GlElementArrayBuffer));
|
| 59 |
+
|
| 60 |
+
for(const auto& tex : geom.textures) {
|
| 61 |
+
auto& gltex = gl.textures[tex.first];
|
| 62 |
+
gltex.Load(tex.second);
|
| 63 |
+
}
|
| 64 |
+
return gl;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
void BindGlElement(GlSlProgram& prog, const GlGeometry::Element& el)
|
| 68 |
+
{
|
| 69 |
+
el.Bind();
|
| 70 |
+
for(auto& a : el.attributes) {
|
| 71 |
+
const GLint attrib_handle = prog.GetAttributeHandle(a.first);
|
| 72 |
+
const GlGeometry::Element::Attribute& attr = a.second;
|
| 73 |
+
if(attrib_handle >= 0) {
|
| 74 |
+
glEnableVertexAttribArray(attrib_handle);
|
| 75 |
+
glVertexAttribPointer(
|
| 76 |
+
attrib_handle, attr.count_per_element, attr.gltype, GL_TRUE,
|
| 77 |
+
attr.stride_bytes,
|
| 78 |
+
reinterpret_cast<uint8_t*>(attr.offset)
|
| 79 |
+
);
|
| 80 |
+
}
|
| 81 |
+
}
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
void UnbindGlElements(GlSlProgram& prog, const GlGeometry::Element& el)
|
| 85 |
+
{
|
| 86 |
+
for(auto& a : el.attributes) {
|
| 87 |
+
const GLint attrib_handle = prog.GetAttributeHandle(a.first);
|
| 88 |
+
if(attrib_handle >= 0) {
|
| 89 |
+
glDisableVertexAttribArray(attrib_handle);
|
| 90 |
+
}
|
| 91 |
+
}
|
| 92 |
+
el.Unbind();
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
void GlDraw(GlSlProgram& prog, const GlGeometry& geom, const GlTexture* matcap)
|
| 96 |
+
{
|
| 97 |
+
// Bind textures
|
| 98 |
+
int num_tex_bound = 0;
|
| 99 |
+
for(auto& tex : geom.textures) {
|
| 100 |
+
glActiveTexture(GL_TEXTURE0 + num_tex_bound);
|
| 101 |
+
tex.second.Bind();
|
| 102 |
+
prog.SetUniform(tex.first, (int)num_tex_bound);
|
| 103 |
+
++num_tex_bound;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
if(matcap) {
|
| 107 |
+
glActiveTexture(GL_TEXTURE0 + num_tex_bound);
|
| 108 |
+
matcap->Bind();
|
| 109 |
+
prog.SetUniform("matcap", (int)num_tex_bound);
|
| 110 |
+
++num_tex_bound;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
// Bind all attribute buffers
|
| 114 |
+
for(auto& buffer : geom.buffers) {
|
| 115 |
+
BindGlElement(prog, buffer.second);
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
// Draw all geometry
|
| 119 |
+
for(auto& buffer : geom.objects) {
|
| 120 |
+
auto it_indices = buffer.second.attributes.find("vertex_indices");
|
| 121 |
+
if(it_indices != buffer.second.attributes.end()) {
|
| 122 |
+
buffer.second.Bind();
|
| 123 |
+
auto& attrib = it_indices->second;
|
| 124 |
+
glDrawElements(
|
| 125 |
+
GL_TRIANGLES, attrib.count_per_element * attrib.num_elements,
|
| 126 |
+
attrib.gltype, reinterpret_cast<uint8_t*>(attrib.offset)
|
| 127 |
+
);
|
| 128 |
+
buffer.second.Unbind();
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
// Unbind attribute buffers
|
| 133 |
+
for(auto& buffer : geom.buffers) {
|
| 134 |
+
UnbindGlElements(prog, buffer.second);
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
// Unbind textures
|
| 138 |
+
glBindTexture(GL_TEXTURE_2D, 0);
|
| 139 |
+
glActiveTexture(GL_TEXTURE0);
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/CMakeLists.txt
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
get_filename_component(COMPONENT ${CMAKE_CURRENT_LIST_DIR} NAME)
|
| 2 |
+
|
| 3 |
+
option(BUILD_PANGOLIN_LIBPNG "Build support for libpng image input" ON)
|
| 4 |
+
if(BUILD_PANGOLIN_LIBPNG)
|
| 5 |
+
find_package(PNG QUIET)
|
| 6 |
+
if(PNG_FOUND)
|
| 7 |
+
target_compile_definitions(${COMPONENT} PRIVATE HAVE_PNG)
|
| 8 |
+
target_include_directories(${COMPONENT} PRIVATE ${PNG_INCLUDE_DIR} )
|
| 9 |
+
target_link_libraries(${COMPONENT} PRIVATE ${PNG_LIBRARY} ${ZLIB_LIBRARY})
|
| 10 |
+
message(STATUS "libpng Found and Enabled")
|
| 11 |
+
endif()
|
| 12 |
+
endif()
|
| 13 |
+
|
| 14 |
+
option(BUILD_PANGOLIN_LIBJPEG "Build support for libjpeg image input" ON)
|
| 15 |
+
if(BUILD_PANGOLIN_LIBJPEG)
|
| 16 |
+
find_package(JPEG QUIET)
|
| 17 |
+
if(JPEG_FOUND)
|
| 18 |
+
target_compile_definitions(${COMPONENT} PRIVATE HAVE_JPEG)
|
| 19 |
+
target_include_directories(${COMPONENT} PRIVATE ${JPEG_INCLUDE_DIR} )
|
| 20 |
+
target_link_libraries(${COMPONENT} PRIVATE ${JPEG_LIBRARY})
|
| 21 |
+
message(STATUS "libjpeg Found and Enabled")
|
| 22 |
+
endif()
|
| 23 |
+
endif()
|
| 24 |
+
|
| 25 |
+
option(BUILD_PANGOLIN_LIBTIFF "Build support for libtiff image input" ON)
|
| 26 |
+
if(BUILD_PANGOLIN_LIBTIFF)
|
| 27 |
+
find_package(TIFF QUIET)
|
| 28 |
+
if(TIFF_FOUND)
|
| 29 |
+
target_compile_definitions(${COMPONENT} PRIVATE HAVE_LIBTIFF)
|
| 30 |
+
target_include_directories(${COMPONENT} PRIVATE ${TIFF_INCLUDE_DIR} )
|
| 31 |
+
target_link_libraries(${COMPONENT} PRIVATE ${TIFF_LIBRARY})
|
| 32 |
+
message(STATUS "libtiff Found and Enabled")
|
| 33 |
+
endif()
|
| 34 |
+
endif()
|
| 35 |
+
|
| 36 |
+
option(BUILD_PANGOLIN_LIBOPENEXR "Build support for libopenexr image input" ON)
|
| 37 |
+
if(BUILD_PANGOLIN_LIBOPENEXR)
|
| 38 |
+
find_package(OpenEXR QUIET)
|
| 39 |
+
if(OpenEXR_FOUND)
|
| 40 |
+
target_compile_definitions(${COMPONENT} PRIVATE HAVE_OPENEXR)
|
| 41 |
+
target_include_directories(${COMPONENT} PRIVATE ${OpenEXR_INCLUDE_DIR} )
|
| 42 |
+
target_link_libraries(${COMPONENT} PRIVATE ${OpenEXR_LIBRARY})
|
| 43 |
+
target_compile_options(${COMPONENT} PRIVATE
|
| 44 |
+
$<$<OR:$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
|
| 45 |
+
-Wno-deprecated-register -Wno-deprecated>
|
| 46 |
+
)
|
| 47 |
+
# https://github.com/stevenlovegrove/Pangolin/issues/677
|
| 48 |
+
set_target_properties(${COMPONENT} PROPERTIES CXX_STANDARD 11)
|
| 49 |
+
message(STATUS "libopenexr Found and Enabled")
|
| 50 |
+
endif()
|
| 51 |
+
endif()
|
| 52 |
+
|
| 53 |
+
option(BUILD_PANGOLIN_LZ4 "Build support for liblz4 compression" ON)
|
| 54 |
+
if(BUILD_PANGOLIN_LZ4)
|
| 55 |
+
find_package(Lz4 QUIET)
|
| 56 |
+
if(Lz4_FOUND)
|
| 57 |
+
target_compile_definitions(${COMPONENT} PRIVATE HAVE_LZ4)
|
| 58 |
+
target_include_directories(${COMPONENT} PRIVATE ${Lz4_INCLUDE_DIRS} )
|
| 59 |
+
target_link_libraries(${COMPONENT} PRIVATE ${Lz4_LIBRARIES})
|
| 60 |
+
message(STATUS "liblz4 Found and Enabled")
|
| 61 |
+
endif()
|
| 62 |
+
endif()
|
| 63 |
+
|
| 64 |
+
option(BUILD_PANGOLIN_ZSTD "Build support for libzstd compression" ON)
|
| 65 |
+
if(BUILD_PANGOLIN_ZSTD)
|
| 66 |
+
find_package(zstd QUIET)
|
| 67 |
+
if(zstd_FOUND)
|
| 68 |
+
target_compile_definitions(${COMPONENT} PRIVATE HAVE_ZSTD)
|
| 69 |
+
target_include_directories(${COMPONENT} PRIVATE ${zstd_INCLUDE_DIR} )
|
| 70 |
+
target_link_libraries(${COMPONENT} PRIVATE ${zstd_LIBRARY})
|
| 71 |
+
message(STATUS "libzstd Found and Enabled")
|
| 72 |
+
endif()
|
| 73 |
+
endif()
|
| 74 |
+
|
| 75 |
+
option(BUILD_PANGOLIN_LIBRAW "Build support for raw images (libraw)" ON)
|
| 76 |
+
if(BUILD_PANGOLIN_LIBRAW)
|
| 77 |
+
find_package(libraw QUIET)
|
| 78 |
+
if(libraw_FOUND)
|
| 79 |
+
target_compile_definitions(${COMPONENT} PRIVATE HAVE_LIBRAW)
|
| 80 |
+
target_include_directories(${COMPONENT} PRIVATE ${libraw_INCLUDE_DIR} )
|
| 81 |
+
target_link_libraries(${COMPONENT} PRIVATE ${libraw_LIBRARIES})
|
| 82 |
+
message(STATUS "libraw Found and Enabled")
|
| 83 |
+
endif()
|
| 84 |
+
endif()
|
| 85 |
+
|
| 86 |
+
target_sources( ${COMPONENT}
|
| 87 |
+
PRIVATE
|
| 88 |
+
${CMAKE_CURRENT_LIST_DIR}/src/pixel_format.cpp
|
| 89 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io.cpp
|
| 90 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_exr.cpp
|
| 91 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_jpg.cpp
|
| 92 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_lz4.cpp
|
| 93 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_packed12bit.cpp
|
| 94 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_pango.cpp
|
| 95 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_png.cpp
|
| 96 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_ppm.cpp
|
| 97 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_raw.cpp
|
| 98 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_tga.cpp
|
| 99 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_bmp.cpp
|
| 100 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_zstd.cpp
|
| 101 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_libraw.cpp
|
| 102 |
+
${CMAKE_CURRENT_LIST_DIR}/src/image_io_tiff.cpp
|
| 103 |
+
)
|
| 104 |
+
|
| 105 |
+
target_link_libraries(${COMPONENT} PUBLIC pango_core)
|
| 106 |
+
target_include_directories(${COMPONENT} PUBLIC
|
| 107 |
+
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
|
| 108 |
+
$<INSTALL_INTERFACE:include>
|
| 109 |
+
)
|
| 110 |
+
install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/include"
|
| 111 |
+
DESTINATION ${CMAKE_INSTALL_PREFIX}
|
| 112 |
+
)
|
third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/copy.h
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
namespace pangolin {
|
| 31 |
+
|
| 32 |
+
// Hold a reference to an object to be copied
|
| 33 |
+
template<typename T>
|
| 34 |
+
struct CopyObject {
|
| 35 |
+
CopyObject(const T& obj) : obj(obj) { }
|
| 36 |
+
const T& obj;
|
| 37 |
+
};
|
| 38 |
+
|
| 39 |
+
// Return copy wrapper for assignment to another object.
|
| 40 |
+
template<typename T>
|
| 41 |
+
typename pangolin::CopyObject<T> Copy(const T& obj) {
|
| 42 |
+
return typename pangolin::CopyObject<T>(obj);
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/image.h
ADDED
|
@@ -0,0 +1,428 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/platform.h>
|
| 31 |
+
#include <pangolin/image/memcpy.h>
|
| 32 |
+
|
| 33 |
+
#include <cstddef>
|
| 34 |
+
#include <functional>
|
| 35 |
+
#include <limits>
|
| 36 |
+
#include <cstring>
|
| 37 |
+
|
| 38 |
+
#ifdef PANGO_ENABLE_BOUNDS_CHECKS
|
| 39 |
+
# define PANGO_BOUNDS_ASSERT(...) PANGO_ENSURE(##__VA_ARGS__)
|
| 40 |
+
#else
|
| 41 |
+
# define PANGO_BOUNDS_ASSERT(...) ((void)0)
|
| 42 |
+
#endif
|
| 43 |
+
|
| 44 |
+
// Allow user defined macro to be inserted into Image class.
|
| 45 |
+
#ifndef PANGO_EXTENSION_IMAGE
|
| 46 |
+
# define PANGO_EXTENSION_IMAGE
|
| 47 |
+
#endif
|
| 48 |
+
|
| 49 |
+
namespace pangolin
|
| 50 |
+
{
|
| 51 |
+
|
| 52 |
+
// Simple image wrapper
|
| 53 |
+
template<typename T>
|
| 54 |
+
struct Image
|
| 55 |
+
{
|
| 56 |
+
using PixelType = T;
|
| 57 |
+
|
| 58 |
+
inline Image()
|
| 59 |
+
: pitch(0), ptr(0), w(0), h(0)
|
| 60 |
+
{
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
inline Image(T* ptr, size_t w, size_t h, size_t pitch)
|
| 64 |
+
: pitch(pitch), ptr(ptr), w(w), h(h)
|
| 65 |
+
{
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
PANGO_HOST_DEVICE inline
|
| 70 |
+
size_t SizeBytes() const
|
| 71 |
+
{
|
| 72 |
+
return pitch * h;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
PANGO_HOST_DEVICE inline
|
| 76 |
+
size_t Area() const
|
| 77 |
+
{
|
| 78 |
+
return w * h;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
PANGO_HOST_DEVICE inline
|
| 82 |
+
bool IsValid() const
|
| 83 |
+
{
|
| 84 |
+
return ptr != 0;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
PANGO_HOST_DEVICE inline
|
| 88 |
+
bool IsContiguous() const
|
| 89 |
+
{
|
| 90 |
+
return w*sizeof(T) == pitch;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
//////////////////////////////////////////////////////
|
| 94 |
+
// Iterators
|
| 95 |
+
//////////////////////////////////////////////////////
|
| 96 |
+
|
| 97 |
+
PANGO_HOST_DEVICE inline
|
| 98 |
+
T* begin()
|
| 99 |
+
{
|
| 100 |
+
return ptr;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
PANGO_HOST_DEVICE inline
|
| 104 |
+
T* end()
|
| 105 |
+
{
|
| 106 |
+
return RowPtr(h-1) + w;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
PANGO_HOST_DEVICE inline
|
| 110 |
+
const T* begin() const
|
| 111 |
+
{
|
| 112 |
+
return ptr;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
PANGO_HOST_DEVICE inline
|
| 116 |
+
const T* end() const
|
| 117 |
+
{
|
| 118 |
+
return RowPtr(h-1) + w;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
PANGO_HOST_DEVICE inline
|
| 122 |
+
size_t size() const
|
| 123 |
+
{
|
| 124 |
+
return w*h;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
//////////////////////////////////////////////////////
|
| 128 |
+
// Image transforms
|
| 129 |
+
//////////////////////////////////////////////////////
|
| 130 |
+
|
| 131 |
+
template<typename UnaryOperation>
|
| 132 |
+
PANGO_HOST_DEVICE inline
|
| 133 |
+
void Transform(UnaryOperation unary_op)
|
| 134 |
+
{
|
| 135 |
+
PANGO_ASSERT(IsValid());
|
| 136 |
+
|
| 137 |
+
for(size_t y=0; y < h; ++y) {
|
| 138 |
+
T* el = RowPtr(y);
|
| 139 |
+
const T* el_end = el+w;
|
| 140 |
+
for( ; el != el_end; ++el) {
|
| 141 |
+
*el = unary_op(*el);
|
| 142 |
+
}
|
| 143 |
+
}
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
PANGO_HOST_DEVICE inline
|
| 147 |
+
void Fill(const T& val)
|
| 148 |
+
{
|
| 149 |
+
Transform( [&](const T&) {return val;} );
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
PANGO_HOST_DEVICE inline
|
| 153 |
+
void Replace(const T& oldval, const T& newval)
|
| 154 |
+
{
|
| 155 |
+
Transform( [&](const T& val) {
|
| 156 |
+
return (val == oldval) ? newval : val;
|
| 157 |
+
});
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
inline
|
| 161 |
+
void Memset(unsigned char v = 0)
|
| 162 |
+
{
|
| 163 |
+
PANGO_ASSERT(IsValid());
|
| 164 |
+
if(IsContiguous()) {
|
| 165 |
+
::pangolin::Memset((char*)ptr, v, pitch*h);
|
| 166 |
+
}else{
|
| 167 |
+
for(size_t y=0; y < h; ++y) {
|
| 168 |
+
::pangolin::Memset((char*)RowPtr(y), v, pitch);
|
| 169 |
+
}
|
| 170 |
+
}
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
inline
|
| 174 |
+
void CopyFrom(const Image<T>& img)
|
| 175 |
+
{
|
| 176 |
+
if(IsValid() && img.IsValid()) {
|
| 177 |
+
PANGO_ASSERT(w >= img.w && h >= img.h);
|
| 178 |
+
PitchedCopy((char*)ptr,pitch,(char*)img.ptr,img.pitch, std::min(img.w,w)*sizeof(T), std::min(img.h,h) );
|
| 179 |
+
}else if( img.IsValid() != IsValid() ){
|
| 180 |
+
PANGO_ASSERT(false && "Cannot copy from / to an unasigned image." );
|
| 181 |
+
}
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
//////////////////////////////////////////////////////
|
| 185 |
+
// Reductions
|
| 186 |
+
//////////////////////////////////////////////////////
|
| 187 |
+
|
| 188 |
+
template<typename BinaryOperation>
|
| 189 |
+
PANGO_HOST_DEVICE inline
|
| 190 |
+
T Accumulate(const T init, BinaryOperation binary_op)
|
| 191 |
+
{
|
| 192 |
+
PANGO_ASSERT(IsValid());
|
| 193 |
+
|
| 194 |
+
T val = init;
|
| 195 |
+
for(size_t y=0; y < h; ++y) {
|
| 196 |
+
T* el = RowPtr(y);
|
| 197 |
+
const T* el_end = el+w;
|
| 198 |
+
for(; el != el_end; ++el) {
|
| 199 |
+
val = binary_op(val, *el);
|
| 200 |
+
}
|
| 201 |
+
}
|
| 202 |
+
return val;
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
std::pair<T,T> MinMax() const
|
| 206 |
+
{
|
| 207 |
+
PANGO_ASSERT(IsValid());
|
| 208 |
+
|
| 209 |
+
std::pair<T,T> minmax(std::numeric_limits<T>::max(), std::numeric_limits<T>::lowest());
|
| 210 |
+
for(size_t r=0; r < h; ++r) {
|
| 211 |
+
const T* ptr = RowPtr(r);
|
| 212 |
+
const T* end = ptr + w;
|
| 213 |
+
while( ptr != end) {
|
| 214 |
+
minmax.first = std::min(*ptr, minmax.first);
|
| 215 |
+
minmax.second = std::max(*ptr, minmax.second);
|
| 216 |
+
++ptr;
|
| 217 |
+
}
|
| 218 |
+
}
|
| 219 |
+
return minmax;
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
template<typename Tout=T>
|
| 223 |
+
Tout Sum() const
|
| 224 |
+
{
|
| 225 |
+
return Accumulate((T)0, [](const T& lhs, const T& rhs){ return lhs + rhs; });
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
template<typename Tout=T>
|
| 229 |
+
Tout Mean() const
|
| 230 |
+
{
|
| 231 |
+
return Sum<Tout>() / Area();
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
|
| 235 |
+
//////////////////////////////////////////////////////
|
| 236 |
+
// Direct Pixel Access
|
| 237 |
+
//////////////////////////////////////////////////////
|
| 238 |
+
|
| 239 |
+
PANGO_HOST_DEVICE inline
|
| 240 |
+
T* RowPtr(size_t y)
|
| 241 |
+
{
|
| 242 |
+
return (T*)((unsigned char*)(ptr) + y*pitch);
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
PANGO_HOST_DEVICE inline
|
| 246 |
+
const T* RowPtr(size_t y) const
|
| 247 |
+
{
|
| 248 |
+
return (T*)((unsigned char*)(ptr) + y*pitch);
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
PANGO_HOST_DEVICE inline
|
| 252 |
+
T& operator()(size_t x, size_t y)
|
| 253 |
+
{
|
| 254 |
+
PANGO_BOUNDS_ASSERT( InBounds(x,y) );
|
| 255 |
+
return RowPtr(y)[x];
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
PANGO_HOST_DEVICE inline
|
| 259 |
+
const T& operator()(size_t x, size_t y) const
|
| 260 |
+
{
|
| 261 |
+
PANGO_BOUNDS_ASSERT( InBounds(x,y) );
|
| 262 |
+
return RowPtr(y)[x];
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
template<typename TVec>
|
| 266 |
+
PANGO_HOST_DEVICE inline
|
| 267 |
+
T& operator()(const TVec& p)
|
| 268 |
+
{
|
| 269 |
+
PANGO_BOUNDS_ASSERT( InBounds(p[0],p[1]) );
|
| 270 |
+
return RowPtr(p[1])[p[0]];
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
template<typename TVec>
|
| 274 |
+
PANGO_HOST_DEVICE inline
|
| 275 |
+
const T& operator()(const TVec& p) const
|
| 276 |
+
{
|
| 277 |
+
PANGO_BOUNDS_ASSERT( InBounds(p[0],p[1]) );
|
| 278 |
+
return RowPtr(p[1])[p[0]];
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
PANGO_HOST_DEVICE inline
|
| 282 |
+
T& operator[](size_t ix)
|
| 283 |
+
{
|
| 284 |
+
PANGO_BOUNDS_ASSERT( InImage(ptr+ix) );
|
| 285 |
+
return ptr[ix];
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
PANGO_HOST_DEVICE inline
|
| 289 |
+
const T& operator[](size_t ix) const
|
| 290 |
+
{
|
| 291 |
+
PANGO_BOUNDS_ASSERT( InImage(ptr+ix) );
|
| 292 |
+
return ptr[ix];
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
//////////////////////////////////////////////////////
|
| 296 |
+
// Bounds Checking
|
| 297 |
+
//////////////////////////////////////////////////////
|
| 298 |
+
|
| 299 |
+
PANGO_HOST_DEVICE
|
| 300 |
+
bool InImage(const T* ptest) const
|
| 301 |
+
{
|
| 302 |
+
return ptr <= ptest && ptest < RowPtr(h);
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
PANGO_HOST_DEVICE inline
|
| 306 |
+
bool InBounds(int x, int y) const
|
| 307 |
+
{
|
| 308 |
+
return 0 <= x && x < (int)w && 0 <= y && y < (int)h;
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
PANGO_HOST_DEVICE inline
|
| 312 |
+
bool InBounds(float x, float y, float border) const
|
| 313 |
+
{
|
| 314 |
+
return border <= x && x < (w-border) && border <= y && y < (h-border);
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
template<typename TVec, typename TBorder>
|
| 318 |
+
PANGO_HOST_DEVICE inline
|
| 319 |
+
bool InBounds( const TVec& p, const TBorder border = (TBorder)0 ) const
|
| 320 |
+
{
|
| 321 |
+
return border <= p[0] && p[0] < ((int)w - border) && border <= p[1] && p[1] < ((int)h - border);
|
| 322 |
+
}
|
| 323 |
+
|
| 324 |
+
//////////////////////////////////////////////////////
|
| 325 |
+
// Obtain slices / subimages
|
| 326 |
+
//////////////////////////////////////////////////////
|
| 327 |
+
|
| 328 |
+
PANGO_HOST_DEVICE inline
|
| 329 |
+
const Image<const T> SubImage(size_t x, size_t y, size_t width, size_t height) const
|
| 330 |
+
{
|
| 331 |
+
PANGO_ASSERT( (x+width) <= w && (y+height) <= h);
|
| 332 |
+
return Image<const T>( RowPtr(y)+x, width, height, pitch);
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
+
PANGO_HOST_DEVICE inline
|
| 336 |
+
Image<T> SubImage(size_t x, size_t y, size_t width, size_t height)
|
| 337 |
+
{
|
| 338 |
+
PANGO_ASSERT( (x+width) <= w && (y+height) <= h);
|
| 339 |
+
return Image<T>( RowPtr(y)+x, width, height, pitch);
|
| 340 |
+
}
|
| 341 |
+
|
| 342 |
+
PANGO_HOST_DEVICE inline
|
| 343 |
+
const Image<T> Row(int y) const
|
| 344 |
+
{
|
| 345 |
+
return SubImage(0,y,w,1);
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
PANGO_HOST_DEVICE inline
|
| 349 |
+
Image<T> Row(int y)
|
| 350 |
+
{
|
| 351 |
+
return SubImage(0,y,w,1);
|
| 352 |
+
}
|
| 353 |
+
|
| 354 |
+
PANGO_HOST_DEVICE inline
|
| 355 |
+
const Image<T> Col(int x) const
|
| 356 |
+
{
|
| 357 |
+
return SubImage(x,0,1,h);
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
PANGO_HOST_DEVICE inline
|
| 361 |
+
Image<T> Col(int x)
|
| 362 |
+
{
|
| 363 |
+
return SubImage(x,0,1,h);
|
| 364 |
+
}
|
| 365 |
+
|
| 366 |
+
//////////////////////////////////////////////////////
|
| 367 |
+
// Data mangling
|
| 368 |
+
//////////////////////////////////////////////////////
|
| 369 |
+
|
| 370 |
+
template<typename TRecast>
|
| 371 |
+
PANGO_HOST_DEVICE inline
|
| 372 |
+
Image<TRecast> Reinterpret() const
|
| 373 |
+
{
|
| 374 |
+
PANGO_ASSERT(sizeof(TRecast) == sizeof(T), "sizeof(TRecast) must match sizeof(T): % != %", sizeof(TRecast), sizeof(T) );
|
| 375 |
+
return UnsafeReinterpret<TRecast>();
|
| 376 |
+
}
|
| 377 |
+
|
| 378 |
+
template<typename TRecast>
|
| 379 |
+
PANGO_HOST_DEVICE inline
|
| 380 |
+
Image<TRecast> UnsafeReinterpret() const
|
| 381 |
+
{
|
| 382 |
+
return Image<TRecast>((TRecast*)ptr,w,h,pitch);
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
+
//////////////////////////////////////////////////////
|
| 386 |
+
// Deprecated methods
|
| 387 |
+
//////////////////////////////////////////////////////
|
| 388 |
+
|
| 389 |
+
// PANGOLIN_DEPRECATED inline
|
| 390 |
+
Image(size_t w, size_t h, size_t pitch, T* ptr)
|
| 391 |
+
: pitch(pitch), ptr(ptr), w(w), h(h)
|
| 392 |
+
{
|
| 393 |
+
}
|
| 394 |
+
|
| 395 |
+
// Use RAII/move aware pangolin::ManagedImage instead
|
| 396 |
+
// PANGOLIN_DEPRECATED inline
|
| 397 |
+
void Dealloc()
|
| 398 |
+
{
|
| 399 |
+
if(ptr) {
|
| 400 |
+
::operator delete(ptr);
|
| 401 |
+
ptr = nullptr;
|
| 402 |
+
}
|
| 403 |
+
}
|
| 404 |
+
|
| 405 |
+
// Use RAII/move aware pangolin::ManagedImage instead
|
| 406 |
+
// PANGOLIN_DEPRECATED inline
|
| 407 |
+
void Alloc(size_t w, size_t h, size_t pitch)
|
| 408 |
+
{
|
| 409 |
+
Dealloc();
|
| 410 |
+
this->w = w;
|
| 411 |
+
this->h = h;
|
| 412 |
+
this->pitch = pitch;
|
| 413 |
+
this->ptr = (T*)::operator new(h*pitch);
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
//////////////////////////////////////////////////////
|
| 417 |
+
// Data members
|
| 418 |
+
//////////////////////////////////////////////////////
|
| 419 |
+
|
| 420 |
+
size_t pitch;
|
| 421 |
+
T* ptr;
|
| 422 |
+
size_t w;
|
| 423 |
+
size_t h;
|
| 424 |
+
|
| 425 |
+
PANGO_EXTENSION_IMAGE
|
| 426 |
+
};
|
| 427 |
+
|
| 428 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/image_convert.h
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <pangolin/image/managed_image.h>
|
| 4 |
+
#include <pangolin/utils/compontent_cast.h>
|
| 5 |
+
|
| 6 |
+
namespace pangolin
|
| 7 |
+
{
|
| 8 |
+
|
| 9 |
+
template <typename To, typename T>
|
| 10 |
+
void ImageConvert(Image<To>& dst, const Image<T>& src, To scale = 1.0)
|
| 11 |
+
{
|
| 12 |
+
for(unsigned int y = 0; y < dst.h; ++y)
|
| 13 |
+
{
|
| 14 |
+
const T* prs = src.RowPtr(y);
|
| 15 |
+
To* prd = dst.RowPtr(y);
|
| 16 |
+
for(unsigned int x = 0; x < dst.w; ++x)
|
| 17 |
+
{
|
| 18 |
+
*(prd++) = scale * ComponentCast<To, T>::cast(*(prs++));
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
template <typename To, typename T>
|
| 24 |
+
ManagedImage<To> ImageConvert(const Image<T>& src, To scale = 1.0)
|
| 25 |
+
{
|
| 26 |
+
ManagedImage<To> dst(src.w, src.h);
|
| 27 |
+
ImageConvert<To,T>(dst,src,scale);
|
| 28 |
+
return dst;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/image_io.h
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2013 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/platform.h>
|
| 31 |
+
|
| 32 |
+
#include <pangolin/image/typed_image.h>
|
| 33 |
+
#include <pangolin/utils/file_extension.h>
|
| 34 |
+
|
| 35 |
+
namespace pangolin {
|
| 36 |
+
|
| 37 |
+
PANGOLIN_EXPORT
|
| 38 |
+
TypedImage LoadImage(std::istream& in, ImageFileType file_type);
|
| 39 |
+
|
| 40 |
+
PANGOLIN_EXPORT
|
| 41 |
+
TypedImage LoadImage(const std::string& filename, ImageFileType file_type);
|
| 42 |
+
|
| 43 |
+
PANGOLIN_EXPORT
|
| 44 |
+
TypedImage LoadImage(const std::string& filename);
|
| 45 |
+
|
| 46 |
+
PANGOLIN_EXPORT
|
| 47 |
+
TypedImage LoadImage(const std::string& filename, const PixelFormat& raw_fmt, size_t raw_width, size_t raw_height, size_t raw_pitch);
|
| 48 |
+
|
| 49 |
+
/// Quality \in [0..100] for lossy formats
|
| 50 |
+
PANGOLIN_EXPORT
|
| 51 |
+
void SaveImage(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, ImageFileType file_type, bool top_line_first = true, float quality = 100.0f);
|
| 52 |
+
|
| 53 |
+
/// Quality \in [0..100] for lossy formats
|
| 54 |
+
PANGOLIN_EXPORT
|
| 55 |
+
void SaveImage(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, const std::string& filename, ImageFileType file_type, bool top_line_first = true, float quality = 100.0f);
|
| 56 |
+
|
| 57 |
+
/// Quality \in [0..100] for lossy formats
|
| 58 |
+
PANGOLIN_EXPORT
|
| 59 |
+
void SaveImage(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, const std::string& filename, bool top_line_first = true, float quality = 100.0f);
|
| 60 |
+
|
| 61 |
+
/// Quality \in [0..100] for lossy formats
|
| 62 |
+
PANGOLIN_EXPORT
|
| 63 |
+
void SaveImage(const TypedImage& image, const std::string& filename, bool top_line_first = true, float quality = 100.0f);
|
| 64 |
+
|
| 65 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/image_utils.h
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2013 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <limits>
|
| 31 |
+
#include <utility>
|
| 32 |
+
|
| 33 |
+
#include <pangolin/image/image.h>
|
| 34 |
+
#include <pangolin/utils/range.h>
|
| 35 |
+
#include <pangolin/gl/gl.h>
|
| 36 |
+
#include <pangolin/gl/glpixformat.h>
|
| 37 |
+
|
| 38 |
+
namespace pangolin
|
| 39 |
+
{
|
| 40 |
+
|
| 41 |
+
namespace internal
|
| 42 |
+
{
|
| 43 |
+
|
| 44 |
+
template <typename T>
|
| 45 |
+
std::pair<float, float> GetMinMax(const Image<T>& img, size_t channels)
|
| 46 |
+
{
|
| 47 |
+
const size_t max_channels = 3;
|
| 48 |
+
const size_t colour_channels = std::min(channels, max_channels);
|
| 49 |
+
std::pair<float, float> chan_mm[max_channels];
|
| 50 |
+
for(size_t c = 0; c < max_channels; ++c)
|
| 51 |
+
{
|
| 52 |
+
chan_mm[c].first = +std::numeric_limits<float>::max();
|
| 53 |
+
chan_mm[c].second = -std::numeric_limits<float>::max();
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
for(size_t y = 0; y < img.h; ++y)
|
| 57 |
+
{
|
| 58 |
+
T* pix = (T*)((char*)img.ptr + y * img.pitch);
|
| 59 |
+
for(size_t x = 0; x < img.w; ++x)
|
| 60 |
+
{
|
| 61 |
+
for(size_t c = 0; c < colour_channels; ++c)
|
| 62 |
+
{
|
| 63 |
+
if(pix[c] < chan_mm[c].first)
|
| 64 |
+
chan_mm[c].first = (float)pix[c];
|
| 65 |
+
if(pix[c] > chan_mm[c].second)
|
| 66 |
+
chan_mm[c].second = (float)pix[c];
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
pix += channels;
|
| 70 |
+
}
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
// Find min / max of all channels, ignoring 4th alpha channel
|
| 74 |
+
std::pair<float, float> mm = chan_mm[0];
|
| 75 |
+
for(size_t c = 1; c < colour_channels; ++c)
|
| 76 |
+
{
|
| 77 |
+
mm.first = std::min(mm.first, chan_mm[c].first);
|
| 78 |
+
mm.second = std::max(mm.second, chan_mm[c].second);
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
return mm;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
template<typename T>
|
| 85 |
+
pangolin::Image<T> GetImageRoi( pangolin::Image<T> img, size_t channels, const pangolin::XYRangei& roi )
|
| 86 |
+
{
|
| 87 |
+
return pangolin::Image<T>(
|
| 88 |
+
img.RowPtr(std::min(roi.y.min,roi.y.max)) + channels*std::min(roi.x.min,roi.x.max),
|
| 89 |
+
roi.x.AbsSize(), roi.y.AbsSize(),
|
| 90 |
+
img.pitch
|
| 91 |
+
);
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
template<typename T>
|
| 95 |
+
std::pair<float,float> GetOffsetScale(const pangolin::Image<T>& img, size_t channels, float type_max, float format_max)
|
| 96 |
+
{
|
| 97 |
+
// Find min / max of all channels, ignoring 4th alpha channel
|
| 98 |
+
const std::pair<float,float> mm = internal::GetMinMax<T>(img,channels);
|
| 99 |
+
const float type_scale = format_max / type_max;
|
| 100 |
+
const float offset = -type_scale* mm.first;
|
| 101 |
+
const float scale = type_max / (mm.second - mm.first);
|
| 102 |
+
return std::pair<float,float>(offset, scale);
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
template<typename T>
|
| 106 |
+
float GetScaleOnly(const pangolin::Image<T>& img, size_t channels, float type_max, float /*format_max*/)
|
| 107 |
+
{
|
| 108 |
+
// Find min / max of all channels, ignoring 4th alpha channel
|
| 109 |
+
const std::pair<float,float> mm = internal::GetMinMax<T>(img,channels);
|
| 110 |
+
const float scale = type_max / mm.second;
|
| 111 |
+
return scale;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
} // internal
|
| 115 |
+
|
| 116 |
+
inline std::pair<float, float> GetMinMax(
|
| 117 |
+
const Image<unsigned char>& img,
|
| 118 |
+
XYRangei iroi, const GlPixFormat& glfmt
|
| 119 |
+
) {
|
| 120 |
+
using namespace internal;
|
| 121 |
+
|
| 122 |
+
iroi.Clamp(0, (int)img.w - 1, 0, (int)img.h - 1);
|
| 123 |
+
|
| 124 |
+
const size_t num_channels = pangolin::GlFormatChannels(glfmt.glformat);
|
| 125 |
+
|
| 126 |
+
if(glfmt.gltype == GL_UNSIGNED_BYTE) {
|
| 127 |
+
return GetMinMax(GetImageRoi(img.template UnsafeReinterpret<unsigned char>(), num_channels, iroi), num_channels);
|
| 128 |
+
} else if(glfmt.gltype == GL_UNSIGNED_SHORT) {
|
| 129 |
+
return GetMinMax(GetImageRoi(img.template UnsafeReinterpret<unsigned short>(), num_channels, iroi), num_channels);
|
| 130 |
+
} else if(glfmt.gltype == GL_FLOAT) {
|
| 131 |
+
return GetMinMax(GetImageRoi(img.template UnsafeReinterpret<float>(), num_channels, iroi), num_channels);
|
| 132 |
+
} else if(glfmt.gltype == GL_DOUBLE) {
|
| 133 |
+
return GetMinMax(GetImageRoi(img.template UnsafeReinterpret<double>(), num_channels, iroi), num_channels);
|
| 134 |
+
} else {
|
| 135 |
+
return std::pair<float, float>(std::numeric_limits<float>::max(), std::numeric_limits<float>::lowest());
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
inline std::pair<float,float> GetOffsetScale(
|
| 140 |
+
const pangolin::Image<unsigned char>& img,
|
| 141 |
+
pangolin::XYRangei iroi, const pangolin::GlPixFormat& glfmt
|
| 142 |
+
) {
|
| 143 |
+
using namespace internal;
|
| 144 |
+
|
| 145 |
+
iroi.Clamp(0, (int)img.w-1, 0, (int)img.h-1 );
|
| 146 |
+
|
| 147 |
+
const size_t num_channels = pangolin::GlFormatChannels(glfmt.glformat);
|
| 148 |
+
|
| 149 |
+
if(glfmt.gltype == GL_UNSIGNED_BYTE) {
|
| 150 |
+
return GetOffsetScale(GetImageRoi(img.template UnsafeReinterpret<unsigned char>(), num_channels, iroi), num_channels, 255.0f, 1.0f);
|
| 151 |
+
}else if(glfmt.gltype == GL_UNSIGNED_SHORT) {
|
| 152 |
+
return GetOffsetScale(GetImageRoi(img.template UnsafeReinterpret<unsigned short>(), num_channels, iroi), num_channels, 65535.0f, 1.0f);
|
| 153 |
+
}else if(glfmt.gltype == GL_FLOAT) {
|
| 154 |
+
return GetOffsetScale(GetImageRoi(img.template UnsafeReinterpret<float>(), num_channels, iroi), num_channels, 1.0f, 1.0f);
|
| 155 |
+
}else if(glfmt.gltype == GL_DOUBLE) {
|
| 156 |
+
return GetOffsetScale(GetImageRoi(img.template UnsafeReinterpret<double>(), num_channels, iroi), num_channels, 1.0f, 1.0f);
|
| 157 |
+
}else{
|
| 158 |
+
return std::pair<float,float>(0.0f, 1.0f);
|
| 159 |
+
}
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
inline float GetScaleOnly(
|
| 163 |
+
const pangolin::Image<unsigned char>& img,
|
| 164 |
+
pangolin::XYRangei iroi, const pangolin::GlPixFormat& glfmt
|
| 165 |
+
) {
|
| 166 |
+
using namespace internal;
|
| 167 |
+
|
| 168 |
+
iroi.Clamp(0, (int)img.w-1, 0, (int)img.h-1 );
|
| 169 |
+
|
| 170 |
+
const size_t num_channels = pangolin::GlFormatChannels(glfmt.glformat);
|
| 171 |
+
|
| 172 |
+
if(glfmt.gltype == GL_UNSIGNED_BYTE) {
|
| 173 |
+
return GetScaleOnly(GetImageRoi(img.template UnsafeReinterpret<unsigned char>(), num_channels, iroi), num_channels, 255.0f, 1.0f);
|
| 174 |
+
}else if(glfmt.gltype == GL_UNSIGNED_SHORT) {
|
| 175 |
+
return GetScaleOnly(GetImageRoi(img.template UnsafeReinterpret<unsigned short>(), num_channels, iroi), num_channels, 65535.0f, 1.0f);
|
| 176 |
+
}else if(glfmt.gltype == GL_FLOAT) {
|
| 177 |
+
return GetScaleOnly(GetImageRoi(img.template UnsafeReinterpret<float>(), num_channels, iroi), num_channels, 1.0f, 1.0f);
|
| 178 |
+
}else if(glfmt.gltype == GL_DOUBLE) {
|
| 179 |
+
return GetScaleOnly(GetImageRoi(img.template UnsafeReinterpret<double>(), num_channels, iroi), num_channels, 1.0f, 1.0f);
|
| 180 |
+
}else{
|
| 181 |
+
return 1.0f;
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/managed_image.h
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/image/image.h>
|
| 31 |
+
#include <pangolin/image/copy.h>
|
| 32 |
+
|
| 33 |
+
namespace pangolin {
|
| 34 |
+
|
| 35 |
+
template<class T> using DefaultImageAllocator = std::allocator<T>;
|
| 36 |
+
|
| 37 |
+
// Image that manages it's own memory, storing a strong pointer to it's memory
|
| 38 |
+
template<typename T, class Allocator = DefaultImageAllocator<T> >
|
| 39 |
+
class ManagedImage : public Image<T>
|
| 40 |
+
{
|
| 41 |
+
public:
|
| 42 |
+
// Destructor
|
| 43 |
+
inline
|
| 44 |
+
~ManagedImage()
|
| 45 |
+
{
|
| 46 |
+
Deallocate();
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
// Null image
|
| 50 |
+
inline
|
| 51 |
+
ManagedImage()
|
| 52 |
+
{
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
// Row image
|
| 56 |
+
inline
|
| 57 |
+
ManagedImage(size_t w)
|
| 58 |
+
: Image<T>(
|
| 59 |
+
Allocator().allocate(w),
|
| 60 |
+
w, 1, w*sizeof(T)
|
| 61 |
+
)
|
| 62 |
+
{
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
inline
|
| 66 |
+
ManagedImage(size_t w, size_t h)
|
| 67 |
+
: Image<T>(
|
| 68 |
+
Allocator().allocate(w*h),
|
| 69 |
+
w, h, w*sizeof(T)
|
| 70 |
+
)
|
| 71 |
+
{
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
inline
|
| 75 |
+
ManagedImage(size_t w, size_t h, size_t pitch_bytes)
|
| 76 |
+
: Image<T>(
|
| 77 |
+
Allocator().allocate( (h*pitch_bytes) / sizeof(T)),
|
| 78 |
+
w, h, pitch_bytes)
|
| 79 |
+
{
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
// Not copy constructable
|
| 83 |
+
inline
|
| 84 |
+
ManagedImage( const ManagedImage<T>& other ) = delete;
|
| 85 |
+
|
| 86 |
+
// Move constructor
|
| 87 |
+
inline
|
| 88 |
+
ManagedImage(ManagedImage<T,Allocator>&& img)
|
| 89 |
+
{
|
| 90 |
+
*this = std::move(img);
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
// Move asignment
|
| 94 |
+
inline
|
| 95 |
+
void operator=(ManagedImage<T,Allocator>&& img)
|
| 96 |
+
{
|
| 97 |
+
Deallocate();
|
| 98 |
+
Image<T>::pitch = img.pitch;
|
| 99 |
+
Image<T>::ptr = img.ptr;
|
| 100 |
+
Image<T>::w = img.w;
|
| 101 |
+
Image<T>::h = img.h;
|
| 102 |
+
img.ptr = nullptr;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
// Explicit copy constructor
|
| 106 |
+
template<typename TOther>
|
| 107 |
+
ManagedImage( const CopyObject<TOther>& other )
|
| 108 |
+
{
|
| 109 |
+
CopyFrom(other.obj);
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
// Explicit copy assignment
|
| 113 |
+
template<typename TOther>
|
| 114 |
+
void operator=(const CopyObject<TOther>& other)
|
| 115 |
+
{
|
| 116 |
+
CopyFrom(other.obj);
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
inline
|
| 120 |
+
void Swap(ManagedImage<T>& img)
|
| 121 |
+
{
|
| 122 |
+
std::swap(img.pitch, Image<T>::pitch);
|
| 123 |
+
std::swap(img.ptr, Image<T>::ptr);
|
| 124 |
+
std::swap(img.w, Image<T>::w);
|
| 125 |
+
std::swap(img.h, Image<T>::h);
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
inline
|
| 129 |
+
void CopyFrom(const Image<T>& img)
|
| 130 |
+
{
|
| 131 |
+
if(!Image<T>::IsValid() || Image<T>::w != img.w || Image<T>::h != img.h) {
|
| 132 |
+
Reinitialise(img.w,img.h);
|
| 133 |
+
}
|
| 134 |
+
Image<T>::CopyFrom(img);
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
inline
|
| 138 |
+
void Reinitialise(size_t w, size_t h)
|
| 139 |
+
{
|
| 140 |
+
if(!Image<T>::ptr || Image<T>::w != w || Image<T>::h != h) {
|
| 141 |
+
*this = ManagedImage<T,Allocator>(w,h);
|
| 142 |
+
}
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
inline
|
| 146 |
+
void Reinitialise(size_t w, size_t h, size_t pitch)
|
| 147 |
+
{
|
| 148 |
+
if(!Image<T>::ptr || Image<T>::w != w || Image<T>::h != h || Image<T>::pitch != pitch) {
|
| 149 |
+
*this = ManagedImage<T,Allocator>(w,h,pitch);
|
| 150 |
+
}
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
inline void Deallocate()
|
| 154 |
+
{
|
| 155 |
+
if (Image<T>::ptr) {
|
| 156 |
+
Allocator().deallocate(Image<T>::ptr, (Image<T>::h * Image<T>::pitch) / sizeof(T) );
|
| 157 |
+
Image<T>::ptr = nullptr;
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
// Move asignment
|
| 162 |
+
template<typename TOther, typename AllocOther> inline
|
| 163 |
+
void OwnAndReinterpret(ManagedImage<TOther,AllocOther>&& img)
|
| 164 |
+
{
|
| 165 |
+
Deallocate();
|
| 166 |
+
Image<T>::pitch = img.pitch;
|
| 167 |
+
Image<T>::ptr = (T*)img.ptr;
|
| 168 |
+
Image<T>::w = img.w;
|
| 169 |
+
Image<T>::h = img.h;
|
| 170 |
+
img.ptr = nullptr;
|
| 171 |
+
}
|
| 172 |
+
};
|
| 173 |
+
|
| 174 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/memcpy.h
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/platform.h>
|
| 31 |
+
|
| 32 |
+
#include <cstring>
|
| 33 |
+
|
| 34 |
+
#ifdef HAVE_CUDA
|
| 35 |
+
# include <cuda_runtime.h>
|
| 36 |
+
#endif
|
| 37 |
+
|
| 38 |
+
namespace pangolin {
|
| 39 |
+
|
| 40 |
+
template<typename T>
|
| 41 |
+
PANGO_HOST_DEVICE inline
|
| 42 |
+
bool IsDevicePtr(T* ptr)
|
| 43 |
+
{
|
| 44 |
+
#ifdef HAVE_CUDA
|
| 45 |
+
cudaPointerAttributes attributes;
|
| 46 |
+
cudaError_t res = cudaPointerGetAttributes(&attributes,ptr);
|
| 47 |
+
|
| 48 |
+
//Flushing the error flag for future CUDA error checks
|
| 49 |
+
if(res != cudaSuccess)
|
| 50 |
+
{
|
| 51 |
+
cudaGetLastError();
|
| 52 |
+
return false;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
return attributes.memoryType == cudaMemoryTypeDevice;
|
| 56 |
+
#else
|
| 57 |
+
PANGOLIN_UNUSED(ptr);
|
| 58 |
+
return false;
|
| 59 |
+
#endif
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
PANGO_HOST_DEVICE inline
|
| 63 |
+
void MemCopy(void *dst, const void *src, size_t size_bytes)
|
| 64 |
+
{
|
| 65 |
+
#ifdef HAVE_CUDA
|
| 66 |
+
cudaMemcpy(dst,src, size_bytes, cudaMemcpyDefault);
|
| 67 |
+
#else
|
| 68 |
+
std::memcpy(dst, src, size_bytes);
|
| 69 |
+
#endif
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
inline
|
| 73 |
+
void PitchedCopy(char* dst, unsigned int dst_pitch_bytes, const char* src, unsigned int src_pitch_bytes, unsigned int width_bytes, unsigned int height)
|
| 74 |
+
{
|
| 75 |
+
#ifdef HAVE_CUDA
|
| 76 |
+
cudaMemcpy2D(dst, dst_pitch_bytes, src, src_pitch_bytes, width_bytes, height, cudaMemcpyDefault);
|
| 77 |
+
#else
|
| 78 |
+
if(dst_pitch_bytes == width_bytes && src_pitch_bytes == width_bytes ) {
|
| 79 |
+
std::memcpy(dst, src, height * width_bytes);
|
| 80 |
+
}else{
|
| 81 |
+
for(unsigned int row=0; row < height; ++row) {
|
| 82 |
+
std::memcpy(dst, src, width_bytes);
|
| 83 |
+
dst += dst_pitch_bytes;
|
| 84 |
+
src += src_pitch_bytes;
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
#endif
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
PANGO_HOST_DEVICE inline
|
| 91 |
+
void Memset(char* ptr, unsigned char v, size_t size_bytes)
|
| 92 |
+
{
|
| 93 |
+
#ifdef __CUDA_ARCH__
|
| 94 |
+
// Called in kernel
|
| 95 |
+
char* end = ptr + size_bytes;
|
| 96 |
+
for(char* p=ptr; p != end; ++p) *p = v;
|
| 97 |
+
#else
|
| 98 |
+
# ifdef HAVE_CUDA
|
| 99 |
+
if(IsDevicePtr(ptr))
|
| 100 |
+
{
|
| 101 |
+
cudaMemset(ptr, v, size_bytes);
|
| 102 |
+
}else
|
| 103 |
+
# endif // HAVE_CUDA
|
| 104 |
+
{
|
| 105 |
+
std::memset(ptr, v, size_bytes);
|
| 106 |
+
}
|
| 107 |
+
#endif // __CUDA_ARCH__
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/pixel_format.h
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011-2013 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/platform.h>
|
| 31 |
+
#include <string>
|
| 32 |
+
#include <vector>
|
| 33 |
+
|
| 34 |
+
namespace pangolin
|
| 35 |
+
{
|
| 36 |
+
|
| 37 |
+
struct PANGOLIN_EXPORT PixelFormat
|
| 38 |
+
{
|
| 39 |
+
// Previously, VideoInterface::PixFormat returned a string.
|
| 40 |
+
// For compatibility, make this string convertable
|
| 41 |
+
inline operator std::string() const { return format; }
|
| 42 |
+
|
| 43 |
+
std::string format;
|
| 44 |
+
unsigned int channels;
|
| 45 |
+
unsigned int channel_bits[4]; //Of the data type
|
| 46 |
+
unsigned int bpp; //Of the data type
|
| 47 |
+
unsigned int channel_bit_depth; //Of the data
|
| 48 |
+
bool planar;
|
| 49 |
+
};
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
//! Return Pixel Format properties given string specification in
|
| 53 |
+
//! FFMPEG notation.
|
| 54 |
+
PANGOLIN_EXPORT
|
| 55 |
+
PixelFormat PixelFormatFromString(const std::string& format);
|
| 56 |
+
|
| 57 |
+
std::vector<PixelFormat> GetSupportedPixelFormats();
|
| 58 |
+
|
| 59 |
+
////////////////////////////////////////////////////////////////////
|
| 60 |
+
/// Deprecated aliases for above
|
| 61 |
+
|
| 62 |
+
PANGOLIN_DEPRECATED("Use PixelFormat instead")
|
| 63 |
+
typedef PixelFormat VideoPixelFormat;
|
| 64 |
+
PANGOLIN_DEPRECATED("Use PixelFormatFromString instead")
|
| 65 |
+
inline PixelFormat VideoFormatFromString(const std::string& format) {
|
| 66 |
+
return PixelFormatFromString(format);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/shared_image.h
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/image/image.h>
|
| 31 |
+
#include <pangolin/image/copy.h>
|
| 32 |
+
|
| 33 |
+
namespace pangolin {
|
| 34 |
+
|
| 35 |
+
template<class T> using DefaultImageAllocator = std::allocator<T>;
|
| 36 |
+
|
| 37 |
+
// Image that manages it's own memory, storing a strong pointer to it's memory
|
| 38 |
+
template<typename T>
|
| 39 |
+
class SharedImage : public Image<T>
|
| 40 |
+
{
|
| 41 |
+
private:
|
| 42 |
+
std::shared_ptr<T[]> shared_memory;
|
| 43 |
+
|
| 44 |
+
public:
|
| 45 |
+
// Destructor
|
| 46 |
+
inline
|
| 47 |
+
~SharedImage()
|
| 48 |
+
{
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
// Null image
|
| 52 |
+
inline
|
| 53 |
+
SharedImage()
|
| 54 |
+
{
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
// Row image
|
| 58 |
+
inline
|
| 59 |
+
SharedImage(size_t w)
|
| 60 |
+
: Image<T>( nullptr, w, 1, w*sizeof(T) ),
|
| 61 |
+
shared_memory(new T[w])
|
| 62 |
+
{
|
| 63 |
+
Image<T>::ptr = shared_memory.get();
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
inline
|
| 67 |
+
SharedImage(size_t w, size_t h)
|
| 68 |
+
: Image<T>( nullptr, w, h, w*sizeof(T) ),
|
| 69 |
+
shared_memory(new T[w*h])
|
| 70 |
+
{
|
| 71 |
+
Image<T>::ptr = shared_memory.get();
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
inline
|
| 75 |
+
SharedImage(size_t w, size_t h, size_t pitch_bytes)
|
| 76 |
+
: Image<T>( nullptr, w, h, pitch_bytes),
|
| 77 |
+
shared_memory(new T[h*pitch_bytes / sizeof(T)])
|
| 78 |
+
{
|
| 79 |
+
Image<T>::ptr = shared_memory.get();
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
// Copyable with shared semantics (not a deep copy).
|
| 83 |
+
inline
|
| 84 |
+
SharedImage( const SharedImage<T>& other ) = default;
|
| 85 |
+
|
| 86 |
+
// Move constructor
|
| 87 |
+
inline
|
| 88 |
+
SharedImage(SharedImage<T>&& img)
|
| 89 |
+
{
|
| 90 |
+
*this = std::move(img);
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
// Move asignment
|
| 94 |
+
inline
|
| 95 |
+
void operator=(SharedImage<T>&& img)
|
| 96 |
+
{
|
| 97 |
+
Image<T>::pitch = img.pitch;
|
| 98 |
+
Image<T>::ptr = img.ptr;
|
| 99 |
+
Image<T>::w = img.w;
|
| 100 |
+
Image<T>::h = img.h;
|
| 101 |
+
shared_memory = std::move(img.shared_memory);
|
| 102 |
+
img.ptr = nullptr;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
// Explicit copy constructor
|
| 106 |
+
template<typename TOther>
|
| 107 |
+
SharedImage( const CopyObject<TOther>& other )
|
| 108 |
+
{
|
| 109 |
+
CopyFrom(other.obj);
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
// Explicit copy assignment
|
| 113 |
+
template<typename TOther>
|
| 114 |
+
void operator=(const CopyObject<TOther>& other)
|
| 115 |
+
{
|
| 116 |
+
CopyFrom(other.obj);
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
inline
|
| 120 |
+
void Swap(SharedImage<T>& img)
|
| 121 |
+
{
|
| 122 |
+
std::swap(img.pitch, Image<T>::pitch);
|
| 123 |
+
std::swap(img.ptr, Image<T>::ptr);
|
| 124 |
+
std::swap(img.w, Image<T>::w);
|
| 125 |
+
std::swap(img.h, Image<T>::h);
|
| 126 |
+
std::swap(img.shared_memory, shared_memory);
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
inline
|
| 130 |
+
void CopyFrom(const Image<T>& img)
|
| 131 |
+
{
|
| 132 |
+
if(!Image<T>::IsValid() || Image<T>::w != img.w || Image<T>::h != img.h) {
|
| 133 |
+
throw std::runtime_error("Incompatible image specification for copy");
|
| 134 |
+
}
|
| 135 |
+
Image<T>::CopyFrom(img);
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
inline void Deallocate()
|
| 139 |
+
{
|
| 140 |
+
shared_memory = nullptr;
|
| 141 |
+
Image<T>::ptr = nullptr;
|
| 142 |
+
}
|
| 143 |
+
};
|
| 144 |
+
|
| 145 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/include/pangolin/image/typed_image.h
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2013 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/image/managed_image.h>
|
| 31 |
+
#include <pangolin/image/pixel_format.h>
|
| 32 |
+
|
| 33 |
+
namespace pangolin {
|
| 34 |
+
|
| 35 |
+
struct TypedImage : public ManagedImage<unsigned char>
|
| 36 |
+
{
|
| 37 |
+
typedef ManagedImage<unsigned char> Base;
|
| 38 |
+
|
| 39 |
+
inline TypedImage()
|
| 40 |
+
: Base()
|
| 41 |
+
{
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
inline TypedImage(size_t w, size_t h, const PixelFormat& fmt)
|
| 45 |
+
: Base(w,h,w*fmt.bpp/8), fmt(fmt)
|
| 46 |
+
{
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
inline TypedImage(size_t w, size_t h, const PixelFormat& fmt, size_t pitch )
|
| 50 |
+
: Base(w,h, pitch), fmt(fmt)
|
| 51 |
+
{
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
inline
|
| 55 |
+
void Reinitialise(size_t w, size_t h, const PixelFormat& fmt)
|
| 56 |
+
{
|
| 57 |
+
Base::Reinitialise(w, h, w*fmt.bpp/8);
|
| 58 |
+
this->fmt = fmt;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
inline
|
| 62 |
+
void Reinitialise(size_t w, size_t h, const PixelFormat& fmt, size_t pitch)
|
| 63 |
+
{
|
| 64 |
+
Base::Reinitialise(w, h, pitch);
|
| 65 |
+
this->fmt = fmt;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
// Not copy constructable
|
| 69 |
+
inline
|
| 70 |
+
TypedImage( const TypedImage& other ) = delete;
|
| 71 |
+
|
| 72 |
+
// Move constructor
|
| 73 |
+
inline
|
| 74 |
+
TypedImage(TypedImage&& img)
|
| 75 |
+
{
|
| 76 |
+
*this = std::move(img);
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
// Move asignment
|
| 80 |
+
inline
|
| 81 |
+
void operator=(TypedImage&& img)
|
| 82 |
+
{
|
| 83 |
+
fmt = img.fmt;
|
| 84 |
+
Base::operator =( std::move(img));
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
PixelFormat fmt;
|
| 89 |
+
};
|
| 90 |
+
|
| 91 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io.cpp
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2013 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#include <pangolin/image/image_io.h>
|
| 29 |
+
|
| 30 |
+
#include <fstream>
|
| 31 |
+
|
| 32 |
+
namespace pangolin {
|
| 33 |
+
|
| 34 |
+
// PNG
|
| 35 |
+
TypedImage LoadPng(std::istream& in);
|
| 36 |
+
void SavePng(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, bool top_line_first, int zlib_compression_level );
|
| 37 |
+
|
| 38 |
+
// JPG
|
| 39 |
+
TypedImage LoadJpg(std::istream& in);
|
| 40 |
+
void SaveJpg(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, float quality);
|
| 41 |
+
|
| 42 |
+
// PPM
|
| 43 |
+
TypedImage LoadPpm(std::istream& in);
|
| 44 |
+
void SavePpm(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, bool top_line_first);
|
| 45 |
+
|
| 46 |
+
// TGA
|
| 47 |
+
TypedImage LoadTga(std::istream& in);
|
| 48 |
+
|
| 49 |
+
// Pango
|
| 50 |
+
TypedImage LoadPango(const std::string& filename);
|
| 51 |
+
void SavePango(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, const std::string& filename, bool top_line_first);
|
| 52 |
+
|
| 53 |
+
// EXR
|
| 54 |
+
TypedImage LoadExr(std::istream& source);
|
| 55 |
+
void SaveExr(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, const std::string& filename, bool top_line_first);
|
| 56 |
+
|
| 57 |
+
// BMP
|
| 58 |
+
TypedImage LoadBmp(std::istream& source);
|
| 59 |
+
void SaveBmp(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, bool top_line_first);
|
| 60 |
+
|
| 61 |
+
// ZSTD (https://github.com/facebook/zstd)
|
| 62 |
+
TypedImage LoadZstd(std::istream& in);
|
| 63 |
+
void SaveZstd(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, int compression_level);
|
| 64 |
+
|
| 65 |
+
// https://github.com/lz4/lz4
|
| 66 |
+
TypedImage LoadLz4(std::istream& in);
|
| 67 |
+
void SaveLz4(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, int compression_level);
|
| 68 |
+
|
| 69 |
+
// packed 12 bit image (obtained from unpacked 16bit)
|
| 70 |
+
TypedImage LoadPacked12bit(std::istream& in);
|
| 71 |
+
void SavePacked12bit(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out);
|
| 72 |
+
|
| 73 |
+
// LibRaw raw camera files
|
| 74 |
+
TypedImage LoadLibRaw(const std::string& filename);
|
| 75 |
+
|
| 76 |
+
// TIFF
|
| 77 |
+
TypedImage LoadTiff(const std::string& filename);
|
| 78 |
+
|
| 79 |
+
TypedImage LoadImage(std::istream& in, ImageFileType file_type)
|
| 80 |
+
{
|
| 81 |
+
switch (file_type) {
|
| 82 |
+
case ImageFileTypePng:
|
| 83 |
+
return LoadPng(in);
|
| 84 |
+
case ImageFileTypeJpg:
|
| 85 |
+
return LoadJpg(in);
|
| 86 |
+
case ImageFileTypePpm:
|
| 87 |
+
return LoadPpm(in);
|
| 88 |
+
case ImageFileTypeTga:
|
| 89 |
+
return LoadTga(in);
|
| 90 |
+
case ImageFileTypeZstd:
|
| 91 |
+
return LoadZstd(in);
|
| 92 |
+
case ImageFileTypeLz4:
|
| 93 |
+
return LoadLz4(in);
|
| 94 |
+
case ImageFileTypeP12b:
|
| 95 |
+
return LoadPacked12bit(in);
|
| 96 |
+
case ImageFileTypeExr:
|
| 97 |
+
return LoadExr(in);
|
| 98 |
+
case ImageFileTypeBmp:
|
| 99 |
+
return LoadBmp(in);
|
| 100 |
+
default:
|
| 101 |
+
throw std::runtime_error("Unable to load image file-type through std::istream");
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
TypedImage LoadImage(const std::string& filename, ImageFileType file_type)
|
| 106 |
+
{
|
| 107 |
+
switch (file_type) {
|
| 108 |
+
case ImageFileTypePng:
|
| 109 |
+
case ImageFileTypeJpg:
|
| 110 |
+
case ImageFileTypePpm:
|
| 111 |
+
case ImageFileTypeTga:
|
| 112 |
+
case ImageFileTypeZstd:
|
| 113 |
+
case ImageFileTypeLz4:
|
| 114 |
+
case ImageFileTypeP12b:
|
| 115 |
+
case ImageFileTypeExr:
|
| 116 |
+
case ImageFileTypeBmp:
|
| 117 |
+
{
|
| 118 |
+
std::ifstream ifs(filename, std::ios_base::in|std::ios_base::binary);
|
| 119 |
+
return LoadImage(ifs, file_type);
|
| 120 |
+
}
|
| 121 |
+
case ImageFileTypePango:
|
| 122 |
+
return LoadPango(filename);
|
| 123 |
+
case ImageFileTypeArw:
|
| 124 |
+
return LoadLibRaw(filename);
|
| 125 |
+
case ImageFileTypeTiff:
|
| 126 |
+
return LoadTiff(filename);
|
| 127 |
+
default:
|
| 128 |
+
throw std::runtime_error("Unsupported image file type, '" + filename + "'");
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
TypedImage LoadImage(const std::string& filename)
|
| 133 |
+
{
|
| 134 |
+
ImageFileType file_type = FileType(filename);
|
| 135 |
+
return LoadImage( filename, file_type );
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
void SaveImage(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, ImageFileType file_type, bool top_line_first, float quality)
|
| 139 |
+
{
|
| 140 |
+
switch (file_type) {
|
| 141 |
+
case ImageFileTypePng:
|
| 142 |
+
// map quality [0..100] to PNG compression levels [0..9]
|
| 143 |
+
return SavePng(image, fmt, out, top_line_first, int(quality*0.09));
|
| 144 |
+
case ImageFileTypeJpg:
|
| 145 |
+
return SaveJpg(image, fmt, out, quality);
|
| 146 |
+
case ImageFileTypePpm:
|
| 147 |
+
return SavePpm(image, fmt, out, top_line_first);
|
| 148 |
+
case ImageFileTypeZstd:
|
| 149 |
+
return SaveZstd(image, fmt, out, (int)quality);
|
| 150 |
+
case ImageFileTypeLz4:
|
| 151 |
+
return SaveLz4(image, fmt, out, (int)quality);
|
| 152 |
+
case ImageFileTypeP12b:
|
| 153 |
+
return SavePacked12bit(image, fmt, out);
|
| 154 |
+
case ImageFileTypeBmp:
|
| 155 |
+
return SaveBmp(image, fmt, out, top_line_first);
|
| 156 |
+
default:
|
| 157 |
+
throw std::runtime_error("Unable to save image file-type through std::istream");
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
void SaveImage(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, const std::string& filename, ImageFileType file_type, bool top_line_first, float quality)
|
| 163 |
+
{
|
| 164 |
+
switch (file_type) {
|
| 165 |
+
case ImageFileTypePng:
|
| 166 |
+
case ImageFileTypeJpg:
|
| 167 |
+
case ImageFileTypePpm:
|
| 168 |
+
case ImageFileTypeZstd:
|
| 169 |
+
case ImageFileTypeLz4:
|
| 170 |
+
case ImageFileTypeP12b:
|
| 171 |
+
case ImageFileTypeBmp:
|
| 172 |
+
{
|
| 173 |
+
std::ofstream ofs(filename, std::ios_base::binary);
|
| 174 |
+
return SaveImage(image, fmt, ofs, file_type, top_line_first, quality);
|
| 175 |
+
}
|
| 176 |
+
case ImageFileTypeExr:
|
| 177 |
+
return SaveExr(image, fmt, filename, top_line_first);
|
| 178 |
+
case ImageFileTypePango:
|
| 179 |
+
return SavePango(image, fmt, filename, top_line_first);
|
| 180 |
+
default:
|
| 181 |
+
throw std::runtime_error("Unsupported image file type, '" + filename + "'");
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
void SaveImage(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, const std::string& filename, bool top_line_first, float quality)
|
| 186 |
+
{
|
| 187 |
+
const std::string ext = FileLowercaseExtention(filename);
|
| 188 |
+
const ImageFileType file_type = FileTypeExtension(ext);
|
| 189 |
+
SaveImage(image, fmt, filename,file_type, top_line_first, quality);
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
void SaveImage(const TypedImage& image, const std::string& filename, bool top_line_first, float quality)
|
| 193 |
+
{
|
| 194 |
+
SaveImage(image, image.fmt, filename, top_line_first, quality);
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_bmp.cpp
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <fstream>
|
| 2 |
+
#include <pangolin/image/typed_image.h>
|
| 3 |
+
|
| 4 |
+
namespace pangolin {
|
| 5 |
+
|
| 6 |
+
#pragma pack(push, 1)
|
| 7 |
+
struct BitmapHeader
|
| 8 |
+
{
|
| 9 |
+
uint16_t magic;
|
| 10 |
+
uint32_t filesize_bytes;
|
| 11 |
+
uint32_t reserved;
|
| 12 |
+
uint32_t offset_bytes;
|
| 13 |
+
};
|
| 14 |
+
struct BitmapInfoHeader
|
| 15 |
+
{
|
| 16 |
+
uint32_t header_size_bytes;
|
| 17 |
+
uint32_t width;
|
| 18 |
+
uint32_t height;
|
| 19 |
+
uint16_t color_planes;
|
| 20 |
+
uint16_t bits_per_pixel;
|
| 21 |
+
uint32_t compression_method;
|
| 22 |
+
uint32_t imagesize_bytes;
|
| 23 |
+
uint32_t w_pixel_per_meter;
|
| 24 |
+
uint32_t h_pixel_per_meter;
|
| 25 |
+
uint32_t colors_in_pallete;
|
| 26 |
+
uint32_t important_colors;
|
| 27 |
+
};
|
| 28 |
+
|
| 29 |
+
static_assert(sizeof(BitmapHeader) == 14, "Unexpected padding on struct");
|
| 30 |
+
static_assert(sizeof(BitmapInfoHeader) == 40, "Unexpected padding on struct");
|
| 31 |
+
#pragma pack(pop)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
// https://en.wikipedia.org/wiki/BMP_file_format
|
| 35 |
+
TypedImage LoadBmp(std::istream& in)
|
| 36 |
+
{
|
| 37 |
+
constexpr uint16_t expected_magic = 'B' | 'M' << 8;
|
| 38 |
+
|
| 39 |
+
BitmapHeader bmp_file_header;
|
| 40 |
+
BitmapInfoHeader bmp_info_header;
|
| 41 |
+
|
| 42 |
+
memset((char*)&bmp_file_header, 0, sizeof(bmp_file_header));
|
| 43 |
+
memset((char*)&bmp_info_header, 0, sizeof(bmp_info_header));
|
| 44 |
+
|
| 45 |
+
in.read((char*)&bmp_file_header, sizeof(bmp_file_header));
|
| 46 |
+
if(!in.good() || bmp_file_header.magic != expected_magic)
|
| 47 |
+
throw std::runtime_error("LoadBmp: invalid magic header");
|
| 48 |
+
|
| 49 |
+
in.read((char*)&bmp_info_header, sizeof(bmp_info_header));
|
| 50 |
+
if(!in.good() || bmp_info_header.header_size_bytes != 40)
|
| 51 |
+
throw std::runtime_error("LoadBmp: unknown info header");
|
| 52 |
+
|
| 53 |
+
if(bmp_info_header.bits_per_pixel != 24 )
|
| 54 |
+
throw std::runtime_error("LoadBmp: unexpected format");
|
| 55 |
+
|
| 56 |
+
const PixelFormat fmt = PixelFormatFromString("RGB24");
|
| 57 |
+
|
| 58 |
+
const size_t w = bmp_info_header.width;
|
| 59 |
+
const size_t h = bmp_info_header.height;
|
| 60 |
+
const size_t padding_bytes = ((4 - (w * 3) % 4) % 4);
|
| 61 |
+
|
| 62 |
+
if( w == 0 || h == 0)
|
| 63 |
+
throw std::runtime_error("LoadBmp: Invalid Bitmap size");
|
| 64 |
+
|
| 65 |
+
TypedImage img(w, h, fmt);
|
| 66 |
+
|
| 67 |
+
for (int y = ( (int)h - 1); y != -1; y--)
|
| 68 |
+
{
|
| 69 |
+
char* p_pix = (char*)img.RowPtr(y);
|
| 70 |
+
in.read(p_pix, w * fmt.channels);
|
| 71 |
+
|
| 72 |
+
if(!in.good())
|
| 73 |
+
throw std::runtime_error("LoadBmp: Unexpected end of stream.");
|
| 74 |
+
|
| 75 |
+
// Convert from BGR to RGB
|
| 76 |
+
for (size_t x = 0; x < w; x++)
|
| 77 |
+
{
|
| 78 |
+
// BGR -> RGB
|
| 79 |
+
std::swap(p_pix[0], p_pix[2]);
|
| 80 |
+
p_pix += fmt.channels;
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
in.ignore(padding_bytes);
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
return img;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
void SaveBmp(const Image<unsigned char>& /*image*/, const pangolin::PixelFormat& /*fmt*/, std::ostream& /*out*/, bool /*top_line_first*/)
|
| 90 |
+
{
|
| 91 |
+
throw std::runtime_error("SaveBMP: Not implemented");
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_exr.cpp
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <pangolin/platform.h>
|
| 2 |
+
|
| 3 |
+
#include <fstream>
|
| 4 |
+
#include <pangolin/image/typed_image.h>
|
| 5 |
+
|
| 6 |
+
#ifdef HAVE_OPENEXR
|
| 7 |
+
#include <ImfChannelList.h>
|
| 8 |
+
#include <ImfInputFile.h>
|
| 9 |
+
#include <ImfOutputFile.h>
|
| 10 |
+
#include <ImfIO.h>
|
| 11 |
+
#endif // HAVE_OPENEXR
|
| 12 |
+
|
| 13 |
+
namespace pangolin {
|
| 14 |
+
|
| 15 |
+
#ifdef HAVE_OPENEXR
|
| 16 |
+
Imf::PixelType OpenEXRPixelType(int channel_bits)
|
| 17 |
+
{
|
| 18 |
+
if( channel_bits == 16 ) {
|
| 19 |
+
return Imf::PixelType::HALF;
|
| 20 |
+
}else if( channel_bits == 32 ) {
|
| 21 |
+
return Imf::PixelType::FLOAT;
|
| 22 |
+
}else{
|
| 23 |
+
throw std::runtime_error("Unsupported OpenEXR Pixel Type.");
|
| 24 |
+
}
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
void SetOpenEXRChannels(Imf::ChannelList& ch, const pangolin::PixelFormat& fmt)
|
| 28 |
+
{
|
| 29 |
+
const char* CHANNEL_NAMES[] = {"R","G","B","A"};
|
| 30 |
+
for(size_t c=0; c < fmt.channels; ++c) {
|
| 31 |
+
ch.insert( CHANNEL_NAMES[c], Imf::Channel(OpenEXRPixelType(fmt.channel_bits[c])) );
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
class StdIStream: public Imf::IStream
|
| 36 |
+
{
|
| 37 |
+
public:
|
| 38 |
+
StdIStream (std::istream &is):
|
| 39 |
+
Imf::IStream ("stream"),
|
| 40 |
+
_is (&is)
|
| 41 |
+
{
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
virtual bool read (char c[/*n*/], int n)
|
| 45 |
+
{
|
| 46 |
+
if (!*_is)
|
| 47 |
+
throw std::runtime_error("Unexpected end of file.");
|
| 48 |
+
_is->read (c, n);
|
| 49 |
+
if (_is->gcount() < n)
|
| 50 |
+
{
|
| 51 |
+
throw std::runtime_error("Early end of file");
|
| 52 |
+
return false;
|
| 53 |
+
}
|
| 54 |
+
return true;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
virtual Imf::Int64 tellg ()
|
| 58 |
+
{
|
| 59 |
+
return std::streamoff (_is->tellg());
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
virtual void seekg (Imf::Int64 pos)
|
| 63 |
+
{
|
| 64 |
+
_is->seekg (pos);
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
virtual void clear ()
|
| 68 |
+
{
|
| 69 |
+
_is->clear();
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
private:
|
| 73 |
+
std::istream * _is;
|
| 74 |
+
};
|
| 75 |
+
|
| 76 |
+
PixelFormat GetPixelFormat(const Imf::Header& header)
|
| 77 |
+
{
|
| 78 |
+
const Imf::ChannelList &channels = header.channels();
|
| 79 |
+
size_t count = 0;
|
| 80 |
+
|
| 81 |
+
std::stringstream pixelFormat;
|
| 82 |
+
size_t depth = 0;
|
| 83 |
+
for (Imf::ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i){
|
| 84 |
+
const Imf::Channel& channel = i.channel();
|
| 85 |
+
if(depth == 0)
|
| 86 |
+
{
|
| 87 |
+
switch(channel.type)
|
| 88 |
+
{
|
| 89 |
+
case Imf::FLOAT: depth = 32; break;
|
| 90 |
+
case Imf::HALF: depth = 16; break;
|
| 91 |
+
default:
|
| 92 |
+
throw std::invalid_argument("Currently, only floating-point OpenEXR files are supported.");
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
count += 1;
|
| 96 |
+
pixelFormat << i.name();
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
std::string colors = pixelFormat.str();
|
| 100 |
+
if (colors == "Y" || colors == "R") {
|
| 101 |
+
colors = "GRAY";
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
if ((count == 1 && colors != "GRAY")
|
| 105 |
+
|| (count == 3 && colors != "RGB" && colors != "BGR")
|
| 106 |
+
|| (count == 4 && colors != "RGBA" && colors != "ABGR")) {
|
| 107 |
+
throw std::runtime_error("bad color format");
|
| 108 |
+
}
|
| 109 |
+
if (count != 1 && count != 3 && count != 4) {
|
| 110 |
+
throw std::invalid_argument("Currently, only 1, 3 or 4-channel OpenEXR files are supported.");
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
return PixelFormatFromString(colors + std::to_string(depth*count) + "F");
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
#endif //HAVE_OPENEXR
|
| 117 |
+
|
| 118 |
+
TypedImage LoadExr(std::istream& source)
|
| 119 |
+
{
|
| 120 |
+
#ifdef HAVE_OPENEXR
|
| 121 |
+
StdIStream istream(source);
|
| 122 |
+
Imf::InputFile file(istream);
|
| 123 |
+
PANGO_WARNING(file.isComplete());
|
| 124 |
+
|
| 125 |
+
Imath::Box2i dw = file.header().dataWindow();
|
| 126 |
+
int width = dw.max.x - dw.min.x + 1;
|
| 127 |
+
int height = dw.max.y - dw.min.y + 1;
|
| 128 |
+
|
| 129 |
+
PixelFormat format = GetPixelFormat(file.header());
|
| 130 |
+
TypedImage img(width, height, format);
|
| 131 |
+
|
| 132 |
+
char *imgBase = (char *) img.ptr - (dw.min.x + dw.min.y * width) * sizeof(float) * format.channels;
|
| 133 |
+
Imf::FrameBuffer fb;
|
| 134 |
+
|
| 135 |
+
const Imf::ChannelList &channels = file.header().channels();
|
| 136 |
+
size_t c = 0;
|
| 137 |
+
unsigned int d = format.channel_bit_depth;
|
| 138 |
+
Imf::PixelType pixeltype;
|
| 139 |
+
switch(d)
|
| 140 |
+
{
|
| 141 |
+
case 16: pixeltype = Imf::HALF; break;
|
| 142 |
+
case 32: pixeltype = Imf::FLOAT; break;
|
| 143 |
+
throw std::invalid_argument("Currently, only floating-point OpenEXR files are supported.");
|
| 144 |
+
}
|
| 145 |
+
unsigned int pixelsize = d/8;
|
| 146 |
+
|
| 147 |
+
auto writeChannel = [&](Imf::ChannelList::ConstIterator& i, size_t j) {
|
| 148 |
+
fb.insert(i.name(), Imf::Slice(
|
| 149 |
+
pixeltype, imgBase + pixelsize * j,
|
| 150 |
+
pixelsize * format.channels,
|
| 151 |
+
pixelsize * format.channels * size_t(width)));
|
| 152 |
+
};
|
| 153 |
+
if(format.format == "ABGR128F") {
|
| 154 |
+
format.format = "RGBA128F";
|
| 155 |
+
static std::map<std::string, size_t> channelOrder = {
|
| 156 |
+
{"R", 0}, {"G", 1}, {"B", 2}, {"A", 3}
|
| 157 |
+
};
|
| 158 |
+
for (Imf::ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) {
|
| 159 |
+
writeChannel(i, channelOrder[i.name()]);
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
else {
|
| 163 |
+
for (Imf::ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) {
|
| 164 |
+
writeChannel(i, c++);
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
file.setFrameBuffer(fb);
|
| 169 |
+
file.readPixels(dw.min.y, dw.max.y);
|
| 170 |
+
|
| 171 |
+
return img;
|
| 172 |
+
#else
|
| 173 |
+
PANGOLIN_UNUSED(source);
|
| 174 |
+
throw std::runtime_error("Rebuild Pangolin for EXR support.");
|
| 175 |
+
#endif //HAVE_OPENEXR
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
void SaveExr(const Image<unsigned char>& image_in, const pangolin::PixelFormat& fmt, const std::string& filename, bool top_line_first)
|
| 179 |
+
{
|
| 180 |
+
#ifdef HAVE_OPENEXR
|
| 181 |
+
ManagedImage<unsigned char> flip_image;
|
| 182 |
+
Image<unsigned char> image;
|
| 183 |
+
|
| 184 |
+
if(top_line_first) {
|
| 185 |
+
image = image_in;
|
| 186 |
+
}else{
|
| 187 |
+
flip_image.Reinitialise(image_in.w, image_in.h, image_in.pitch);
|
| 188 |
+
for(size_t y=0; y<image_in.h; ++y) {
|
| 189 |
+
std::memcpy(flip_image.RowPtr(y), image_in.RowPtr(image_in.h - 1 - y), image_in.pitch);
|
| 190 |
+
}
|
| 191 |
+
image = flip_image;
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
Imf::Header header (image.w, image.h);
|
| 196 |
+
SetOpenEXRChannels(header.channels(), fmt);
|
| 197 |
+
|
| 198 |
+
Imf::OutputFile file (filename.c_str(), header);
|
| 199 |
+
Imf::FrameBuffer frameBuffer;
|
| 200 |
+
|
| 201 |
+
size_t ch_bits = 0;
|
| 202 |
+
const char* CHANNEL_NAMES[] = {"R","G","B","A"};
|
| 203 |
+
for(unsigned int i=0; i<fmt.channels; i++)
|
| 204 |
+
{
|
| 205 |
+
const Imf::Channel *channel = header.channels().findChannel(CHANNEL_NAMES[i]);
|
| 206 |
+
frameBuffer.insert(
|
| 207 |
+
CHANNEL_NAMES[i],
|
| 208 |
+
Imf::Slice(
|
| 209 |
+
channel->type,
|
| 210 |
+
(char*)image.ptr + (ch_bits/8),
|
| 211 |
+
fmt.bpp/8, // xstride
|
| 212 |
+
image.pitch // ystride
|
| 213 |
+
)
|
| 214 |
+
);
|
| 215 |
+
|
| 216 |
+
ch_bits += fmt.channel_bits[i];
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
file.setFrameBuffer(frameBuffer);
|
| 220 |
+
file.writePixels(image.h);
|
| 221 |
+
|
| 222 |
+
#else
|
| 223 |
+
PANGOLIN_UNUSED(image_in);
|
| 224 |
+
PANGOLIN_UNUSED(fmt);
|
| 225 |
+
PANGOLIN_UNUSED(filename);
|
| 226 |
+
PANGOLIN_UNUSED(top_line_first);
|
| 227 |
+
throw std::runtime_error("EXR Support not enabled. Please rebuild Pangolin.");
|
| 228 |
+
#endif // HAVE_OPENEXR
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_jpg.cpp
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <algorithm>
|
| 2 |
+
#include <fstream>
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
#include <pangolin/platform.h>
|
| 6 |
+
|
| 7 |
+
#include <pangolin/image/typed_image.h>
|
| 8 |
+
|
| 9 |
+
#ifdef HAVE_JPEG
|
| 10 |
+
# include <jpeglib.h>
|
| 11 |
+
# ifdef _WIN_
|
| 12 |
+
// Undef windows Macro polution from jpeglib.h
|
| 13 |
+
# undef LoadImage
|
| 14 |
+
# endif
|
| 15 |
+
#endif // HAVE_JPEG
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
// Inspired by https://cs.stanford.edu/~acoates/jpegAndIOS.txt
|
| 19 |
+
|
| 20 |
+
namespace pangolin {
|
| 21 |
+
|
| 22 |
+
#ifdef HAVE_JPEG
|
| 23 |
+
|
| 24 |
+
void error_handler(j_common_ptr cinfo) {
|
| 25 |
+
char msg[JMSG_LENGTH_MAX];
|
| 26 |
+
(*(cinfo->err->format_message)) (cinfo, msg);
|
| 27 |
+
throw std::runtime_error(msg);
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
const static size_t PANGO_JPEG_BUF_SIZE = 16384;
|
| 31 |
+
|
| 32 |
+
struct pango_jpeg_source_mgr {
|
| 33 |
+
struct jpeg_source_mgr pub;
|
| 34 |
+
std::istream* is;
|
| 35 |
+
JOCTET* buffer;
|
| 36 |
+
};
|
| 37 |
+
|
| 38 |
+
static void pango_jpeg_init_source(j_decompress_ptr /*cinfo*/) {
|
| 39 |
+
}
|
| 40 |
+
// https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/jdatasrc.c#L69
|
| 41 |
+
// ignore current state of src->pub.next_input_byte and src->pub.bytes_in_buffer
|
| 42 |
+
static boolean pango_jpeg_fill_input_buffer(j_decompress_ptr cinfo) {
|
| 43 |
+
pango_jpeg_source_mgr* src = (pango_jpeg_source_mgr*)cinfo->src;
|
| 44 |
+
src->is->read((char*)src->buffer, PANGO_JPEG_BUF_SIZE);
|
| 45 |
+
size_t bytes = src->is->gcount();
|
| 46 |
+
if (bytes == 0) {
|
| 47 |
+
/* Insert a fake EOI marker */
|
| 48 |
+
src->buffer[0] = (JOCTET) 0xFF;
|
| 49 |
+
src->buffer[1] = (JOCTET) JPEG_EOI;
|
| 50 |
+
bytes = 2;
|
| 51 |
+
}
|
| 52 |
+
src->pub.next_input_byte = src->buffer;
|
| 53 |
+
src->pub.bytes_in_buffer = bytes;
|
| 54 |
+
return TRUE;
|
| 55 |
+
}
|
| 56 |
+
static void pango_jpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
|
| 57 |
+
pango_jpeg_source_mgr* src = (pango_jpeg_source_mgr*)cinfo->src;
|
| 58 |
+
if (num_bytes > 0) {
|
| 59 |
+
while (num_bytes > (long)src->pub.bytes_in_buffer) {
|
| 60 |
+
num_bytes -= (long)src->pub.bytes_in_buffer;
|
| 61 |
+
pango_jpeg_fill_input_buffer(cinfo);
|
| 62 |
+
}
|
| 63 |
+
src->pub.next_input_byte += num_bytes;
|
| 64 |
+
src->pub.bytes_in_buffer -= num_bytes;
|
| 65 |
+
}
|
| 66 |
+
}
|
| 67 |
+
static void pango_jpeg_term_source(j_decompress_ptr cinfo) {
|
| 68 |
+
// must seek backward so that future reads will start at correct place.
|
| 69 |
+
pango_jpeg_source_mgr* src = (pango_jpeg_source_mgr*)cinfo->src;
|
| 70 |
+
src->is->clear();
|
| 71 |
+
src->is->seekg( src->is->tellg() - (std::streampos)src->pub.bytes_in_buffer );
|
| 72 |
+
src->pub.bytes_in_buffer = 0;
|
| 73 |
+
src->pub.next_input_byte = nullptr;
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
static void pango_jpeg_set_source_mgr(j_decompress_ptr cinfo, std::istream& is) {
|
| 77 |
+
pango_jpeg_source_mgr* src = nullptr;
|
| 78 |
+
|
| 79 |
+
if (cinfo->src == 0)
|
| 80 |
+
{
|
| 81 |
+
cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)
|
| 82 |
+
((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(pango_jpeg_source_mgr));
|
| 83 |
+
|
| 84 |
+
src = (pango_jpeg_source_mgr*) cinfo->src;
|
| 85 |
+
src->buffer = (JOCTET *)(*cinfo->mem->alloc_small)
|
| 86 |
+
((j_common_ptr) cinfo, JPOOL_PERMANENT, PANGO_JPEG_BUF_SIZE*sizeof(JOCTET));
|
| 87 |
+
}else{
|
| 88 |
+
src = (pango_jpeg_source_mgr*) cinfo->src;
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
src->is = &is;
|
| 92 |
+
src->pub.init_source = pango_jpeg_init_source;
|
| 93 |
+
src->pub.fill_input_buffer = pango_jpeg_fill_input_buffer;
|
| 94 |
+
src->pub.skip_input_data = pango_jpeg_skip_input_data;
|
| 95 |
+
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
| 96 |
+
src->pub.term_source = pango_jpeg_term_source;
|
| 97 |
+
src->pub.bytes_in_buffer = 0;
|
| 98 |
+
src->pub.next_input_byte = nullptr;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
struct pango_jpeg_destination_mgr {
|
| 102 |
+
struct jpeg_destination_mgr pub; /* public fields */
|
| 103 |
+
std::ostream* os; /* target stream */
|
| 104 |
+
JOCTET * buffer; /* start of buffer */
|
| 105 |
+
};
|
| 106 |
+
|
| 107 |
+
void pango_jpeg_init_destination (j_compress_ptr cinfo) {
|
| 108 |
+
pango_jpeg_destination_mgr* dest = (pango_jpeg_destination_mgr*) cinfo->dest;
|
| 109 |
+
dest->buffer = (JOCTET *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
| 110 |
+
PANGO_JPEG_BUF_SIZE * sizeof(JOCTET));
|
| 111 |
+
dest->pub.next_output_byte = dest->buffer;
|
| 112 |
+
dest->pub.free_in_buffer = PANGO_JPEG_BUF_SIZE;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
boolean pango_jpeg_empty_output_buffer(j_compress_ptr cinfo) {
|
| 116 |
+
pango_jpeg_destination_mgr* dest = (pango_jpeg_destination_mgr*)cinfo->dest;
|
| 117 |
+
|
| 118 |
+
dest->os->write((const char*)dest->buffer, PANGO_JPEG_BUF_SIZE);
|
| 119 |
+
|
| 120 |
+
if (dest->os->fail()) {
|
| 121 |
+
throw std::runtime_error("Couldn't write entire jpeg buffer to stream.");
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
dest->pub.next_output_byte = dest->buffer;
|
| 125 |
+
dest->pub.free_in_buffer = PANGO_JPEG_BUF_SIZE;
|
| 126 |
+
return TRUE;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
void pango_jpeg_term_destination (j_compress_ptr cinfo) {
|
| 130 |
+
pango_jpeg_destination_mgr* dest = (pango_jpeg_destination_mgr*) cinfo->dest;
|
| 131 |
+
size_t datacount = PANGO_JPEG_BUF_SIZE - dest->pub.free_in_buffer;
|
| 132 |
+
|
| 133 |
+
/* Write any data remaining in the buffer */
|
| 134 |
+
if (datacount > 0) {
|
| 135 |
+
dest->os->write((const char*)dest->buffer, datacount);
|
| 136 |
+
if (dest->os->fail()) {
|
| 137 |
+
throw std::runtime_error("Couldn't write remaining jpeg data to stream.");
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
dest->os->flush();
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
void pango_jpeg_set_dest_mgr(j_compress_ptr cinfo, std::ostream& os) {
|
| 144 |
+
pango_jpeg_destination_mgr* dest;
|
| 145 |
+
|
| 146 |
+
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
|
| 147 |
+
cinfo->dest = (struct jpeg_destination_mgr *)
|
| 148 |
+
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
| 149 |
+
sizeof(pango_jpeg_destination_mgr));
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
dest = (pango_jpeg_destination_mgr*)cinfo->dest;
|
| 153 |
+
dest->pub.init_destination = pango_jpeg_init_destination;
|
| 154 |
+
dest->pub.empty_output_buffer = pango_jpeg_empty_output_buffer;
|
| 155 |
+
dest->pub.term_destination = pango_jpeg_term_destination;
|
| 156 |
+
dest->os = &os;
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
#endif // HAVE_JPEG
|
| 160 |
+
|
| 161 |
+
TypedImage LoadJpg(std::istream& is) {
|
| 162 |
+
#ifdef HAVE_JPEG
|
| 163 |
+
TypedImage image;
|
| 164 |
+
|
| 165 |
+
struct jpeg_decompress_struct cinfo;
|
| 166 |
+
struct jpeg_error_mgr jerr;
|
| 167 |
+
|
| 168 |
+
// Setup decompression structure
|
| 169 |
+
cinfo.err = jpeg_std_error(&jerr);
|
| 170 |
+
jerr.error_exit = error_handler;
|
| 171 |
+
jpeg_create_decompress(&cinfo);
|
| 172 |
+
pango_jpeg_set_source_mgr(&cinfo, is);
|
| 173 |
+
|
| 174 |
+
// read info from header.
|
| 175 |
+
int r = jpeg_read_header(&cinfo, TRUE);
|
| 176 |
+
if (r != JPEG_HEADER_OK) {
|
| 177 |
+
throw std::runtime_error("Failed to read JPEG header.");
|
| 178 |
+
} else if (cinfo.num_components != 3 && cinfo.num_components != 1) {
|
| 179 |
+
throw std::runtime_error("Unsupported number of color components");
|
| 180 |
+
} else {
|
| 181 |
+
jpeg_start_decompress(&cinfo);
|
| 182 |
+
// resize storage if necessary
|
| 183 |
+
PixelFormat fmt = PixelFormatFromString(cinfo.output_components == 3 ? "RGB24" : "GRAY8");
|
| 184 |
+
image.Reinitialise(cinfo.output_width, cinfo.output_height, fmt);
|
| 185 |
+
JSAMPARRAY imageBuffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE,
|
| 186 |
+
cinfo.output_width*cinfo.output_components, 1);
|
| 187 |
+
for (size_t y = 0; y < cinfo.output_height; y++) {
|
| 188 |
+
jpeg_read_scanlines(&cinfo, imageBuffer, 1);
|
| 189 |
+
uint8_t* dstRow = (uint8_t*)image.RowPtr(y);
|
| 190 |
+
memcpy(dstRow, imageBuffer[0], cinfo.output_width*cinfo.output_components);
|
| 191 |
+
}
|
| 192 |
+
jpeg_finish_decompress(&cinfo);
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
// clean up.
|
| 196 |
+
jpeg_destroy_decompress(&cinfo);
|
| 197 |
+
|
| 198 |
+
return image;
|
| 199 |
+
#else
|
| 200 |
+
PANGOLIN_UNUSED(is);
|
| 201 |
+
throw std::runtime_error("Rebuild Pangolin for JPEG support.");
|
| 202 |
+
#endif // HAVE_JPEG
|
| 203 |
+
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
std::vector<std::streampos> GetMJpegOffsets(std::ifstream& is) {
|
| 207 |
+
std::vector<std::streampos> offsets;
|
| 208 |
+
|
| 209 |
+
#ifdef HAVE_JPEG
|
| 210 |
+
struct jpeg_decompress_struct cinfo;
|
| 211 |
+
struct jpeg_error_mgr jerr;
|
| 212 |
+
cinfo.err = jpeg_std_error(&jerr);
|
| 213 |
+
jerr.error_exit = error_handler;
|
| 214 |
+
jpeg_create_decompress(&cinfo);
|
| 215 |
+
pango_jpeg_set_source_mgr(&cinfo, is);
|
| 216 |
+
|
| 217 |
+
try {
|
| 218 |
+
while(true) {
|
| 219 |
+
// read info from header.
|
| 220 |
+
std::streampos jpeg_start_pos = is.tellg();
|
| 221 |
+
int r = jpeg_read_header(&cinfo, TRUE);
|
| 222 |
+
if (r != JPEG_HEADER_OK) {
|
| 223 |
+
throw std::runtime_error("Failed to read JPEG header.");
|
| 224 |
+
} else if (cinfo.num_components != 3 && cinfo.num_components != 1) {
|
| 225 |
+
throw std::runtime_error("Unsupported number of color components");
|
| 226 |
+
} else {
|
| 227 |
+
jpeg_start_decompress(&cinfo);
|
| 228 |
+
|
| 229 |
+
// resize storage if necessary
|
| 230 |
+
JSAMPARRAY imageBuffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE,
|
| 231 |
+
cinfo.output_width*cinfo.output_components, 1);
|
| 232 |
+
// TODO: Is there a better way to truly skip ANY decoding?
|
| 233 |
+
#ifdef LIBJPEG_TURBO_VERSION
|
| 234 |
+
// bug in libjpeg-turbo prevents us from skipping to end, so skip to end-1
|
| 235 |
+
jpeg_skip_scanlines(&cinfo, cinfo.output_height-1);
|
| 236 |
+
jpeg_read_scanlines(&cinfo, imageBuffer, 1);
|
| 237 |
+
#else
|
| 238 |
+
for (size_t y = 0; y < cinfo.output_height; y++) {
|
| 239 |
+
jpeg_read_scanlines(&cinfo, imageBuffer, 1);
|
| 240 |
+
}
|
| 241 |
+
#endif
|
| 242 |
+
jpeg_finish_decompress(&cinfo);
|
| 243 |
+
offsets.push_back(jpeg_start_pos);
|
| 244 |
+
cinfo.src->term_source(&cinfo);
|
| 245 |
+
}
|
| 246 |
+
}
|
| 247 |
+
} catch (const std::runtime_error&) {
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
jpeg_destroy_decompress(&cinfo);
|
| 251 |
+
|
| 252 |
+
if(offsets.size() > 0) {
|
| 253 |
+
is.clear(); // clear eof marker
|
| 254 |
+
is.seekg(offsets[0]);
|
| 255 |
+
}
|
| 256 |
+
#endif
|
| 257 |
+
return offsets;
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
TypedImage LoadJpg(const std::string& filename) {
|
| 261 |
+
std::ifstream f(filename);
|
| 262 |
+
return LoadJpg(f);
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
+
void SaveJpg(const Image<unsigned char>& img, const PixelFormat& fmt, std::ostream& os, float quality) {
|
| 266 |
+
#ifdef HAVE_JPEG
|
| 267 |
+
const int iquality = (int)std::max(std::min(quality, 100.0f),0.0f);
|
| 268 |
+
|
| 269 |
+
struct jpeg_compress_struct cinfo;
|
| 270 |
+
struct jpeg_error_mgr jerr;
|
| 271 |
+
|
| 272 |
+
if (fmt.channels != 1 && fmt.channels != 3) {
|
| 273 |
+
throw std::runtime_error("Unsupported number of image channels.");
|
| 274 |
+
}
|
| 275 |
+
if (fmt.bpp != 8 && fmt.bpp != 24) {
|
| 276 |
+
throw std::runtime_error("Unsupported image depth.");
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
// set up compression structure
|
| 280 |
+
cinfo.err = jpeg_std_error(&jerr);
|
| 281 |
+
jpeg_create_compress(&cinfo);
|
| 282 |
+
pango_jpeg_set_dest_mgr(&cinfo, os);
|
| 283 |
+
|
| 284 |
+
cinfo.image_width = (JDIMENSION)img.w;
|
| 285 |
+
cinfo.image_height = (JDIMENSION)img.h;
|
| 286 |
+
cinfo.input_components = fmt.channels;
|
| 287 |
+
if (fmt.channels == 3) {
|
| 288 |
+
cinfo.in_color_space = JCS_RGB;
|
| 289 |
+
} else {
|
| 290 |
+
cinfo.in_color_space = JCS_GRAYSCALE;
|
| 291 |
+
}
|
| 292 |
+
|
| 293 |
+
jpeg_set_defaults(&cinfo);
|
| 294 |
+
jpeg_set_quality(&cinfo, iquality, (boolean)true);
|
| 295 |
+
jpeg_start_compress(&cinfo, (boolean)true);
|
| 296 |
+
|
| 297 |
+
JSAMPROW row;
|
| 298 |
+
while (cinfo.next_scanline < cinfo.image_height) {
|
| 299 |
+
row = (JSAMPROW)((char*)img.RowPtr(cinfo.next_scanline));
|
| 300 |
+
jpeg_write_scanlines(&cinfo, &row, 1);
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
jpeg_finish_compress(&cinfo);
|
| 304 |
+
jpeg_destroy_compress(&cinfo);
|
| 305 |
+
#else
|
| 306 |
+
PANGOLIN_UNUSED(img);
|
| 307 |
+
PANGOLIN_UNUSED(fmt);
|
| 308 |
+
PANGOLIN_UNUSED(os);
|
| 309 |
+
PANGOLIN_UNUSED(quality);
|
| 310 |
+
throw std::runtime_error("Rebuild Pangolin for JPEG support.");
|
| 311 |
+
#endif // HAVE_JPEG
|
| 312 |
+
}
|
| 313 |
+
|
| 314 |
+
void SaveJpg(const Image<unsigned char>& img, const PixelFormat& fmt, const std::string& filename, float quality) {
|
| 315 |
+
std::ofstream f(filename);
|
| 316 |
+
SaveJpg(img, fmt, f, quality);
|
| 317 |
+
}
|
| 318 |
+
|
| 319 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_libraw.cpp
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <fstream>
|
| 2 |
+
#include <pangolin/image/typed_image.h>
|
| 3 |
+
|
| 4 |
+
#ifdef HAVE_LIBRAW
|
| 5 |
+
# include <libraw/libraw.h>
|
| 6 |
+
#endif
|
| 7 |
+
|
| 8 |
+
namespace pangolin {
|
| 9 |
+
|
| 10 |
+
TypedImage LoadLibRaw(
|
| 11 |
+
const std::string& filename
|
| 12 |
+
) {
|
| 13 |
+
#ifdef HAVE_LIBRAW
|
| 14 |
+
static LibRaw RawProcessor;
|
| 15 |
+
|
| 16 |
+
int ret;
|
| 17 |
+
|
| 18 |
+
if ((ret = RawProcessor.open_file(filename.c_str())) != LIBRAW_SUCCESS)
|
| 19 |
+
{
|
| 20 |
+
throw std::runtime_error(libraw_strerror(ret));
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
|
| 24 |
+
{
|
| 25 |
+
throw std::runtime_error(libraw_strerror(ret));
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
const auto& S = RawProcessor.imgdata.sizes;
|
| 29 |
+
TypedImage image(S.width, S.height, PixelFormatFromString("GRAY16LE"), sizeof(uint16_t) * S.raw_width);
|
| 30 |
+
PitchedCopy((char*)image.ptr, image.pitch, (char*)RawProcessor.imgdata.rawdata.raw_image, sizeof(uint16_t) * S.raw_width, sizeof(uint16_t) * image.w, image.h);
|
| 31 |
+
|
| 32 |
+
// TODO: Support image metadata so that we can extract these fields.
|
| 33 |
+
// RawProcessor.imgdata.other.iso_speed
|
| 34 |
+
// RawProcessor.imgdata.other.aperture
|
| 35 |
+
// RawProcessor.imgdata.other.focal_len
|
| 36 |
+
// RawProcessor.imgdata.other.shutter
|
| 37 |
+
// RawProcessor.imgdata.other.timestamp
|
| 38 |
+
// RawProcessor.imgdata.makernotes.common.exifCameraElevationAngle
|
| 39 |
+
// RawProcessor.imgdata.makernotes.sony.SonyDateTime
|
| 40 |
+
|
| 41 |
+
return image;
|
| 42 |
+
#else
|
| 43 |
+
PANGOLIN_UNUSED(filename);
|
| 44 |
+
throw std::runtime_error("Rebuild Pangolin for libraw support.");
|
| 45 |
+
#endif
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_lz4.cpp
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <fstream>
|
| 2 |
+
#include <memory>
|
| 3 |
+
|
| 4 |
+
#include <pangolin/image/typed_image.h>
|
| 5 |
+
|
| 6 |
+
#ifdef HAVE_LZ4
|
| 7 |
+
# include <lz4.h>
|
| 8 |
+
#endif
|
| 9 |
+
|
| 10 |
+
namespace pangolin {
|
| 11 |
+
|
| 12 |
+
#pragma pack(push, 1)
|
| 13 |
+
struct lz4_image_header
|
| 14 |
+
{
|
| 15 |
+
char magic[3];
|
| 16 |
+
char fmt[16];
|
| 17 |
+
size_t w, h;
|
| 18 |
+
int64_t compressed_size;
|
| 19 |
+
};
|
| 20 |
+
#pragma pack(pop)
|
| 21 |
+
|
| 22 |
+
void SaveLz4(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, int compression_level)
|
| 23 |
+
{
|
| 24 |
+
#ifdef HAVE_LZ4
|
| 25 |
+
const int64_t src_size = image.SizeBytes();
|
| 26 |
+
const int64_t max_dst_size = LZ4_compressBound(src_size);
|
| 27 |
+
std::unique_ptr<char[]> output_buffer(new char[max_dst_size]);
|
| 28 |
+
|
| 29 |
+
// Same as LZ4_compress_default(), but allows to select an "acceleration" factor.
|
| 30 |
+
// The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
|
| 31 |
+
// It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
|
| 32 |
+
// An acceleration value of "1" is the same as regular LZ4_compress_default()
|
| 33 |
+
// Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1.
|
| 34 |
+
const int64_t compressed_data_size = LZ4_compress_fast((char*)image.ptr, output_buffer.get(), src_size, max_dst_size, compression_level);
|
| 35 |
+
|
| 36 |
+
if (compressed_data_size < 0)
|
| 37 |
+
throw std::runtime_error("A negative result from LZ4_compress_default indicates a failure trying to compress the data.");
|
| 38 |
+
if (compressed_data_size == 0)
|
| 39 |
+
throw std::runtime_error("A result of 0 for LZ4 means compression worked, but was stopped because the destination buffer couldn't hold all the information.");
|
| 40 |
+
|
| 41 |
+
lz4_image_header header;
|
| 42 |
+
memcpy(header.magic,"LZ4",3);
|
| 43 |
+
strncpy(header.fmt, fmt.format.c_str(), sizeof(header.fmt));
|
| 44 |
+
header.w = image.w;
|
| 45 |
+
header.h = image.h;
|
| 46 |
+
header.compressed_size = compressed_data_size;
|
| 47 |
+
out.write((char*)&header, sizeof(header));
|
| 48 |
+
|
| 49 |
+
out.write(output_buffer.get(), compressed_data_size);
|
| 50 |
+
|
| 51 |
+
#else
|
| 52 |
+
PANGOLIN_UNUSED(image);
|
| 53 |
+
PANGOLIN_UNUSED(fmt);
|
| 54 |
+
PANGOLIN_UNUSED(out);
|
| 55 |
+
PANGOLIN_UNUSED(compression_level);
|
| 56 |
+
throw std::runtime_error("Rebuild Pangolin for LZ4 support.");
|
| 57 |
+
#endif // HAVE_LZ4
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
TypedImage LoadLz4(std::istream& in)
|
| 61 |
+
{
|
| 62 |
+
#ifdef HAVE_LZ4
|
| 63 |
+
// Read in header, uncompressed
|
| 64 |
+
lz4_image_header header;
|
| 65 |
+
in.read( (char*)&header, sizeof(header));
|
| 66 |
+
|
| 67 |
+
TypedImage img(header.w, header.h, PixelFormatFromString(header.fmt));
|
| 68 |
+
std::unique_ptr<char[]> input_buffer(new char[header.compressed_size]);
|
| 69 |
+
|
| 70 |
+
in.read(input_buffer.get(), header.compressed_size);
|
| 71 |
+
const int decompressed_size = LZ4_decompress_safe(input_buffer.get(), (char*)img.ptr, header.compressed_size, img.SizeBytes());
|
| 72 |
+
if (decompressed_size < 0)
|
| 73 |
+
throw std::runtime_error(FormatString("A negative result from LZ4_decompress_safe indicates a failure trying to decompress the data. See exit code (%) for value returned.", decompressed_size));
|
| 74 |
+
if (decompressed_size == 0)
|
| 75 |
+
throw std::runtime_error("I'm not sure this function can ever return 0. Documentation in lz4.h doesn't indicate so.");
|
| 76 |
+
if (decompressed_size != (int)img.SizeBytes())
|
| 77 |
+
throw std::runtime_error(FormatString("decompressed size % is not equal to predicted size %", decompressed_size, img.SizeBytes()));
|
| 78 |
+
|
| 79 |
+
return img;
|
| 80 |
+
#else
|
| 81 |
+
PANGOLIN_UNUSED(in);
|
| 82 |
+
throw std::runtime_error("Rebuild Pangolin for LZ4 support.");
|
| 83 |
+
#endif // HAVE_LZ4
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_packed12bit.cpp
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <fstream>
|
| 2 |
+
#include <memory>
|
| 3 |
+
|
| 4 |
+
#include <pangolin/image/typed_image.h>
|
| 5 |
+
|
| 6 |
+
namespace pangolin {
|
| 7 |
+
|
| 8 |
+
#pragma pack(push, 1)
|
| 9 |
+
struct packed12bit_image_header
|
| 10 |
+
{
|
| 11 |
+
char magic[4];
|
| 12 |
+
char fmt[16];
|
| 13 |
+
size_t w, h;
|
| 14 |
+
};
|
| 15 |
+
#pragma pack(pop)
|
| 16 |
+
|
| 17 |
+
void SavePacked12bit(const Image<uint8_t>& image, const pangolin::PixelFormat& fmt, std::ostream& out)
|
| 18 |
+
{
|
| 19 |
+
|
| 20 |
+
if (fmt.bpp != 16) {
|
| 21 |
+
throw std::runtime_error("packed12bit currently only supported with 16bit input image");
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
const size_t dest_pitch = (image.w*12)/ 8 + ((image.w*12) % 8 > 0? 1 : 0);
|
| 25 |
+
const size_t dest_size = image.h*dest_pitch;
|
| 26 |
+
std::unique_ptr<uint8_t[]> output_buffer(new uint8_t[dest_size]);
|
| 27 |
+
|
| 28 |
+
for(size_t r=0; r<image.h; ++r) {
|
| 29 |
+
uint8_t* pout = output_buffer.get() + r*dest_pitch;
|
| 30 |
+
uint16_t* pin = (uint16_t*)(image.ptr + r*image.pitch);
|
| 31 |
+
const uint16_t* pin_end = (uint16_t*)(image.ptr + (r+1)*image.pitch);
|
| 32 |
+
while(pin < pin_end) {
|
| 33 |
+
uint32_t val = (*(pin++) & 0x00000FFF);
|
| 34 |
+
val |= uint32_t(*(pin++) & 0x00000FFF) << 12;
|
| 35 |
+
*(pout++) = uint8_t( val & 0x000000FF);
|
| 36 |
+
*(pout++) = uint8_t((val & 0x0000FF00) >> 8);
|
| 37 |
+
*(pout++) = uint8_t((val & 0x00FF0000) >> 16);
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
packed12bit_image_header header;
|
| 42 |
+
static_assert (sizeof(header.magic) == 4, "[bug]");
|
| 43 |
+
memcpy(header.magic, "P12B", 4);
|
| 44 |
+
memset(header.fmt, '\0', sizeof(header.fmt));
|
| 45 |
+
memcpy(header.fmt, fmt.format.c_str(), std::min(sizeof(header.fmt), fmt.format.size()) );
|
| 46 |
+
header.w = image.w;
|
| 47 |
+
header.h = image.h;
|
| 48 |
+
out.write((char*)&header, sizeof(header));
|
| 49 |
+
out.write((char*)output_buffer.get(), dest_size);
|
| 50 |
+
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
TypedImage LoadPacked12bit(std::istream& in)
|
| 54 |
+
{
|
| 55 |
+
// Read in header, uncompressed
|
| 56 |
+
packed12bit_image_header header;
|
| 57 |
+
in.read((char*)&header, sizeof(header));
|
| 58 |
+
|
| 59 |
+
TypedImage img(header.w, header.h, PixelFormatFromString(header.fmt));
|
| 60 |
+
|
| 61 |
+
if (img.fmt.bpp != 16) {
|
| 62 |
+
throw std::runtime_error("packed12bit currently only supported with 16bit input image");
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
const size_t input_pitch = (img.w*12)/ 8 + ((img.w*12) % 8 > 0? 1 : 0);
|
| 66 |
+
const size_t input_size = img.h*input_pitch;
|
| 67 |
+
std::unique_ptr<uint8_t[]> input_buffer(new uint8_t[input_size]);
|
| 68 |
+
|
| 69 |
+
in.read((char*)input_buffer.get(), input_size);
|
| 70 |
+
|
| 71 |
+
for(size_t r=0; r<img.h; ++r) {
|
| 72 |
+
uint16_t* pout = (uint16_t*)(img.ptr + r*img.pitch);
|
| 73 |
+
uint8_t* pin = input_buffer.get() + r*input_pitch;
|
| 74 |
+
const uint8_t* pin_end = input_buffer.get() + (r+1)*input_pitch;
|
| 75 |
+
while(pin < pin_end) {
|
| 76 |
+
uint32_t val = *(pin++);
|
| 77 |
+
val |= uint32_t(*(pin++)) << 8;
|
| 78 |
+
val |= uint32_t(*(pin++)) << 16;
|
| 79 |
+
*(pout++) = uint16_t( val & 0x000FFF);
|
| 80 |
+
*(pout++) = uint16_t((val & 0xFFF000) >> 12);
|
| 81 |
+
}
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
return img;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_pango.cpp
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <pangolin/platform.h>
|
| 2 |
+
|
| 3 |
+
#include <pangolin/image/typed_image.h>
|
| 4 |
+
|
| 5 |
+
#ifdef BUILD_PANGOLIN_VIDEO
|
| 6 |
+
# include <pangolin/video/drivers/pango.h>
|
| 7 |
+
# include <pangolin/video/drivers/pango_video_output.h>
|
| 8 |
+
#endif
|
| 9 |
+
|
| 10 |
+
namespace pangolin {
|
| 11 |
+
|
| 12 |
+
TypedImage LoadPango(const std::string& uri)
|
| 13 |
+
{
|
| 14 |
+
PANGOLIN_UNUSED(uri);
|
| 15 |
+
|
| 16 |
+
#ifdef BUILD_PANGOLIN_VIDEO
|
| 17 |
+
std::unique_ptr<VideoInterface> video = OpenVideo(uri);
|
| 18 |
+
if(!video || video->Streams().size() != 1) {
|
| 19 |
+
throw pangolin::VideoException("Wrong number of streams: exactly one expected.");
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
std::unique_ptr<uint8_t[]> buffer( new uint8_t[video->SizeBytes()] );
|
| 23 |
+
const StreamInfo& stream_info = video->Streams()[0];
|
| 24 |
+
|
| 25 |
+
// Grab first image from video
|
| 26 |
+
if(!video->GrabNext(buffer.get(), true)) {
|
| 27 |
+
throw pangolin::VideoException("Failed to grab image from stream");
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
// Allocate storage for user image to return
|
| 31 |
+
TypedImage image(stream_info.Width(), stream_info.Height(), stream_info.PixFormat());
|
| 32 |
+
|
| 33 |
+
// Copy image data into user buffer.
|
| 34 |
+
const Image<unsigned char> img = stream_info.StreamImage(buffer.get());
|
| 35 |
+
PANGO_ENSURE(image.pitch <= img.pitch);
|
| 36 |
+
for(size_t y=0; y < image.h; ++y) {
|
| 37 |
+
std::memcpy(image.RowPtr(y), img.RowPtr(y), image.pitch);
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
return image;
|
| 41 |
+
#else
|
| 42 |
+
throw std::runtime_error("Video Support not enabled. Please rebuild Pangolin.");
|
| 43 |
+
#endif
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
void SavePango(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, const std::string& uri, bool /*top_line_first*/)
|
| 47 |
+
{
|
| 48 |
+
PANGOLIN_UNUSED(image);
|
| 49 |
+
PANGOLIN_UNUSED(fmt);
|
| 50 |
+
PANGOLIN_UNUSED(uri);
|
| 51 |
+
|
| 52 |
+
#ifdef BUILD_PANGOLIN_VIDEO
|
| 53 |
+
std::unique_ptr<VideoOutputInterface> video = OpenVideoOutput(uri);
|
| 54 |
+
StreamInfo stream(fmt, image.w, image.h, image.pitch);
|
| 55 |
+
video->SetStreams({stream});
|
| 56 |
+
video->WriteStreams(image.ptr);
|
| 57 |
+
#else
|
| 58 |
+
throw std::runtime_error("Video Support not enabled. Please rebuild Pangolin.");
|
| 59 |
+
#endif
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_png.cpp
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <pangolin/platform.h>
|
| 2 |
+
|
| 3 |
+
#include <fstream>
|
| 4 |
+
#include <pangolin/image/image_io.h>
|
| 5 |
+
#include <vector>
|
| 6 |
+
|
| 7 |
+
#ifdef HAVE_PNG
|
| 8 |
+
# include <png.h>
|
| 9 |
+
#endif // HAVE_PNG
|
| 10 |
+
|
| 11 |
+
namespace pangolin {
|
| 12 |
+
|
| 13 |
+
#ifdef HAVE_PNG
|
| 14 |
+
|
| 15 |
+
PixelFormat PngFormat(png_structp png_ptr, png_infop info_ptr )
|
| 16 |
+
{
|
| 17 |
+
const png_byte colour = png_get_color_type(png_ptr, info_ptr);
|
| 18 |
+
const png_byte depth = png_get_bit_depth(png_ptr, info_ptr);
|
| 19 |
+
|
| 20 |
+
if( depth == 8 ) {
|
| 21 |
+
if( colour == PNG_COLOR_MASK_COLOR ) {
|
| 22 |
+
return PixelFormatFromString("RGB24");
|
| 23 |
+
} else if( colour == (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) ) {
|
| 24 |
+
return PixelFormatFromString("RGBA32");
|
| 25 |
+
} else if( colour == PNG_COLOR_MASK_ALPHA ) {
|
| 26 |
+
return PixelFormatFromString("Y400A");
|
| 27 |
+
} else {
|
| 28 |
+
return PixelFormatFromString("GRAY8");
|
| 29 |
+
}
|
| 30 |
+
}else if( depth == 16 ) {
|
| 31 |
+
if( colour == 0 ) {
|
| 32 |
+
return PixelFormatFromString("GRAY16LE");
|
| 33 |
+
}
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
throw std::runtime_error("Unsupported PNG format");
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
void PNGAPI PngWarningsCallback(png_structp /*png_ptr*/, png_const_charp /*warning_message*/)
|
| 40 |
+
{
|
| 41 |
+
// Override default behaviour - don't do anything.
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
#define PNGSIGSIZE 8
|
| 45 |
+
bool pango_png_validate(std::istream& source)
|
| 46 |
+
{
|
| 47 |
+
png_byte pngsig[PNGSIGSIZE];
|
| 48 |
+
source.read((char*)pngsig, PNGSIGSIZE);
|
| 49 |
+
return source.good() && png_sig_cmp(pngsig, 0, PNGSIGSIZE) == 0;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
void pango_png_stream_read(png_structp pngPtr, png_bytep data, png_size_t length) {
|
| 53 |
+
std::istream* s = (std::istream*)png_get_io_ptr(pngPtr);
|
| 54 |
+
PANGO_ASSERT(s);
|
| 55 |
+
s->read((char*)data, length);
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
void pango_png_stream_write(png_structp pngPtr, png_bytep data, png_size_t length) {
|
| 59 |
+
std::ostream* s = (std::ostream*)png_get_io_ptr(pngPtr);
|
| 60 |
+
PANGO_ASSERT(s);
|
| 61 |
+
s->write((char*)data, length);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
void pango_png_stream_write_flush(png_structp pngPtr)
|
| 65 |
+
{
|
| 66 |
+
std::ostream* s = (std::ostream*)png_get_io_ptr(pngPtr);
|
| 67 |
+
PANGO_ASSERT(s);
|
| 68 |
+
s->flush();
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
#endif // HAVE_PNG
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
TypedImage LoadPng(std::istream& source)
|
| 75 |
+
{
|
| 76 |
+
#ifdef HAVE_PNG
|
| 77 |
+
//so First, we validate our stream with the validate function I just mentioned
|
| 78 |
+
if (!pango_png_validate(source)) {
|
| 79 |
+
throw std::runtime_error("Not valid PNG header");
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
//set up initial png structs
|
| 83 |
+
png_structp png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, &PngWarningsCallback);
|
| 84 |
+
if (!png_ptr) {
|
| 85 |
+
throw std::runtime_error( "PNG Init error 1" );
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
png_infop info_ptr = png_create_info_struct(png_ptr);
|
| 89 |
+
if (!info_ptr) {
|
| 90 |
+
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
|
| 91 |
+
throw std::runtime_error( "PNG Init error 2" );
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
png_infop end_info = png_create_info_struct(png_ptr);
|
| 95 |
+
if (!end_info) {
|
| 96 |
+
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
| 97 |
+
throw std::runtime_error( "PNG Init error 3" );
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
png_set_read_fn(png_ptr,(png_voidp)&source, pango_png_stream_read);
|
| 101 |
+
|
| 102 |
+
png_set_sig_bytes(png_ptr, PNGSIGSIZE);
|
| 103 |
+
|
| 104 |
+
// Setup transformation options
|
| 105 |
+
if( png_get_bit_depth(png_ptr, info_ptr) == 1) {
|
| 106 |
+
//Unpack bools to bytes to ease loading.
|
| 107 |
+
png_set_packing(png_ptr);
|
| 108 |
+
} else if( png_get_bit_depth(png_ptr, info_ptr) < 8) {
|
| 109 |
+
//Expand nonbool colour depths up to 8bpp
|
| 110 |
+
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
//Get rid of palette, by transforming it to RGB
|
| 114 |
+
if(png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) {
|
| 115 |
+
png_set_palette_to_rgb(png_ptr);
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
//read the file
|
| 119 |
+
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_SWAP_ENDIAN, NULL);
|
| 120 |
+
|
| 121 |
+
if( png_get_interlace_type(png_ptr,info_ptr) != PNG_INTERLACE_NONE) {
|
| 122 |
+
throw std::runtime_error( "Interlace not yet supported" );
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
const size_t w = png_get_image_width(png_ptr,info_ptr);
|
| 126 |
+
const size_t h = png_get_image_height(png_ptr,info_ptr);
|
| 127 |
+
const size_t pitch = png_get_rowbytes(png_ptr, info_ptr);
|
| 128 |
+
|
| 129 |
+
TypedImage img(w, h, PngFormat(png_ptr, info_ptr), pitch);
|
| 130 |
+
|
| 131 |
+
png_bytepp rows = png_get_rows(png_ptr, info_ptr);
|
| 132 |
+
for( unsigned int r = 0; r < h; r++) {
|
| 133 |
+
memcpy( img.ptr + pitch*r, rows[r], pitch );
|
| 134 |
+
}
|
| 135 |
+
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
| 136 |
+
|
| 137 |
+
return img;
|
| 138 |
+
#else
|
| 139 |
+
PANGOLIN_UNUSED(source);
|
| 140 |
+
throw std::runtime_error("Rebuild Pangolin for PNG support.");
|
| 141 |
+
#endif // HAVE_PNG
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
TypedImage LoadPng(const std::string& filename)
|
| 145 |
+
{
|
| 146 |
+
std::ifstream f(filename);
|
| 147 |
+
return LoadPng(f);
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
void SavePng(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& stream, bool top_line_first, int zlib_compression_level)
|
| 151 |
+
{
|
| 152 |
+
#ifdef HAVE_PNG
|
| 153 |
+
// Check image has supported bit depth
|
| 154 |
+
for(unsigned int i=1; i < fmt.channels; ++i) {
|
| 155 |
+
if( fmt.channel_bits[i] != fmt.channel_bits[0] ) {
|
| 156 |
+
throw std::runtime_error("PNG Saving only supported for images where each channel has the same bit depth.");
|
| 157 |
+
}
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
png_structp png_ptr;
|
| 161 |
+
png_infop info_ptr;
|
| 162 |
+
|
| 163 |
+
// Initialize write structure
|
| 164 |
+
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
| 165 |
+
if (png_ptr == NULL) {
|
| 166 |
+
throw std::runtime_error( "PNG Error: Could not allocate write struct." );
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
// Initialize info structure
|
| 170 |
+
info_ptr = png_create_info_struct(png_ptr);
|
| 171 |
+
if (info_ptr == NULL) {
|
| 172 |
+
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
| 173 |
+
throw std::runtime_error( "PNG Error: Could not allocate info struct." );
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
// Setup Exception handling
|
| 177 |
+
if (setjmp(png_jmpbuf(png_ptr))) {
|
| 178 |
+
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
|
| 179 |
+
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
| 180 |
+
throw std::runtime_error( "PNG Error: Error during png creation." );
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
png_set_compression_level(png_ptr, zlib_compression_level);
|
| 184 |
+
|
| 185 |
+
png_set_write_fn(png_ptr,(png_voidp)&stream, pango_png_stream_write, pango_png_stream_write_flush);
|
| 186 |
+
|
| 187 |
+
const int bit_depth = fmt.channel_bits[0];
|
| 188 |
+
|
| 189 |
+
int colour_type;
|
| 190 |
+
switch (fmt.channels) {
|
| 191 |
+
case 1: colour_type = PNG_COLOR_TYPE_GRAY; break;
|
| 192 |
+
case 2: colour_type = PNG_COLOR_TYPE_GRAY_ALPHA; break;
|
| 193 |
+
case 3: colour_type = PNG_COLOR_TYPE_RGB; break;
|
| 194 |
+
case 4: colour_type = PNG_COLOR_TYPE_RGBA; break;
|
| 195 |
+
default:
|
| 196 |
+
throw std::runtime_error( "PNG Error: unexpected image channel number");
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
// Write header
|
| 200 |
+
png_set_IHDR(
|
| 201 |
+
png_ptr, info_ptr, (png_uint_32)image.w, (png_uint_32)image.h, bit_depth, colour_type,
|
| 202 |
+
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT
|
| 203 |
+
);
|
| 204 |
+
|
| 205 |
+
// Setup rows to write:
|
| 206 |
+
std::vector<png_bytep> rows(image.h);
|
| 207 |
+
if(top_line_first) {
|
| 208 |
+
for (unsigned int y = 0; y< image.h; y++) {
|
| 209 |
+
rows[y] = image.ptr + y*image.pitch;
|
| 210 |
+
}
|
| 211 |
+
}else{
|
| 212 |
+
for (unsigned int y = 0; y< image.h; y++) {
|
| 213 |
+
rows[y] = image.ptr + (image.h-1-y)*image.pitch;
|
| 214 |
+
}
|
| 215 |
+
}
|
| 216 |
+
png_set_rows(png_ptr,info_ptr, &rows[0]);
|
| 217 |
+
|
| 218 |
+
// Write image data: switch to little-endian byte order, to match host.
|
| 219 |
+
png_write_png(png_ptr,info_ptr, PNG_TRANSFORM_SWAP_ENDIAN, 0);
|
| 220 |
+
|
| 221 |
+
// Free resources
|
| 222 |
+
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
|
| 223 |
+
png_destroy_write_struct(&png_ptr, &info_ptr);
|
| 224 |
+
#else
|
| 225 |
+
PANGOLIN_UNUSED(image);
|
| 226 |
+
PANGOLIN_UNUSED(fmt);
|
| 227 |
+
PANGOLIN_UNUSED(stream);
|
| 228 |
+
PANGOLIN_UNUSED(top_line_first);
|
| 229 |
+
PANGOLIN_UNUSED(zlib_compression_level);
|
| 230 |
+
throw std::runtime_error("Rebuild Pangolin for PNG support.");
|
| 231 |
+
#endif // HAVE_PNG
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_ppm.cpp
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <fstream>
|
| 2 |
+
#include <pangolin/image/typed_image.h>
|
| 3 |
+
|
| 4 |
+
namespace pangolin {
|
| 5 |
+
|
| 6 |
+
PixelFormat PpmFormat(const std::string& strType, int num_colours)
|
| 7 |
+
{
|
| 8 |
+
if(strType == "P5") {
|
| 9 |
+
if(num_colours < 256) {
|
| 10 |
+
return PixelFormatFromString("GRAY8");
|
| 11 |
+
} else {
|
| 12 |
+
return PixelFormatFromString("GRAY16LE");
|
| 13 |
+
}
|
| 14 |
+
}else if(strType == "P6") {
|
| 15 |
+
return PixelFormatFromString("RGB24");
|
| 16 |
+
}else{
|
| 17 |
+
throw std::runtime_error("Unsupported PPM/PGM format");
|
| 18 |
+
}
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
void PpmConsumeWhitespaceAndComments(std::istream& in)
|
| 22 |
+
{
|
| 23 |
+
// TODO: Make a little more general / more efficient
|
| 24 |
+
while( in.peek() == ' ' ) in.get();
|
| 25 |
+
while( in.peek() == '\n' ) in.get();
|
| 26 |
+
while( in.peek() == '#' ) in.ignore(4096, '\n');
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
TypedImage LoadPpm(std::istream& in)
|
| 30 |
+
{
|
| 31 |
+
// Parse header
|
| 32 |
+
std::string ppm_type = "";
|
| 33 |
+
int num_colors = 0;
|
| 34 |
+
int w = 0;
|
| 35 |
+
int h = 0;
|
| 36 |
+
|
| 37 |
+
in >> ppm_type;
|
| 38 |
+
PpmConsumeWhitespaceAndComments(in);
|
| 39 |
+
in >> w;
|
| 40 |
+
PpmConsumeWhitespaceAndComments(in);
|
| 41 |
+
in >> h;
|
| 42 |
+
PpmConsumeWhitespaceAndComments(in);
|
| 43 |
+
in >> num_colors;
|
| 44 |
+
in.ignore(1,'\n');
|
| 45 |
+
|
| 46 |
+
if(!in.fail() && w > 0 && h > 0) {
|
| 47 |
+
TypedImage img(w, h, PpmFormat(ppm_type, num_colors) );
|
| 48 |
+
|
| 49 |
+
// Read in data
|
| 50 |
+
for(size_t r=0; r<img.h; ++r) {
|
| 51 |
+
in.read( (char*)img.ptr + r*img.pitch, img.pitch );
|
| 52 |
+
}
|
| 53 |
+
if(!in.fail()) {
|
| 54 |
+
return img;
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
throw std::runtime_error("Unable to load PPM file.");
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
void SavePpm(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, bool top_line_first)
|
| 62 |
+
{
|
| 63 |
+
// Setup header variables
|
| 64 |
+
std::string ppm_type = "";
|
| 65 |
+
int num_colors = 0;
|
| 66 |
+
int w = (int)image.w;
|
| 67 |
+
int h = (int)image.h;
|
| 68 |
+
|
| 69 |
+
if(fmt.format == "GRAY8") {
|
| 70 |
+
ppm_type = "P5";
|
| 71 |
+
num_colors = 255;
|
| 72 |
+
}else if(fmt.format == "GRAY16LE") {
|
| 73 |
+
ppm_type = "P5";
|
| 74 |
+
num_colors = 65535;
|
| 75 |
+
}else if(fmt.format == "RGB24") {
|
| 76 |
+
ppm_type = "P6";
|
| 77 |
+
num_colors = 255;
|
| 78 |
+
}else{
|
| 79 |
+
throw std::runtime_error("Unsupported pixel format");
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
// Write header
|
| 83 |
+
out << ppm_type;
|
| 84 |
+
out << " ";
|
| 85 |
+
out << w;
|
| 86 |
+
out << " ";
|
| 87 |
+
out << h;
|
| 88 |
+
out << " ";
|
| 89 |
+
out << num_colors;
|
| 90 |
+
out << "\n";
|
| 91 |
+
|
| 92 |
+
// Write out data
|
| 93 |
+
if(top_line_first) {
|
| 94 |
+
for(size_t r=0; r<image.h; ++r) {
|
| 95 |
+
out.write( (char*)image.ptr + r*image.pitch, image.pitch );
|
| 96 |
+
}
|
| 97 |
+
}else{
|
| 98 |
+
for(size_t r=0; r<image.h; ++r) {
|
| 99 |
+
out.write( (char*)image.ptr + (image.h-1-r)*image.pitch, image.pitch );
|
| 100 |
+
}
|
| 101 |
+
}
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_raw.cpp
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <fstream>
|
| 2 |
+
#include <pangolin/image/typed_image.h>
|
| 3 |
+
|
| 4 |
+
namespace pangolin {
|
| 5 |
+
|
| 6 |
+
TypedImage LoadImage(
|
| 7 |
+
const std::string& filename,
|
| 8 |
+
const PixelFormat& raw_fmt,
|
| 9 |
+
size_t raw_width, size_t raw_height, size_t raw_pitch
|
| 10 |
+
) {
|
| 11 |
+
TypedImage img(raw_width, raw_height, raw_fmt, raw_pitch);
|
| 12 |
+
|
| 13 |
+
// Read from file, row at a time.
|
| 14 |
+
std::ifstream bFile( filename.c_str(), std::ios::in | std::ios::binary );
|
| 15 |
+
for(size_t r=0; r<img.h; ++r) {
|
| 16 |
+
bFile.read( (char*)img.ptr + r*img.pitch, img.pitch );
|
| 17 |
+
if(bFile.fail()) {
|
| 18 |
+
pango_print_warn("Unable to read raw image file to completion.");
|
| 19 |
+
break;
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
return img;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_tga.cpp
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <pangolin/platform.h>
|
| 2 |
+
|
| 3 |
+
#include <pangolin/image/image_io.h>
|
| 4 |
+
|
| 5 |
+
namespace pangolin {
|
| 6 |
+
|
| 7 |
+
PixelFormat TgaFormat(int depth, int color_type, int color_map)
|
| 8 |
+
{
|
| 9 |
+
if(color_map == 0) {
|
| 10 |
+
if(color_type == 2) {
|
| 11 |
+
// Colour
|
| 12 |
+
if(depth == 24) {
|
| 13 |
+
return PixelFormatFromString("RGB24");
|
| 14 |
+
}else if(depth == 32) {
|
| 15 |
+
return PixelFormatFromString("RGBA32");
|
| 16 |
+
}
|
| 17 |
+
}else if(color_type == 3){
|
| 18 |
+
// Greyscale
|
| 19 |
+
if(depth == 8) {
|
| 20 |
+
return PixelFormatFromString("GRAY8");
|
| 21 |
+
}else if(depth == 16) {
|
| 22 |
+
return PixelFormatFromString("Y400A");
|
| 23 |
+
}
|
| 24 |
+
}
|
| 25 |
+
}
|
| 26 |
+
throw std::runtime_error("Unsupported TGA format");
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
TypedImage LoadTga(std::istream& in)
|
| 30 |
+
{
|
| 31 |
+
unsigned char type[4];
|
| 32 |
+
unsigned char info[6];
|
| 33 |
+
|
| 34 |
+
in.read((char*)type, 3*sizeof(char));
|
| 35 |
+
in.seekg(12);
|
| 36 |
+
in.read((char*)info,6*sizeof(char));
|
| 37 |
+
|
| 38 |
+
const int width = info[0] + (info[1] * 256);
|
| 39 |
+
const int height = info[2] + (info[3] * 256);
|
| 40 |
+
|
| 41 |
+
if(in.good()) {
|
| 42 |
+
TypedImage img(width, height, TgaFormat(info[4], type[2], type[1]) );
|
| 43 |
+
|
| 44 |
+
//read in image data
|
| 45 |
+
const size_t data_size = img.h * img.pitch;
|
| 46 |
+
in.read((char*)img.ptr, sizeof(char)*data_size);
|
| 47 |
+
return img;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
throw std::runtime_error("Unable to load TGA file");
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_tiff.cpp
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <cassert>
|
| 2 |
+
#include <pangolin/image/typed_image.h>
|
| 3 |
+
|
| 4 |
+
#ifdef HAVE_LIBTIFF
|
| 5 |
+
# include <tiffio.h>
|
| 6 |
+
#endif
|
| 7 |
+
|
| 8 |
+
namespace pangolin {
|
| 9 |
+
|
| 10 |
+
#ifdef HAVE_LIBTIFF
|
| 11 |
+
template<typename T>
|
| 12 |
+
T GetOrThrow(TIFF* tif, uint32_t tag)
|
| 13 |
+
{
|
| 14 |
+
T r;
|
| 15 |
+
if (TIFFGetField(tif, tag, &r) != 1) {
|
| 16 |
+
throw std::runtime_error("Expected tag missing when reading tiff (" + std::to_string(tag) + ")");
|
| 17 |
+
}
|
| 18 |
+
return r;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
template<typename T>
|
| 22 |
+
T GetOrDefault(TIFF* tif, uint32_t tag, T default_val)
|
| 23 |
+
{
|
| 24 |
+
T r = default_val;
|
| 25 |
+
TIFFGetField(tif, tag, &r);
|
| 26 |
+
return r;
|
| 27 |
+
}
|
| 28 |
+
#endif
|
| 29 |
+
|
| 30 |
+
TypedImage LoadTiff(
|
| 31 |
+
const std::string& filename
|
| 32 |
+
) {
|
| 33 |
+
#ifdef HAVE_LIBTIFF
|
| 34 |
+
TIFF* tif = TIFFOpen(filename.c_str(),"r");
|
| 35 |
+
if (!tif) {
|
| 36 |
+
throw std::runtime_error("libtiff failed to open " + filename);
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
const auto width = GetOrThrow<uint32_t>(tif, TIFFTAG_IMAGEWIDTH);
|
| 40 |
+
const auto height = GetOrThrow<uint32_t>(tif, TIFFTAG_IMAGELENGTH);
|
| 41 |
+
const auto channels = GetOrThrow<uint16_t>(tif, TIFFTAG_SAMPLESPERPIXEL);
|
| 42 |
+
const auto bits_per_channel = GetOrThrow<uint16_t>(tif, TIFFTAG_BITSPERSAMPLE);
|
| 43 |
+
const auto sample_format = GetOrDefault<uint16_t>(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
|
| 44 |
+
const auto planar = GetOrThrow<uint16_t>(tif, TIFFTAG_PLANARCONFIG);
|
| 45 |
+
// const auto photom = GetOrThrow<uint16_t>(tif, TIFFTAG_PHOTOMETRIC);
|
| 46 |
+
|
| 47 |
+
// comparison of unsigned with >= 0 is always true!
|
| 48 |
+
//assert(width >= 0 && height >= 0 && channels >= 0 && bits_per_channel > 0);
|
| 49 |
+
|
| 50 |
+
if(planar != PLANARCONFIG_CONTIG /*|| photom != PHOTOMETRIC_RGB*/ || bits_per_channel % 8 != 0 || !(channels == 1 || channels == 3))
|
| 51 |
+
throw std::runtime_error("TIFF support is currently limited. Consider contributing to image_io_tiff.cpp.");
|
| 52 |
+
|
| 53 |
+
std::string sfmt;
|
| 54 |
+
switch(sample_format) {
|
| 55 |
+
case SAMPLEFORMAT_UINT: sfmt = (channels == 3) ? "RGB24" : "GRAY8"; break;
|
| 56 |
+
case SAMPLEFORMAT_IEEEFP: sfmt = (channels == 3) ? "RGB96F" : "GRAY32F"; break;
|
| 57 |
+
default: throw std::runtime_error("TIFF support is currently limited. Consider contributing to image_io_tiff.cpp.");
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
TypedImage image(width, height, PixelFormatFromString(sfmt));
|
| 61 |
+
const tsize_t scanlength_bytes = TIFFScanlineSize(tif);
|
| 62 |
+
if(scanlength_bytes != tsize_t(image.pitch))
|
| 63 |
+
throw std::runtime_error("TIFF: unexpected scanline length");
|
| 64 |
+
|
| 65 |
+
for (size_t row = 0; row < height; ++row) {
|
| 66 |
+
TIFFReadScanline(tif, image.RowPtr(row), row);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
TIFFClose(tif);
|
| 70 |
+
|
| 71 |
+
return image;
|
| 72 |
+
#else
|
| 73 |
+
PANGOLIN_UNUSED(filename);
|
| 74 |
+
throw std::runtime_error("Rebuild Pangolin for libtiff support.");
|
| 75 |
+
#endif
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
}
|
| 79 |
+
|
third-party/DPVO/Pangolin/components/pango_image/src/image_io_zstd.cpp
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
#include <fstream>
|
| 3 |
+
#include <memory>
|
| 4 |
+
|
| 5 |
+
#include <pangolin/image/typed_image.h>
|
| 6 |
+
|
| 7 |
+
#ifdef HAVE_ZSTD
|
| 8 |
+
# include <zstd.h>
|
| 9 |
+
#endif
|
| 10 |
+
|
| 11 |
+
namespace pangolin {
|
| 12 |
+
|
| 13 |
+
#pragma pack(push, 1)
|
| 14 |
+
struct zstd_image_header
|
| 15 |
+
{
|
| 16 |
+
char magic[4];
|
| 17 |
+
char fmt[16];
|
| 18 |
+
size_t w, h;
|
| 19 |
+
};
|
| 20 |
+
#pragma pack(pop)
|
| 21 |
+
|
| 22 |
+
void SaveZstd(const Image<unsigned char>& image, const pangolin::PixelFormat& fmt, std::ostream& out, int compression_level)
|
| 23 |
+
{
|
| 24 |
+
#ifdef HAVE_ZSTD
|
| 25 |
+
// Write out header, uncompressed
|
| 26 |
+
zstd_image_header header;
|
| 27 |
+
memcpy(header.magic,"ZSTD",4);
|
| 28 |
+
#pragma GCC diagnostic push
|
| 29 |
+
#pragma GCC diagnostic ignored "-Wstringop-truncation"
|
| 30 |
+
strncpy(header.fmt, fmt.format.c_str(), sizeof(header.fmt));
|
| 31 |
+
#pragma GCC diagnostic pop
|
| 32 |
+
header.w = image.w;
|
| 33 |
+
header.h = image.h;
|
| 34 |
+
out.write((char*)&header, sizeof(header));
|
| 35 |
+
|
| 36 |
+
// Write out image data
|
| 37 |
+
const size_t output_buffer_size = ZSTD_CStreamOutSize();
|
| 38 |
+
std::unique_ptr<char[]> output_buffer(new char[output_buffer_size]);
|
| 39 |
+
|
| 40 |
+
ZSTD_CStream* const cstream = ZSTD_createCStream();
|
| 41 |
+
if (cstream==nullptr) {
|
| 42 |
+
throw std::runtime_error("ZSTD_createCStream() error");
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
size_t const initResult = ZSTD_initCStream(cstream, compression_level);
|
| 46 |
+
if (ZSTD_isError(initResult)) {
|
| 47 |
+
throw std::runtime_error(FormatString("ZSTD_initCStream() error : %", ZSTD_getErrorName(initResult)));
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
const size_t row_size_bytes = (fmt.bpp * image.w)/8;
|
| 51 |
+
|
| 52 |
+
for(size_t y=0; y < image.h; ++y) {
|
| 53 |
+
ZSTD_inBuffer input = { image.RowPtr(y), row_size_bytes, 0 };
|
| 54 |
+
|
| 55 |
+
while (input.pos < input.size) {
|
| 56 |
+
ZSTD_outBuffer output = { output_buffer.get(), output_buffer_size, 0 };
|
| 57 |
+
size_t left_to_read = ZSTD_compressStream(cstream, &output , &input);
|
| 58 |
+
if (ZSTD_isError(left_to_read)) {
|
| 59 |
+
throw std::runtime_error(FormatString("ZSTD_compressStream() error : %", ZSTD_getErrorName(left_to_read)));
|
| 60 |
+
}
|
| 61 |
+
out.write(output_buffer.get(), output.pos);
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
ZSTD_outBuffer output = { output_buffer.get(), output_buffer_size, 0 };
|
| 66 |
+
size_t const remainingToFlush = ZSTD_endStream(cstream, &output); /* close frame */
|
| 67 |
+
if (remainingToFlush) {
|
| 68 |
+
throw std::runtime_error("not fully flushed");
|
| 69 |
+
}
|
| 70 |
+
out.write(output_buffer.get(), output.pos);
|
| 71 |
+
|
| 72 |
+
ZSTD_freeCStream(cstream);
|
| 73 |
+
#else
|
| 74 |
+
PANGOLIN_UNUSED(image);
|
| 75 |
+
PANGOLIN_UNUSED(fmt);
|
| 76 |
+
PANGOLIN_UNUSED(out);
|
| 77 |
+
PANGOLIN_UNUSED(compression_level);
|
| 78 |
+
throw std::runtime_error("Rebuild Pangolin for ZSTD support.");
|
| 79 |
+
#endif // HAVE_ZSTD
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
TypedImage LoadZstd(std::istream& in)
|
| 83 |
+
{
|
| 84 |
+
#ifdef HAVE_ZSTD
|
| 85 |
+
// Read in header, uncompressed
|
| 86 |
+
zstd_image_header header;
|
| 87 |
+
in.read( (char*)&header, sizeof(header));
|
| 88 |
+
|
| 89 |
+
TypedImage img(header.w, header.h, PixelFormatFromString(header.fmt));
|
| 90 |
+
|
| 91 |
+
const size_t input_buffer_size = ZSTD_DStreamInSize();
|
| 92 |
+
std::unique_ptr<char[]> input_buffer(new char[input_buffer_size]);
|
| 93 |
+
|
| 94 |
+
ZSTD_DStream* dstream = ZSTD_createDStream();
|
| 95 |
+
if(!dstream) {
|
| 96 |
+
throw std::runtime_error("ZSTD_createDStream() error");
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
size_t read_size_hint = ZSTD_initDStream(dstream);
|
| 100 |
+
if (ZSTD_isError(read_size_hint)) {
|
| 101 |
+
throw std::runtime_error(FormatString("ZSTD_initDStream() error : % \n", ZSTD_getErrorName(read_size_hint)));
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
// Image represents our fixed buffer.
|
| 105 |
+
ZSTD_outBuffer output = { img.ptr, img.SizeBytes(), 0 };
|
| 106 |
+
|
| 107 |
+
while(read_size_hint)
|
| 108 |
+
{
|
| 109 |
+
in.read(input_buffer.get(), read_size_hint);
|
| 110 |
+
ZSTD_inBuffer input = { input_buffer.get(), read_size_hint, 0 };
|
| 111 |
+
while (input.pos < input.size) {
|
| 112 |
+
read_size_hint = ZSTD_decompressStream(dstream, &output , &input);
|
| 113 |
+
if (ZSTD_isError(read_size_hint)) {
|
| 114 |
+
throw std::runtime_error(FormatString("ZSTD_decompressStream() error : %", ZSTD_getErrorName(read_size_hint)));
|
| 115 |
+
}
|
| 116 |
+
}
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
ZSTD_freeDStream(dstream);
|
| 120 |
+
|
| 121 |
+
return img;
|
| 122 |
+
#else
|
| 123 |
+
PANGOLIN_UNUSED(in);
|
| 124 |
+
throw std::runtime_error("Rebuild Pangolin for ZSTD support.");
|
| 125 |
+
#endif // HAVE_ZSTD
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
}
|
third-party/DPVO/Pangolin/components/pango_image/src/pixel_format.cpp
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#include <pangolin/image/pixel_format.h>
|
| 29 |
+
|
| 30 |
+
#include <vector>
|
| 31 |
+
#include <stdexcept>
|
| 32 |
+
|
| 33 |
+
namespace pangolin
|
| 34 |
+
{
|
| 35 |
+
|
| 36 |
+
// Not to exceed 8 byte Format code.
|
| 37 |
+
const PixelFormat SupportedPixelFormats[] =
|
| 38 |
+
{
|
| 39 |
+
{"GRAY8", 1, {8}, 8, 8, false},
|
| 40 |
+
{"GRAY10", 1, {10}, 10, 10, false},
|
| 41 |
+
{"GRAY12", 1, {12}, 12, 12, false},
|
| 42 |
+
{"GRAY16LE", 1, {16}, 16, 16, false},
|
| 43 |
+
{"GRAY32", 1, {32}, 32, 32, false},
|
| 44 |
+
{"Y400A", 2, {8,8}, 16, 8, false},
|
| 45 |
+
{"RGB24", 3, {8,8,8}, 24, 8, false},
|
| 46 |
+
{"BGR24", 3, {8,8,8}, 24, 8, false},
|
| 47 |
+
{"RGB48", 3, {16,16,16}, 48, 16, false},
|
| 48 |
+
{"BGR48", 3, {16,16,16}, 48, 16, false},
|
| 49 |
+
{"YUYV422", 3, {4,2,2}, 16, 8, false},
|
| 50 |
+
{"UYVY422", 3, {4,2,2}, 16, 8, false},
|
| 51 |
+
{"RGBA32", 4, {8,8,8,8}, 32, 8, false},
|
| 52 |
+
{"BGRA32", 4, {8,8,8,8}, 32, 8, false},
|
| 53 |
+
{"RGBA64", 4, {16,16,16,16}, 64, 16, false},
|
| 54 |
+
{"BGRA64", 4, {16,16,16,16}, 64, 16, false},
|
| 55 |
+
{"GRAY32F", 1, {32}, 32, 32, false},
|
| 56 |
+
{"GRAY64F", 1, {64}, 64, 64, false},
|
| 57 |
+
{"RGB48F", 3, {16,16,16}, 48, 16, false},
|
| 58 |
+
{"BGR48F", 3, {16,16,16}, 48, 16, false},
|
| 59 |
+
{"RGBA64F", 4, {16,16,16,16}, 64, 16, false},
|
| 60 |
+
{"BGRA64F", 4, {16,16,16,16}, 64, 16, false},
|
| 61 |
+
{"RGB96F", 3, {32,32,32}, 96, 32, false},
|
| 62 |
+
{"BGR96F", 3, {32,32,32}, 96, 32, false},
|
| 63 |
+
{"RGBA128F", 4, {32,32,32,32}, 128, 32, false},
|
| 64 |
+
{"ABGR128F", 4, {32,32,32,32}, 128, 32, false},
|
| 65 |
+
{"",0,{0,0,0,0},0,0,0}
|
| 66 |
+
};
|
| 67 |
+
|
| 68 |
+
PixelFormat PixelFormatFromString(const std::string& format)
|
| 69 |
+
{
|
| 70 |
+
for(int i=0; !SupportedPixelFormats[i].format.empty(); ++i)
|
| 71 |
+
if(!format.compare(SupportedPixelFormats[i].format))
|
| 72 |
+
return SupportedPixelFormats[i];
|
| 73 |
+
throw std::runtime_error( std::string("Unknown Format: ") + format);
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
std::vector<PixelFormat> GetSupportedPixelFormats()
|
| 77 |
+
{
|
| 78 |
+
std::vector<PixelFormat> result;
|
| 79 |
+
const PixelFormat* pixelFormat = SupportedPixelFormats;
|
| 80 |
+
while( pixelFormat->format.length() > 0 ){
|
| 81 |
+
result.push_back( *pixelFormat );
|
| 82 |
+
pixelFormat++;
|
| 83 |
+
}
|
| 84 |
+
return result;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/CMakeLists.txt
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
get_filename_component(COMPONENT ${CMAKE_CURRENT_LIST_DIR} NAME)
|
| 2 |
+
|
| 3 |
+
file(GLOB BINARY_FILES_TO_EMBED "${CMAKE_CURRENT_LIST_DIR}/src/fonts/*.ttf")
|
| 4 |
+
include(EmbedBinaryFiles)
|
| 5 |
+
embed_binary_files_rule(fonts.cpp ${BINARY_FILES_TO_EMBED})
|
| 6 |
+
|
| 7 |
+
target_sources( ${COMPONENT}
|
| 8 |
+
PRIVATE
|
| 9 |
+
${CMAKE_CURRENT_LIST_DIR}/src/glchar.cpp
|
| 10 |
+
${CMAKE_CURRENT_LIST_DIR}/src/gldraw.cpp
|
| 11 |
+
${CMAKE_CURRENT_LIST_DIR}/src/glfont.cpp
|
| 12 |
+
${CMAKE_CURRENT_LIST_DIR}/src/gltext.cpp
|
| 13 |
+
${CMAKE_CURRENT_LIST_DIR}/src/glpangoglu.cpp
|
| 14 |
+
${CMAKE_CURRENT_LIST_DIR}/src/gltexturecache.cpp
|
| 15 |
+
${CMAKE_CURRENT_LIST_DIR}/src/viewport.cpp
|
| 16 |
+
${CMAKE_CURRENT_LIST_DIR}/src/opengl_render_state.cpp
|
| 17 |
+
${CMAKE_CURRENT_LIST_DIR}/src/stb_truetype.h
|
| 18 |
+
${CMAKE_CURRENT_BINARY_DIR}/fonts.cpp
|
| 19 |
+
)
|
| 20 |
+
|
| 21 |
+
find_package (Eigen3 REQUIRED QUIET)
|
| 22 |
+
message(STATUS "Found Eigen: '${EIGEN3_INCLUDE_DIRS}'")
|
| 23 |
+
target_compile_definitions(${COMPONENT} PUBLIC HAVE_EIGEN HAVE_GLEW)
|
| 24 |
+
|
| 25 |
+
target_link_libraries(${COMPONENT} PUBLIC pango_core pango_image Eigen3::Eigen)
|
| 26 |
+
target_include_directories(${COMPONENT} PUBLIC
|
| 27 |
+
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
|
| 28 |
+
$<INSTALL_INTERFACE:include>
|
| 29 |
+
)
|
| 30 |
+
install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/include"
|
| 31 |
+
DESTINATION ${CMAKE_INSTALL_PREFIX}
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
+
if(EMSCRIPTEN)
|
| 35 |
+
target_compile_definitions(${COMPONENT} PUBLIC HAVE_GLES HAVE_GLES_2)
|
| 36 |
+
target_sources( ${COMPONENT} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/compat/gl2engine.cpp)
|
| 37 |
+
else()
|
| 38 |
+
if(_LINUX_)
|
| 39 |
+
set(OpenGL_GL_PREFERENCE "GLVND")
|
| 40 |
+
endif()
|
| 41 |
+
find_package(OpenGL REQUIRED QUIET)
|
| 42 |
+
find_package(GLEW REQUIRED QUIET)
|
| 43 |
+
target_include_directories( ${COMPONENT} PUBLIC
|
| 44 |
+
$<BUILD_INTERFACE:${OPENGL_INCLUDE_DIR}>
|
| 45 |
+
$<BUILD_INTERFACE:${GLEW_INCLUDE_DIR}>
|
| 46 |
+
)
|
| 47 |
+
target_link_libraries( ${COMPONENT} PUBLIC
|
| 48 |
+
${GLEW_LIBRARY} ${OPENGL_LIBRARIES}
|
| 49 |
+
)
|
| 50 |
+
endif()
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/cg.h
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <sstream>
|
| 31 |
+
#include <algorithm>
|
| 32 |
+
|
| 33 |
+
// Cg includes
|
| 34 |
+
#include <Cg/cg.h>
|
| 35 |
+
#include <Cg/cgGL.h>
|
| 36 |
+
|
| 37 |
+
#include "gl.h"
|
| 38 |
+
|
| 39 |
+
#ifdef HAVE_TOON
|
| 40 |
+
#include <TooN/TooN.h>
|
| 41 |
+
#endif // HAVE_TOON
|
| 42 |
+
|
| 43 |
+
namespace pangolin
|
| 44 |
+
{
|
| 45 |
+
|
| 46 |
+
////////////////////////////////////////////////
|
| 47 |
+
// Interface
|
| 48 |
+
////////////////////////////////////////////////
|
| 49 |
+
|
| 50 |
+
/// Lightweight object wrapper for NVidia Cg Shader program objects.
|
| 51 |
+
class CgProgram
|
| 52 |
+
{
|
| 53 |
+
friend class CgLoader;
|
| 54 |
+
public:
|
| 55 |
+
void SetUniform(const std::string& name, GlTexture& tex);
|
| 56 |
+
void SetUniform(const std::string& name, float f);
|
| 57 |
+
void SetUniform(const std::string& name, float v0, float v1);
|
| 58 |
+
void SetUniform(const std::string& name, float v0, float v1, float v2, float v3);
|
| 59 |
+
|
| 60 |
+
#ifdef HAVE_TOON
|
| 61 |
+
void SetUniform(const std::string& name, const TooN::Vector<2>& v );
|
| 62 |
+
void SetUniform(const std::string& name, const TooN::Vector<3>& v );
|
| 63 |
+
|
| 64 |
+
template <int R, int C>
|
| 65 |
+
void SetUniform(const std::string& name, const TooN::Matrix<R,C>& M );
|
| 66 |
+
#endif
|
| 67 |
+
|
| 68 |
+
void UpdateParams();
|
| 69 |
+
|
| 70 |
+
protected:
|
| 71 |
+
CGprogram mProg;
|
| 72 |
+
CGcontext mContext;
|
| 73 |
+
CGprofile mProfile;
|
| 74 |
+
};
|
| 75 |
+
|
| 76 |
+
class CgLoader
|
| 77 |
+
{
|
| 78 |
+
public:
|
| 79 |
+
CgLoader();
|
| 80 |
+
~CgLoader();
|
| 81 |
+
|
| 82 |
+
// Call AFTER glewInit (or similar)
|
| 83 |
+
void Initialise();
|
| 84 |
+
|
| 85 |
+
CgProgram LoadProgramFromFile(const std::string& file, const std::string& function, bool isVertexShader );
|
| 86 |
+
|
| 87 |
+
void EnableProgram(CgProgram program);
|
| 88 |
+
void DisablePrograms();
|
| 89 |
+
|
| 90 |
+
void RenderDummyQuad();
|
| 91 |
+
void RenderDummyQuadWithTexCoords(int w, int h);
|
| 92 |
+
|
| 93 |
+
protected:
|
| 94 |
+
CGcontext mContext;
|
| 95 |
+
CGprofile mFragmentProfile;
|
| 96 |
+
CGprofile mVertexProfile;
|
| 97 |
+
};
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
////////////////////////////////////////////////
|
| 103 |
+
// Implementation
|
| 104 |
+
////////////////////////////////////////////////
|
| 105 |
+
|
| 106 |
+
inline bool cgOkay()
|
| 107 |
+
{
|
| 108 |
+
CGerror error;
|
| 109 |
+
const char *string = cgGetLastErrorString(&error);
|
| 110 |
+
|
| 111 |
+
if (error != CG_NO_ERROR) {
|
| 112 |
+
std::cout << "CG Error: " << string << std::endl;
|
| 113 |
+
// assert(0);
|
| 114 |
+
return false;
|
| 115 |
+
}
|
| 116 |
+
return true;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
inline CgLoader::CgLoader()
|
| 120 |
+
:mContext(0)
|
| 121 |
+
{
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
inline CgLoader::~CgLoader()
|
| 125 |
+
{
|
| 126 |
+
if(mContext)
|
| 127 |
+
{
|
| 128 |
+
// Destroying context destroys all programs associated with it
|
| 129 |
+
cgDestroyContext(mContext);
|
| 130 |
+
}
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
inline void CgLoader::Initialise()
|
| 135 |
+
{
|
| 136 |
+
mContext = cgCreateContext();
|
| 137 |
+
cgSetParameterSettingMode(mContext, CG_DEFERRED_PARAMETER_SETTING);
|
| 138 |
+
cgOkay();
|
| 139 |
+
|
| 140 |
+
mFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
|
| 141 |
+
cgGLSetOptimalOptions(mFragmentProfile);
|
| 142 |
+
cgOkay();
|
| 143 |
+
|
| 144 |
+
mVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
|
| 145 |
+
cgGLSetOptimalOptions(mVertexProfile);
|
| 146 |
+
cgOkay();
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
inline CgProgram CgLoader::LoadProgramFromFile(const std::string& file, const std::string& function, bool isVertexShader )
|
| 150 |
+
{
|
| 151 |
+
if( !mContext ) {
|
| 152 |
+
Initialise();
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
CgProgram prog;
|
| 156 |
+
|
| 157 |
+
prog.mContext = mContext;
|
| 158 |
+
prog.mProfile = isVertexShader ? mVertexProfile : mFragmentProfile;
|
| 159 |
+
prog.mProg = cgCreateProgramFromFile( prog.mContext, CG_SOURCE, file.c_str(), prog.mProfile, function.c_str(), NULL);
|
| 160 |
+
|
| 161 |
+
if( !cgOkay() )
|
| 162 |
+
{
|
| 163 |
+
std::cout << cgGetLastListing(mContext) << std::endl;
|
| 164 |
+
assert(0);
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
cgGLLoadProgram(prog.mProg);
|
| 168 |
+
if( !cgOkay() )
|
| 169 |
+
{
|
| 170 |
+
const char* err = cgGetProgramString( prog.mProg, CG_COMPILED_PROGRAM );
|
| 171 |
+
int pos;
|
| 172 |
+
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
|
| 173 |
+
std::cout << err << std::endl;
|
| 174 |
+
std::cout << "@ " << pos << std::endl;
|
| 175 |
+
assert(0);
|
| 176 |
+
}
|
| 177 |
+
return prog;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
inline void CgLoader::EnableProgram(CgProgram program)
|
| 181 |
+
{
|
| 182 |
+
cgGLBindProgram(program.mProg);
|
| 183 |
+
cgGLEnableProfile(program.mProfile);
|
| 184 |
+
cgOkay();
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
inline void CgLoader::DisablePrograms()
|
| 188 |
+
{
|
| 189 |
+
cgGLDisableProfile(mFragmentProfile);
|
| 190 |
+
cgGLDisableProfile(mVertexProfile);
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
inline void CgLoader::RenderDummyQuad()
|
| 194 |
+
{
|
| 195 |
+
glBegin(GL_QUADS);
|
| 196 |
+
glVertex2d(-1,1);
|
| 197 |
+
glVertex2d(1,1);
|
| 198 |
+
glVertex2d(1,-1);
|
| 199 |
+
glVertex2d(-1,-1);
|
| 200 |
+
glEnd();
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
inline void CgLoader::RenderDummyQuadWithTexCoords(int w, int h)
|
| 204 |
+
{
|
| 205 |
+
glBegin(GL_QUADS);
|
| 206 |
+
glTexCoord2f(0, 0);
|
| 207 |
+
glVertex2d(-1,-1);
|
| 208 |
+
glTexCoord2f(w, 0);
|
| 209 |
+
glVertex2d(1,-1);
|
| 210 |
+
glTexCoord2f(w, h);
|
| 211 |
+
glVertex2d(1,1);
|
| 212 |
+
glTexCoord2f(0, h);
|
| 213 |
+
glVertex2d(-1,1);
|
| 214 |
+
glEnd();
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
void CgProgram::SetUniform(const std::string& name, float f)
|
| 218 |
+
{
|
| 219 |
+
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
| 220 |
+
cgSetParameter1f( p, f );
|
| 221 |
+
cgUpdateProgramParameters(mProg);
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
+
void CgProgram::SetUniform(const std::string& name, GlTexture& tex)
|
| 225 |
+
{
|
| 226 |
+
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
| 227 |
+
cgGLSetTextureParameter(p, tex.tid );
|
| 228 |
+
cgGLEnableTextureParameter(p);
|
| 229 |
+
cgUpdateProgramParameters(mProg);
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
void CgProgram::SetUniform(const std::string& name, float v0, float v1, float v2, float v3)
|
| 233 |
+
{
|
| 234 |
+
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
| 235 |
+
cgGLSetParameter4f(p, v0,v1,v2,v3);
|
| 236 |
+
cgUpdateProgramParameters(mProg);
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
void CgProgram::SetUniform(const std::string& name, float v0, float v1)
|
| 240 |
+
{
|
| 241 |
+
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
| 242 |
+
cgGLSetParameter2f(p, v0,v1);
|
| 243 |
+
cgUpdateProgramParameters(mProg);
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
#ifdef HAVE_TOON
|
| 247 |
+
void CgProgram::SetUniform(const std::string& name, const TooN::Vector<2>& v )
|
| 248 |
+
{
|
| 249 |
+
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
| 250 |
+
cgGLSetParameter2f(p, v[0],v[1] );
|
| 251 |
+
cgUpdateProgramParameters(mProg);
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
void CgProgram::SetUniform(const std::string& name, const TooN::Vector<3>& v )
|
| 255 |
+
{
|
| 256 |
+
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
| 257 |
+
cgGLSetParameter3f(p, v[0],v[1],v[2] );
|
| 258 |
+
cgUpdateProgramParameters(mProg);
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
template <int R, int C>
|
| 262 |
+
void CgProgram::SetUniform(const std::string& name, const TooN::Matrix<R,C>& M )
|
| 263 |
+
{
|
| 264 |
+
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
| 265 |
+
float Mdata[R*C];
|
| 266 |
+
|
| 267 |
+
int i=0;
|
| 268 |
+
for( int r=0; r<R; ++r )
|
| 269 |
+
for( int c=0; c<C; ++c )
|
| 270 |
+
Mdata[i++] = (float)(M[r][c]);
|
| 271 |
+
|
| 272 |
+
cgGLSetMatrixParameterfr(p, Mdata );
|
| 273 |
+
cgUpdateProgramParameters(mProg);
|
| 274 |
+
}
|
| 275 |
+
#endif
|
| 276 |
+
|
| 277 |
+
void CgProgram::UpdateParams()
|
| 278 |
+
{
|
| 279 |
+
cgUpdateProgramParameters(mProg);
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
|
| 283 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/colour.h
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <cmath>
|
| 31 |
+
#include <limits>
|
| 32 |
+
#include <stdexcept>
|
| 33 |
+
|
| 34 |
+
namespace pangolin
|
| 35 |
+
{
|
| 36 |
+
|
| 37 |
+
/// Represent OpenGL floating point colour: Red, Green and Blue with alpha.
|
| 38 |
+
struct Colour
|
| 39 |
+
{
|
| 40 |
+
inline static Colour White() {
|
| 41 |
+
return Colour(1.0f,1.0f,1.0f,1.0f);
|
| 42 |
+
}
|
| 43 |
+
inline static Colour Black() {
|
| 44 |
+
return Colour(0.0f,0.0f,0.0f,1.0f);
|
| 45 |
+
}
|
| 46 |
+
inline static Colour Red() {
|
| 47 |
+
return Colour(1.0f,0.0f,0.0f,1.0f);
|
| 48 |
+
}
|
| 49 |
+
inline static Colour Green() {
|
| 50 |
+
return Colour(0.0f,1.0f,0.0f,1.0f);
|
| 51 |
+
}
|
| 52 |
+
inline static Colour Blue() {
|
| 53 |
+
return Colour(0.0f,0.0f,1.0f,1.0f);
|
| 54 |
+
}
|
| 55 |
+
inline static Colour Unspecified() {
|
| 56 |
+
return Colour(
|
| 57 |
+
std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::quiet_NaN(),
|
| 58 |
+
std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::quiet_NaN()
|
| 59 |
+
);
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
/// Default constructs white.
|
| 63 |
+
inline Colour()
|
| 64 |
+
: red(1.0f), green(1.0f), blue(1.0f), alpha(1.0f)
|
| 65 |
+
{
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
/// Construct from component values
|
| 69 |
+
inline Colour(const float red, const float green, const float blue, const float alpha = 1.0f)
|
| 70 |
+
: red(red), green(green), blue(blue), alpha(alpha)
|
| 71 |
+
{
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
/// Construct from rgba array.
|
| 75 |
+
inline Colour(const float rgba[4])
|
| 76 |
+
{
|
| 77 |
+
r = rgba[0];
|
| 78 |
+
g = rgba[1];
|
| 79 |
+
b = rgba[2];
|
| 80 |
+
a = rgba[3];
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
/// Return pointer to OpenGL compatible RGBA array.
|
| 84 |
+
inline float* Get()
|
| 85 |
+
{
|
| 86 |
+
return c;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
/// Return this colour with alpha adjusted.
|
| 90 |
+
inline Colour WithAlpha(const float alpha)
|
| 91 |
+
{
|
| 92 |
+
return Colour(r,g,b,alpha);
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
/// Construct from HSV Colour
|
| 96 |
+
/// @param hue Colour hue in range [0,1]
|
| 97 |
+
/// @param sat Saturation in range [0,1]
|
| 98 |
+
/// @param val Value / Brightness in range [0,1].
|
| 99 |
+
static inline Colour Hsv(const float hue, const float sat = 1.0f, const float val = 1.0f, const float alpha = 1.0f)
|
| 100 |
+
{
|
| 101 |
+
const float h = 6.0f * hue;
|
| 102 |
+
const int i = (int)floor(h);
|
| 103 |
+
const float f = (i%2 == 0) ? 1-(h-i) : h-i;
|
| 104 |
+
const float m = val * (1-sat);
|
| 105 |
+
const float n = val * (1-sat*f);
|
| 106 |
+
|
| 107 |
+
switch(i)
|
| 108 |
+
{
|
| 109 |
+
case 0: return Colour(val,n,m,alpha);
|
| 110 |
+
case 1: return Colour(n,val,m,alpha);
|
| 111 |
+
case 2: return Colour(m,val,n,alpha);
|
| 112 |
+
case 3: return Colour(m,n,val,alpha);
|
| 113 |
+
case 4: return Colour(n,m,val,alpha);
|
| 114 |
+
case 5: return Colour(val,m,n,alpha);
|
| 115 |
+
default:
|
| 116 |
+
throw std::runtime_error("Found extra colour in rainbow.");
|
| 117 |
+
}
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
union {
|
| 121 |
+
struct {
|
| 122 |
+
float red;
|
| 123 |
+
float green;
|
| 124 |
+
float blue;
|
| 125 |
+
float alpha;
|
| 126 |
+
};
|
| 127 |
+
struct {
|
| 128 |
+
float r;
|
| 129 |
+
float g;
|
| 130 |
+
float b;
|
| 131 |
+
float a;
|
| 132 |
+
};
|
| 133 |
+
float c[4];
|
| 134 |
+
};
|
| 135 |
+
|
| 136 |
+
};
|
| 137 |
+
|
| 138 |
+
/// A ColourWheel is like a continuous colour palate that can be sampled.
|
| 139 |
+
/// In the future, different ColourWheels will be supported, but this one
|
| 140 |
+
/// is based on sampling hues in HSV colourspace. An indefinite number of
|
| 141 |
+
/// unique colours are sampled using the golden angle.
|
| 142 |
+
class ColourWheel
|
| 143 |
+
{
|
| 144 |
+
public:
|
| 145 |
+
/// Construct ColourWheel with Saturation, Value and Alpha constant.
|
| 146 |
+
inline ColourWheel(float saturation = 0.5f, float value = 1.0f, float alpha = 1.0f)
|
| 147 |
+
: unique_colours(0), sat(saturation), val(value), alpha(alpha)
|
| 148 |
+
{
|
| 149 |
+
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
/// Use Golden ratio (/angle) to pick well spaced colours.
|
| 153 |
+
inline Colour GetColourBin(int i) const
|
| 154 |
+
{
|
| 155 |
+
float hue = i * 0.5f * (3.0f - sqrt(5.0f));
|
| 156 |
+
hue -= (int)hue;
|
| 157 |
+
return Colour::Hsv(hue,sat,val,alpha);
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
/// Return next unique colour from ColourWheel.
|
| 161 |
+
inline Colour GetUniqueColour()
|
| 162 |
+
{
|
| 163 |
+
return GetColourBin(unique_colours++);
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
/// Reset colour wheel counter to initial state
|
| 167 |
+
inline void Reset() {
|
| 168 |
+
unique_colours = 0;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
protected:
|
| 172 |
+
int unique_colours;
|
| 173 |
+
float sat;
|
| 174 |
+
float val;
|
| 175 |
+
float alpha;
|
| 176 |
+
};
|
| 177 |
+
|
| 178 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/compat/gl2engine.h
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <stack>
|
| 31 |
+
|
| 32 |
+
#include <pangolin/gl/opengl_render_state.h>
|
| 33 |
+
#include <pangolin/gl/glsl.h>
|
| 34 |
+
|
| 35 |
+
namespace pangolin {
|
| 36 |
+
|
| 37 |
+
class GlEngine
|
| 38 |
+
{
|
| 39 |
+
public:
|
| 40 |
+
const char* vert =
|
| 41 |
+
"attribute vec4 a_position;\n"
|
| 42 |
+
"attribute vec4 a_color;\n"
|
| 43 |
+
"attribute vec3 a_normal;\n"
|
| 44 |
+
"attribute vec2 a_texcoord;\n"
|
| 45 |
+
"uniform vec4 u_color;\n"
|
| 46 |
+
"uniform mat4 u_modelViewProjectionMatrix;\n"
|
| 47 |
+
"varying vec4 v_frontColor;\n"
|
| 48 |
+
"varying vec2 v_texcoord;\n"
|
| 49 |
+
"void main() {\n"
|
| 50 |
+
" gl_Position = u_modelViewProjectionMatrix * a_position;\n"
|
| 51 |
+
" v_frontColor = u_color;\n"
|
| 52 |
+
" v_texcoord = a_texcoord;\n"
|
| 53 |
+
"}\n";
|
| 54 |
+
|
| 55 |
+
const char* frag =
|
| 56 |
+
#ifdef HAVE_GLES_2
|
| 57 |
+
"precision mediump float;\n"
|
| 58 |
+
#endif // HAVE_GLES_2
|
| 59 |
+
"varying vec4 v_frontColor;\n"
|
| 60 |
+
"varying vec2 v_texcoord;\n"
|
| 61 |
+
"uniform sampler2D u_texture;\n"
|
| 62 |
+
"uniform bool u_textureEnable;\n"
|
| 63 |
+
"void main() {\n"
|
| 64 |
+
" gl_FragColor = v_frontColor;\n"
|
| 65 |
+
" if(u_textureEnable) {\n"
|
| 66 |
+
" gl_FragColor *= texture2D(u_texture, v_texcoord);\n"
|
| 67 |
+
" }\n"
|
| 68 |
+
"}\n";
|
| 69 |
+
|
| 70 |
+
GlEngine()
|
| 71 |
+
{
|
| 72 |
+
// Initialise default state
|
| 73 |
+
projection.push(IdentityMatrix());
|
| 74 |
+
modelview.push(IdentityMatrix());
|
| 75 |
+
currentmatrix = &modelview;
|
| 76 |
+
|
| 77 |
+
// Set GL_TEXTURE0 as default active texture
|
| 78 |
+
glActiveTexture(GL_TEXTURE0);
|
| 79 |
+
|
| 80 |
+
// Compile and link shaders
|
| 81 |
+
prog_fixed.AddShader(GlSlVertexShader, vert);
|
| 82 |
+
prog_fixed.AddShader(GlSlFragmentShader, frag);
|
| 83 |
+
prog_fixed.BindPangolinDefaultAttribLocationsAndLink();
|
| 84 |
+
|
| 85 |
+
// Save locations of uniforms
|
| 86 |
+
u_color = prog_fixed.GetUniformHandle("u_color");
|
| 87 |
+
u_modelViewProjectionMatrix = prog_fixed.GetUniformHandle("u_modelViewProjectionMatrix");
|
| 88 |
+
u_texture = prog_fixed.GetUniformHandle("u_texture");
|
| 89 |
+
u_textureEnable = prog_fixed.GetUniformHandle("u_textureEnable");
|
| 90 |
+
|
| 91 |
+
// Initialise default uniform values
|
| 92 |
+
UpdateMatrices();
|
| 93 |
+
SetColor(1.0,1.0,1.0,1.0);
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
void UpdateMatrices()
|
| 97 |
+
{
|
| 98 |
+
OpenGlMatrix pmv = projection.top() * modelview.top();
|
| 99 |
+
prog_fixed.SaveBind();
|
| 100 |
+
glUniformMatrix4fv( u_modelViewProjectionMatrix, 1, false, pmv.m );
|
| 101 |
+
prog_fixed.Unbind();
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
void SetColor(float r, float g, float b, float a)
|
| 105 |
+
{
|
| 106 |
+
prog_fixed.SaveBind();
|
| 107 |
+
glUniform4f( u_color, r, g, b, a);
|
| 108 |
+
prog_fixed.Unbind();
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
void EnableTexturing(GLboolean v)
|
| 112 |
+
{
|
| 113 |
+
prog_fixed.SaveBind();
|
| 114 |
+
glUniform1i( u_textureEnable, v);
|
| 115 |
+
prog_fixed.Unbind();
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
//protected:
|
| 119 |
+
std::stack<OpenGlMatrix> projection;
|
| 120 |
+
std::stack<OpenGlMatrix> modelview;
|
| 121 |
+
std::stack<OpenGlMatrix>* currentmatrix;
|
| 122 |
+
|
| 123 |
+
GLenum matrixmode;
|
| 124 |
+
|
| 125 |
+
float color[4];
|
| 126 |
+
|
| 127 |
+
GlSlProgram prog_fixed;
|
| 128 |
+
|
| 129 |
+
GLint u_color;
|
| 130 |
+
GLint u_modelViewProjectionMatrix;
|
| 131 |
+
GLint u_texture;
|
| 132 |
+
GLint u_textureEnable;
|
| 133 |
+
};
|
| 134 |
+
|
| 135 |
+
GlEngine& glEngine();
|
| 136 |
+
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
///////////////////////////////////////////////////////////////////////////////
|
| 140 |
+
// OpenGL 1.0 compatibility - Emulate fixed pipeline
|
| 141 |
+
///////////////////////////////////////////////////////////////////////////////
|
| 142 |
+
|
| 143 |
+
// Missing defines that we'll be using
|
| 144 |
+
#define GL_MODELVIEW 0x1700
|
| 145 |
+
#define GL_PROJECTION 0x1701
|
| 146 |
+
#define GL_SHADE_MODEL 0x0B54
|
| 147 |
+
#define GL_POINT_SIZE 0x0B11
|
| 148 |
+
|
| 149 |
+
#define GL_MULTISAMPLE 0x809D
|
| 150 |
+
|
| 151 |
+
#define GL_LIGHTING 0x0B50
|
| 152 |
+
#define GL_POINT_SMOOTH 0x0B10
|
| 153 |
+
#define GL_LINE_SMOOTH 0x0B20
|
| 154 |
+
#define GL_SCISSOR_TEST 0x0C11
|
| 155 |
+
#define GL_COLOR_MATERIAL 0x0B57
|
| 156 |
+
|
| 157 |
+
#define GL_FLAT 0x1D00
|
| 158 |
+
#define GL_SMOOTH 0x1D01
|
| 159 |
+
|
| 160 |
+
#define GL_MODULATE 0x2100
|
| 161 |
+
#define GL_DECAL 0x2101
|
| 162 |
+
#define GL_ADD 0x0104
|
| 163 |
+
#define GL_TEXTURE_ENV_MODE 0x2200
|
| 164 |
+
#define GL_TEXTURE_ENV_COLOR 0x2201
|
| 165 |
+
#define GL_TEXTURE_ENV 0x2300
|
| 166 |
+
|
| 167 |
+
#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50
|
| 168 |
+
#define GL_POINT_SMOOTH_HINT 0x0C51
|
| 169 |
+
#define GL_LINE_SMOOTH_HINT 0x0C52
|
| 170 |
+
|
| 171 |
+
#define GL_VERTEX_ARRAY 0x8074
|
| 172 |
+
#define GL_NORMAL_ARRAY 0x8075
|
| 173 |
+
#define GL_COLOR_ARRAY 0x8076
|
| 174 |
+
#define GL_TEXTURE_COORD_ARRAY 0x8078
|
| 175 |
+
|
| 176 |
+
inline void glEnableClientState(GLenum cap)
|
| 177 |
+
{
|
| 178 |
+
pangolin::GlEngine& gl = pangolin::glEngine();
|
| 179 |
+
if(cap == GL_VERTEX_ARRAY) {
|
| 180 |
+
glEnableVertexAttribArray(pangolin::DEFAULT_LOCATION_POSITION);
|
| 181 |
+
}else if(cap == GL_COLOR_ARRAY) {
|
| 182 |
+
glEnableVertexAttribArray(pangolin::DEFAULT_LOCATION_COLOUR);
|
| 183 |
+
}else if(cap == GL_NORMAL_ARRAY) {
|
| 184 |
+
glEnableVertexAttribArray(pangolin::DEFAULT_LOCATION_NORMAL);
|
| 185 |
+
}else if(cap == GL_TEXTURE_COORD_ARRAY) {
|
| 186 |
+
glEnableVertexAttribArray(pangolin::DEFAULT_LOCATION_TEXCOORD);
|
| 187 |
+
gl.EnableTexturing(true);
|
| 188 |
+
}else{
|
| 189 |
+
pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__);
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
inline void glDisableClientState(GLenum cap)
|
| 194 |
+
{
|
| 195 |
+
pangolin::GlEngine& gl = pangolin::glEngine();
|
| 196 |
+
if(cap == GL_VERTEX_ARRAY) {
|
| 197 |
+
glDisableVertexAttribArray(pangolin::DEFAULT_LOCATION_POSITION);
|
| 198 |
+
}else if(cap == GL_COLOR_ARRAY) {
|
| 199 |
+
glDisableVertexAttribArray(pangolin::DEFAULT_LOCATION_COLOUR);
|
| 200 |
+
}else if(cap == GL_NORMAL_ARRAY) {
|
| 201 |
+
glDisableVertexAttribArray(pangolin::DEFAULT_LOCATION_NORMAL);
|
| 202 |
+
}else if(cap == GL_TEXTURE_COORD_ARRAY) {
|
| 203 |
+
glDisableVertexAttribArray(pangolin::DEFAULT_LOCATION_TEXCOORD);
|
| 204 |
+
gl.EnableTexturing(false);
|
| 205 |
+
}else{
|
| 206 |
+
pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__);
|
| 207 |
+
}
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
inline void glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid * pointer)
|
| 211 |
+
{
|
| 212 |
+
glVertexAttribPointer(pangolin::DEFAULT_LOCATION_POSITION, size, type, GL_FALSE, stride, pointer);
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
inline void glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid * pointer)
|
| 216 |
+
{
|
| 217 |
+
glVertexAttribPointer(pangolin::DEFAULT_LOCATION_TEXCOORD, size, type, GL_FALSE, stride, pointer);
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
inline void glMatrixMode(GLenum mode)
|
| 221 |
+
{
|
| 222 |
+
pangolin::GlEngine& gl = pangolin::glEngine();
|
| 223 |
+
gl.currentmatrix = (mode == pangolin::GlProjectionStack) ? &gl.projection : &gl.modelview;
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
inline void glLoadIdentity()
|
| 227 |
+
{
|
| 228 |
+
pangolin::GlEngine& gl = pangolin::glEngine();
|
| 229 |
+
gl.currentmatrix->top() = pangolin::IdentityMatrix();
|
| 230 |
+
gl.UpdateMatrices();
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
inline void glLoadMatrixf(const GLfloat* m)
|
| 234 |
+
{
|
| 235 |
+
pangolin::GlEngine& gl = pangolin::glEngine();
|
| 236 |
+
pangolin::GLprecision* cm = gl.currentmatrix->top().m;
|
| 237 |
+
for(int i=0; i<16; ++i) cm[i] = (pangolin::GLprecision)m[i];
|
| 238 |
+
gl.UpdateMatrices();
|
| 239 |
+
}
|
| 240 |
+
|
| 241 |
+
inline void glLoadMatrixd(const GLdouble* m)
|
| 242 |
+
{
|
| 243 |
+
pangolin::GlEngine& gl = pangolin::glEngine();
|
| 244 |
+
pangolin::GLprecision* cm = gl.currentmatrix->top().m;
|
| 245 |
+
for(int i=0; i<16; ++i) cm[i] = (pangolin::GLprecision)m[i];
|
| 246 |
+
gl.UpdateMatrices();
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
inline void glMultMatrixf(const GLfloat* m)
|
| 250 |
+
{
|
| 251 |
+
// pangolin::GlEngine& gl = pangolin::glEngine();
|
| 252 |
+
// float res[16];
|
| 253 |
+
// pangolin::MatMul<4,4,4,float>(res, m, gl.currentmatrix->m );
|
| 254 |
+
// std::memcpy(gl.currentmatrix->m, res, sizeof(float) * 16 );
|
| 255 |
+
pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__);
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
inline void glMultMatrixd(const GLdouble* m)
|
| 259 |
+
{
|
| 260 |
+
pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__);
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
inline void glPushMatrix(void)
|
| 264 |
+
{
|
| 265 |
+
pangolin::GlEngine& gl = pangolin::glEngine();
|
| 266 |
+
gl.currentmatrix->push(gl.currentmatrix->top());
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
inline void glPopMatrix(void)
|
| 270 |
+
{
|
| 271 |
+
pangolin::GlEngine& gl = pangolin::glEngine();
|
| 272 |
+
gl.currentmatrix->pop();
|
| 273 |
+
gl.UpdateMatrices();
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
inline void glTranslatef(GLfloat x, GLfloat y, GLfloat z )
|
| 277 |
+
{
|
| 278 |
+
pangolin::GlEngine& gl = pangolin::glEngine();
|
| 279 |
+
pangolin::GLprecision* cm = gl.currentmatrix->top().m;
|
| 280 |
+
cm[12] += x;
|
| 281 |
+
cm[13] += y;
|
| 282 |
+
cm[14] += z;
|
| 283 |
+
gl.UpdateMatrices();
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
inline void glOrtho(
|
| 287 |
+
GLdouble l, GLdouble r,
|
| 288 |
+
GLdouble b, GLdouble t,
|
| 289 |
+
GLdouble n, GLdouble f)
|
| 290 |
+
{
|
| 291 |
+
pangolin::GlEngine& gl = pangolin::glEngine();
|
| 292 |
+
gl.currentmatrix->top() = pangolin::ProjectionMatrixOrthographic(l,r,b,t,n,f);
|
| 293 |
+
gl.UpdateMatrices();
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
inline void glColor4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
|
| 297 |
+
{
|
| 298 |
+
pangolin::glEngine().SetColor(red,green,blue,alpha);
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
inline void glShadeModel( GLenum mode)
|
| 302 |
+
{
|
| 303 |
+
pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__);
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
inline void glPointSize(GLfloat size)
|
| 307 |
+
{
|
| 308 |
+
pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__);
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
inline void glTexEnvf( GLenum target,
|
| 312 |
+
GLenum pname,
|
| 313 |
+
GLfloat param)
|
| 314 |
+
{
|
| 315 |
+
pango_print_error("Not Implemented: %s, %s, %d", __FUNCTION__, __FILE__, __LINE__);
|
| 316 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/compat/gl_es_compat.h
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
|
| 3 |
+
#include <pangolin/platform.h>
|
| 4 |
+
|
| 5 |
+
#define GLdouble GLfloat
|
| 6 |
+
#define glClearDepth glClearDepthf
|
| 7 |
+
#define glFrustum glFrustumf
|
| 8 |
+
|
| 9 |
+
#define glColor4fv(a) glColor4f(a[0], a[1], a[2], a[3])
|
| 10 |
+
#define glColor3fv(a) glColor4f(a[0], a[1], a[2], 1.0f)
|
| 11 |
+
#define glColor3f(a,b,c) glColor4f(a, b, c, 1.0f)
|
| 12 |
+
|
| 13 |
+
#define glGenFramebuffersEXT glGenFramebuffers
|
| 14 |
+
#define glDeleteFramebuffersEXT glDeleteFramebuffers
|
| 15 |
+
#define glBindFramebufferEXT glBindFramebuffer
|
| 16 |
+
#define glFramebufferTexture2DEXT glFramebufferTexture2D
|
| 17 |
+
|
| 18 |
+
#define glGetDoublev glGetFloatv
|
| 19 |
+
|
| 20 |
+
#include <pangolin/gl/compat/gl2engine.h>
|
| 21 |
+
|
| 22 |
+
inline void glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
|
| 23 |
+
{
|
| 24 |
+
GLfloat verts[] = { x1,y1, x2,y1, x2,y2, x1,y2 };
|
| 25 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
| 26 |
+
glVertexPointer(2, GL_FLOAT, 0, verts);
|
| 27 |
+
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| 28 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
inline void glRecti(int x1, int y1, int x2, int y2)
|
| 32 |
+
{
|
| 33 |
+
GLfloat verts[] = { (float)x1,(float)y1, (float)x2,(float)y1,
|
| 34 |
+
(float)x2,(float)y2, (float)x1,(float)y2 };
|
| 35 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
| 36 |
+
glVertexPointer(2, GL_FLOAT, 0, verts);
|
| 37 |
+
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| 38 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
| 39 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gl.h
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/gl/viewport.h>
|
| 31 |
+
#include <pangolin/gl/glinclude.h>
|
| 32 |
+
#include <pangolin/image/image_io.h>
|
| 33 |
+
|
| 34 |
+
#if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files
|
| 35 |
+
#define USE_EIGEN
|
| 36 |
+
#endif
|
| 37 |
+
|
| 38 |
+
#ifdef USE_EIGEN
|
| 39 |
+
#include <Eigen/Core>
|
| 40 |
+
#endif
|
| 41 |
+
|
| 42 |
+
#include <cstdlib>
|
| 43 |
+
#include <iostream>
|
| 44 |
+
#include <math.h>
|
| 45 |
+
|
| 46 |
+
namespace pangolin
|
| 47 |
+
{
|
| 48 |
+
|
| 49 |
+
////////////////////////////////////////////////
|
| 50 |
+
// Interface
|
| 51 |
+
////////////////////////////////////////////////
|
| 52 |
+
|
| 53 |
+
class PANGOLIN_EXPORT GlTexture
|
| 54 |
+
{
|
| 55 |
+
public:
|
| 56 |
+
//! internal_format normally one of GL_RGBA8, GL_LUMINANCE8, GL_INTENSITY16
|
| 57 |
+
GlTexture(GLint width, GLint height, GLint internal_format = GL_RGBA8, bool sampling_linear = true, int border = 0, GLenum glformat = GL_RGBA, GLenum gltype = GL_UNSIGNED_BYTE, GLvoid* data = NULL );
|
| 58 |
+
|
| 59 |
+
// Construct this texture from a CPU image
|
| 60 |
+
GlTexture(const TypedImage& img, bool sampling_linear=true);
|
| 61 |
+
|
| 62 |
+
//! Move Constructor / asignment
|
| 63 |
+
GlTexture(GlTexture&& tex);
|
| 64 |
+
GlTexture& operator=(GlTexture&& tex);
|
| 65 |
+
|
| 66 |
+
//! Default constructor represents 'no texture'
|
| 67 |
+
GlTexture();
|
| 68 |
+
virtual ~GlTexture();
|
| 69 |
+
|
| 70 |
+
bool IsValid() const;
|
| 71 |
+
|
| 72 |
+
//! Delete OpenGL resources and fall back to representing 'no texture'
|
| 73 |
+
void Delete();
|
| 74 |
+
|
| 75 |
+
//! Reinitialise teture width / height / format
|
| 76 |
+
virtual void Reinitialise(GLsizei width, GLsizei height, GLint internal_format = GL_RGBA8, bool sampling_linear = true, int border = 0, GLenum glformat = GL_RGBA, GLenum gltype = GL_UNSIGNED_BYTE, GLvoid* data = NULL );
|
| 77 |
+
|
| 78 |
+
void Bind() const;
|
| 79 |
+
void Unbind() const;
|
| 80 |
+
|
| 81 |
+
//! data_layout normally one of GL_LUMINANCE, GL_RGB, ...
|
| 82 |
+
//! data_type normally one of GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT
|
| 83 |
+
void Upload(const void* image, GLenum data_format = GL_LUMINANCE, GLenum data_type = GL_FLOAT);
|
| 84 |
+
|
| 85 |
+
//! Upload data to texture, overwriting a sub-region of it.
|
| 86 |
+
//! data ptr contains packed data_w x data_h of pixel data.
|
| 87 |
+
void Upload(const void* data,
|
| 88 |
+
GLsizei tex_x_offset, GLsizei tex_y_offset,
|
| 89 |
+
GLsizei data_w, GLsizei data_h,
|
| 90 |
+
GLenum data_format, GLenum data_type
|
| 91 |
+
);
|
| 92 |
+
|
| 93 |
+
void Load(const TypedImage& image, bool sampling_linear = true);
|
| 94 |
+
|
| 95 |
+
void LoadFromFile(const std::string& filename, bool sampling_linear = true);
|
| 96 |
+
|
| 97 |
+
void Download(void* image, GLenum data_layout = GL_LUMINANCE, GLenum data_type = GL_FLOAT) const;
|
| 98 |
+
|
| 99 |
+
void Download(TypedImage& image) const;
|
| 100 |
+
|
| 101 |
+
void CopyFrom(const GlTexture& tex);
|
| 102 |
+
|
| 103 |
+
void Save(const std::string& filename, bool top_line_first = true);
|
| 104 |
+
|
| 105 |
+
void SetLinear();
|
| 106 |
+
void SetNearestNeighbour();
|
| 107 |
+
|
| 108 |
+
void RenderToViewport(const bool flip) const;
|
| 109 |
+
void RenderToViewport() const;
|
| 110 |
+
void RenderToViewport(Viewport tex_vp, bool flipx=false, bool flipy=false) const;
|
| 111 |
+
void RenderToViewportFlipY() const;
|
| 112 |
+
void RenderToViewportFlipXFlipY() const;
|
| 113 |
+
|
| 114 |
+
GLint internal_format;
|
| 115 |
+
GLuint tid;
|
| 116 |
+
GLint width;
|
| 117 |
+
GLint height;
|
| 118 |
+
|
| 119 |
+
private:
|
| 120 |
+
// Private copy constructor
|
| 121 |
+
GlTexture(const GlTexture&) {}
|
| 122 |
+
};
|
| 123 |
+
|
| 124 |
+
struct PANGOLIN_EXPORT GlRenderBuffer
|
| 125 |
+
{
|
| 126 |
+
GlRenderBuffer();
|
| 127 |
+
GlRenderBuffer(GLint width, GLint height, GLint internal_format = GL_DEPTH_COMPONENT24);
|
| 128 |
+
|
| 129 |
+
void Reinitialise(GLint width, GLint height, GLint internal_format = GL_DEPTH_COMPONENT24);
|
| 130 |
+
|
| 131 |
+
//! Move Constructor
|
| 132 |
+
GlRenderBuffer(GlRenderBuffer&& tex);
|
| 133 |
+
|
| 134 |
+
~GlRenderBuffer();
|
| 135 |
+
|
| 136 |
+
GLint width;
|
| 137 |
+
GLint height;
|
| 138 |
+
GLuint rbid;
|
| 139 |
+
|
| 140 |
+
private:
|
| 141 |
+
// Private copy constructor
|
| 142 |
+
GlRenderBuffer(const GlRenderBuffer&) {}
|
| 143 |
+
};
|
| 144 |
+
|
| 145 |
+
struct PANGOLIN_EXPORT GlFramebuffer
|
| 146 |
+
{
|
| 147 |
+
GlFramebuffer();
|
| 148 |
+
~GlFramebuffer();
|
| 149 |
+
|
| 150 |
+
GlFramebuffer(GlTexture& colour);
|
| 151 |
+
GlFramebuffer(GlTexture& colour, GlRenderBuffer& depth);
|
| 152 |
+
GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlRenderBuffer& depth);
|
| 153 |
+
GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlTexture& colour2, GlRenderBuffer& depth);
|
| 154 |
+
GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlTexture& colour2, GlTexture& colour3, GlRenderBuffer& depth);
|
| 155 |
+
|
| 156 |
+
void Bind() const;
|
| 157 |
+
void Unbind() const;
|
| 158 |
+
|
| 159 |
+
void Reinitialise();
|
| 160 |
+
|
| 161 |
+
// Attach Colour texture to frame buffer
|
| 162 |
+
// Return attachment texture is bound to (e.g. GL_COLOR_ATTACHMENT0_EXT)
|
| 163 |
+
GLenum AttachColour(GlTexture& tex);
|
| 164 |
+
|
| 165 |
+
// Attach Depth render buffer to frame buffer
|
| 166 |
+
void AttachDepth(GlRenderBuffer& rb);
|
| 167 |
+
|
| 168 |
+
GLuint fbid;
|
| 169 |
+
unsigned attachments;
|
| 170 |
+
};
|
| 171 |
+
|
| 172 |
+
enum GlBufferType
|
| 173 |
+
{
|
| 174 |
+
GlUndefined = 0,
|
| 175 |
+
GlArrayBuffer = GL_ARRAY_BUFFER, // VBO's, CBO's, NBO's
|
| 176 |
+
GlElementArrayBuffer = GL_ELEMENT_ARRAY_BUFFER, // IBO's
|
| 177 |
+
#ifndef HAVE_GLES
|
| 178 |
+
GlPixelPackBuffer = GL_PIXEL_PACK_BUFFER, // PBO's
|
| 179 |
+
GlPixelUnpackBuffer = GL_PIXEL_UNPACK_BUFFER,
|
| 180 |
+
GlShaderStorageBuffer = GL_SHADER_STORAGE_BUFFER
|
| 181 |
+
#endif
|
| 182 |
+
};
|
| 183 |
+
|
| 184 |
+
// This encapsulates a GL Buffer object.
|
| 185 |
+
struct PANGOLIN_EXPORT GlBufferData
|
| 186 |
+
{
|
| 187 |
+
//! Default constructor represents 'no buffer'
|
| 188 |
+
GlBufferData();
|
| 189 |
+
|
| 190 |
+
GlBufferData(GlBufferType buffer_type, GLsizeiptr size_bytes, GLenum gluse = GL_DYNAMIC_DRAW, const void *data = 0 );
|
| 191 |
+
|
| 192 |
+
template<typename T>
|
| 193 |
+
GlBufferData(GlBufferType buffer_type, const std::vector<T>& data, GLenum gluse = GL_STATIC_DRAW);
|
| 194 |
+
|
| 195 |
+
virtual ~GlBufferData();
|
| 196 |
+
|
| 197 |
+
void Free();
|
| 198 |
+
|
| 199 |
+
//! Move Constructor
|
| 200 |
+
GlBufferData(GlBufferData&& tex);
|
| 201 |
+
GlBufferData& operator=(GlBufferData&& tex);
|
| 202 |
+
|
| 203 |
+
bool IsValid() const;
|
| 204 |
+
|
| 205 |
+
GLsizeiptr SizeBytes() const;
|
| 206 |
+
|
| 207 |
+
void Reinitialise(GlBufferType buffer_type, GLsizeiptr size_bytes, GLenum gluse = GL_DYNAMIC_DRAW, const void *data = 0 );
|
| 208 |
+
|
| 209 |
+
void Bind() const;
|
| 210 |
+
void Unbind() const;
|
| 211 |
+
void Upload(const GLvoid* data, GLsizeiptr size_bytes, GLintptr offset = 0);
|
| 212 |
+
void Download(GLvoid* ptr, GLsizeiptr size_bytes, GLintptr offset = 0) const;
|
| 213 |
+
|
| 214 |
+
|
| 215 |
+
template<typename T>
|
| 216 |
+
void Upload(const std::vector<T>& data, GLintptr offset = 0);
|
| 217 |
+
|
| 218 |
+
#ifdef USE_EIGEN
|
| 219 |
+
template<typename Derived>
|
| 220 |
+
void Upload(const Eigen::DenseBase<Derived>& data, GLintptr offset = 0);
|
| 221 |
+
#endif
|
| 222 |
+
|
| 223 |
+
GLuint bo;
|
| 224 |
+
GlBufferType buffer_type;
|
| 225 |
+
GLenum gluse;
|
| 226 |
+
GLsizeiptr size_bytes;
|
| 227 |
+
|
| 228 |
+
private:
|
| 229 |
+
GlBufferData(const GlBufferData&) {}
|
| 230 |
+
};
|
| 231 |
+
|
| 232 |
+
// This encapsulates a GL Buffer object, also storing information about its contents.
|
| 233 |
+
// You should try to use GlBufferData instead.
|
| 234 |
+
struct PANGOLIN_EXPORT GlBuffer : public GlBufferData
|
| 235 |
+
{
|
| 236 |
+
//! Default constructor represents 'no buffer'
|
| 237 |
+
GlBuffer();
|
| 238 |
+
GlBuffer(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse = GL_DYNAMIC_DRAW );
|
| 239 |
+
GlBuffer(const GlBuffer&) = delete;
|
| 240 |
+
|
| 241 |
+
//! Move Constructor
|
| 242 |
+
GlBuffer(GlBuffer&& tex);
|
| 243 |
+
GlBuffer& operator=(GlBuffer&& tex);
|
| 244 |
+
|
| 245 |
+
void Reinitialise(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse, const void* data = nullptr );
|
| 246 |
+
void Reinitialise(GlBuffer const& other );
|
| 247 |
+
void Resize(GLuint num_elements);
|
| 248 |
+
|
| 249 |
+
#ifdef USE_EIGEN
|
| 250 |
+
template<typename Scalar, int R, int C>
|
| 251 |
+
GlBuffer(GlBufferType buffer_type, const std::vector<Eigen::Matrix<Scalar, R,C>>& data, GLenum gluse = GL_STATIC_DRAW);
|
| 252 |
+
#endif
|
| 253 |
+
|
| 254 |
+
GLenum datatype;
|
| 255 |
+
GLuint num_elements;
|
| 256 |
+
GLuint count_per_element;
|
| 257 |
+
};
|
| 258 |
+
|
| 259 |
+
class PANGOLIN_EXPORT GlSizeableBuffer
|
| 260 |
+
: public pangolin::GlBuffer
|
| 261 |
+
{
|
| 262 |
+
public:
|
| 263 |
+
GlSizeableBuffer(pangolin::GlBufferType buffer_type, GLuint initial_num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse = GL_DYNAMIC_DRAW );
|
| 264 |
+
|
| 265 |
+
void Clear();
|
| 266 |
+
|
| 267 |
+
#ifdef USE_EIGEN
|
| 268 |
+
template<typename Derived>
|
| 269 |
+
void Add(const Eigen::DenseBase<Derived>& vec);
|
| 270 |
+
|
| 271 |
+
template<typename Derived>
|
| 272 |
+
void Update(const Eigen::DenseBase<Derived>& vec, size_t position = 0);
|
| 273 |
+
#endif
|
| 274 |
+
|
| 275 |
+
size_t start() const;
|
| 276 |
+
|
| 277 |
+
size_t size() const;
|
| 278 |
+
|
| 279 |
+
protected:
|
| 280 |
+
void CheckResize(size_t num_verts);
|
| 281 |
+
|
| 282 |
+
size_t NextSize(size_t min_size) const;
|
| 283 |
+
|
| 284 |
+
size_t m_num_verts;
|
| 285 |
+
};
|
| 286 |
+
|
| 287 |
+
size_t GlFormatChannels(GLenum data_layout);
|
| 288 |
+
|
| 289 |
+
size_t GlDataTypeBytes(GLenum type);
|
| 290 |
+
|
| 291 |
+
TypedImage ReadFramebuffer(const Viewport& v, const std::string& pixel_format = "RGBA32");
|
| 292 |
+
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
// Include implementation
|
| 296 |
+
#include <pangolin/gl/gl.hpp>
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gl.hpp
ADDED
|
@@ -0,0 +1,956 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/gl/gl.h>
|
| 31 |
+
#include <pangolin/gl/glpixformat.h>
|
| 32 |
+
#include <pangolin/image/image_io.h>
|
| 33 |
+
#include <pangolin/utils/type_convert.h>
|
| 34 |
+
#include <algorithm>
|
| 35 |
+
#include <stdexcept>
|
| 36 |
+
#include <assert.h>
|
| 37 |
+
|
| 38 |
+
namespace pangolin
|
| 39 |
+
{
|
| 40 |
+
|
| 41 |
+
////////////////////////////////////////////////
|
| 42 |
+
// Implementation of gl.h
|
| 43 |
+
////////////////////////////////////////////////
|
| 44 |
+
|
| 45 |
+
#ifndef HAVE_GLES
|
| 46 |
+
const int MAX_ATTACHMENTS = 8;
|
| 47 |
+
const static GLuint attachment_buffers[] = {
|
| 48 |
+
GL_COLOR_ATTACHMENT0_EXT,
|
| 49 |
+
GL_COLOR_ATTACHMENT1_EXT,
|
| 50 |
+
GL_COLOR_ATTACHMENT2_EXT,
|
| 51 |
+
GL_COLOR_ATTACHMENT3_EXT,
|
| 52 |
+
GL_COLOR_ATTACHMENT4_EXT,
|
| 53 |
+
GL_COLOR_ATTACHMENT5_EXT,
|
| 54 |
+
GL_COLOR_ATTACHMENT6_EXT,
|
| 55 |
+
GL_COLOR_ATTACHMENT7_EXT
|
| 56 |
+
};
|
| 57 |
+
#else // HAVE_GLES
|
| 58 |
+
const int MAX_ATTACHMENTS = 1;
|
| 59 |
+
const static GLuint attachment_buffers[] = {
|
| 60 |
+
GL_COLOR_ATTACHMENT0_EXT
|
| 61 |
+
};
|
| 62 |
+
#endif // HAVE_GLES
|
| 63 |
+
|
| 64 |
+
const static size_t datatype_bytes[] = {
|
| 65 |
+
1, // #define GL_BYTE 0x1400
|
| 66 |
+
1, // #define GL_UNSIGNED_BYTE 0x1401
|
| 67 |
+
2, // #define GL_SHORT 0x1402
|
| 68 |
+
2, // #define GL_UNSIGNED_SHORT 0x1403
|
| 69 |
+
4, // #define GL_INT 0x1404
|
| 70 |
+
4, // #define GL_UNSIGNED_INT 0x1405
|
| 71 |
+
4, // #define GL_FLOAT 0x1406
|
| 72 |
+
2, // #define GL_2_BYTES 0x1407
|
| 73 |
+
3, // #define GL_3_BYTES 0x1408
|
| 74 |
+
4, // #define GL_4_BYTES 0x1409
|
| 75 |
+
8 // #define GL_DOUBLE 0x140A
|
| 76 |
+
};
|
| 77 |
+
|
| 78 |
+
const static size_t format_channels[] = {
|
| 79 |
+
1, // #define GL_RED 0x1903
|
| 80 |
+
1, // #define GL_GREEN 0x1904
|
| 81 |
+
1, // #define GL_BLUE 0x1905
|
| 82 |
+
1, // #define GL_ALPHA 0x1906
|
| 83 |
+
3, // #define GL_RGB 0x1907
|
| 84 |
+
4, // #define GL_RGBA 0x1908
|
| 85 |
+
1, // #define GL_LUMINANCE 0x1909
|
| 86 |
+
2 // #define GL_LUMINANCE_ALPHA 0x190A
|
| 87 |
+
};
|
| 88 |
+
|
| 89 |
+
inline size_t GlDataTypeBytes(GLenum type)
|
| 90 |
+
{
|
| 91 |
+
return datatype_bytes[type - GL_BYTE];
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
inline size_t GlFormatChannels(GLenum data_layout)
|
| 95 |
+
{
|
| 96 |
+
if (data_layout == GL_BGR) return 3;
|
| 97 |
+
if (data_layout == GL_BGRA) return 4;
|
| 98 |
+
return format_channels[data_layout - GL_RED];
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
//template<typename T>
|
| 102 |
+
//struct GlDataTypeTrait {};
|
| 103 |
+
//template<> struct GlDataTypeTrait<float>{ static const GLenum type = GL_FLOAT; };
|
| 104 |
+
//template<> struct GlDataTypeTrait<int>{ static const GLenum type = GL_INT; };
|
| 105 |
+
//template<> struct GlDataTypeTrait<unsigned char>{ static const GLenum type = GL_UNSIGNED_BYTE; };
|
| 106 |
+
|
| 107 |
+
inline GlTexture::GlTexture()
|
| 108 |
+
: internal_format(0), tid(0), width(0), height(0)
|
| 109 |
+
{
|
| 110 |
+
// Not a texture constructor
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
inline GlTexture::GlTexture(GLint width, GLint height, GLint internal_format, bool sampling_linear, int border, GLenum glformat, GLenum gltype, GLvoid* data )
|
| 114 |
+
: internal_format(0), tid(0)
|
| 115 |
+
{
|
| 116 |
+
Reinitialise(width,height,internal_format,sampling_linear,border,glformat,gltype,data);
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
inline GlTexture::GlTexture(const TypedImage& img, bool sampling_linear)
|
| 120 |
+
{
|
| 121 |
+
this->Load(img, sampling_linear);
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
inline GlTexture::GlTexture(GlTexture&& tex)
|
| 125 |
+
{
|
| 126 |
+
*this = std::move(tex);
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
inline GlTexture& GlTexture::operator=(GlTexture&& tex)
|
| 130 |
+
{
|
| 131 |
+
if (&tex != this) {
|
| 132 |
+
internal_format = tex.internal_format;
|
| 133 |
+
tid = tex.tid;
|
| 134 |
+
width = tex.width;
|
| 135 |
+
height = tex.height;
|
| 136 |
+
|
| 137 |
+
tex.internal_format = 0;
|
| 138 |
+
tex.tid = 0;
|
| 139 |
+
}
|
| 140 |
+
return *this;
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
inline bool GlTexture::IsValid() const
|
| 144 |
+
{
|
| 145 |
+
return tid != 0;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
inline void GlTexture::Delete()
|
| 149 |
+
{
|
| 150 |
+
if(internal_format!=0 ) {
|
| 151 |
+
glDeleteTextures(1,&tid);
|
| 152 |
+
internal_format = 0;
|
| 153 |
+
tid = 0;
|
| 154 |
+
width = 0;
|
| 155 |
+
height = 0;
|
| 156 |
+
}
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
inline GlTexture::~GlTexture()
|
| 160 |
+
{
|
| 161 |
+
Delete();
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
inline void GlTexture::Bind() const
|
| 165 |
+
{
|
| 166 |
+
glBindTexture(GL_TEXTURE_2D, tid);
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
inline void GlTexture::Unbind() const
|
| 170 |
+
{
|
| 171 |
+
glBindTexture(GL_TEXTURE_2D, 0);
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
inline void GlTexture::Reinitialise(GLsizei w, GLsizei h, GLint int_format, bool sampling_linear, int border, GLenum glformat, GLenum gltype, GLvoid* data )
|
| 175 |
+
{
|
| 176 |
+
if(tid!=0) {
|
| 177 |
+
glDeleteTextures(1,&tid);
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
internal_format = int_format;
|
| 181 |
+
width = w;
|
| 182 |
+
height = h;
|
| 183 |
+
|
| 184 |
+
glGenTextures(1,&tid);
|
| 185 |
+
Bind();
|
| 186 |
+
|
| 187 |
+
// GL_LUMINANCE and GL_FLOAT don't seem to actually affect buffer, but some values are required
|
| 188 |
+
// for call to succeed.
|
| 189 |
+
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, border, glformat, gltype, data);
|
| 190 |
+
|
| 191 |
+
if(sampling_linear) {
|
| 192 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
| 193 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
| 194 |
+
}else{
|
| 195 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| 196 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| 200 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| 201 |
+
|
| 202 |
+
CheckGlDieOnError();
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
inline void GlTexture::Upload(
|
| 206 |
+
const void* data,
|
| 207 |
+
GLenum data_format, GLenum data_type
|
| 208 |
+
) {
|
| 209 |
+
Bind();
|
| 210 |
+
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,width,height,data_format,data_type,data);
|
| 211 |
+
CheckGlDieOnError();
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
inline void GlTexture::Upload(
|
| 215 |
+
const void* data,
|
| 216 |
+
GLsizei tex_x_offset, GLsizei tex_y_offset,
|
| 217 |
+
GLsizei data_w, GLsizei data_h,
|
| 218 |
+
GLenum data_format, GLenum data_type )
|
| 219 |
+
{
|
| 220 |
+
Bind();
|
| 221 |
+
glTexSubImage2D(GL_TEXTURE_2D,0,tex_x_offset,tex_y_offset,data_w,data_h,data_format,data_type,data);
|
| 222 |
+
CheckGlDieOnError();
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
inline void GlTexture::Load(const TypedImage& image, bool sampling_linear)
|
| 226 |
+
{
|
| 227 |
+
GlPixFormat fmt(image.fmt);
|
| 228 |
+
Reinitialise((GLint)image.w, (GLint)image.h, GL_RGBA32F, sampling_linear, 0, fmt.glformat, fmt.gltype, image.ptr );
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
inline void GlTexture::LoadFromFile(const std::string& filename, bool sampling_linear)
|
| 232 |
+
{
|
| 233 |
+
TypedImage image = LoadImage(filename);
|
| 234 |
+
Load(image, sampling_linear);
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
inline void GlTexture::Download(void* image, GLenum data_layout, GLenum data_type) const
|
| 238 |
+
{
|
| 239 |
+
Bind();
|
| 240 |
+
#ifndef HAVE_GLES
|
| 241 |
+
glGetTexImage(GL_TEXTURE_2D, 0, data_layout, data_type, image);
|
| 242 |
+
#else
|
| 243 |
+
throw std::runtime_error("glGetTexImage not implemented on this platform.");
|
| 244 |
+
#endif // HAVE_GLES
|
| 245 |
+
Unbind();
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
inline void GlTexture::Download(TypedImage& image) const
|
| 249 |
+
{
|
| 250 |
+
switch (internal_format)
|
| 251 |
+
{
|
| 252 |
+
case GL_LUMINANCE8:
|
| 253 |
+
image.Reinitialise(width, height, PixelFormatFromString("GRAY8") );
|
| 254 |
+
Download(image.ptr, GL_LUMINANCE, GL_UNSIGNED_BYTE);
|
| 255 |
+
break;
|
| 256 |
+
case GL_LUMINANCE16:
|
| 257 |
+
image.Reinitialise(width, height, PixelFormatFromString("GRAY16LE") );
|
| 258 |
+
Download(image.ptr, GL_LUMINANCE, GL_UNSIGNED_SHORT);
|
| 259 |
+
break;
|
| 260 |
+
case GL_RGB8:
|
| 261 |
+
image.Reinitialise(width, height, PixelFormatFromString("RGB24"));
|
| 262 |
+
Download(image.ptr, GL_RGB, GL_UNSIGNED_BYTE);
|
| 263 |
+
break;
|
| 264 |
+
case GL_RGBA8:
|
| 265 |
+
image.Reinitialise(width, height, PixelFormatFromString("RGBA32"));
|
| 266 |
+
Download(image.ptr, GL_RGBA, GL_UNSIGNED_BYTE);
|
| 267 |
+
break;
|
| 268 |
+
case GL_RED_INTEGER:
|
| 269 |
+
image.Reinitialise(width, height, PixelFormatFromString("GRAY32") );
|
| 270 |
+
Download(image.ptr, GL_RED, GL_UNSIGNED_INT);
|
| 271 |
+
break;
|
| 272 |
+
case GL_LUMINANCE:
|
| 273 |
+
case GL_LUMINANCE32F_ARB:
|
| 274 |
+
case GL_R32F:
|
| 275 |
+
image.Reinitialise(width, height, PixelFormatFromString("GRAY32F"));
|
| 276 |
+
Download(image.ptr, GL_LUMINANCE, GL_FLOAT);
|
| 277 |
+
break;
|
| 278 |
+
case GL_RGB16:
|
| 279 |
+
image.Reinitialise(width, height, PixelFormatFromString("RGB48"));
|
| 280 |
+
Download(image.ptr, GL_RGB, GL_UNSIGNED_SHORT);
|
| 281 |
+
break;
|
| 282 |
+
case GL_RGBA16:
|
| 283 |
+
image.Reinitialise(width, height, PixelFormatFromString("RGBA64"));
|
| 284 |
+
Download(image.ptr, GL_RGBA, GL_UNSIGNED_SHORT);
|
| 285 |
+
break;
|
| 286 |
+
case GL_RGB16F:
|
| 287 |
+
image.Reinitialise(width, height, PixelFormatFromString("RGB48F"));
|
| 288 |
+
Download(image.ptr, GL_RGB, GL_HALF_FLOAT);
|
| 289 |
+
break;
|
| 290 |
+
case GL_RGBA16F:
|
| 291 |
+
image.Reinitialise(width, height, PixelFormatFromString("RGBA64F"));
|
| 292 |
+
Download(image.ptr, GL_RGBA, GL_HALF_FLOAT);
|
| 293 |
+
break;
|
| 294 |
+
case GL_RGB:
|
| 295 |
+
case GL_RGB32F:
|
| 296 |
+
image.Reinitialise(width, height, PixelFormatFromString("RGB96F"));
|
| 297 |
+
Download(image.ptr, GL_RGB, GL_FLOAT);
|
| 298 |
+
break;
|
| 299 |
+
case GL_RGBA:
|
| 300 |
+
case GL_RGBA32F:
|
| 301 |
+
image.Reinitialise(width, height, PixelFormatFromString("RGBA128F"));
|
| 302 |
+
Download(image.ptr, GL_RGBA, GL_FLOAT);
|
| 303 |
+
break;
|
| 304 |
+
case GL_DEPTH_COMPONENT16:
|
| 305 |
+
image.Reinitialise(width, height, PixelFormatFromString("GRAY16LE"));
|
| 306 |
+
Download(image.ptr, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
|
| 307 |
+
break;
|
| 308 |
+
case GL_DEPTH_COMPONENT24:
|
| 309 |
+
image.Reinitialise(width, height, PixelFormatFromString("GRAY32"));
|
| 310 |
+
Download(image.ptr, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
|
| 311 |
+
break;
|
| 312 |
+
case GL_DEPTH_COMPONENT32F:
|
| 313 |
+
image.Reinitialise(width, height, PixelFormatFromString("GRAY32F"));
|
| 314 |
+
Download(image.ptr, GL_DEPTH_COMPONENT, GL_FLOAT);
|
| 315 |
+
break;
|
| 316 |
+
default:
|
| 317 |
+
throw std::runtime_error(
|
| 318 |
+
"GlTexture::Download - Unknown internal format (" +
|
| 319 |
+
pangolin::Convert<std::string,GLint>::Do(internal_format) +
|
| 320 |
+
")"
|
| 321 |
+
);
|
| 322 |
+
}
|
| 323 |
+
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
inline void GlTexture::CopyFrom(const GlTexture& tex)
|
| 327 |
+
{
|
| 328 |
+
#ifndef HAVE_GLES
|
| 329 |
+
if(!tid || width != tex.width || height != tex.height ||
|
| 330 |
+
internal_format != tex.internal_format)
|
| 331 |
+
{
|
| 332 |
+
Reinitialise(tex.width, tex.height, tex.internal_format, true);
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
+
glCopyImageSubDataNV(tex.tid, GL_TEXTURE_2D, 0, 0, 0, 0,
|
| 336 |
+
tid, GL_TEXTURE_2D, 0, 0, 0, 0,
|
| 337 |
+
width, height, 1);
|
| 338 |
+
CheckGlDieOnError();
|
| 339 |
+
#else
|
| 340 |
+
throw std::runtime_error("glCopyImageSubDataNV not implemented on this platform.");
|
| 341 |
+
#endif
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
inline void GlTexture::Save(const std::string& filename, bool top_line_first)
|
| 345 |
+
{
|
| 346 |
+
TypedImage image;
|
| 347 |
+
Download(image);
|
| 348 |
+
pangolin::SaveImage(image, filename, top_line_first);
|
| 349 |
+
}
|
| 350 |
+
|
| 351 |
+
inline void GlTexture::SetLinear()
|
| 352 |
+
{
|
| 353 |
+
Bind();
|
| 354 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
| 355 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
| 356 |
+
Unbind();
|
| 357 |
+
}
|
| 358 |
+
|
| 359 |
+
inline void GlTexture::SetNearestNeighbour()
|
| 360 |
+
{
|
| 361 |
+
Bind();
|
| 362 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| 363 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
| 364 |
+
Unbind();
|
| 365 |
+
}
|
| 366 |
+
|
| 367 |
+
inline void GlTexture::RenderToViewport(const bool flip) const
|
| 368 |
+
{
|
| 369 |
+
if(flip) {
|
| 370 |
+
RenderToViewportFlipY();
|
| 371 |
+
}else{
|
| 372 |
+
RenderToViewport();
|
| 373 |
+
}
|
| 374 |
+
}
|
| 375 |
+
|
| 376 |
+
inline void GlTexture::RenderToViewport() const
|
| 377 |
+
{
|
| 378 |
+
glMatrixMode(GL_PROJECTION);
|
| 379 |
+
glLoadIdentity();
|
| 380 |
+
glMatrixMode(GL_MODELVIEW);
|
| 381 |
+
glLoadIdentity();
|
| 382 |
+
|
| 383 |
+
GLfloat sq_vert[] = { -1,-1, 1,-1, 1, 1, -1, 1 };
|
| 384 |
+
glVertexPointer(2, GL_FLOAT, 0, sq_vert);
|
| 385 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
| 386 |
+
|
| 387 |
+
GLfloat sq_tex[] = { 0,0, 1,0, 1,1, 0,1 };
|
| 388 |
+
glTexCoordPointer(2, GL_FLOAT, 0, sq_tex);
|
| 389 |
+
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 390 |
+
|
| 391 |
+
#ifndef HAVE_GLES
|
| 392 |
+
glEnable(GL_TEXTURE_2D);
|
| 393 |
+
#endif
|
| 394 |
+
Bind();
|
| 395 |
+
|
| 396 |
+
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| 397 |
+
|
| 398 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
| 399 |
+
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 400 |
+
|
| 401 |
+
#ifndef HAVE_GLES
|
| 402 |
+
glDisable(GL_TEXTURE_2D);
|
| 403 |
+
#endif
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
inline void GlTexture::RenderToViewport(Viewport tex_vp, bool flipx, bool flipy) const
|
| 407 |
+
{
|
| 408 |
+
glMatrixMode(GL_PROJECTION);
|
| 409 |
+
glLoadIdentity();
|
| 410 |
+
glMatrixMode(GL_MODELVIEW);
|
| 411 |
+
glLoadIdentity();
|
| 412 |
+
|
| 413 |
+
GLfloat sq_vert[] = { -1,-1, 1,-1, 1, 1, -1, 1 };
|
| 414 |
+
glVertexPointer(2, GL_FLOAT, 0, sq_vert);
|
| 415 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
| 416 |
+
|
| 417 |
+
GLfloat l = tex_vp.l / (float)(width);
|
| 418 |
+
GLfloat b = tex_vp.b / (float)(height);
|
| 419 |
+
GLfloat r = (tex_vp.l+tex_vp.w) / (float)(width);
|
| 420 |
+
GLfloat t = (tex_vp.b+tex_vp.h) / (float)(height);
|
| 421 |
+
|
| 422 |
+
if(flipx) std::swap(l,r);
|
| 423 |
+
if(flipy) std::swap(b,t);
|
| 424 |
+
|
| 425 |
+
GLfloat sq_tex[] = { l,b, r,b, r,t, l,t };
|
| 426 |
+
glTexCoordPointer(2, GL_FLOAT, 0, sq_tex);
|
| 427 |
+
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 428 |
+
|
| 429 |
+
glEnable(GL_TEXTURE_2D);
|
| 430 |
+
Bind();
|
| 431 |
+
|
| 432 |
+
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| 433 |
+
|
| 434 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
| 435 |
+
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 436 |
+
|
| 437 |
+
glDisable(GL_TEXTURE_2D);
|
| 438 |
+
}
|
| 439 |
+
|
| 440 |
+
inline void GlTexture::RenderToViewportFlipY() const
|
| 441 |
+
{
|
| 442 |
+
glMatrixMode(GL_PROJECTION);
|
| 443 |
+
glLoadIdentity();
|
| 444 |
+
glMatrixMode(GL_MODELVIEW);
|
| 445 |
+
glLoadIdentity();
|
| 446 |
+
|
| 447 |
+
GLfloat sq_vert[] = { -1,-1, 1,-1, 1, 1, -1, 1 };
|
| 448 |
+
glVertexPointer(2, GL_FLOAT, 0, sq_vert);
|
| 449 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
| 450 |
+
|
| 451 |
+
GLfloat sq_tex[] = { 0,1, 1,1, 1,0, 0,0 };
|
| 452 |
+
glTexCoordPointer(2, GL_FLOAT, 0, sq_tex);
|
| 453 |
+
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 454 |
+
|
| 455 |
+
glEnable(GL_TEXTURE_2D);
|
| 456 |
+
Bind();
|
| 457 |
+
|
| 458 |
+
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| 459 |
+
|
| 460 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
| 461 |
+
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 462 |
+
|
| 463 |
+
glDisable(GL_TEXTURE_2D);
|
| 464 |
+
}
|
| 465 |
+
|
| 466 |
+
inline void GlTexture::RenderToViewportFlipXFlipY() const
|
| 467 |
+
{
|
| 468 |
+
glMatrixMode(GL_PROJECTION);
|
| 469 |
+
glLoadIdentity();
|
| 470 |
+
glMatrixMode(GL_MODELVIEW);
|
| 471 |
+
glLoadIdentity();
|
| 472 |
+
|
| 473 |
+
GLfloat sq_vert[] = { 1,1, -1,1, -1,-1, 1,-1 };
|
| 474 |
+
glVertexPointer(2, GL_FLOAT, 0, sq_vert);
|
| 475 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
| 476 |
+
|
| 477 |
+
GLfloat sq_tex[] = { 0,0, 1,0, 1,1, 0,1 };
|
| 478 |
+
glTexCoordPointer(2, GL_FLOAT, 0, sq_tex);
|
| 479 |
+
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 480 |
+
|
| 481 |
+
glEnable(GL_TEXTURE_2D);
|
| 482 |
+
Bind();
|
| 483 |
+
|
| 484 |
+
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| 485 |
+
|
| 486 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
| 487 |
+
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 488 |
+
|
| 489 |
+
glDisable(GL_TEXTURE_2D);
|
| 490 |
+
}
|
| 491 |
+
|
| 492 |
+
////////////////////////////////////////////////////////////////////////////
|
| 493 |
+
|
| 494 |
+
inline GlRenderBuffer::GlRenderBuffer()
|
| 495 |
+
: width(0), height(0), rbid(0)
|
| 496 |
+
{
|
| 497 |
+
}
|
| 498 |
+
|
| 499 |
+
inline GlRenderBuffer::GlRenderBuffer(GLint width, GLint height, GLint internal_format )
|
| 500 |
+
: width(0), height(0), rbid(0)
|
| 501 |
+
{
|
| 502 |
+
Reinitialise(width,height,internal_format);
|
| 503 |
+
}
|
| 504 |
+
|
| 505 |
+
#ifndef HAVE_GLES
|
| 506 |
+
inline void GlRenderBuffer::Reinitialise(GLint width, GLint height, GLint internal_format)
|
| 507 |
+
{
|
| 508 |
+
if( this->width != 0 ) {
|
| 509 |
+
glDeleteRenderbuffersEXT(1, &rbid);
|
| 510 |
+
}
|
| 511 |
+
|
| 512 |
+
this->width = width;
|
| 513 |
+
this->height = height;
|
| 514 |
+
glGenRenderbuffersEXT(1, &rbid);
|
| 515 |
+
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbid);
|
| 516 |
+
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internal_format, width, height);
|
| 517 |
+
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
| 518 |
+
}
|
| 519 |
+
|
| 520 |
+
inline GlRenderBuffer::~GlRenderBuffer()
|
| 521 |
+
{
|
| 522 |
+
if( width!=0 ) {
|
| 523 |
+
glDeleteRenderbuffersEXT(1, &rbid);
|
| 524 |
+
}
|
| 525 |
+
}
|
| 526 |
+
#else
|
| 527 |
+
inline void GlRenderBuffer::Reinitialise(GLint width, GLint height, GLint internal_format)
|
| 528 |
+
{
|
| 529 |
+
if( width!=0 ) {
|
| 530 |
+
glDeleteTextures(1, &rbid);
|
| 531 |
+
}
|
| 532 |
+
|
| 533 |
+
// Use a texture instead...
|
| 534 |
+
glGenTextures(1, &rbid);
|
| 535 |
+
glBindTexture(GL_TEXTURE_2D, rbid);
|
| 536 |
+
|
| 537 |
+
glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
|
| 538 |
+
width, height,
|
| 539 |
+
0, internal_format, GL_UNSIGNED_SHORT, NULL);
|
| 540 |
+
|
| 541 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| 542 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| 543 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
| 544 |
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
inline GlRenderBuffer::~GlRenderBuffer()
|
| 548 |
+
{
|
| 549 |
+
// We have no GL context whilst exiting.
|
| 550 |
+
if( width!=0 ) {
|
| 551 |
+
glDeleteTextures(1, &rbid);
|
| 552 |
+
}
|
| 553 |
+
}
|
| 554 |
+
#endif // HAVE_GLES
|
| 555 |
+
|
| 556 |
+
inline GlRenderBuffer::GlRenderBuffer(GlRenderBuffer&& tex)
|
| 557 |
+
: width(tex.width), height(tex.height), rbid(tex.rbid)
|
| 558 |
+
{
|
| 559 |
+
tex.rbid = tex.width = tex.height = 0;
|
| 560 |
+
}
|
| 561 |
+
|
| 562 |
+
////////////////////////////////////////////////////////////////////////////
|
| 563 |
+
|
| 564 |
+
inline GlFramebuffer::GlFramebuffer()
|
| 565 |
+
: fbid(0), attachments(0)
|
| 566 |
+
{
|
| 567 |
+
}
|
| 568 |
+
|
| 569 |
+
inline GlFramebuffer::~GlFramebuffer()
|
| 570 |
+
{
|
| 571 |
+
if(fbid) {
|
| 572 |
+
glDeleteFramebuffersEXT(1, &fbid);
|
| 573 |
+
}
|
| 574 |
+
}
|
| 575 |
+
|
| 576 |
+
inline GlFramebuffer::GlFramebuffer(GlTexture& colour)
|
| 577 |
+
: attachments(0)
|
| 578 |
+
{
|
| 579 |
+
glGenFramebuffersEXT(1, &fbid);
|
| 580 |
+
AttachColour(colour);
|
| 581 |
+
CheckGlDieOnError();
|
| 582 |
+
}
|
| 583 |
+
|
| 584 |
+
inline GlFramebuffer::GlFramebuffer(GlTexture& colour, GlRenderBuffer& depth)
|
| 585 |
+
: attachments(0)
|
| 586 |
+
{
|
| 587 |
+
glGenFramebuffersEXT(1, &fbid);
|
| 588 |
+
AttachColour(colour);
|
| 589 |
+
AttachDepth(depth);
|
| 590 |
+
CheckGlDieOnError();
|
| 591 |
+
}
|
| 592 |
+
|
| 593 |
+
inline GlFramebuffer::GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlRenderBuffer& depth)
|
| 594 |
+
: attachments(0)
|
| 595 |
+
{
|
| 596 |
+
glGenFramebuffersEXT(1, &fbid);
|
| 597 |
+
AttachColour(colour0);
|
| 598 |
+
AttachColour(colour1);
|
| 599 |
+
AttachDepth(depth);
|
| 600 |
+
CheckGlDieOnError();
|
| 601 |
+
}
|
| 602 |
+
|
| 603 |
+
inline GlFramebuffer::GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlTexture& colour2, GlRenderBuffer& depth)
|
| 604 |
+
: attachments(0)
|
| 605 |
+
{
|
| 606 |
+
glGenFramebuffersEXT(1, &fbid);
|
| 607 |
+
AttachColour(colour0);
|
| 608 |
+
AttachColour(colour1);
|
| 609 |
+
AttachColour(colour2);
|
| 610 |
+
AttachDepth(depth);
|
| 611 |
+
CheckGlDieOnError();
|
| 612 |
+
}
|
| 613 |
+
|
| 614 |
+
inline GlFramebuffer::GlFramebuffer(GlTexture& colour0, GlTexture& colour1, GlTexture& colour2, GlTexture& colour3, GlRenderBuffer& depth)
|
| 615 |
+
: attachments(0)
|
| 616 |
+
{
|
| 617 |
+
glGenFramebuffersEXT(1, &fbid);
|
| 618 |
+
AttachColour(colour0);
|
| 619 |
+
AttachColour(colour1);
|
| 620 |
+
AttachColour(colour2);
|
| 621 |
+
AttachColour(colour3);
|
| 622 |
+
AttachDepth(depth);
|
| 623 |
+
CheckGlDieOnError();
|
| 624 |
+
}
|
| 625 |
+
|
| 626 |
+
inline void GlFramebuffer::Bind() const
|
| 627 |
+
{
|
| 628 |
+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbid);
|
| 629 |
+
glDrawBuffers( attachments, attachment_buffers );
|
| 630 |
+
}
|
| 631 |
+
|
| 632 |
+
inline void GlFramebuffer::Reinitialise()
|
| 633 |
+
{
|
| 634 |
+
if(fbid) {
|
| 635 |
+
glDeleteFramebuffersEXT(1, &fbid);
|
| 636 |
+
}
|
| 637 |
+
glGenFramebuffersEXT(1, &fbid);
|
| 638 |
+
}
|
| 639 |
+
|
| 640 |
+
inline void GlFramebuffer::Unbind() const
|
| 641 |
+
{
|
| 642 |
+
glDrawBuffers( 1, attachment_buffers );
|
| 643 |
+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
| 644 |
+
}
|
| 645 |
+
|
| 646 |
+
inline GLenum GlFramebuffer::AttachColour(GlTexture& tex )
|
| 647 |
+
{
|
| 648 |
+
if(!fbid) Reinitialise();
|
| 649 |
+
|
| 650 |
+
const GLenum color_attachment = GL_COLOR_ATTACHMENT0_EXT + attachments;
|
| 651 |
+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbid);
|
| 652 |
+
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, color_attachment, GL_TEXTURE_2D, tex.tid, 0);
|
| 653 |
+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
| 654 |
+
attachments++;
|
| 655 |
+
CheckGlDieOnError();
|
| 656 |
+
return color_attachment;
|
| 657 |
+
}
|
| 658 |
+
|
| 659 |
+
inline void GlFramebuffer::AttachDepth(GlRenderBuffer& rb )
|
| 660 |
+
{
|
| 661 |
+
if(!fbid) Reinitialise();
|
| 662 |
+
|
| 663 |
+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbid);
|
| 664 |
+
#if !defined(HAVE_GLES)
|
| 665 |
+
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rb.rbid);
|
| 666 |
+
#elif defined(HAVE_GLES_2)
|
| 667 |
+
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, rb.rbid, 0);
|
| 668 |
+
#else
|
| 669 |
+
throw std::exception();
|
| 670 |
+
#endif
|
| 671 |
+
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
| 672 |
+
CheckGlDieOnError();
|
| 673 |
+
}
|
| 674 |
+
|
| 675 |
+
////////////////////////////////////////////////////////////////////////////
|
| 676 |
+
|
| 677 |
+
inline GlBufferData::GlBufferData()
|
| 678 |
+
: bo(0)
|
| 679 |
+
{
|
| 680 |
+
}
|
| 681 |
+
|
| 682 |
+
inline GlBufferData::GlBufferData(GlBufferType buffer_type, GLsizeiptr size_bytes, GLenum gluse, const void* data )
|
| 683 |
+
: bo(0)
|
| 684 |
+
{
|
| 685 |
+
Reinitialise(buffer_type, size_bytes, gluse, data );
|
| 686 |
+
}
|
| 687 |
+
|
| 688 |
+
template<typename T>
|
| 689 |
+
GlBufferData::GlBufferData(GlBufferType buffer_type, const std::vector<T>& data, GLenum gluse)
|
| 690 |
+
: bo(0)
|
| 691 |
+
{
|
| 692 |
+
Reinitialise(buffer_type, data.size()*sizeof(T), gluse, &data[0]);
|
| 693 |
+
}
|
| 694 |
+
|
| 695 |
+
//! Move Constructor
|
| 696 |
+
inline GlBufferData::GlBufferData(GlBufferData&& tex)
|
| 697 |
+
: bo(0)
|
| 698 |
+
{
|
| 699 |
+
*this = std::move(tex);
|
| 700 |
+
}
|
| 701 |
+
|
| 702 |
+
inline GlBufferData& GlBufferData::operator=(GlBufferData&& tex)
|
| 703 |
+
{
|
| 704 |
+
Free();
|
| 705 |
+
this->bo = tex.bo;
|
| 706 |
+
this->buffer_type = tex.buffer_type;
|
| 707 |
+
this->gluse = tex.gluse;
|
| 708 |
+
this->size_bytes = tex.size_bytes;
|
| 709 |
+
tex.bo = 0;
|
| 710 |
+
return *this;
|
| 711 |
+
}
|
| 712 |
+
|
| 713 |
+
inline GlBufferData::~GlBufferData()
|
| 714 |
+
{
|
| 715 |
+
Free();
|
| 716 |
+
}
|
| 717 |
+
|
| 718 |
+
inline void GlBufferData::Free()
|
| 719 |
+
{
|
| 720 |
+
if(bo!=0) {
|
| 721 |
+
glDeleteBuffers(1, &bo);
|
| 722 |
+
}
|
| 723 |
+
}
|
| 724 |
+
|
| 725 |
+
inline bool GlBufferData::IsValid() const
|
| 726 |
+
{
|
| 727 |
+
return bo != 0;
|
| 728 |
+
}
|
| 729 |
+
|
| 730 |
+
inline GLsizeiptr GlBufferData::SizeBytes() const
|
| 731 |
+
{
|
| 732 |
+
return size_bytes;
|
| 733 |
+
}
|
| 734 |
+
|
| 735 |
+
inline void GlBufferData::Reinitialise(GlBufferType buffer_type, GLsizeiptr size_bytes, GLenum gluse, const void* data )
|
| 736 |
+
{
|
| 737 |
+
if(!bo) {
|
| 738 |
+
glGenBuffers(1, &bo);
|
| 739 |
+
}
|
| 740 |
+
|
| 741 |
+
this->buffer_type = buffer_type;
|
| 742 |
+
this->gluse = gluse;
|
| 743 |
+
this->size_bytes = size_bytes;
|
| 744 |
+
|
| 745 |
+
Bind();
|
| 746 |
+
glBufferData(buffer_type, size_bytes, data, gluse);
|
| 747 |
+
Unbind();
|
| 748 |
+
}
|
| 749 |
+
|
| 750 |
+
inline void GlBufferData::Bind() const
|
| 751 |
+
{
|
| 752 |
+
glBindBuffer(buffer_type, bo);
|
| 753 |
+
}
|
| 754 |
+
|
| 755 |
+
inline void GlBufferData::Unbind() const
|
| 756 |
+
{
|
| 757 |
+
glBindBuffer(buffer_type, 0);
|
| 758 |
+
}
|
| 759 |
+
|
| 760 |
+
inline void GlBufferData::Upload(const GLvoid* data, GLsizeiptr size_bytes, GLintptr offset)
|
| 761 |
+
{
|
| 762 |
+
if(offset + size_bytes > this->size_bytes) {
|
| 763 |
+
throw std::runtime_error("GlBufferData: Trying to upload past capacity.");
|
| 764 |
+
}
|
| 765 |
+
|
| 766 |
+
Bind();
|
| 767 |
+
glBufferSubData(buffer_type,offset,size_bytes,data);
|
| 768 |
+
Unbind();
|
| 769 |
+
}
|
| 770 |
+
|
| 771 |
+
inline void GlBufferData::Download(GLvoid* data, GLsizeiptr size_bytes, GLintptr offset) const
|
| 772 |
+
{
|
| 773 |
+
Bind();
|
| 774 |
+
glGetBufferSubData(buffer_type, offset, size_bytes, data);
|
| 775 |
+
Unbind();
|
| 776 |
+
}
|
| 777 |
+
|
| 778 |
+
template<typename T>
|
| 779 |
+
inline void GlBufferData::Upload(const std::vector<T>& data, GLintptr offset)
|
| 780 |
+
{
|
| 781 |
+
const size_t total_bytes = data.size() * sizeof(T);
|
| 782 |
+
assert(offset + total_bytes <= size_bytes);
|
| 783 |
+
Upload(&data[0], total_bytes, offset);
|
| 784 |
+
}
|
| 785 |
+
|
| 786 |
+
#ifdef USE_EIGEN
|
| 787 |
+
template<typename Derived>
|
| 788 |
+
inline void GlBufferData::Upload(const Eigen::DenseBase<Derived>& data, GLintptr offset)
|
| 789 |
+
{
|
| 790 |
+
const size_t num_elements = data.outerSize();
|
| 791 |
+
const size_t matrix_bytes = data.outerStride() * num_elements;
|
| 792 |
+
assert(offset + matrix_bytes <= size_bytes);
|
| 793 |
+
Upload(data.data(), matrix_bytes, offset);
|
| 794 |
+
}
|
| 795 |
+
#endif
|
| 796 |
+
|
| 797 |
+
////////////////////////////////////////////////////////////////////////////
|
| 798 |
+
|
| 799 |
+
inline GlBuffer::GlBuffer()
|
| 800 |
+
: GlBufferData(), datatype(0), num_elements(0), count_per_element(0)
|
| 801 |
+
{
|
| 802 |
+
}
|
| 803 |
+
|
| 804 |
+
inline GlBuffer::GlBuffer(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse )
|
| 805 |
+
: GlBufferData(buffer_type, GLuint(num_elements * count_per_element * GlDataTypeBytes(datatype)), gluse),
|
| 806 |
+
datatype(datatype), num_elements(num_elements), count_per_element(count_per_element)
|
| 807 |
+
{
|
| 808 |
+
}
|
| 809 |
+
|
| 810 |
+
|
| 811 |
+
inline GlBuffer::GlBuffer(GlBuffer&& o)
|
| 812 |
+
: GlBufferData()
|
| 813 |
+
{
|
| 814 |
+
*this = std::move(o);
|
| 815 |
+
}
|
| 816 |
+
|
| 817 |
+
inline GlBuffer& GlBuffer::operator=(GlBuffer&& o)
|
| 818 |
+
{
|
| 819 |
+
datatype = o.datatype;
|
| 820 |
+
num_elements = o.num_elements;
|
| 821 |
+
count_per_element = o.count_per_element;
|
| 822 |
+
GlBufferData::operator =(std::move(o));
|
| 823 |
+
return *this;
|
| 824 |
+
}
|
| 825 |
+
|
| 826 |
+
inline void GlBuffer::Reinitialise(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse, const void *data )
|
| 827 |
+
{
|
| 828 |
+
this->datatype = datatype;
|
| 829 |
+
this->num_elements = num_elements;
|
| 830 |
+
this->count_per_element = count_per_element;
|
| 831 |
+
const GLuint size_bytes = GLuint(num_elements * count_per_element * GlDataTypeBytes(datatype));
|
| 832 |
+
GlBufferData::Reinitialise(buffer_type, size_bytes, gluse, data);
|
| 833 |
+
}
|
| 834 |
+
|
| 835 |
+
inline void GlBuffer::Reinitialise(GlBuffer const& other )
|
| 836 |
+
{
|
| 837 |
+
Reinitialise(other.buffer_type, other.num_elements, other.datatype, other.count_per_element, other.gluse);
|
| 838 |
+
}
|
| 839 |
+
|
| 840 |
+
inline void GlBuffer::Resize(GLuint new_num_elements)
|
| 841 |
+
{
|
| 842 |
+
if(bo!=0 && num_elements > 0) {
|
| 843 |
+
#ifndef HAVE_GLES
|
| 844 |
+
// Backup current data, reinit memory, restore old data
|
| 845 |
+
const size_t backup_elements = std::min(new_num_elements,num_elements);
|
| 846 |
+
const size_t backup_size_bytes = backup_elements*GlDataTypeBytes(datatype)*count_per_element;
|
| 847 |
+
unsigned char* backup = new unsigned char[backup_size_bytes];
|
| 848 |
+
Bind();
|
| 849 |
+
glGetBufferSubData(buffer_type, 0, backup_size_bytes, backup);
|
| 850 |
+
glBufferData(buffer_type, new_num_elements*GlDataTypeBytes(datatype)*count_per_element, 0, gluse);
|
| 851 |
+
glBufferSubData(buffer_type, 0, backup_size_bytes, backup);
|
| 852 |
+
Unbind();
|
| 853 |
+
delete[] backup;
|
| 854 |
+
#else
|
| 855 |
+
throw std::exception();
|
| 856 |
+
#endif
|
| 857 |
+
}else{
|
| 858 |
+
Reinitialise(buffer_type, new_num_elements, datatype, count_per_element, gluse);
|
| 859 |
+
}
|
| 860 |
+
num_elements = new_num_elements;
|
| 861 |
+
}
|
| 862 |
+
|
| 863 |
+
#ifdef USE_EIGEN
|
| 864 |
+
template<typename Scalar, int R, int C>
|
| 865 |
+
GlBuffer::GlBuffer(GlBufferType buffer_type, const std::vector<Eigen::Matrix<Scalar, R,C>>& data, GLenum gluse)
|
| 866 |
+
: GlBufferData(buffer_type, data, gluse)
|
| 867 |
+
{
|
| 868 |
+
typedef typename Eigen::Matrix<Scalar, R,C> Element;
|
| 869 |
+
static_assert( Element::SizeAtCompileTime != Eigen::Dynamic, "No Dynamically sized elements.");
|
| 870 |
+
static_assert( Element::SizeAtCompileTime * sizeof(Scalar) == sizeof(Element), "No padded elements.");
|
| 871 |
+
|
| 872 |
+
datatype = pangolin::GlFormatTraits<Scalar>::gltype;
|
| 873 |
+
num_elements = data.size();
|
| 874 |
+
count_per_element = Element::SizeAtCompileTime;
|
| 875 |
+
}
|
| 876 |
+
#endif
|
| 877 |
+
|
| 878 |
+
////////////////////////////////////////////////////////////////////////////
|
| 879 |
+
|
| 880 |
+
inline GlSizeableBuffer::GlSizeableBuffer(GlBufferType buffer_type, GLuint initial_num_elements, GLenum datatype, GLuint count_per_element, GLenum gluse )
|
| 881 |
+
: GlBuffer(buffer_type, initial_num_elements, datatype, count_per_element, gluse), m_num_verts(0)
|
| 882 |
+
{
|
| 883 |
+
|
| 884 |
+
}
|
| 885 |
+
|
| 886 |
+
inline void GlSizeableBuffer::Clear()
|
| 887 |
+
{
|
| 888 |
+
m_num_verts = 0;
|
| 889 |
+
}
|
| 890 |
+
|
| 891 |
+
#ifdef USE_EIGEN
|
| 892 |
+
template<typename Derived> inline
|
| 893 |
+
void GlSizeableBuffer::Add(const Eigen::DenseBase<Derived>& vec)
|
| 894 |
+
{
|
| 895 |
+
typedef typename Eigen::DenseBase<Derived>::Scalar Scalar;
|
| 896 |
+
assert(vec.rows()==GlBuffer::count_per_element);
|
| 897 |
+
CheckResize(m_num_verts + 1);
|
| 898 |
+
// TODO: taking address of first element is really dodgey. Need to work out
|
| 899 |
+
// when this is okay!
|
| 900 |
+
Upload(&vec(0,0), sizeof(Scalar)*vec.rows()*vec.cols(), sizeof(Scalar)*vec.rows()*m_num_verts);
|
| 901 |
+
m_num_verts += vec.cols();
|
| 902 |
+
}
|
| 903 |
+
|
| 904 |
+
template<typename Derived> inline
|
| 905 |
+
void GlSizeableBuffer::Update(const Eigen::DenseBase<Derived>& vec, size_t position )
|
| 906 |
+
{
|
| 907 |
+
typedef typename Eigen::DenseBase<Derived>::Scalar Scalar;
|
| 908 |
+
assert(vec.rows()==GlBuffer::count_per_element);
|
| 909 |
+
CheckResize(position + vec.cols() );
|
| 910 |
+
// TODO: taking address of first element is really dodgey. Need to work out
|
| 911 |
+
// when this is okay!
|
| 912 |
+
Upload(&vec(0,0), sizeof(Scalar)*vec.rows()*vec.cols(), sizeof(Scalar)*vec.rows()*position );
|
| 913 |
+
m_num_verts = std::max(position+vec.cols(), m_num_verts);
|
| 914 |
+
}
|
| 915 |
+
#endif
|
| 916 |
+
|
| 917 |
+
inline size_t GlSizeableBuffer::start() const {
|
| 918 |
+
return 0;
|
| 919 |
+
}
|
| 920 |
+
|
| 921 |
+
inline size_t GlSizeableBuffer::size() const {
|
| 922 |
+
return m_num_verts;
|
| 923 |
+
}
|
| 924 |
+
|
| 925 |
+
inline void GlSizeableBuffer::CheckResize(size_t num_verts)
|
| 926 |
+
{
|
| 927 |
+
if( num_verts > GlBuffer::num_elements) {
|
| 928 |
+
const size_t new_size = NextSize(num_verts);
|
| 929 |
+
GlBuffer::Resize((GLuint)new_size);
|
| 930 |
+
}
|
| 931 |
+
}
|
| 932 |
+
|
| 933 |
+
inline size_t GlSizeableBuffer::NextSize(size_t min_size) const
|
| 934 |
+
{
|
| 935 |
+
size_t new_size = std::max(GlBuffer::num_elements, 1u);
|
| 936 |
+
while(new_size < min_size) {
|
| 937 |
+
new_size *= 2;
|
| 938 |
+
}
|
| 939 |
+
return new_size;
|
| 940 |
+
}
|
| 941 |
+
|
| 942 |
+
////////////////////////////////////////////////////////////////////////////
|
| 943 |
+
|
| 944 |
+
inline TypedImage ReadFramebuffer(const Viewport& v, const std::string& pixel_format)
|
| 945 |
+
{
|
| 946 |
+
const PixelFormat fmt = PixelFormatFromString(pixel_format);
|
| 947 |
+
const GlPixFormat glfmt(fmt);
|
| 948 |
+
|
| 949 |
+
TypedImage buffer(v.w, v.h, fmt );
|
| 950 |
+
glReadBuffer(GL_BACK);
|
| 951 |
+
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
| 952 |
+
glReadPixels(v.l, v.b, v.w, v.h, glfmt.glformat, glfmt.gltype, buffer.ptr );
|
| 953 |
+
return buffer;
|
| 954 |
+
}
|
| 955 |
+
|
| 956 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glchar.h
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2013 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/gl/glplatform.h>
|
| 31 |
+
#include <map>
|
| 32 |
+
|
| 33 |
+
namespace pangolin {
|
| 34 |
+
|
| 35 |
+
struct PANGOLIN_EXPORT XYUV
|
| 36 |
+
{
|
| 37 |
+
XYUV() {}
|
| 38 |
+
XYUV(GLfloat x, GLfloat y, GLfloat tu, GLfloat tv)
|
| 39 |
+
: x(x), y(y), tu(tu), tv(tv) {}
|
| 40 |
+
|
| 41 |
+
XYUV operator+(float dx) const {
|
| 42 |
+
return XYUV(x+dx,y,tu,tv);
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
GLfloat x, y, tu, tv;
|
| 46 |
+
};
|
| 47 |
+
|
| 48 |
+
class PANGOLIN_EXPORT GlChar
|
| 49 |
+
{
|
| 50 |
+
public:
|
| 51 |
+
GlChar();
|
| 52 |
+
GlChar(int tw, int th, int x, int y, int w, int h, GLfloat x_step, GLfloat ox, GLfloat oy);
|
| 53 |
+
|
| 54 |
+
inline const XYUV& GetVert(size_t i) const {
|
| 55 |
+
return vs[i];
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
inline GLfloat StepX() const {
|
| 59 |
+
return x_step;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
inline GLfloat YMin() const {
|
| 63 |
+
return y_min;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
inline GLfloat YMax() const {
|
| 67 |
+
return y_max;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
void Draw() const;
|
| 71 |
+
|
| 72 |
+
protected:
|
| 73 |
+
XYUV vs[4];
|
| 74 |
+
GLfloat x_step;
|
| 75 |
+
GLfloat y_min, y_max;
|
| 76 |
+
};
|
| 77 |
+
|
| 78 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glcuda.h
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <algorithm>
|
| 31 |
+
#include <cuda_runtime.h>
|
| 32 |
+
|
| 33 |
+
#include "gl.h"
|
| 34 |
+
// Must include glew.h before gl.h
|
| 35 |
+
#include <cuda_gl_interop.h>
|
| 36 |
+
|
| 37 |
+
namespace pangolin
|
| 38 |
+
{
|
| 39 |
+
|
| 40 |
+
////////////////////////////////////////////////
|
| 41 |
+
// Interface
|
| 42 |
+
////////////////////////////////////////////////
|
| 43 |
+
|
| 44 |
+
struct GlBufferCudaPtr : public GlBuffer
|
| 45 |
+
{
|
| 46 |
+
//! Default constructor represents 'no buffer'
|
| 47 |
+
GlBufferCudaPtr();
|
| 48 |
+
|
| 49 |
+
GlBufferCudaPtr(GlBufferType buffer_type, GLuint size_bytes, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ );
|
| 50 |
+
GlBufferCudaPtr(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ );
|
| 51 |
+
|
| 52 |
+
PANGOLIN_DEPRECATED("Please use GlBufferCudaPtr(buffer_type, width*height, datatype,...) instead")
|
| 53 |
+
GlBufferCudaPtr(GlBufferType buffer_type, GLuint width, GLuint height, GLenum datatype, GLuint count_per_element, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ );
|
| 54 |
+
|
| 55 |
+
~GlBufferCudaPtr();
|
| 56 |
+
|
| 57 |
+
void Reinitialise(GlBufferType buffer_type, GLuint size_bytes, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ );
|
| 58 |
+
void Reinitialise(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ );
|
| 59 |
+
|
| 60 |
+
/**
|
| 61 |
+
* Use parameters from another @c GlBufferCudaPtr to initialize this buffer.
|
| 62 |
+
*/
|
| 63 |
+
void Reinitialise(const GlBufferCudaPtr& other);
|
| 64 |
+
|
| 65 |
+
unsigned int cuda_use;
|
| 66 |
+
cudaGraphicsResource* cuda_res;
|
| 67 |
+
};
|
| 68 |
+
|
| 69 |
+
struct GlTextureCudaArray : GlTexture
|
| 70 |
+
{
|
| 71 |
+
GlTextureCudaArray();
|
| 72 |
+
// Some internal_formats aren't accepted. I have trouble with GL_RGB8
|
| 73 |
+
GlTextureCudaArray(int width, int height, GLint internal_format, bool sampling_linear = true, int border = 0, GLenum glformat = GL_RGBA, GLenum gltype = GL_UNSIGNED_BYTE, GLvoid* data = NULL);
|
| 74 |
+
~GlTextureCudaArray();
|
| 75 |
+
|
| 76 |
+
void Reinitialise(int width, int height, GLint internal_format, bool sampling_linear = true, int border = 0, GLenum glformat = GL_RGBA, GLenum gltype = GL_UNSIGNED_BYTE, GLvoid* data = NULL) override;
|
| 77 |
+
cudaGraphicsResource* cuda_res;
|
| 78 |
+
};
|
| 79 |
+
|
| 80 |
+
struct CudaScopedMappedPtr
|
| 81 |
+
{
|
| 82 |
+
CudaScopedMappedPtr(const GlBufferCudaPtr& buffer);
|
| 83 |
+
~CudaScopedMappedPtr();
|
| 84 |
+
void* operator*();
|
| 85 |
+
cudaGraphicsResource* res;
|
| 86 |
+
|
| 87 |
+
private:
|
| 88 |
+
CudaScopedMappedPtr(const CudaScopedMappedPtr&) {}
|
| 89 |
+
};
|
| 90 |
+
|
| 91 |
+
struct CudaScopedMappedArray
|
| 92 |
+
{
|
| 93 |
+
CudaScopedMappedArray(const GlTextureCudaArray& tex);
|
| 94 |
+
~CudaScopedMappedArray();
|
| 95 |
+
cudaArray* operator*();
|
| 96 |
+
cudaGraphicsResource* res;
|
| 97 |
+
|
| 98 |
+
private:
|
| 99 |
+
CudaScopedMappedArray(const CudaScopedMappedArray&) {}
|
| 100 |
+
};
|
| 101 |
+
|
| 102 |
+
void CopyPboToTex(GlBufferCudaPtr& buffer, GlTexture& tex);
|
| 103 |
+
|
| 104 |
+
void swap(GlBufferCudaPtr& a, GlBufferCudaPtr& b);
|
| 105 |
+
|
| 106 |
+
////////////////////////////////////////////////
|
| 107 |
+
// Implementation
|
| 108 |
+
////////////////////////////////////////////////
|
| 109 |
+
|
| 110 |
+
inline GlBufferCudaPtr::GlBufferCudaPtr()
|
| 111 |
+
: cuda_res(0)
|
| 112 |
+
{
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
inline GlBufferCudaPtr::GlBufferCudaPtr(GlBufferType buffer_type, GLuint size_bytes, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ )
|
| 116 |
+
: cuda_res(0)
|
| 117 |
+
{
|
| 118 |
+
Reinitialise(buffer_type, size_bytes, cudause, gluse);
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
inline GlBufferCudaPtr::GlBufferCudaPtr(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, unsigned int cudause, GLenum gluse )
|
| 122 |
+
: cuda_res(0)
|
| 123 |
+
{
|
| 124 |
+
Reinitialise(buffer_type, num_elements, datatype, count_per_element, cudause, gluse);
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
inline GlBufferCudaPtr::GlBufferCudaPtr(GlBufferType buffer_type, GLuint width, GLuint height, GLenum datatype, GLuint count_per_element, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ )
|
| 128 |
+
: cuda_res(0)
|
| 129 |
+
{
|
| 130 |
+
Reinitialise(buffer_type, width*height, datatype, count_per_element, cudause, gluse);
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
inline GlBufferCudaPtr::~GlBufferCudaPtr()
|
| 134 |
+
{
|
| 135 |
+
if(cuda_res) {
|
| 136 |
+
cudaGraphicsUnregisterResource(cuda_res);
|
| 137 |
+
}
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
inline void GlBufferCudaPtr::Reinitialise(GlBufferType buffer_type, GLuint size_bytes, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ )
|
| 141 |
+
{
|
| 142 |
+
GlBufferCudaPtr::Reinitialise(buffer_type, size_bytes, GL_BYTE, 1, cudause, gluse);
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
inline void GlBufferCudaPtr::Reinitialise(GlBufferType buffer_type, GLuint num_elements, GLenum datatype, GLuint count_per_element, unsigned int cudause /*= cudaGraphicsMapFlagsNone*/, GLenum gluse /*= GL_DYNAMIC_DRAW*/ )
|
| 146 |
+
{
|
| 147 |
+
if(cuda_res) {
|
| 148 |
+
cudaGraphicsUnregisterResource(cuda_res);
|
| 149 |
+
}
|
| 150 |
+
GlBuffer::Reinitialise(buffer_type, num_elements, datatype, count_per_element, gluse);
|
| 151 |
+
|
| 152 |
+
cuda_use = cudause;
|
| 153 |
+
cudaGraphicsGLRegisterBuffer( &cuda_res, bo, cudause );
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
inline void GlBufferCudaPtr::Reinitialise(const GlBufferCudaPtr& other)
|
| 157 |
+
{
|
| 158 |
+
Reinitialise(other.buffer_type, other.num_elements, other.datatype, other.count_per_element, other.cuda_use, other.gluse);
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
inline GlTextureCudaArray::GlTextureCudaArray()
|
| 162 |
+
: GlTexture(), cuda_res(0)
|
| 163 |
+
{
|
| 164 |
+
// Not a texture
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
inline GlTextureCudaArray::GlTextureCudaArray(int width, int height, GLint internal_format, bool sampling_linear, int border, GLenum glformat, GLenum gltype, GLvoid *data)
|
| 168 |
+
:GlTexture(width,height,internal_format, sampling_linear, border, glformat, gltype, data)
|
| 169 |
+
{
|
| 170 |
+
// TODO: specify flags too
|
| 171 |
+
const cudaError_t err = cudaGraphicsGLRegisterImage(&cuda_res, tid, GL_TEXTURE_2D, cudaGraphicsMapFlagsNone);
|
| 172 |
+
if( err != cudaSuccess ) {
|
| 173 |
+
std::cout << "cudaGraphicsGLRegisterImage failed: " << err << std::endl;
|
| 174 |
+
}
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
inline GlTextureCudaArray::~GlTextureCudaArray()
|
| 178 |
+
{
|
| 179 |
+
if(cuda_res) {
|
| 180 |
+
cudaGraphicsUnregisterResource(cuda_res);
|
| 181 |
+
}
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
inline void GlTextureCudaArray::Reinitialise(int width, int height, GLint internal_format, bool sampling_linear, int border, GLenum glformat, GLenum gltype, GLvoid* data)
|
| 185 |
+
{
|
| 186 |
+
if(cuda_res) {
|
| 187 |
+
cudaGraphicsUnregisterResource(cuda_res);
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
GlTexture::Reinitialise(width, height, internal_format, sampling_linear, border, glformat, gltype, data);
|
| 191 |
+
|
| 192 |
+
const cudaError_t err = cudaGraphicsGLRegisterImage(&cuda_res, tid, GL_TEXTURE_2D, cudaGraphicsMapFlagsNone);
|
| 193 |
+
if( err != cudaSuccess ) {
|
| 194 |
+
std::cout << "cudaGraphicsGLRegisterImage failed: " << err << std::endl;
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
inline CudaScopedMappedPtr::CudaScopedMappedPtr(const GlBufferCudaPtr& buffer)
|
| 199 |
+
: res(buffer.cuda_res)
|
| 200 |
+
{
|
| 201 |
+
cudaGraphicsMapResources(1, &res, 0);
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
inline CudaScopedMappedPtr::~CudaScopedMappedPtr()
|
| 205 |
+
{
|
| 206 |
+
cudaGraphicsUnmapResources(1, &res, 0);
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
inline void* CudaScopedMappedPtr::operator*()
|
| 210 |
+
{
|
| 211 |
+
size_t num_bytes;
|
| 212 |
+
void* d_ptr;
|
| 213 |
+
cudaGraphicsResourceGetMappedPointer(&d_ptr,&num_bytes,res);
|
| 214 |
+
return d_ptr;
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
inline CudaScopedMappedArray::CudaScopedMappedArray(const GlTextureCudaArray& tex)
|
| 218 |
+
: res(tex.cuda_res)
|
| 219 |
+
{
|
| 220 |
+
cudaGraphicsMapResources(1, &res);
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
inline CudaScopedMappedArray::~CudaScopedMappedArray()
|
| 224 |
+
{
|
| 225 |
+
cudaGraphicsUnmapResources(1, &res);
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
inline cudaArray* CudaScopedMappedArray::operator*()
|
| 229 |
+
{
|
| 230 |
+
cudaArray* array;
|
| 231 |
+
cudaGraphicsSubResourceGetMappedArray(&array, res, 0, 0);
|
| 232 |
+
return array;
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
inline void CopyPboToTex(const GlBufferCudaPtr& buffer, GlTexture& tex, GLenum buffer_layout, GLenum buffer_data_type )
|
| 236 |
+
{
|
| 237 |
+
buffer.Bind();
|
| 238 |
+
tex.Bind();
|
| 239 |
+
glTexImage2D(GL_TEXTURE_2D, 0, tex.internal_format, tex.width, tex.height, 0, buffer_layout, buffer_data_type, 0);
|
| 240 |
+
buffer.Unbind();
|
| 241 |
+
tex.Unbind();
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
template<typename T>
|
| 245 |
+
inline void CopyDevMemtoTex(T* d_img, size_t pitch, GlTextureCudaArray& tex )
|
| 246 |
+
{
|
| 247 |
+
CudaScopedMappedArray arr_tex(tex);
|
| 248 |
+
cudaMemcpy2DToArray(*arr_tex, 0, 0, d_img, pitch, tex.width*sizeof(T), tex.height, cudaMemcpyDeviceToDevice );
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
inline void swap(GlBufferCudaPtr& a, GlBufferCudaPtr& b)
|
| 252 |
+
{
|
| 253 |
+
std::swap(a.bo, b.bo);
|
| 254 |
+
std::swap(a.cuda_res, b.cuda_res);
|
| 255 |
+
std::swap(a.buffer_type, b.buffer_type);
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
|
| 259 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gldraw.h
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/gl/glinclude.h>
|
| 31 |
+
#include <pangolin/gl/glformattraits.h>
|
| 32 |
+
#include <pangolin/gl/opengl_render_state.h>
|
| 33 |
+
|
| 34 |
+
#include <vector>
|
| 35 |
+
#include <math.h>
|
| 36 |
+
|
| 37 |
+
#if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files
|
| 38 |
+
# define USE_EIGEN
|
| 39 |
+
#endif
|
| 40 |
+
|
| 41 |
+
#ifdef USE_EIGEN
|
| 42 |
+
# include <Eigen/Core>
|
| 43 |
+
# include <Eigen/Geometry>
|
| 44 |
+
#endif // USE_EIGEN
|
| 45 |
+
|
| 46 |
+
namespace pangolin
|
| 47 |
+
{
|
| 48 |
+
|
| 49 |
+
// h [0,360)
|
| 50 |
+
// s [0,1]
|
| 51 |
+
// v [0,1]
|
| 52 |
+
inline void glColorHSV( GLfloat hue, GLfloat s=1.0f, GLfloat v=1.0f )
|
| 53 |
+
{
|
| 54 |
+
const GLfloat h = hue / 60.0f;
|
| 55 |
+
const int i = (int)floor(h);
|
| 56 |
+
const GLfloat f = (i%2 == 0) ? 1-(h-i) : h-i;
|
| 57 |
+
const GLfloat m = v * (1-s);
|
| 58 |
+
const GLfloat n = v * (1-s*f);
|
| 59 |
+
switch(i)
|
| 60 |
+
{
|
| 61 |
+
case 0: glColor4f(v,n,m,1); break;
|
| 62 |
+
case 1: glColor4f(n,v,m,1); break;
|
| 63 |
+
case 2: glColor4f(m,v,n,1); break;
|
| 64 |
+
case 3: glColor4f(m,n,v,1); break;
|
| 65 |
+
case 4: glColor4f(n,m,v,1); break;
|
| 66 |
+
case 5: glColor4f(v,m,n,1); break;
|
| 67 |
+
default:
|
| 68 |
+
break;
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
inline void glColorBin( int bin, int max_bins, GLfloat sat=1.0f, GLfloat val=1.0f )
|
| 73 |
+
{
|
| 74 |
+
if( bin >= 0 ) {
|
| 75 |
+
const GLfloat hue = (GLfloat)(bin%max_bins) * 360.0f / (GLfloat)max_bins;
|
| 76 |
+
glColorHSV(hue,sat,val);
|
| 77 |
+
}else{
|
| 78 |
+
glColor4f(1,1,1,1);
|
| 79 |
+
}
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
template<typename T>
|
| 83 |
+
inline void glDrawVertices(
|
| 84 |
+
size_t num_vertices, const T* const vertex_ptr, GLenum mode,
|
| 85 |
+
size_t elements_per_vertex = GlFormatTraits<T>::components,
|
| 86 |
+
size_t vertex_stride_bytes = 0 )
|
| 87 |
+
{
|
| 88 |
+
if(num_vertices > 0)
|
| 89 |
+
{
|
| 90 |
+
PANGO_ENSURE(vertex_ptr != nullptr);
|
| 91 |
+
PANGO_ENSURE(mode != GL_LINES || num_vertices % 2 == 0, "number of vertices (%) must be even in GL_LINES mode", num_vertices );
|
| 92 |
+
|
| 93 |
+
glVertexPointer((GLint)elements_per_vertex, GlFormatTraits<T>::gltype, (GLsizei)vertex_stride_bytes, vertex_ptr);
|
| 94 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
| 95 |
+
glDrawArrays(mode, 0, (GLsizei)num_vertices);
|
| 96 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
| 97 |
+
}
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
template<typename TV, typename TC>
|
| 101 |
+
inline void glDrawColoredVertices(
|
| 102 |
+
size_t num_vertices, const TV* const vertex_ptr, const TC* const color_ptr, GLenum mode,
|
| 103 |
+
size_t elements_per_vertex = GlFormatTraits<TV>::components,
|
| 104 |
+
size_t elements_per_color = GlFormatTraits<TC>::components,
|
| 105 |
+
size_t vertex_stride_bytes = 0,
|
| 106 |
+
size_t color_stride_bytes = 0
|
| 107 |
+
) {
|
| 108 |
+
if(color_ptr) {
|
| 109 |
+
glColorPointer((GLint)elements_per_color, GlFormatTraits<TC>::gltype, (GLsizei)color_stride_bytes, color_ptr);
|
| 110 |
+
glEnableClientState(GL_COLOR_ARRAY);
|
| 111 |
+
glDrawVertices<TV>(num_vertices, vertex_ptr, mode, elements_per_vertex, vertex_stride_bytes);
|
| 112 |
+
glDisableClientState(GL_COLOR_ARRAY);
|
| 113 |
+
}else{
|
| 114 |
+
glDrawVertices<TV>(num_vertices, vertex_ptr, mode, elements_per_vertex, vertex_stride_bytes);
|
| 115 |
+
}
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
inline void glDrawLine( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
|
| 119 |
+
{
|
| 120 |
+
const GLfloat verts[] = { x1,y1, x2,y2 };
|
| 121 |
+
glDrawVertices<float>(2, verts, GL_LINES, 2);
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
inline void glDrawLine( GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2)
|
| 125 |
+
{
|
| 126 |
+
const GLfloat verts[] = { x1,y1,z1, x2,y2,z2 };
|
| 127 |
+
glDrawVertices<float>(2, verts, GL_LINES, 3);
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
inline void glDrawCross( GLfloat x, GLfloat y, GLfloat rad )
|
| 131 |
+
{
|
| 132 |
+
const GLfloat verts[] = { x-rad,y, x+rad, y, x,y-rad, x, y+rad};
|
| 133 |
+
glDrawVertices<float>(4, verts, GL_LINES, 2);
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
inline void glDrawCross( GLfloat x, GLfloat y, GLfloat z, GLfloat rad )
|
| 137 |
+
{
|
| 138 |
+
const GLfloat verts[] = { x-rad,y,z, x+rad,y,z, x,y-rad,z, x,y+rad,z, x,y,z-rad, x,y,z+rad };
|
| 139 |
+
glDrawVertices<float>(6, verts, GL_LINES, 3);
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
inline void glDrawAxis(float s)
|
| 143 |
+
{
|
| 144 |
+
const GLfloat cols[] = { 1,0,0, 1,0,0, 0,1,0, 0,1,0, 0,0,1, 0,0,1 };
|
| 145 |
+
const GLfloat verts[] = { 0,0,0, s,0,0, 0,0,0, 0,s,0, 0,0,0, 0,0,s };
|
| 146 |
+
glDrawColoredVertices<float,float>(6, verts, cols, GL_LINES, 3, 3);
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
inline void glDrawRect( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLenum mode = GL_TRIANGLE_FAN )
|
| 150 |
+
{
|
| 151 |
+
const GLfloat verts[] = { x1,y1, x2,y1, x2,y2, x1,y2 };
|
| 152 |
+
glDrawVertices<float>(4, verts, mode, 2);
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
inline void glDrawRectPerimeter( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
|
| 156 |
+
{
|
| 157 |
+
glDrawRect(x1,y1, x2,y2, GL_LINE_LOOP);
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
inline void glDrawCirclePerimeter( float x, float y, float rad )
|
| 161 |
+
{
|
| 162 |
+
const int N = 50;
|
| 163 |
+
GLfloat verts[N*2];
|
| 164 |
+
|
| 165 |
+
const float TAU_DIV_N = 2*(float)M_PI/N;
|
| 166 |
+
for(int i = 0; i < N*2; i+=2) {
|
| 167 |
+
verts[i] = x + rad * cos(i*TAU_DIV_N);
|
| 168 |
+
verts[i+1] = y + rad * sin(i*TAU_DIV_N);
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
glDrawVertices<float>(N, verts, GL_LINES, 2);
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
inline void glDrawCircle( GLfloat x, GLfloat y, GLfloat rad )
|
| 175 |
+
{
|
| 176 |
+
const int N = 50;
|
| 177 |
+
GLfloat verts[N*2];
|
| 178 |
+
|
| 179 |
+
// Draw vertices anticlockwise for front face
|
| 180 |
+
const float TAU_DIV_N = 2*(float)M_PI/N;
|
| 181 |
+
for(int i = 0; i < N*2; i+=2) {
|
| 182 |
+
verts[i] = x + rad * cos(-i*TAU_DIV_N);
|
| 183 |
+
verts[i+1] = y + rad * sin(-i*TAU_DIV_N);
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
// Render filled shape and outline (to make it look smooth)
|
| 187 |
+
glVertexPointer(2, GL_FLOAT, 0, verts);
|
| 188 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
| 189 |
+
glDrawArrays(GL_TRIANGLE_FAN, 0, N);
|
| 190 |
+
glDrawArrays(GL_LINE_STRIP, 0, N);
|
| 191 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
inline void glDrawColouredCube(GLfloat axis_min=-0.5f, GLfloat axis_max = +0.5f)
|
| 195 |
+
{
|
| 196 |
+
const GLfloat l = axis_min;
|
| 197 |
+
const GLfloat h = axis_max;
|
| 198 |
+
|
| 199 |
+
const GLfloat verts[] = {
|
| 200 |
+
l,l,h, h,l,h, l,h,h, h,h,h, // FRONT
|
| 201 |
+
l,l,l, l,h,l, h,l,l, h,h,l, // BACK
|
| 202 |
+
l,l,h, l,h,h, l,l,l, l,h,l, // LEFT
|
| 203 |
+
h,l,l, h,h,l, h,l,h, h,h,h, // RIGHT
|
| 204 |
+
l,h,h, h,h,h, l,h,l, h,h,l, // TOP
|
| 205 |
+
l,l,h, l,l,l, h,l,h, h,l,l // BOTTOM
|
| 206 |
+
};
|
| 207 |
+
|
| 208 |
+
glVertexPointer(3, GL_FLOAT, 0, verts);
|
| 209 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
| 210 |
+
|
| 211 |
+
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
| 212 |
+
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
| 213 |
+
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
|
| 214 |
+
|
| 215 |
+
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
| 216 |
+
glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
|
| 217 |
+
glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
|
| 218 |
+
|
| 219 |
+
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
| 220 |
+
glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);
|
| 221 |
+
glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);
|
| 222 |
+
|
| 223 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
inline void glDraw_x0(GLfloat scale, int grid)
|
| 227 |
+
{
|
| 228 |
+
const GLfloat maxord = grid*scale;
|
| 229 |
+
for (int i = -grid; i <= grid; ++i) {
|
| 230 |
+
glDrawLine(0.0, i*scale, -maxord, 0.0, i*scale, +maxord);
|
| 231 |
+
glDrawLine(0.0, -maxord, i*scale, 0.0, +maxord, i*scale);
|
| 232 |
+
}
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
inline void glDraw_y0(GLfloat scale, int grid)
|
| 236 |
+
{
|
| 237 |
+
const GLfloat maxord = grid*scale;
|
| 238 |
+
for (int i = -grid; i <= grid; ++i) {
|
| 239 |
+
glDrawLine(i*scale, 0.0, -maxord, i*scale, 0.0, +maxord);
|
| 240 |
+
glDrawLine(-maxord, 0.0, i*scale, +maxord, 0.0, i*scale);
|
| 241 |
+
}
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
inline void glDraw_z0(GLfloat scale, int grid)
|
| 245 |
+
{
|
| 246 |
+
const GLfloat maxord = grid*scale;
|
| 247 |
+
for(int i=-grid; i<=grid; ++i ) {
|
| 248 |
+
glDrawLine(i*scale,-maxord, i*scale,+maxord);
|
| 249 |
+
glDrawLine(-maxord, i*scale, +maxord, i*scale);
|
| 250 |
+
}
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
inline void glDrawFrustum( GLfloat u0, GLfloat v0, GLfloat fu, GLfloat fv, int w, int h, GLfloat scale )
|
| 254 |
+
{
|
| 255 |
+
const GLfloat xl = scale * u0;
|
| 256 |
+
const GLfloat xh = scale * (w*fu + u0);
|
| 257 |
+
const GLfloat yl = scale * v0;
|
| 258 |
+
const GLfloat yh = scale * (h*fv + v0);
|
| 259 |
+
|
| 260 |
+
const GLfloat verts[] = {
|
| 261 |
+
xl,yl,scale, xh,yl,scale,
|
| 262 |
+
xh,yh,scale, xl,yh,scale,
|
| 263 |
+
xl,yl,scale, 0,0,0,
|
| 264 |
+
xh,yl,scale, 0,0,0,
|
| 265 |
+
xl,yh,scale, 0,0,0,
|
| 266 |
+
xh,yh,scale
|
| 267 |
+
};
|
| 268 |
+
|
| 269 |
+
glDrawVertices(11, verts, GL_LINE_STRIP, 3);
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
inline void glDrawTexture(GLenum target, GLuint texid)
|
| 273 |
+
{
|
| 274 |
+
glBindTexture(target, texid);
|
| 275 |
+
glEnable(target);
|
| 276 |
+
|
| 277 |
+
const GLfloat sq_vert[] = { -1,-1, 1,-1, 1, 1, -1, 1 };
|
| 278 |
+
glVertexPointer(2, GL_FLOAT, 0, sq_vert);
|
| 279 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
| 280 |
+
|
| 281 |
+
const GLfloat sq_tex[] = { 0,0, 1,0, 1,1, 0,1 };
|
| 282 |
+
glTexCoordPointer(2, GL_FLOAT, 0, sq_tex);
|
| 283 |
+
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 284 |
+
|
| 285 |
+
glColor4f(1,1,1,1);
|
| 286 |
+
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| 287 |
+
|
| 288 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
| 289 |
+
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 290 |
+
|
| 291 |
+
glDisable(target);
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
inline void glDrawTextureFlipY(GLenum target, GLuint texid)
|
| 295 |
+
{
|
| 296 |
+
glBindTexture(target, texid);
|
| 297 |
+
glEnable(target);
|
| 298 |
+
|
| 299 |
+
const GLfloat sq_vert[] = { -1,-1, 1,-1, 1, 1, -1, 1 };
|
| 300 |
+
glVertexPointer(2, GL_FLOAT, 0, sq_vert);
|
| 301 |
+
glEnableClientState(GL_VERTEX_ARRAY);
|
| 302 |
+
|
| 303 |
+
const GLfloat sq_tex[] = { 0,1, 1,1, 1,0, 0,0 };
|
| 304 |
+
glTexCoordPointer(2, GL_FLOAT, 0, sq_tex);
|
| 305 |
+
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 306 |
+
|
| 307 |
+
glColor4f(1,1,1,1);
|
| 308 |
+
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
| 309 |
+
|
| 310 |
+
glDisableClientState(GL_VERTEX_ARRAY);
|
| 311 |
+
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
| 312 |
+
|
| 313 |
+
glDisable(target);
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
|
| 317 |
+
#ifdef USE_EIGEN
|
| 318 |
+
|
| 319 |
+
#ifndef HAVE_GLES
|
| 320 |
+
inline void glVertex( const Eigen::Vector3d& p )
|
| 321 |
+
{
|
| 322 |
+
glVertex3dv(p.data());
|
| 323 |
+
}
|
| 324 |
+
#endif
|
| 325 |
+
|
| 326 |
+
inline void glDrawLine( const Eigen::Vector2d& p1, const Eigen::Vector2d& p2 )
|
| 327 |
+
{
|
| 328 |
+
glDrawLine((GLfloat)p1(0), (GLfloat)p1(1), (GLfloat)p2(0), (GLfloat)p2(1));
|
| 329 |
+
}
|
| 330 |
+
|
| 331 |
+
// Draws a vector of 2d or 3d vertices using provided ``mode``.
|
| 332 |
+
//
|
| 333 |
+
// Preconditions:
|
| 334 |
+
// - ``mode`` must be GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP, etc
|
| 335 |
+
// - If ``mode == GL_LINES``, then ``vertices.size()`` must be a multiple of 2.
|
| 336 |
+
//
|
| 337 |
+
template<typename P, int N, class Allocator>
|
| 338 |
+
void glDrawVertices(const std::vector<Eigen::Matrix<P, N, 1>, Allocator>& vertices, GLenum mode)
|
| 339 |
+
{
|
| 340 |
+
glDrawVertices(vertices.size(), vertices.data(), mode);
|
| 341 |
+
}
|
| 342 |
+
|
| 343 |
+
// Draws a vector of 2d or 3d points.
|
| 344 |
+
//
|
| 345 |
+
template<typename P, int N, class Allocator>
|
| 346 |
+
void glDrawPoints(const std::vector<Eigen::Matrix<P, N, 1>, Allocator>& vertices)
|
| 347 |
+
{
|
| 348 |
+
glDrawVertices(vertices, GL_POINTS);
|
| 349 |
+
}
|
| 350 |
+
|
| 351 |
+
// Draws a vector of 2d or 3d lines.
|
| 352 |
+
//
|
| 353 |
+
// Precondition: ``vertices.size()`` must be a multiple of 2.
|
| 354 |
+
//
|
| 355 |
+
template<typename P, int N, class Allocator>
|
| 356 |
+
void glDrawLines(const std::vector<Eigen::Matrix<P, N, 1>, Allocator>& vertices)
|
| 357 |
+
{
|
| 358 |
+
glDrawVertices(vertices, GL_LINES);
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
// Draws a 2d or 3d line strip.
|
| 362 |
+
//
|
| 363 |
+
template<typename P, int N, class Allocator>
|
| 364 |
+
void glDrawLineStrip(const std::vector<Eigen::Matrix<P, N, 1>, Allocator>& vertices)
|
| 365 |
+
{
|
| 366 |
+
glDrawVertices(vertices, GL_LINE_STRIP);
|
| 367 |
+
}
|
| 368 |
+
|
| 369 |
+
// Draws a 2d or 3d line loop.
|
| 370 |
+
//
|
| 371 |
+
template<typename P, int N, class Allocator>
|
| 372 |
+
void glDrawLineLoop(const std::vector<Eigen::Matrix<P, N, 1>, Allocator>& vertices)
|
| 373 |
+
{
|
| 374 |
+
glDrawVertices(vertices, GL_LINE_LOOP);
|
| 375 |
+
}
|
| 376 |
+
|
| 377 |
+
inline void glDrawCross( const Eigen::Vector2d& p, double r = 5.0 )
|
| 378 |
+
{
|
| 379 |
+
glDrawCross((GLfloat)p(0), (GLfloat)p(1), (GLfloat)r);
|
| 380 |
+
}
|
| 381 |
+
|
| 382 |
+
inline void glDrawCross( const Eigen::Vector3d& p, double r = 5.0 )
|
| 383 |
+
{
|
| 384 |
+
glDrawCross((GLfloat)p(0), (GLfloat)p(1), (GLfloat)p(2), (GLfloat)r);
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
inline void glDrawCircle( const Eigen::Vector2d& p, double radius = 5.0 )
|
| 388 |
+
{
|
| 389 |
+
glDrawCircle((GLfloat)p(0), (GLfloat)p(1), (GLfloat)radius);
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
inline void glDrawCirclePerimeter( const Eigen::Vector2d& p, double radius = 5.0 )
|
| 393 |
+
{
|
| 394 |
+
glDrawCirclePerimeter((GLfloat)p(0), (GLfloat)p(1), (GLfloat)radius);
|
| 395 |
+
}
|
| 396 |
+
|
| 397 |
+
inline void glSetFrameOfReference( const Eigen::Matrix4f& T_wf )
|
| 398 |
+
{
|
| 399 |
+
glMatrixMode(GL_MODELVIEW);
|
| 400 |
+
glPushMatrix();
|
| 401 |
+
glMultMatrixf( T_wf.data() );
|
| 402 |
+
}
|
| 403 |
+
|
| 404 |
+
inline void glSetFrameOfReference( const Eigen::Matrix4d& T_wf )
|
| 405 |
+
{
|
| 406 |
+
glMatrixMode(GL_MODELVIEW);
|
| 407 |
+
glPushMatrix();
|
| 408 |
+
#ifndef HAVE_GLES
|
| 409 |
+
glMultMatrixd( T_wf.data() );
|
| 410 |
+
#else
|
| 411 |
+
const Eigen::Matrix4f fT_wf = T_wf.cast<GLfloat>();
|
| 412 |
+
glMultMatrixf( fT_wf.data() );
|
| 413 |
+
#endif
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
inline void glSetFrameOfReference( const pangolin::OpenGlMatrix& T_wf )
|
| 417 |
+
{
|
| 418 |
+
glMatrixMode(GL_MODELVIEW);
|
| 419 |
+
glPushMatrix();
|
| 420 |
+
glMultMatrixd( T_wf.m );
|
| 421 |
+
}
|
| 422 |
+
|
| 423 |
+
inline void glUnsetFrameOfReference()
|
| 424 |
+
{
|
| 425 |
+
glPopMatrix();
|
| 426 |
+
}
|
| 427 |
+
|
| 428 |
+
template<typename T, typename S>
|
| 429 |
+
inline void glDrawAxis( const T& T_wf, S scale )
|
| 430 |
+
{
|
| 431 |
+
glSetFrameOfReference(T_wf);
|
| 432 |
+
glDrawAxis(scale);
|
| 433 |
+
glUnsetFrameOfReference();
|
| 434 |
+
}
|
| 435 |
+
|
| 436 |
+
template<typename T>
|
| 437 |
+
inline void glDrawFrustum( const Eigen::Matrix<T,3,3>& Kinv, int w, int h, GLfloat scale )
|
| 438 |
+
{
|
| 439 |
+
glDrawFrustum((GLfloat)Kinv(0,2), (GLfloat)Kinv(1,2), (GLfloat)Kinv(0,0), (GLfloat)Kinv(1,1), w, h, scale);
|
| 440 |
+
}
|
| 441 |
+
|
| 442 |
+
template<typename T>
|
| 443 |
+
inline void glDrawFrustum( const Eigen::Matrix<T,3,3>& Kinv, int w, int h, const Eigen::Matrix<T,4,4>& T_wf, T scale )
|
| 444 |
+
{
|
| 445 |
+
glSetFrameOfReference(T_wf);
|
| 446 |
+
glDrawFrustum(Kinv,w,h,scale);
|
| 447 |
+
glUnsetFrameOfReference();
|
| 448 |
+
}
|
| 449 |
+
|
| 450 |
+
template<typename T>
|
| 451 |
+
inline void glDrawAlignedBox( const Eigen::AlignedBox<T,2>& box, GLenum mode = GL_TRIANGLE_FAN )
|
| 452 |
+
{
|
| 453 |
+
const Eigen::Matrix<float,2,1> l = box.min().template cast<float>();
|
| 454 |
+
const Eigen::Matrix<float,2,1> h = box.max().template cast<float>();
|
| 455 |
+
|
| 456 |
+
GLfloat verts[] = {
|
| 457 |
+
l[0], l[1],
|
| 458 |
+
h[0], l[1],
|
| 459 |
+
h[0], h[1],
|
| 460 |
+
l[0], h[1]
|
| 461 |
+
};
|
| 462 |
+
|
| 463 |
+
glDrawVertices(4, verts, mode, 2);
|
| 464 |
+
}
|
| 465 |
+
|
| 466 |
+
template<typename T>
|
| 467 |
+
inline void glDrawAlignedBoxPerimeter( const Eigen::AlignedBox<T,2>& box)
|
| 468 |
+
{
|
| 469 |
+
glDrawAlignedBox<T>(box, GL_LINE_LOOP);
|
| 470 |
+
}
|
| 471 |
+
|
| 472 |
+
template<typename T>
|
| 473 |
+
inline void glDrawAlignedBox( const Eigen::AlignedBox<T,3>& box)
|
| 474 |
+
{
|
| 475 |
+
const Eigen::Matrix<float,3,1> l = box.min().template cast<float>();
|
| 476 |
+
const Eigen::Matrix<float,3,1> h = box.max().template cast<float>();
|
| 477 |
+
|
| 478 |
+
GLfloat verts[] = {
|
| 479 |
+
l[0], l[1], l[2],
|
| 480 |
+
l[0], l[1], h[2],
|
| 481 |
+
h[0], l[1], h[2],
|
| 482 |
+
h[0], l[1], l[2],
|
| 483 |
+
l[0], l[1], l[2],
|
| 484 |
+
l[0], h[1], l[2],
|
| 485 |
+
h[0], h[1], l[2],
|
| 486 |
+
h[0], l[1], l[2],
|
| 487 |
+
h[0], h[1], l[2],
|
| 488 |
+
h[0], h[1], h[2],
|
| 489 |
+
l[0], h[1], h[2],
|
| 490 |
+
l[0], h[1], l[2],
|
| 491 |
+
l[0], h[1], h[2],
|
| 492 |
+
l[0], l[1], h[2],
|
| 493 |
+
h[0], l[1], h[2],
|
| 494 |
+
h[0], h[1], h[2]
|
| 495 |
+
};
|
| 496 |
+
|
| 497 |
+
glDrawVertices(16, verts, GL_LINE_STRIP, 3);
|
| 498 |
+
}
|
| 499 |
+
|
| 500 |
+
#endif // USE_EIGEN
|
| 501 |
+
|
| 502 |
+
#ifndef HAVE_GLES
|
| 503 |
+
inline void glPixelTransferScale( float r, float g, float b )
|
| 504 |
+
{
|
| 505 |
+
glPixelTransferf(GL_RED_SCALE,r);
|
| 506 |
+
glPixelTransferf(GL_GREEN_SCALE,g);
|
| 507 |
+
glPixelTransferf(GL_BLUE_SCALE,b);
|
| 508 |
+
}
|
| 509 |
+
|
| 510 |
+
inline void glPixelTransferScale( float scale )
|
| 511 |
+
{
|
| 512 |
+
glPixelTransferScale(scale,scale,scale);
|
| 513 |
+
}
|
| 514 |
+
#endif
|
| 515 |
+
|
| 516 |
+
void glRecordGraphic(float x, float y, float radius);
|
| 517 |
+
|
| 518 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glfont.h
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2015 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/gl/gltext.h>
|
| 31 |
+
|
| 32 |
+
#include <cstdio>
|
| 33 |
+
#include <cstdarg>
|
| 34 |
+
|
| 35 |
+
namespace pangolin {
|
| 36 |
+
|
| 37 |
+
class PANGOLIN_EXPORT GlFont
|
| 38 |
+
{
|
| 39 |
+
public:
|
| 40 |
+
// Load GL Font data. Delay uploading as texture until first use.
|
| 41 |
+
GlFont(const unsigned char* ttf_buffer, float pixel_height, int tex_w=512, int tex_h=512);
|
| 42 |
+
GlFont(const std::string& filename, float pixel_height, int tex_w=512, int tex_h=512);
|
| 43 |
+
GlFont(float pixel_height, int tex_w=512, int tex_h=512);
|
| 44 |
+
|
| 45 |
+
virtual ~GlFont();
|
| 46 |
+
|
| 47 |
+
// Generate renderable GlText object from this font.
|
| 48 |
+
GlText Text( const char* fmt, ... );
|
| 49 |
+
|
| 50 |
+
GlText Text( const std::string& str );
|
| 51 |
+
|
| 52 |
+
inline float Height() const {
|
| 53 |
+
return font_height_px;
|
| 54 |
+
}
|
| 55 |
+
inline float MaxWidth() const {
|
| 56 |
+
return font_max_width_px;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
protected:
|
| 60 |
+
void InitialiseFont(const unsigned char* ttf_buffer, float pixel_height, int tex_w, int tex_h);
|
| 61 |
+
|
| 62 |
+
// This can only be called once GL context is initialised
|
| 63 |
+
void InitialiseGlTexture();
|
| 64 |
+
|
| 65 |
+
const static int FIRST_CHAR = 32;
|
| 66 |
+
const static int NUM_CHARS = 96;
|
| 67 |
+
|
| 68 |
+
float font_height_px;
|
| 69 |
+
float font_max_width_px;
|
| 70 |
+
|
| 71 |
+
int tex_w;
|
| 72 |
+
int tex_h;
|
| 73 |
+
unsigned char* font_bitmap;
|
| 74 |
+
GlTexture mTex;
|
| 75 |
+
|
| 76 |
+
GlChar chardata[NUM_CHARS];
|
| 77 |
+
GLfloat kern_table[NUM_CHARS*NUM_CHARS];
|
| 78 |
+
};
|
| 79 |
+
|
| 80 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glformattraits.h
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/gl/glplatform.h>
|
| 31 |
+
|
| 32 |
+
#ifdef HAVE_EIGEN
|
| 33 |
+
# include <Eigen/Core>
|
| 34 |
+
#endif
|
| 35 |
+
|
| 36 |
+
namespace pangolin
|
| 37 |
+
{
|
| 38 |
+
|
| 39 |
+
template<typename T>
|
| 40 |
+
struct GlFormatTraits;
|
| 41 |
+
//{
|
| 42 |
+
// static const GLint glinternalformat = 0;
|
| 43 |
+
// static const GLenum glformat = 0;
|
| 44 |
+
// static const GLenum gltype = 0;
|
| 45 |
+
// static const T glmin = 0;
|
| 46 |
+
// static const T glmax = 0;
|
| 47 |
+
//};
|
| 48 |
+
|
| 49 |
+
template<>
|
| 50 |
+
struct GlFormatTraits<unsigned char>
|
| 51 |
+
{
|
| 52 |
+
static const GLint glinternalformat = GL_LUMINANCE8;
|
| 53 |
+
static const GLenum glformat = GL_LUMINANCE;
|
| 54 |
+
static const GLenum gltype = GL_UNSIGNED_BYTE;
|
| 55 |
+
static const size_t components = 1;
|
| 56 |
+
};
|
| 57 |
+
|
| 58 |
+
template<>
|
| 59 |
+
struct GlFormatTraits<unsigned short>
|
| 60 |
+
{
|
| 61 |
+
static const GLint glinternalformat = GL_LUMINANCE16;
|
| 62 |
+
static const GLenum glformat = GL_LUMINANCE;
|
| 63 |
+
static const GLenum gltype = GL_UNSIGNED_SHORT;
|
| 64 |
+
static const size_t components = 1;
|
| 65 |
+
};
|
| 66 |
+
|
| 67 |
+
template<>
|
| 68 |
+
struct GlFormatTraits<unsigned int>
|
| 69 |
+
{
|
| 70 |
+
static const GLint glinternalformat = GL_LUMINANCE32UI_EXT;
|
| 71 |
+
static const GLenum glformat = GL_LUMINANCE_INTEGER_EXT;
|
| 72 |
+
static const GLenum gltype = GL_UNSIGNED_INT;
|
| 73 |
+
static const size_t components = 1;
|
| 74 |
+
};
|
| 75 |
+
|
| 76 |
+
template<>
|
| 77 |
+
struct GlFormatTraits<int>
|
| 78 |
+
{
|
| 79 |
+
static const GLint glinternalformat = GL_LUMINANCE32I_EXT;
|
| 80 |
+
static const GLenum glformat = GL_LUMINANCE_INTEGER_EXT;
|
| 81 |
+
static const GLenum gltype = GL_INT;
|
| 82 |
+
static const size_t components = 1;
|
| 83 |
+
};
|
| 84 |
+
|
| 85 |
+
template<>
|
| 86 |
+
struct GlFormatTraits<float>
|
| 87 |
+
{
|
| 88 |
+
static const GLint glinternalformat = GL_LUMINANCE32F_ARB;
|
| 89 |
+
static const GLenum glformat = GL_LUMINANCE;
|
| 90 |
+
static const GLenum gltype = GL_FLOAT;
|
| 91 |
+
static const size_t components = 1;
|
| 92 |
+
};
|
| 93 |
+
|
| 94 |
+
template<>
|
| 95 |
+
struct GlFormatTraits<double>
|
| 96 |
+
{
|
| 97 |
+
static const GLint glinternalformat = GL_LUMINANCE32F_ARB;
|
| 98 |
+
static const GLenum glformat = GL_LUMINANCE;
|
| 99 |
+
static const GLenum gltype = GL_DOUBLE;
|
| 100 |
+
static const size_t components = 1;
|
| 101 |
+
};
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
#ifdef HAVE_EIGEN
|
| 106 |
+
|
| 107 |
+
//////////////////////////////////////////////////////////////////
|
| 108 |
+
|
| 109 |
+
template <>
|
| 110 |
+
struct GlFormatTraits<Eigen::Matrix<unsigned char,2,1>>
|
| 111 |
+
{
|
| 112 |
+
static const GLint glinternalformat = GL_RG8;
|
| 113 |
+
static const GLenum glformat = GL_RG;
|
| 114 |
+
static const GLenum gltype = GL_UNSIGNED_BYTE;
|
| 115 |
+
static const size_t components = 2;
|
| 116 |
+
};
|
| 117 |
+
|
| 118 |
+
template <>
|
| 119 |
+
struct GlFormatTraits<Eigen::Matrix<unsigned short,2,1>>
|
| 120 |
+
{
|
| 121 |
+
static const GLint glinternalformat = GL_RG16;
|
| 122 |
+
static const GLenum glformat = GL_RG;
|
| 123 |
+
static const GLenum gltype = GL_UNSIGNED_SHORT;
|
| 124 |
+
static const size_t components = 2;
|
| 125 |
+
};
|
| 126 |
+
|
| 127 |
+
template <>
|
| 128 |
+
struct GlFormatTraits<Eigen::Vector2i>
|
| 129 |
+
{
|
| 130 |
+
static const GLint glinternalformat = GL_RG32I;
|
| 131 |
+
static const GLenum glformat = GL_RG;
|
| 132 |
+
static const GLenum gltype = GL_INT;
|
| 133 |
+
static const size_t components = 2;
|
| 134 |
+
};
|
| 135 |
+
|
| 136 |
+
template <>
|
| 137 |
+
struct GlFormatTraits<Eigen::Vector2f>
|
| 138 |
+
{
|
| 139 |
+
static const GLint glinternalformat = GL_RG32F;
|
| 140 |
+
static const GLenum glformat = GL_RG;
|
| 141 |
+
static const GLenum gltype = GL_FLOAT;
|
| 142 |
+
static const size_t components = 2;
|
| 143 |
+
};
|
| 144 |
+
|
| 145 |
+
template <>
|
| 146 |
+
struct GlFormatTraits<Eigen::Vector2d>
|
| 147 |
+
{
|
| 148 |
+
static const GLint glinternalformat = GL_RG32F;
|
| 149 |
+
static const GLenum glformat = GL_RG;
|
| 150 |
+
static const GLenum gltype = GL_DOUBLE;
|
| 151 |
+
static const size_t components = 2;
|
| 152 |
+
};
|
| 153 |
+
|
| 154 |
+
//////////////////////////////////////////////////////////////////
|
| 155 |
+
|
| 156 |
+
template <>
|
| 157 |
+
struct GlFormatTraits<Eigen::Matrix<unsigned char,3,1>>
|
| 158 |
+
{
|
| 159 |
+
static const GLint glinternalformat = GL_RGB8;
|
| 160 |
+
static const GLenum glformat = GL_RGB;
|
| 161 |
+
static const GLenum gltype = GL_UNSIGNED_BYTE;
|
| 162 |
+
static const size_t components = 3;
|
| 163 |
+
};
|
| 164 |
+
|
| 165 |
+
template <>
|
| 166 |
+
struct GlFormatTraits<Eigen::Matrix<unsigned short,3,1>>
|
| 167 |
+
{
|
| 168 |
+
static const GLint glinternalformat = GL_RGBA16;
|
| 169 |
+
static const GLenum glformat = GL_RGB;
|
| 170 |
+
static const GLenum gltype = GL_UNSIGNED_SHORT;
|
| 171 |
+
static const size_t components = 3;
|
| 172 |
+
};
|
| 173 |
+
|
| 174 |
+
template <>
|
| 175 |
+
struct GlFormatTraits<Eigen::Vector3f>
|
| 176 |
+
{
|
| 177 |
+
static const GLint glinternalformat = GL_RGB32F;
|
| 178 |
+
static const GLenum glformat = GL_RGB;
|
| 179 |
+
static const GLenum gltype = GL_FLOAT;
|
| 180 |
+
static const size_t components = 3;
|
| 181 |
+
};
|
| 182 |
+
|
| 183 |
+
template <>
|
| 184 |
+
struct GlFormatTraits<Eigen::Vector3d>
|
| 185 |
+
{
|
| 186 |
+
static const GLint glinternalformat = GL_RGB32F;
|
| 187 |
+
static const GLenum glformat = GL_RGB;
|
| 188 |
+
static const GLenum gltype = GL_DOUBLE;
|
| 189 |
+
static const size_t components = 3;
|
| 190 |
+
};
|
| 191 |
+
|
| 192 |
+
//////////////////////////////////////////////////////////////////
|
| 193 |
+
|
| 194 |
+
template <>
|
| 195 |
+
struct GlFormatTraits<Eigen::Matrix<unsigned char,4,1>>
|
| 196 |
+
{
|
| 197 |
+
static const GLint glinternalformat = GL_RGBA8;
|
| 198 |
+
static const GLenum glformat = GL_RGBA;
|
| 199 |
+
static const GLenum gltype = GL_UNSIGNED_BYTE;
|
| 200 |
+
static const size_t components = 4;
|
| 201 |
+
};
|
| 202 |
+
|
| 203 |
+
template <>
|
| 204 |
+
struct GlFormatTraits<Eigen::Matrix<unsigned short,4,1>>
|
| 205 |
+
{
|
| 206 |
+
static const GLint glinternalformat = GL_RGBA16;
|
| 207 |
+
static const GLenum glformat = GL_RGBA;
|
| 208 |
+
static const GLenum gltype = GL_UNSIGNED_SHORT;
|
| 209 |
+
static const size_t components = 4;
|
| 210 |
+
};
|
| 211 |
+
|
| 212 |
+
template <>
|
| 213 |
+
struct GlFormatTraits<Eigen::Vector4f>
|
| 214 |
+
{
|
| 215 |
+
static const GLint glinternalformat = GL_RGBA32F;
|
| 216 |
+
static const GLenum glformat = GL_RGBA;
|
| 217 |
+
static const GLenum gltype = GL_FLOAT;
|
| 218 |
+
static const size_t components = 4;
|
| 219 |
+
};
|
| 220 |
+
|
| 221 |
+
template <>
|
| 222 |
+
struct GlFormatTraits<Eigen::Vector4d>
|
| 223 |
+
{
|
| 224 |
+
static const GLint glinternalformat = GL_RGBA32F;
|
| 225 |
+
static const GLenum glformat = GL_RGBA;
|
| 226 |
+
static const GLenum gltype = GL_DOUBLE;
|
| 227 |
+
static const size_t components = 4;
|
| 228 |
+
};
|
| 229 |
+
|
| 230 |
+
#endif // HAVE_EIGEN
|
| 231 |
+
|
| 232 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glinclude.h
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove, Richard Newcombe
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/gl/glplatform.h>
|
| 31 |
+
|
| 32 |
+
#ifdef HAVE_GLES
|
| 33 |
+
#include <pangolin/gl/compat/gl_es_compat.h>
|
| 34 |
+
#endif
|
| 35 |
+
|
| 36 |
+
#define CheckGlDieOnError() pangolin::_CheckGlDieOnError( __FILE__, __LINE__ );
|
| 37 |
+
namespace pangolin {
|
| 38 |
+
inline void _CheckGlDieOnError( const char *sFile, const int nLine )
|
| 39 |
+
{
|
| 40 |
+
const GLenum glError = glGetError();
|
| 41 |
+
if( glError != GL_NO_ERROR ) {
|
| 42 |
+
pango_print_error( "OpenGL Error: %s (%d)\n", glErrorString(glError), glError );
|
| 43 |
+
pango_print_error("In: %s, line %d\n", sFile, nLine);
|
| 44 |
+
}
|
| 45 |
+
}
|
| 46 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glpangoglu.h
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/gl/glplatform.h>
|
| 31 |
+
|
| 32 |
+
namespace pangolin {
|
| 33 |
+
|
| 34 |
+
/// Clone of glErrorString
|
| 35 |
+
PANGOLIN_EXPORT
|
| 36 |
+
const GLubyte* glErrorString(GLenum error);
|
| 37 |
+
|
| 38 |
+
/// Clone of gluProject
|
| 39 |
+
PANGOLIN_EXPORT
|
| 40 |
+
GLint glProject(
|
| 41 |
+
float objx, float objy, float objz,
|
| 42 |
+
const float* const modelMatrix/*[16]*/,
|
| 43 |
+
const float* const projMatrix/*[16]*/,
|
| 44 |
+
const GLint* const viewport/*[4]*/,
|
| 45 |
+
float* winx, float* winy, float* winz
|
| 46 |
+
);
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
/// Clone of gluUnProject
|
| 50 |
+
PANGOLIN_EXPORT
|
| 51 |
+
GLint glUnProject(
|
| 52 |
+
float winx, float winy, float winz,
|
| 53 |
+
const float* const modelMatrix/*[16]*/,
|
| 54 |
+
const float* const projMatrix/*[16]*/,
|
| 55 |
+
const GLint* const viewport/*[4]*/,
|
| 56 |
+
float* objx, float* objy, float* objz
|
| 57 |
+
);
|
| 58 |
+
|
| 59 |
+
/// Clone of gluProject
|
| 60 |
+
PANGOLIN_EXPORT
|
| 61 |
+
GLint glProject(
|
| 62 |
+
double objx, double objy, double objz,
|
| 63 |
+
const double* const modelMatrix/*[16]*/,
|
| 64 |
+
const double* const projMatrix/*[16]*/,
|
| 65 |
+
const GLint* const viewport/*[4]*/,
|
| 66 |
+
double* winx, double* winy, double* winz
|
| 67 |
+
);
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
/// Clone of gluUnProject
|
| 71 |
+
PANGOLIN_EXPORT
|
| 72 |
+
GLint glUnProject(
|
| 73 |
+
double winx, double winy, double winz,
|
| 74 |
+
const double* const modelMatrix/*[16]*/,
|
| 75 |
+
const double* const projMatrix/*[16]*/,
|
| 76 |
+
const GLint* const viewport/*[4]*/,
|
| 77 |
+
double* objx, double* objy, double* objz
|
| 78 |
+
);
|
| 79 |
+
|
| 80 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glpixformat.h
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/gl/glplatform.h>
|
| 31 |
+
#include <pangolin/gl/glformattraits.h>
|
| 32 |
+
#include <pangolin/image/pixel_format.h>
|
| 33 |
+
#include <stdexcept>
|
| 34 |
+
|
| 35 |
+
namespace pangolin {
|
| 36 |
+
|
| 37 |
+
// This class may dissapear in the future
|
| 38 |
+
struct GlPixFormat
|
| 39 |
+
{
|
| 40 |
+
GlPixFormat() {}
|
| 41 |
+
|
| 42 |
+
GlPixFormat(const PixelFormat& fmt)
|
| 43 |
+
{
|
| 44 |
+
switch( fmt.channels) {
|
| 45 |
+
case 1: glformat = GL_LUMINANCE; break;
|
| 46 |
+
case 3: glformat = fmt.format.substr(0, 3) == "BGR"? GL_BGR : GL_RGB; break;
|
| 47 |
+
case 4: glformat = fmt.format.substr(0, 4) == "BGRA"? GL_BGRA : GL_RGBA; break;
|
| 48 |
+
default: throw std::runtime_error("Unable to form OpenGL format from video format: '" + fmt.format + "'.");
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
const bool is_integral = fmt.format.find('F') == std::string::npos;
|
| 52 |
+
|
| 53 |
+
switch (fmt.channel_bits[0]) {
|
| 54 |
+
case 8: gltype = GL_UNSIGNED_BYTE; break;
|
| 55 |
+
case 10: gltype = GL_UNSIGNED_SHORT; break;
|
| 56 |
+
case 12: gltype = GL_UNSIGNED_SHORT; break;
|
| 57 |
+
case 16: gltype = GL_UNSIGNED_SHORT; break;
|
| 58 |
+
case 32: gltype = (is_integral ? GL_UNSIGNED_INT : GL_FLOAT); break;
|
| 59 |
+
case 64: gltype = (is_integral ? GL_UNSIGNED_INT64_NV : GL_DOUBLE); break;
|
| 60 |
+
default: throw std::runtime_error("Unknown OpenGL data type for video format: '" + fmt.format + "'.");
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
if(glformat == GL_LUMINANCE) {
|
| 64 |
+
if(gltype == GL_UNSIGNED_BYTE) {
|
| 65 |
+
scalable_internal_format = GL_LUMINANCE8;
|
| 66 |
+
}else if(gltype == GL_UNSIGNED_SHORT){
|
| 67 |
+
if(fmt.channel_bits[0] == 12) {
|
| 68 |
+
scalable_internal_format = GL_LUMINANCE12;
|
| 69 |
+
}
|
| 70 |
+
else if(fmt.channel_bits[0] == 10) {
|
| 71 |
+
scalable_internal_format = GL_LUMINANCE12; // there is no GL_LUMINANCE10
|
| 72 |
+
} else {
|
| 73 |
+
scalable_internal_format = GL_LUMINANCE16;
|
| 74 |
+
}
|
| 75 |
+
}else{
|
| 76 |
+
scalable_internal_format = GL_LUMINANCE32F_ARB;
|
| 77 |
+
}
|
| 78 |
+
}else{
|
| 79 |
+
if(gltype == GL_UNSIGNED_BYTE) {
|
| 80 |
+
scalable_internal_format = GL_RGBA8;
|
| 81 |
+
}else if(gltype == GL_UNSIGNED_SHORT) {
|
| 82 |
+
if(fmt.channel_bits[0] == 10) {
|
| 83 |
+
scalable_internal_format = GL_RGB10;
|
| 84 |
+
} else if(fmt.channel_bits[0] == 12) {
|
| 85 |
+
scalable_internal_format = GL_RGB12;
|
| 86 |
+
} else {
|
| 87 |
+
scalable_internal_format = GL_RGBA16;
|
| 88 |
+
}
|
| 89 |
+
}else{
|
| 90 |
+
scalable_internal_format = GL_RGBA32F;
|
| 91 |
+
}
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
template<typename T>
|
| 96 |
+
static GlPixFormat FromType()
|
| 97 |
+
{
|
| 98 |
+
GlPixFormat fmt;
|
| 99 |
+
fmt.glformat = GlFormatTraits<T>::glformat;
|
| 100 |
+
fmt.gltype = GlFormatTraits<T>::gltype;
|
| 101 |
+
fmt.scalable_internal_format = GlFormatTraits<T>::glinternalformat;
|
| 102 |
+
return fmt;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
GLint glformat;
|
| 106 |
+
GLenum gltype;
|
| 107 |
+
GLint scalable_internal_format;
|
| 108 |
+
};
|
| 109 |
+
|
| 110 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glplatform.h
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
//////////////////////////////////////////////////////////
|
| 31 |
+
// Attempt to portably include Necessary OpenGL headers
|
| 32 |
+
//////////////////////////////////////////////////////////
|
| 33 |
+
|
| 34 |
+
#include <pangolin/platform.h>
|
| 35 |
+
|
| 36 |
+
#ifdef _WIN_
|
| 37 |
+
// Define maths quantities when using <cmath> to match posix systems
|
| 38 |
+
#ifndef _USE_MATH_DEFINES
|
| 39 |
+
# define _USE_MATH_DEFINES
|
| 40 |
+
#endif
|
| 41 |
+
|
| 42 |
+
// Don't define min / max macros in windows.h or other unnecessary macros
|
| 43 |
+
#ifndef NOMINMAX
|
| 44 |
+
# define NOMINMAX
|
| 45 |
+
#endif
|
| 46 |
+
#ifndef WIN32_LEAN_AND_MEAN
|
| 47 |
+
# define WIN32_LEAN_AND_MEAN
|
| 48 |
+
#endif
|
| 49 |
+
#include <Windows.h>
|
| 50 |
+
|
| 51 |
+
// Undef nuisance Windows.h macros which interfere with our methods
|
| 52 |
+
#undef LoadImage
|
| 53 |
+
#undef near
|
| 54 |
+
#undef far
|
| 55 |
+
#undef ERROR
|
| 56 |
+
#endif
|
| 57 |
+
|
| 58 |
+
#ifdef HAVE_GLEW
|
| 59 |
+
#include <GL/glew.h>
|
| 60 |
+
#endif
|
| 61 |
+
|
| 62 |
+
#ifdef HAVE_GLES
|
| 63 |
+
#if defined(_ANDROID_)
|
| 64 |
+
#include <EGL/egl.h>
|
| 65 |
+
#ifdef HAVE_GLES_2
|
| 66 |
+
#include <GLES2/gl2.h>
|
| 67 |
+
#include <GLES2/gl2ext.h>
|
| 68 |
+
#else
|
| 69 |
+
#include <GLES/gl.h>
|
| 70 |
+
#define GL_GLEXT_PROTOTYPES
|
| 71 |
+
#include <GLES/glext.h>
|
| 72 |
+
#endif
|
| 73 |
+
#elif defined(_APPLE_IOS_)
|
| 74 |
+
#include <OpenGLES/ES2/gl.h>
|
| 75 |
+
#include <OpenGLES/ES2/glext.h>
|
| 76 |
+
#endif
|
| 77 |
+
#else
|
| 78 |
+
#ifdef _OSX_
|
| 79 |
+
#define GL_SILENCE_DEPRECATION
|
| 80 |
+
#include <OpenGL/gl.h>
|
| 81 |
+
#else
|
| 82 |
+
#include <GL/gl.h>
|
| 83 |
+
#endif
|
| 84 |
+
#endif // HAVE_GLES
|
| 85 |
+
|
| 86 |
+
#include <pangolin/gl/glpangoglu.h>
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glsl.h
ADDED
|
@@ -0,0 +1,812 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <sstream>
|
| 31 |
+
#include <fstream>
|
| 32 |
+
#include <algorithm>
|
| 33 |
+
#include <vector>
|
| 34 |
+
#include <map>
|
| 35 |
+
#include <cctype>
|
| 36 |
+
|
| 37 |
+
#include <pangolin/gl/glplatform.h>
|
| 38 |
+
#include <pangolin/gl/colour.h>
|
| 39 |
+
#include <pangolin/gl/opengl_render_state.h>
|
| 40 |
+
#include <pangolin/utils/file_utils.h>
|
| 41 |
+
|
| 42 |
+
#ifdef HAVE_GLES
|
| 43 |
+
#define GLhandleARB GLuint
|
| 44 |
+
#endif
|
| 45 |
+
|
| 46 |
+
#if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files
|
| 47 |
+
#define USE_EIGEN
|
| 48 |
+
#endif
|
| 49 |
+
|
| 50 |
+
#ifdef USE_EIGEN
|
| 51 |
+
#include <Eigen/Core>
|
| 52 |
+
#endif // USE_EIGEN
|
| 53 |
+
|
| 54 |
+
namespace pangolin
|
| 55 |
+
{
|
| 56 |
+
|
| 57 |
+
////////////////////////////////////////////////
|
| 58 |
+
// Standard attribute locations
|
| 59 |
+
////////////////////////////////////////////////
|
| 60 |
+
|
| 61 |
+
const GLuint DEFAULT_LOCATION_POSITION = 0;
|
| 62 |
+
const GLuint DEFAULT_LOCATION_COLOUR = 1;
|
| 63 |
+
const GLuint DEFAULT_LOCATION_NORMAL = 2;
|
| 64 |
+
const GLuint DEFAULT_LOCATION_TEXCOORD = 3;
|
| 65 |
+
|
| 66 |
+
const char DEFAULT_NAME_POSITION[] = "a_position";
|
| 67 |
+
const char DEFAULT_NAME_COLOUR[] = "a_color";
|
| 68 |
+
const char DEFAULT_NAME_NORMAL[] = "a_normal";
|
| 69 |
+
const char DEFAULT_NAME_TEXCOORD[] = "a_texcoord";
|
| 70 |
+
|
| 71 |
+
////////////////////////////////////////////////
|
| 72 |
+
// Interface
|
| 73 |
+
////////////////////////////////////////////////
|
| 74 |
+
|
| 75 |
+
enum GlSlShaderType
|
| 76 |
+
{
|
| 77 |
+
GlSlAnnotatedShader = 0,
|
| 78 |
+
GlSlFragmentShader = GL_FRAGMENT_SHADER,
|
| 79 |
+
GlSlVertexShader = GL_VERTEX_SHADER,
|
| 80 |
+
GlSlGeometryShader = 0x8DD9 /*GL_GEOMETRY_SHADER*/,
|
| 81 |
+
GlSlComputeShader = 0x91B9 /*GL_COMPUTE_SHADER*/
|
| 82 |
+
};
|
| 83 |
+
|
| 84 |
+
class GlSlProgram
|
| 85 |
+
{
|
| 86 |
+
public:
|
| 87 |
+
GlSlProgram();
|
| 88 |
+
|
| 89 |
+
//! Move Constructor
|
| 90 |
+
GlSlProgram(GlSlProgram&& tex);
|
| 91 |
+
|
| 92 |
+
~GlSlProgram();
|
| 93 |
+
|
| 94 |
+
bool AddShader(
|
| 95 |
+
GlSlShaderType shader_type,
|
| 96 |
+
const std::string& source_code,
|
| 97 |
+
const std::map<std::string,std::string>& program_defines = std::map<std::string,std::string>(),
|
| 98 |
+
const std::vector<std::string>& search_path = std::vector<std::string>()
|
| 99 |
+
);
|
| 100 |
+
|
| 101 |
+
bool AddShaderFromFile(
|
| 102 |
+
GlSlShaderType shader_type,
|
| 103 |
+
const std::string& filename,
|
| 104 |
+
const std::map<std::string,std::string>& program_defines = std::map<std::string,std::string>(),
|
| 105 |
+
const std::vector<std::string>& search_path = std::vector<std::string>()
|
| 106 |
+
);
|
| 107 |
+
|
| 108 |
+
bool Link();
|
| 109 |
+
|
| 110 |
+
// Remove all shaders from this program, and reload from files.
|
| 111 |
+
bool ReloadShaderFiles();
|
| 112 |
+
|
| 113 |
+
GLint GetAttributeHandle(const std::string& name);
|
| 114 |
+
GLint GetUniformHandle(const std::string& name);
|
| 115 |
+
|
| 116 |
+
// Before setting uniforms, be sure to Bind() the GlSl program first.
|
| 117 |
+
void SetUniform(const std::string& name, int x);
|
| 118 |
+
void SetUniform(const std::string& name, int x1, int x2);
|
| 119 |
+
void SetUniform(const std::string& name, int x1, int x2, int x3);
|
| 120 |
+
void SetUniform(const std::string& name, int x1, int x2, int x3, int x4);
|
| 121 |
+
|
| 122 |
+
void SetUniform(const std::string& name, float f);
|
| 123 |
+
void SetUniform(const std::string& name, float f1, float f2);
|
| 124 |
+
void SetUniform(const std::string& name, float f1, float f2, float f3);
|
| 125 |
+
void SetUniform(const std::string& name, float f1, float f2, float f3, float f4);
|
| 126 |
+
|
| 127 |
+
void SetUniform(const std::string& name, Colour c);
|
| 128 |
+
|
| 129 |
+
void SetUniform(const std::string& name, const OpenGlMatrix& m);
|
| 130 |
+
|
| 131 |
+
#ifdef USE_EIGEN
|
| 132 |
+
void SetUniform(const std::string& name, const Eigen::Vector2f& v);
|
| 133 |
+
void SetUniform(const std::string& name, const Eigen::Vector3f& v);
|
| 134 |
+
void SetUniform(const std::string& name, const Eigen::Vector4f& v);
|
| 135 |
+
void SetUniform(const std::string& name, const Eigen::Matrix2f& m);
|
| 136 |
+
void SetUniform(const std::string& name, const Eigen::Matrix3f& m);
|
| 137 |
+
void SetUniform(const std::string& name, const Eigen::Matrix4f& m);
|
| 138 |
+
|
| 139 |
+
void SetUniform(const std::string& name, const Eigen::Vector2d& v);
|
| 140 |
+
void SetUniform(const std::string& name, const Eigen::Vector3d& v);
|
| 141 |
+
void SetUniform(const std::string& name, const Eigen::Vector4d& v);
|
| 142 |
+
void SetUniform(const std::string& name, const Eigen::Matrix2d& m);
|
| 143 |
+
void SetUniform(const std::string& name, const Eigen::Matrix3d& m);
|
| 144 |
+
void SetUniform(const std::string& name, const Eigen::Matrix4d& m);
|
| 145 |
+
#endif
|
| 146 |
+
|
| 147 |
+
#if GL_VERSION_4_3
|
| 148 |
+
GLint GetProgramResourceIndex(const std::string& name);
|
| 149 |
+
void SetShaderStorageBlock(const std::string& name, const int& bindingIndex);
|
| 150 |
+
#endif
|
| 151 |
+
|
| 152 |
+
void Bind();
|
| 153 |
+
void SaveBind();
|
| 154 |
+
void Unbind();
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
void BindPangolinDefaultAttribLocationsAndLink();
|
| 158 |
+
|
| 159 |
+
// Unlink all shaders from program
|
| 160 |
+
void ClearShaders();
|
| 161 |
+
|
| 162 |
+
GLint ProgramId() const {
|
| 163 |
+
return prog;
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
bool Valid() const {
|
| 167 |
+
return ProgramId() != 0;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
protected:
|
| 171 |
+
struct ShaderFileOrCode
|
| 172 |
+
{
|
| 173 |
+
GlSlShaderType shader_type;
|
| 174 |
+
std::string filename;
|
| 175 |
+
std::string code;
|
| 176 |
+
std::map<std::string,std::string> program_defines;
|
| 177 |
+
std::vector<std::string> search_path;
|
| 178 |
+
};
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
// Convenience method to load shader description
|
| 182 |
+
bool AddShaderFile(const ShaderFileOrCode &shader_file);
|
| 183 |
+
|
| 184 |
+
std::string ParseIncludeFilename(
|
| 185 |
+
const std::string& location
|
| 186 |
+
);
|
| 187 |
+
|
| 188 |
+
std::string SearchIncludePath(
|
| 189 |
+
const std::string& filename,
|
| 190 |
+
const std::vector<std::string>& search_path,
|
| 191 |
+
const std::string& current_path
|
| 192 |
+
);
|
| 193 |
+
|
| 194 |
+
bool AddPreprocessedShader(
|
| 195 |
+
GlSlShaderType shader_type,
|
| 196 |
+
const std::string& source_code,
|
| 197 |
+
const std::string& name_for_errors
|
| 198 |
+
);
|
| 199 |
+
|
| 200 |
+
void PreprocessGLSL(
|
| 201 |
+
std::istream& input,
|
| 202 |
+
std::ostream& output,
|
| 203 |
+
const std::map<std::string,std::string>& program_defines,
|
| 204 |
+
const std::vector<std::string>& search_path,
|
| 205 |
+
const std::string& current_path
|
| 206 |
+
);
|
| 207 |
+
|
| 208 |
+
// Split 'code' into several code blocks per shader type
|
| 209 |
+
// shader blocks in 'code' must be annotated with:
|
| 210 |
+
// @start vertex, @start fragment, @start geometry or @start compute
|
| 211 |
+
static std::map<GlSlShaderType,std::string>
|
| 212 |
+
SplitAnnotatedShaders(const std::string& code);
|
| 213 |
+
|
| 214 |
+
bool linked;
|
| 215 |
+
std::vector<GLhandleARB> shaders;
|
| 216 |
+
GLenum prog;
|
| 217 |
+
GLint prev_prog;
|
| 218 |
+
std::vector<ShaderFileOrCode> shader_files;
|
| 219 |
+
};
|
| 220 |
+
|
| 221 |
+
class GlSlUtilities
|
| 222 |
+
{
|
| 223 |
+
public:
|
| 224 |
+
inline static GlSlProgram& OffsetAndScale(float offset, float scale) {
|
| 225 |
+
GlSlProgram& prog = Instance().prog_offsetscale;
|
| 226 |
+
prog.Bind();
|
| 227 |
+
prog.SetUniform("offset", offset);
|
| 228 |
+
prog.SetUniform("scale", scale);
|
| 229 |
+
return prog;
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
inline static GlSlProgram& OffsetAndScaleGamma(float offset, float scale) {
|
| 233 |
+
GlSlProgram& prog = Instance().prog_offsetscalegamma;
|
| 234 |
+
prog.Bind();
|
| 235 |
+
prog.SetUniform("offset", offset);
|
| 236 |
+
prog.SetUniform("scale", scale);
|
| 237 |
+
return prog;
|
| 238 |
+
}
|
| 239 |
+
|
| 240 |
+
inline static GlSlProgram& Scale(float scale, float bias = 0.0f) {
|
| 241 |
+
GlSlProgram& prog = Instance().prog_scale;
|
| 242 |
+
prog.Bind();
|
| 243 |
+
prog.SetUniform("scale", scale);
|
| 244 |
+
prog.SetUniform("bias", bias);
|
| 245 |
+
return prog;
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
inline static void UseNone()
|
| 249 |
+
{
|
| 250 |
+
glUseProgram(0);
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
protected:
|
| 254 |
+
static GlSlUtilities& Instance() {
|
| 255 |
+
// TODO: BUG: The GlSLUtilities instance needs to be tied
|
| 256 |
+
// to the OpenGL context, not the thread, or globally.
|
| 257 |
+
#ifndef PANGO_NO_THREADLOCAL
|
| 258 |
+
thread_local
|
| 259 |
+
#else
|
| 260 |
+
static
|
| 261 |
+
#endif
|
| 262 |
+
GlSlUtilities instance;
|
| 263 |
+
return instance;
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
// protected constructor
|
| 267 |
+
GlSlUtilities() {
|
| 268 |
+
const char* source_scale =
|
| 269 |
+
"uniform float scale;"
|
| 270 |
+
"uniform float bias;"
|
| 271 |
+
"uniform sampler2D tex;"
|
| 272 |
+
"void main() {"
|
| 273 |
+
" vec2 uv = gl_TexCoord[0].st;"
|
| 274 |
+
" if(0.0 <= uv.x && uv.x <= 1.0 && 0.0 <= uv.y && uv.y <= 1.0) {"
|
| 275 |
+
" gl_FragColor = texture2D(tex,uv);"
|
| 276 |
+
" gl_FragColor.xyz *= scale;"
|
| 277 |
+
" gl_FragColor.xyz += vec3(bias,bias,bias);"
|
| 278 |
+
" }else{"
|
| 279 |
+
" float v = 0.1;"
|
| 280 |
+
" gl_FragColor.xyz = vec3(v,v,v);"
|
| 281 |
+
" }"
|
| 282 |
+
"}";
|
| 283 |
+
prog_scale.AddShader(GlSlFragmentShader, source_scale);
|
| 284 |
+
prog_scale.Link();
|
| 285 |
+
|
| 286 |
+
// shader performs automatically gamma correction, assuming that image data is linear
|
| 287 |
+
// maps to (approximate) sRGB
|
| 288 |
+
const char* source_offsetscalegamma =
|
| 289 |
+
"uniform float offset;"
|
| 290 |
+
"uniform float scale;"
|
| 291 |
+
"uniform sampler2D tex;"
|
| 292 |
+
"void main() {"
|
| 293 |
+
" vec2 uv = gl_TexCoord[0].st;"
|
| 294 |
+
" if(0.0 <= uv.x && uv.x <= 1.0 && 0.0 <= uv.y && uv.y <= 1.0) {"
|
| 295 |
+
" gl_FragColor = texture2D(tex,gl_TexCoord[0].st);"
|
| 296 |
+
" gl_FragColor.xyz += vec3(offset,offset,offset);"
|
| 297 |
+
" gl_FragColor.xyz *= scale;"
|
| 298 |
+
" gl_FragColor.xyz = pow(gl_FragColor.xyz,vec3(0.45,0.45,0.45));"
|
| 299 |
+
" }else{"
|
| 300 |
+
" float v = 0.1;"
|
| 301 |
+
" gl_FragColor.xyz = vec3(v,v,v);"
|
| 302 |
+
" }"
|
| 303 |
+
"}";
|
| 304 |
+
prog_offsetscalegamma.AddShader(GlSlFragmentShader, source_offsetscalegamma);
|
| 305 |
+
prog_offsetscalegamma.Link();
|
| 306 |
+
|
| 307 |
+
const char* source_offsetscale =
|
| 308 |
+
"uniform float offset;"
|
| 309 |
+
"uniform float scale;"
|
| 310 |
+
"uniform sampler2D tex;"
|
| 311 |
+
"void main() {"
|
| 312 |
+
" vec2 uv = gl_TexCoord[0].st;"
|
| 313 |
+
" if(0.0 <= uv.x && uv.x <= 1.0 && 0.0 <= uv.y && uv.y <= 1.0) {"
|
| 314 |
+
" gl_FragColor = texture2D(tex,gl_TexCoord[0].st);"
|
| 315 |
+
" gl_FragColor.xyz += vec3(offset,offset,offset);"
|
| 316 |
+
" gl_FragColor.xyz *= scale;"
|
| 317 |
+
" }else{"
|
| 318 |
+
" float v = 0.1;"
|
| 319 |
+
" gl_FragColor.xyz = vec3(v,v,v);"
|
| 320 |
+
" }"
|
| 321 |
+
"}";
|
| 322 |
+
prog_offsetscale.AddShader(GlSlFragmentShader, source_offsetscale);
|
| 323 |
+
prog_offsetscale.Link();
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
GlSlProgram prog_scale;
|
| 327 |
+
GlSlProgram prog_offsetscale;
|
| 328 |
+
GlSlProgram prog_offsetscalegamma;
|
| 329 |
+
};
|
| 330 |
+
|
| 331 |
+
|
| 332 |
+
////////////////////////////////////////////////
|
| 333 |
+
// Implementation
|
| 334 |
+
////////////////////////////////////////////////
|
| 335 |
+
|
| 336 |
+
inline bool IsLinkSuccessPrintLog(GLhandleARB prog)
|
| 337 |
+
{
|
| 338 |
+
GLint status;
|
| 339 |
+
glGetProgramiv(prog, GL_LINK_STATUS, &status);
|
| 340 |
+
if(status != GL_TRUE) {
|
| 341 |
+
pango_print_error("GLSL Program link failed: ");
|
| 342 |
+
const int PROGRAM_LOG_MAX_LEN = 10240;
|
| 343 |
+
char infolog[PROGRAM_LOG_MAX_LEN];
|
| 344 |
+
GLsizei len;
|
| 345 |
+
glGetProgramInfoLog(prog, PROGRAM_LOG_MAX_LEN, &len, infolog);
|
| 346 |
+
if(len) {
|
| 347 |
+
pango_print_error("%s\n",infolog);
|
| 348 |
+
}else{
|
| 349 |
+
pango_print_error("No details provided.\n");
|
| 350 |
+
}
|
| 351 |
+
return false;
|
| 352 |
+
}
|
| 353 |
+
return true;
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
inline bool IsCompileSuccessPrintLog(GLhandleARB shader, const std::string& name_for_errors, const std::string& source_code = {})
|
| 357 |
+
{
|
| 358 |
+
GLint status;
|
| 359 |
+
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
| 360 |
+
if(status != GL_TRUE) {
|
| 361 |
+
pango_print_error("GLSL Shader compilation failed: ");
|
| 362 |
+
const int SHADER_LOG_MAX_LEN = 10240;
|
| 363 |
+
char infolog[SHADER_LOG_MAX_LEN];
|
| 364 |
+
GLsizei len;
|
| 365 |
+
glGetShaderInfoLog(shader, SHADER_LOG_MAX_LEN, &len, infolog);
|
| 366 |
+
if(len) {
|
| 367 |
+
pango_print_error("%s:\n%s\n",name_for_errors.c_str(), infolog);
|
| 368 |
+
}else{
|
| 369 |
+
pango_print_error("%s:\nNo details provided.\n",name_for_errors.c_str());
|
| 370 |
+
}
|
| 371 |
+
if(!source_code.empty())
|
| 372 |
+
{
|
| 373 |
+
pango_print_error("In source code:\n%s\n",source_code.c_str());
|
| 374 |
+
}
|
| 375 |
+
return false;
|
| 376 |
+
}
|
| 377 |
+
return true;
|
| 378 |
+
}
|
| 379 |
+
|
| 380 |
+
inline GlSlProgram::GlSlProgram()
|
| 381 |
+
: linked(false), prog(0), prev_prog(0)
|
| 382 |
+
{
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
+
//! Move Constructor
|
| 386 |
+
inline GlSlProgram::GlSlProgram(GlSlProgram&& o)
|
| 387 |
+
: linked(o.linked), shaders(o.shaders), prog(o.prog), prev_prog(o.prev_prog)
|
| 388 |
+
{
|
| 389 |
+
o.prog = 0;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
inline GlSlProgram::~GlSlProgram()
|
| 393 |
+
{
|
| 394 |
+
if(prog) {
|
| 395 |
+
ClearShaders();
|
| 396 |
+
glDeleteProgram(prog);
|
| 397 |
+
}
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
inline void PrintSourceCode(const std::string& src)
|
| 401 |
+
{
|
| 402 |
+
std::stringstream ss(src);
|
| 403 |
+
std::string line;
|
| 404 |
+
|
| 405 |
+
for(int linenum=1; std::getline(ss,line,'\n'); ++linenum) {
|
| 406 |
+
std::cout << linenum << ":\t" << line << std::endl;
|
| 407 |
+
}
|
| 408 |
+
}
|
| 409 |
+
|
| 410 |
+
inline bool GlSlProgram::AddPreprocessedShader(
|
| 411 |
+
GlSlShaderType shader_type,
|
| 412 |
+
const std::string& source_code,
|
| 413 |
+
const std::string& name_for_errors
|
| 414 |
+
) {
|
| 415 |
+
if(!prog) {
|
| 416 |
+
prog = glCreateProgram();
|
| 417 |
+
}
|
| 418 |
+
|
| 419 |
+
GLhandleARB shader = glCreateShader(shader_type);
|
| 420 |
+
const char* source = source_code.c_str();
|
| 421 |
+
glShaderSource(shader, 1, &source, NULL);
|
| 422 |
+
glCompileShader(shader);
|
| 423 |
+
bool success = IsCompileSuccessPrintLog(shader, name_for_errors, source_code);
|
| 424 |
+
if(success) {
|
| 425 |
+
glAttachShader(prog, shader);
|
| 426 |
+
shaders.push_back(shader);
|
| 427 |
+
linked = false;
|
| 428 |
+
}
|
| 429 |
+
return success;
|
| 430 |
+
}
|
| 431 |
+
|
| 432 |
+
inline std::string GlSlProgram::ParseIncludeFilename(const std::string& location)
|
| 433 |
+
{
|
| 434 |
+
size_t start = location.find_first_of("\"<");
|
| 435 |
+
if(start != std::string::npos) {
|
| 436 |
+
size_t end = location.find_first_of("\">", start+1);
|
| 437 |
+
if(end != std::string::npos) {
|
| 438 |
+
return location.substr(start+1, end - start - 1);
|
| 439 |
+
}
|
| 440 |
+
}
|
| 441 |
+
throw std::runtime_error("GLSL Parser: Unable to parse include location " + location );
|
| 442 |
+
}
|
| 443 |
+
|
| 444 |
+
inline std::string GlSlProgram::SearchIncludePath(
|
| 445 |
+
const std::string& filename,
|
| 446 |
+
const std::vector<std::string>& search_path,
|
| 447 |
+
const std::string& current_path
|
| 448 |
+
) {
|
| 449 |
+
if(FileExists(current_path + "/" + filename)) {
|
| 450 |
+
return current_path + "/" + filename;
|
| 451 |
+
}else{
|
| 452 |
+
for(size_t i=0; i < search_path.size(); ++i) {
|
| 453 |
+
const std::string hypoth = search_path[i] + "/" + filename;
|
| 454 |
+
if( FileExists(hypoth) ) {
|
| 455 |
+
return hypoth;
|
| 456 |
+
}
|
| 457 |
+
}
|
| 458 |
+
}
|
| 459 |
+
return "";
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
inline void GlSlProgram::PreprocessGLSL(
|
| 463 |
+
std::istream& input, std::ostream& output,
|
| 464 |
+
const std::map<std::string,std::string>& program_defines,
|
| 465 |
+
const std::vector<std::string> &search_path,
|
| 466 |
+
const std::string ¤t_path
|
| 467 |
+
) {
|
| 468 |
+
const size_t MAXLINESIZE = 10240;
|
| 469 |
+
char line[MAXLINESIZE] = "";
|
| 470 |
+
|
| 471 |
+
while(!input.eof()) {
|
| 472 |
+
// Take like from source
|
| 473 |
+
input.getline(line,MAXLINESIZE);
|
| 474 |
+
|
| 475 |
+
// Transform
|
| 476 |
+
if( !strncmp(line, "#include", 8 ) ) {
|
| 477 |
+
// C++ / G3D style include directive
|
| 478 |
+
const std::string import_file = ParseIncludeFilename(line+8);
|
| 479 |
+
const std::string resolved_file = SearchIncludePath(import_file, search_path, current_path);
|
| 480 |
+
|
| 481 |
+
std::ifstream ifs(resolved_file.c_str());
|
| 482 |
+
if(ifs.good()) {
|
| 483 |
+
const std::string file_path = pangolin::PathParent(resolved_file);
|
| 484 |
+
PreprocessGLSL(ifs, output, program_defines, search_path, file_path);
|
| 485 |
+
}else{
|
| 486 |
+
throw std::runtime_error("GLSL Parser: Unable to open " + import_file );
|
| 487 |
+
}
|
| 488 |
+
}else if( !strncmp(line, "#expect", 7) ) {
|
| 489 |
+
// G3D style 'expect' directive, annotating expected preprocessor
|
| 490 |
+
// definition with document string
|
| 491 |
+
|
| 492 |
+
// Consume whitespace before token
|
| 493 |
+
size_t token_start = 7;
|
| 494 |
+
while( std::isspace(line[token_start]) ) ++token_start;
|
| 495 |
+
|
| 496 |
+
// Iterate over contigous charecters until \0 or whitespace
|
| 497 |
+
size_t token_end = token_start;
|
| 498 |
+
while( line[token_end] && !std::isspace(line[token_end]) ) ++token_end;
|
| 499 |
+
|
| 500 |
+
std::string token(line+token_start, line+token_end);
|
| 501 |
+
std::map<std::string,std::string>::const_iterator it = program_defines.find(token);
|
| 502 |
+
if( it == program_defines.end() ) {
|
| 503 |
+
pango_print_warn("Expected define missing (defaulting to 0): '%s'\n%s\n", token.c_str(), line + token_end );
|
| 504 |
+
output << "#define " << token << " 0" << std::endl;
|
| 505 |
+
}else{
|
| 506 |
+
output << "#define " << token << " " << it->second << std::endl;
|
| 507 |
+
}
|
| 508 |
+
}else{
|
| 509 |
+
// Output directly
|
| 510 |
+
output << line << std::endl;
|
| 511 |
+
}
|
| 512 |
+
}
|
| 513 |
+
}
|
| 514 |
+
|
| 515 |
+
inline void GlSlProgram::ClearShaders()
|
| 516 |
+
{
|
| 517 |
+
// Remove and delete each shader
|
| 518 |
+
for(size_t i=0; i<shaders.size(); ++i ) {
|
| 519 |
+
glDetachShader(prog, shaders[i]);
|
| 520 |
+
glDeleteShader(shaders[i]);
|
| 521 |
+
}
|
| 522 |
+
shaders.clear();
|
| 523 |
+
}
|
| 524 |
+
|
| 525 |
+
inline bool GlSlProgram::AddShaderFile(const ShaderFileOrCode& shader_file)
|
| 526 |
+
{
|
| 527 |
+
std::stringstream buffer;
|
| 528 |
+
|
| 529 |
+
if(shader_file.code.empty()) {
|
| 530 |
+
std::ifstream ifs(shader_file.filename.c_str());
|
| 531 |
+
if(ifs.is_open()) {
|
| 532 |
+
PreprocessGLSL(ifs, buffer, shader_file.program_defines, shader_file.search_path, ".");
|
| 533 |
+
}else{
|
| 534 |
+
throw std::runtime_error(FormatString("Unable to open shader file '%'", shader_file.filename));
|
| 535 |
+
}
|
| 536 |
+
}else{
|
| 537 |
+
std::istringstream iss(shader_file.code);
|
| 538 |
+
PreprocessGLSL(iss, buffer, shader_file.program_defines, shader_file.search_path, ".");
|
| 539 |
+
}
|
| 540 |
+
|
| 541 |
+
const std::string code = buffer.str();
|
| 542 |
+
const std::string input_name = !shader_file.filename.empty() ? shader_file.filename : "<string>";
|
| 543 |
+
|
| 544 |
+
if(shader_file.shader_type == GlSlAnnotatedShader) {
|
| 545 |
+
const std::map<GlSlShaderType,std::string> split_progs = SplitAnnotatedShaders(code);
|
| 546 |
+
for(const auto& type_code : split_progs) {
|
| 547 |
+
if(!AddPreprocessedShader(type_code.first, type_code.second, input_name )) {
|
| 548 |
+
return false;
|
| 549 |
+
}
|
| 550 |
+
}
|
| 551 |
+
return true;
|
| 552 |
+
}else{
|
| 553 |
+
return AddPreprocessedShader(shader_file.shader_type, code, input_name);
|
| 554 |
+
}
|
| 555 |
+
}
|
| 556 |
+
|
| 557 |
+
inline bool GlSlProgram::AddShaderFromFile(
|
| 558 |
+
GlSlShaderType shader_type,
|
| 559 |
+
const std::string& filename,
|
| 560 |
+
const std::map<std::string,std::string>& program_defines,
|
| 561 |
+
const std::vector<std::string>& search_path
|
| 562 |
+
) {
|
| 563 |
+
ShaderFileOrCode shader_file = {
|
| 564 |
+
shader_type,
|
| 565 |
+
pangolin::PathExpand(filename),
|
| 566 |
+
std::string(),
|
| 567 |
+
program_defines,
|
| 568 |
+
search_path
|
| 569 |
+
};
|
| 570 |
+
shader_files.push_back(shader_file);
|
| 571 |
+
return AddShaderFile(shader_file);
|
| 572 |
+
}
|
| 573 |
+
|
| 574 |
+
inline bool GlSlProgram::AddShader(
|
| 575 |
+
GlSlShaderType shader_type,
|
| 576 |
+
const std::string& source_code,
|
| 577 |
+
const std::map<std::string,std::string>& program_defines,
|
| 578 |
+
const std::vector<std::string>& search_path
|
| 579 |
+
) {
|
| 580 |
+
ShaderFileOrCode shader_file = {
|
| 581 |
+
shader_type,
|
| 582 |
+
std::string(),
|
| 583 |
+
source_code,
|
| 584 |
+
program_defines,
|
| 585 |
+
search_path
|
| 586 |
+
};
|
| 587 |
+
shader_files.push_back(shader_file);
|
| 588 |
+
return AddShaderFile(shader_file);
|
| 589 |
+
}
|
| 590 |
+
|
| 591 |
+
inline bool GlSlProgram::ReloadShaderFiles()
|
| 592 |
+
{
|
| 593 |
+
ClearShaders();
|
| 594 |
+
|
| 595 |
+
for(const auto& sf : shader_files) {
|
| 596 |
+
if(!AddShaderFile(sf)) {
|
| 597 |
+
return false;
|
| 598 |
+
}
|
| 599 |
+
}
|
| 600 |
+
|
| 601 |
+
Link();
|
| 602 |
+
return true;
|
| 603 |
+
}
|
| 604 |
+
|
| 605 |
+
inline std::map<GlSlShaderType,std::string>
|
| 606 |
+
GlSlProgram::SplitAnnotatedShaders(const std::string& code)
|
| 607 |
+
{
|
| 608 |
+
std::map<GlSlShaderType,std::string> ret;
|
| 609 |
+
|
| 610 |
+
std::stringstream input(code);
|
| 611 |
+
std::stringstream output;
|
| 612 |
+
|
| 613 |
+
const size_t MAXLINESIZE = 10240;
|
| 614 |
+
char line[MAXLINESIZE];
|
| 615 |
+
|
| 616 |
+
GlSlShaderType current_type = GlSlAnnotatedShader;
|
| 617 |
+
auto finish_block = [&](GlSlShaderType type){
|
| 618 |
+
if(current_type != GlSlAnnotatedShader) {
|
| 619 |
+
ret[current_type] = output.str();
|
| 620 |
+
}
|
| 621 |
+
output.str(std::string());
|
| 622 |
+
current_type = type;
|
| 623 |
+
};
|
| 624 |
+
|
| 625 |
+
while(!input.eof()) {
|
| 626 |
+
// Take like from source
|
| 627 |
+
input.getline(line,MAXLINESIZE);
|
| 628 |
+
|
| 629 |
+
// Transform
|
| 630 |
+
if( !strncmp(line, "@start", 6 ) ) {
|
| 631 |
+
const std::string str_shader_type = pangolin::Trim(std::string(line).substr(6));
|
| 632 |
+
if(str_shader_type == "vertex") {
|
| 633 |
+
finish_block(GlSlVertexShader);
|
| 634 |
+
}else if(str_shader_type == "fragment") {
|
| 635 |
+
finish_block(GlSlFragmentShader);
|
| 636 |
+
}else if(str_shader_type == "geometry") {
|
| 637 |
+
finish_block(GlSlGeometryShader);
|
| 638 |
+
}else if(str_shader_type == "compute") {
|
| 639 |
+
finish_block(GlSlComputeShader);
|
| 640 |
+
}
|
| 641 |
+
}else{
|
| 642 |
+
output << line << std::endl;
|
| 643 |
+
}
|
| 644 |
+
}
|
| 645 |
+
|
| 646 |
+
finish_block(GlSlAnnotatedShader);
|
| 647 |
+
|
| 648 |
+
return ret;
|
| 649 |
+
}
|
| 650 |
+
|
| 651 |
+
inline bool GlSlProgram::Link()
|
| 652 |
+
{
|
| 653 |
+
glLinkProgram(prog);
|
| 654 |
+
return IsLinkSuccessPrintLog(prog);
|
| 655 |
+
}
|
| 656 |
+
|
| 657 |
+
inline void GlSlProgram::Bind()
|
| 658 |
+
{
|
| 659 |
+
prev_prog = 0;
|
| 660 |
+
glUseProgram(prog);
|
| 661 |
+
}
|
| 662 |
+
|
| 663 |
+
inline void GlSlProgram::SaveBind()
|
| 664 |
+
{
|
| 665 |
+
glGetIntegerv(GL_CURRENT_PROGRAM, &prev_prog);
|
| 666 |
+
glUseProgram(prog);
|
| 667 |
+
}
|
| 668 |
+
|
| 669 |
+
inline void GlSlProgram::Unbind()
|
| 670 |
+
{
|
| 671 |
+
glUseProgram(prev_prog);
|
| 672 |
+
}
|
| 673 |
+
|
| 674 |
+
inline GLint GlSlProgram::GetAttributeHandle(const std::string& name)
|
| 675 |
+
{
|
| 676 |
+
return glGetAttribLocation(prog, name.c_str());
|
| 677 |
+
}
|
| 678 |
+
|
| 679 |
+
inline GLint GlSlProgram::GetUniformHandle(const std::string& name)
|
| 680 |
+
{
|
| 681 |
+
return glGetUniformLocation(prog, name.c_str());
|
| 682 |
+
}
|
| 683 |
+
|
| 684 |
+
inline void GlSlProgram::SetUniform(const std::string& name, int x)
|
| 685 |
+
{
|
| 686 |
+
glUniform1i( GetUniformHandle(name), x);
|
| 687 |
+
}
|
| 688 |
+
|
| 689 |
+
inline void GlSlProgram::SetUniform(const std::string& name, int x1, int x2)
|
| 690 |
+
{
|
| 691 |
+
glUniform2i( GetUniformHandle(name), x1, x2);
|
| 692 |
+
}
|
| 693 |
+
|
| 694 |
+
inline void GlSlProgram::SetUniform(const std::string& name, int x1, int x2, int x3)
|
| 695 |
+
{
|
| 696 |
+
glUniform3i( GetUniformHandle(name), x1, x2, x3);
|
| 697 |
+
}
|
| 698 |
+
|
| 699 |
+
inline void GlSlProgram::SetUniform(const std::string& name, int x1, int x2, int x3, int x4)
|
| 700 |
+
{
|
| 701 |
+
glUniform4i( GetUniformHandle(name), x1, x2, x3, x4);
|
| 702 |
+
}
|
| 703 |
+
|
| 704 |
+
inline void GlSlProgram::SetUniform(const std::string& name, float f)
|
| 705 |
+
{
|
| 706 |
+
glUniform1f( GetUniformHandle(name), f);
|
| 707 |
+
}
|
| 708 |
+
|
| 709 |
+
inline void GlSlProgram::SetUniform(const std::string& name, float f1, float f2)
|
| 710 |
+
{
|
| 711 |
+
glUniform2f( GetUniformHandle(name), f1,f2);
|
| 712 |
+
}
|
| 713 |
+
|
| 714 |
+
inline void GlSlProgram::SetUniform(const std::string& name, float f1, float f2, float f3)
|
| 715 |
+
{
|
| 716 |
+
glUniform3f( GetUniformHandle(name), f1,f2,f3);
|
| 717 |
+
}
|
| 718 |
+
|
| 719 |
+
inline void GlSlProgram::SetUniform(const std::string& name, float f1, float f2, float f3, float f4)
|
| 720 |
+
{
|
| 721 |
+
glUniform4f( GetUniformHandle(name), f1,f2,f3,f4);
|
| 722 |
+
}
|
| 723 |
+
|
| 724 |
+
inline void GlSlProgram::SetUniform(const std::string& name, Colour c)
|
| 725 |
+
{
|
| 726 |
+
glUniform4f( GetUniformHandle(name), c.r, c.g, c.b, c.a);
|
| 727 |
+
}
|
| 728 |
+
|
| 729 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const OpenGlMatrix& mat)
|
| 730 |
+
{
|
| 731 |
+
// glUniformMatrix4dv seems to be crashing...
|
| 732 |
+
float m[16];
|
| 733 |
+
for (int i = 0; i < 16; ++i) {
|
| 734 |
+
m[i] = (float)mat.m[i];
|
| 735 |
+
}
|
| 736 |
+
glUniformMatrix4fv( GetUniformHandle(name), 1, GL_FALSE, m);
|
| 737 |
+
}
|
| 738 |
+
|
| 739 |
+
#ifdef HAVE_EIGEN
|
| 740 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Vector2f& v)
|
| 741 |
+
{
|
| 742 |
+
glUniform2f( GetUniformHandle(name), v[0], v[1]);
|
| 743 |
+
}
|
| 744 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Vector3f& v)
|
| 745 |
+
{
|
| 746 |
+
glUniform3f( GetUniformHandle(name), v[0], v[1], v[2]);
|
| 747 |
+
}
|
| 748 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Vector4f& v)
|
| 749 |
+
{
|
| 750 |
+
glUniform4f( GetUniformHandle(name), v[0], v[1], v[2], v[3]);
|
| 751 |
+
}
|
| 752 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Matrix2f& m)
|
| 753 |
+
{
|
| 754 |
+
glUniformMatrix2fv( GetUniformHandle(name), 1, GL_FALSE, m.data());
|
| 755 |
+
}
|
| 756 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Matrix3f& m)
|
| 757 |
+
{
|
| 758 |
+
glUniformMatrix3fv( GetUniformHandle(name), 1, GL_FALSE, m.data());
|
| 759 |
+
}
|
| 760 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Matrix4f& m)
|
| 761 |
+
{
|
| 762 |
+
glUniformMatrix4fv( GetUniformHandle(name), 1, GL_FALSE, m.data());
|
| 763 |
+
}
|
| 764 |
+
|
| 765 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Vector2d& v)
|
| 766 |
+
{
|
| 767 |
+
glUniform2d( GetUniformHandle(name), v[0], v[1]);
|
| 768 |
+
}
|
| 769 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Vector3d& v)
|
| 770 |
+
{
|
| 771 |
+
glUniform3d( GetUniformHandle(name), v[0], v[1], v[2]);
|
| 772 |
+
}
|
| 773 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Vector4d& v)
|
| 774 |
+
{
|
| 775 |
+
glUniform4d( GetUniformHandle(name), v[0], v[1], v[2], v[3]);
|
| 776 |
+
}
|
| 777 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Matrix2d& m)
|
| 778 |
+
{
|
| 779 |
+
glUniformMatrix2dv( GetUniformHandle(name), 1, GL_FALSE, m.data());
|
| 780 |
+
}
|
| 781 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Matrix3d& m)
|
| 782 |
+
{
|
| 783 |
+
glUniformMatrix3dv( GetUniformHandle(name), 1, GL_FALSE, m.data());
|
| 784 |
+
}
|
| 785 |
+
inline void GlSlProgram::SetUniform(const std::string& name, const Eigen::Matrix4d& m)
|
| 786 |
+
{
|
| 787 |
+
glUniformMatrix4dv( GetUniformHandle(name), 1, GL_FALSE, m.data());
|
| 788 |
+
}
|
| 789 |
+
#endif
|
| 790 |
+
|
| 791 |
+
inline void GlSlProgram::BindPangolinDefaultAttribLocationsAndLink()
|
| 792 |
+
{
|
| 793 |
+
glBindAttribLocation(prog, DEFAULT_LOCATION_POSITION, DEFAULT_NAME_POSITION);
|
| 794 |
+
glBindAttribLocation(prog, DEFAULT_LOCATION_COLOUR, DEFAULT_NAME_COLOUR);
|
| 795 |
+
glBindAttribLocation(prog, DEFAULT_LOCATION_NORMAL, DEFAULT_NAME_NORMAL);
|
| 796 |
+
glBindAttribLocation(prog, DEFAULT_LOCATION_TEXCOORD, DEFAULT_NAME_TEXCOORD);
|
| 797 |
+
Link();
|
| 798 |
+
}
|
| 799 |
+
|
| 800 |
+
#if GL_VERSION_4_3
|
| 801 |
+
inline GLint GlSlProgram::GetProgramResourceIndex(const std::string& name)
|
| 802 |
+
{
|
| 803 |
+
return glGetProgramResourceIndex(prog, GL_SHADER_STORAGE_BLOCK, name.c_str());
|
| 804 |
+
}
|
| 805 |
+
|
| 806 |
+
inline void GlSlProgram::SetShaderStorageBlock(const std::string& name, const int& bindingIndex)
|
| 807 |
+
{
|
| 808 |
+
glShaderStorageBlockBinding(prog, GetProgramResourceIndex(name), bindingIndex);
|
| 809 |
+
}
|
| 810 |
+
#endif
|
| 811 |
+
|
| 812 |
+
}
|
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glstate.h
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* This file is part of the Pangolin Project.
|
| 2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
| 3 |
+
*
|
| 4 |
+
* Copyright (c) 2013 Vincent Mamo, Steven Lovegrove
|
| 5 |
+
*
|
| 6 |
+
* Permission is hereby granted, free of charge, to any person
|
| 7 |
+
* obtaining a copy of this software and associated documentation
|
| 8 |
+
* files (the "Software"), to deal in the Software without
|
| 9 |
+
* restriction, including without limitation the rights to use,
|
| 10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
* copies of the Software, and to permit persons to whom the
|
| 12 |
+
* Software is furnished to do so, subject to the following
|
| 13 |
+
* conditions:
|
| 14 |
+
*
|
| 15 |
+
* The above copyright notice and this permission notice shall be
|
| 16 |
+
* included in all copies or substantial portions of the Software.
|
| 17 |
+
*
|
| 18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
| 20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
| 23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
| 24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
*/
|
| 27 |
+
|
| 28 |
+
#pragma once
|
| 29 |
+
|
| 30 |
+
#include <pangolin/gl/glinclude.h>
|
| 31 |
+
#include <stack>
|
| 32 |
+
|
| 33 |
+
namespace pangolin
|
| 34 |
+
{
|
| 35 |
+
|
| 36 |
+
class GlState {
|
| 37 |
+
|
| 38 |
+
class CapabilityState {
|
| 39 |
+
public:
|
| 40 |
+
|
| 41 |
+
CapabilityState(GLenum cap, GLboolean enable)
|
| 42 |
+
: m_cap(cap), m_enable(enable)
|
| 43 |
+
{
|
| 44 |
+
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
void Apply() {
|
| 48 |
+
if(m_enable) {
|
| 49 |
+
::glEnable(m_cap);
|
| 50 |
+
}else{
|
| 51 |
+
::glDisable(m_cap);
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
void UnApply() {
|
| 56 |
+
if(m_enable) {
|
| 57 |
+
::glDisable(m_cap);
|
| 58 |
+
}else{
|
| 59 |
+
::glEnable(m_cap);
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
protected:
|
| 64 |
+
GLenum m_cap;
|
| 65 |
+
GLboolean m_enable;
|
| 66 |
+
};
|
| 67 |
+
|
| 68 |
+
public:
|
| 69 |
+
GlState()
|
| 70 |
+
: m_DepthMaskCalled(false),
|
| 71 |
+
m_ShadeModelCalled(false),
|
| 72 |
+
m_CullFaceCalled(false),
|
| 73 |
+
m_PointSizeCalled(false),
|
| 74 |
+
m_LineWidthCalled(false),
|
| 75 |
+
m_ColorMaskCalled(false),
|
| 76 |
+
m_ViewportCalled(false)
|
| 77 |
+
{
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
~GlState() {
|
| 81 |
+
// Restore original state
|
| 82 |
+
while (!m_history.empty()) {
|
| 83 |
+
m_history.top().UnApply();
|
| 84 |
+
m_history.pop();
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
if (m_DepthMaskCalled) {
|
| 88 |
+
::glDepthMask(m_OriginalDepthMask);
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
if (m_ShadeModelCalled) {
|
| 92 |
+
::glShadeModel(m_OriginalShadeModel);
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
if (m_CullFaceCalled) {
|
| 96 |
+
::glCullFace(m_OriginalCullFace);
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
if(m_PointSizeCalled) {
|
| 100 |
+
::glPointSize(m_OriginalPointSize);
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
if(m_LineWidthCalled) {
|
| 104 |
+
::glLineWidth(m_OriginalLineWidth);
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
if (m_ColorMaskCalled) {
|
| 108 |
+
::glColorMask(m_OriginalColorMask[0], m_OriginalColorMask[1], m_OriginalColorMask[2], m_OriginalColorMask[3]);
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
if (m_ViewportCalled) {
|
| 112 |
+
::glViewport(m_OriginalViewport[0], m_OriginalViewport[1], m_OriginalViewport[2], m_OriginalViewport[3]);
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
static inline GLboolean IsEnabled(GLenum cap)
|
| 117 |
+
{
|
| 118 |
+
GLboolean curVal;
|
| 119 |
+
glGetBooleanv(cap, &curVal);
|
| 120 |
+
return curVal;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
inline void glEnable(GLenum cap)
|
| 124 |
+
{
|
| 125 |
+
if(!IsEnabled(cap)) {
|
| 126 |
+
m_history.push(CapabilityState(cap,true));
|
| 127 |
+
::glEnable(cap);
|
| 128 |
+
}
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
inline void glDisable(GLenum cap)
|
| 132 |
+
{
|
| 133 |
+
if(IsEnabled(cap)) {
|
| 134 |
+
m_history.push(CapabilityState(cap,false));
|
| 135 |
+
::glDisable(cap);
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
bool m_DepthMaskCalled;
|
| 140 |
+
GLboolean m_OriginalDepthMask;
|
| 141 |
+
inline void glDepthMask(GLboolean flag)
|
| 142 |
+
{
|
| 143 |
+
if(!m_DepthMaskCalled) {
|
| 144 |
+
m_DepthMaskCalled = true;
|
| 145 |
+
glGetBooleanv(GL_DEPTH_WRITEMASK, &m_OriginalDepthMask);
|
| 146 |
+
}
|
| 147 |
+
::glDepthMask(flag);
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
bool m_ShadeModelCalled;
|
| 151 |
+
GLint m_OriginalShadeModel;
|
| 152 |
+
inline void glShadeModel(GLint mode)
|
| 153 |
+
{
|
| 154 |
+
if(!m_ShadeModelCalled) {
|
| 155 |
+
m_ShadeModelCalled = true;
|
| 156 |
+
glGetIntegerv(GL_SHADE_MODEL, &m_OriginalShadeModel);
|
| 157 |
+
}
|
| 158 |
+
::glShadeModel(mode);
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
bool m_CullFaceCalled;
|
| 162 |
+
GLint m_OriginalCullFace;
|
| 163 |
+
void glCullFace(GLenum mode)
|
| 164 |
+
{
|
| 165 |
+
if(!m_ShadeModelCalled) {
|
| 166 |
+
m_ShadeModelCalled = true;
|
| 167 |
+
glGetIntegerv(GL_CULL_FACE_MODE, &m_OriginalCullFace);
|
| 168 |
+
}
|
| 169 |
+
::glCullFace(mode);
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
bool m_PointSizeCalled;
|
| 173 |
+
GLfloat m_OriginalPointSize;
|
| 174 |
+
void glPointSize(GLfloat size)
|
| 175 |
+
{
|
| 176 |
+
if(!m_PointSizeCalled) {
|
| 177 |
+
m_PointSizeCalled = true;
|
| 178 |
+
glGetFloatv(GL_POINT_SIZE, &m_OriginalPointSize);
|
| 179 |
+
}
|
| 180 |
+
::glPointSize(size);
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
bool m_LineWidthCalled;
|
| 184 |
+
GLfloat m_OriginalLineWidth;
|
| 185 |
+
void glLineWidth(GLfloat width)
|
| 186 |
+
{
|
| 187 |
+
if(!m_LineWidthCalled) {
|
| 188 |
+
m_LineWidthCalled = true;
|
| 189 |
+
glGetFloatv(GL_LINE_WIDTH, &m_OriginalLineWidth);
|
| 190 |
+
}
|
| 191 |
+
::glLineWidth(width);
|
| 192 |
+
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
bool m_ColorMaskCalled;
|
| 196 |
+
GLboolean m_OriginalColorMask[4];
|
| 197 |
+
inline void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
|
| 198 |
+
{
|
| 199 |
+
if(!m_ColorMaskCalled) {
|
| 200 |
+
m_ColorMaskCalled = true;
|
| 201 |
+
glGetBooleanv(GL_COLOR_WRITEMASK, m_OriginalColorMask);
|
| 202 |
+
}
|
| 203 |
+
::glColorMask(red, green, blue, alpha);
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
bool m_ViewportCalled;
|
| 207 |
+
GLint m_OriginalViewport[4];
|
| 208 |
+
inline void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
|
| 209 |
+
{
|
| 210 |
+
if(!m_ViewportCalled) {
|
| 211 |
+
m_ViewportCalled = true;
|
| 212 |
+
glGetIntegerv(GL_VIEWPORT, m_OriginalViewport);
|
| 213 |
+
}
|
| 214 |
+
::glViewport(x, y, width, height);
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
std::stack<CapabilityState> m_history;
|
| 218 |
+
};
|
| 219 |
+
|
| 220 |
+
}
|