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 |
+
}
|