34 #include <opencv2/imgproc/imgproc.hpp> 36 #include "pcl/common/transforms.h" 38 #include <GLES2/gl2.h> 60 "precision mediump float;\n" 61 "precision mediump int;\n" 62 "attribute vec3 aVertex;\n" 63 "attribute vec3 aColor;\n" 65 "uniform mat4 uMVP;\n" 66 "uniform float uPointSize;\n" 68 "varying vec3 vColor;\n" 69 "varying float vLightWeighting;\n" 72 " gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n" 73 " gl_PointSize = uPointSize;\n" 74 " vLightWeighting = 1.0;\n" 78 "precision mediump float;\n" 79 "precision mediump int;\n" 80 "attribute vec3 aVertex;\n" 81 "attribute vec3 aNormal;\n" 82 "attribute vec3 aColor;\n" 84 "uniform mat4 uMVP;\n" 86 "uniform vec3 uLightingDirection;\n" 87 "uniform float uPointSize;\n" 89 "varying vec3 vColor;\n" 90 "varying float vLightWeighting;\n" 93 " gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n" 94 " gl_PointSize = uPointSize;\n" 95 " vec3 transformedNormal = uN * aNormal;\n" 96 " vLightWeighting = max(dot(transformedNormal, uLightingDirection)*0.5+0.5, 0.0);\n" 97 " if(vLightWeighting<0.5)" 98 " vLightWeighting=0.5;\n" 103 "precision mediump float;\n" 104 "precision mediump int;\n" 105 "uniform float uGainR;\n" 106 "uniform float uGainG;\n" 107 "uniform float uGainB;\n" 108 "varying vec3 vColor;\n" 109 "varying float vLightWeighting;\n" 111 " vec4 textureColor = vec4(vColor.z, vColor.y, vColor.x, 1.0);\n" 112 " gl_FragColor = vec4(textureColor.r * uGainR * vLightWeighting, textureColor.g * uGainG * vLightWeighting, textureColor.b * uGainB * vLightWeighting, textureColor.a);\n" 115 "precision highp float;\n" 116 "precision mediump int;\n" 117 "uniform float uGainR;\n" 118 "uniform float uGainG;\n" 119 "uniform float uGainB;\n" 120 "uniform float uNearZ;\n" 121 "uniform float uFarZ;\n" 122 "uniform sampler2D uDepthTexture;\n" 123 "uniform vec2 uScreenScale;\n" 124 "varying vec3 vColor;\n" 125 "varying float vLightWeighting;\n" 127 " vec4 textureColor = vec4(vColor.z, vColor.y, vColor.x, 1.0);\n" 128 " float alpha = 1.0;\n" 129 " vec2 coord = uScreenScale * gl_FragCoord.xy;\n;" 130 " float depth = texture2D(uDepthTexture, coord).r;\n" 131 " float num = (2.0 * uNearZ * uFarZ);\n" 132 " float diff = (uFarZ - uNearZ);\n" 133 " float add = (uFarZ + uNearZ);\n" 134 " float ndcDepth = depth * 2.0 - 1.0;\n" 135 " float linearDepth = num / (add - ndcDepth * diff);\n" 136 " float ndcFragz = gl_FragCoord.z * 2.0 - 1.0;\n" 137 " float linearFragz = num / (add - ndcFragz * diff);\n" 138 " if(linearFragz > linearDepth + 0.05)\n" 140 " gl_FragColor = vec4(textureColor.r * uGainR * vLightWeighting, textureColor.g * uGainG * vLightWeighting, textureColor.b * uGainB * vLightWeighting, alpha);\n" 144 "precision mediump float;\n" 145 "precision mediump int;\n" 146 "attribute vec3 aVertex;\n" 147 "uniform mat4 uMVP;\n" 148 "uniform float uPointSize;\n" 150 " gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n" 151 " gl_PointSize = uPointSize;\n" 154 "precision highp float;\n" 155 "precision mediump int;\n" 157 " float toFixed = 255.0/256.0;\n" 158 " vec4 enc = vec4(1.0, 255.0, 65025.0, 160581375.0) * toFixed * gl_FragCoord.z;\n" 159 " enc = fract(enc);\n" 160 " gl_FragColor = enc;\n" 165 "precision mediump float;\n" 166 "precision mediump int;\n" 167 "attribute vec3 aVertex;\n" 168 "attribute vec2 aTexCoord;\n" 170 "uniform mat4 uMVP;\n" 172 "varying vec2 vTexCoord;\n" 173 "varying float vLightWeighting;\n" 176 " gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n" 178 " if(aTexCoord.x < 0.0) {\n" 179 " vTexCoord.x = 1.0;\n" 180 " vTexCoord.y = 1.0;\n" 182 " vTexCoord = aTexCoord;\n" 185 " vLightWeighting = 1.0;\n" 188 "precision mediump float;\n" 189 "precision mediump int;\n" 190 "attribute vec3 aVertex;\n" 191 "attribute vec3 aNormal;\n" 192 "attribute vec2 aTexCoord;\n" 194 "uniform mat4 uMVP;\n" 196 "uniform vec3 uLightingDirection;\n" 198 "varying vec2 vTexCoord;\n" 199 "varying float vLightWeighting;\n" 202 " gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n" 204 " if(aTexCoord.x < 0.0) {\n" 205 " vTexCoord.x = 1.0;\n" 206 " vTexCoord.y = 1.0;\n" 208 " vTexCoord = aTexCoord;\n" 211 " vec3 transformedNormal = uN * aNormal;\n" 212 " vLightWeighting = max(dot(transformedNormal, uLightingDirection)*0.5+0.5, 0.0);\n" 213 " if(vLightWeighting<0.5) \n" 214 " vLightWeighting=0.5;\n" 217 "precision mediump float;\n" 218 "precision mediump int;\n" 219 "uniform sampler2D uTexture;\n" 220 "uniform float uGainR;\n" 221 "uniform float uGainG;\n" 222 "uniform float uGainB;\n" 223 "varying vec2 vTexCoord;\n" 224 "varying float vLightWeighting;\n" 227 " vec4 textureColor = texture2D(uTexture, vTexCoord);\n" 228 " gl_FragColor = vec4(textureColor.r * uGainR * vLightWeighting, textureColor.g * uGainG * vLightWeighting, textureColor.b * uGainB * vLightWeighting, textureColor.a);\n" 231 "precision highp float;\n" 232 "precision mediump int;\n" 233 "uniform sampler2D uTexture;\n" 234 "uniform sampler2D uDepthTexture;\n" 235 "uniform float uGainR;\n" 236 "uniform float uGainG;\n" 237 "uniform float uGainB;\n" 238 "uniform vec2 uScreenScale;\n" 239 "uniform float uNearZ;\n" 240 "uniform float uFarZ;\n" 241 "varying vec2 vTexCoord;\n" 242 "varying float vLightWeighting;\n" 245 " vec4 textureColor = texture2D(uTexture, vTexCoord);\n" 246 " float alpha = 1.0;\n" 247 " vec2 coord = uScreenScale * gl_FragCoord.xy;\n;" 248 " float depth = texture2D(uDepthTexture, coord).r;\n" 249 " float num = (2.0 * uNearZ * uFarZ);\n" 250 " float diff = (uFarZ - uNearZ);\n" 251 " float add = (uFarZ + uNearZ);\n" 252 " float ndcDepth = depth * 2.0 - 1.0;\n" 253 " float linearDepth = num / (add - ndcDepth * diff);\n" 254 " float ndcFragz = gl_FragCoord.z * 2.0 - 1.0;\n" 255 " float linearFragz = num / (add - ndcFragz * diff);\n" 256 " if(linearFragz > linearDepth + 0.05)\n" 258 " gl_FragColor = vec4(textureColor.r * uGainR * vLightWeighting, textureColor.g * uGainG * vLightWeighting, textureColor.b * uGainB * vLightWeighting, alpha);\n" 301 const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
302 const pcl::IndicesPtr & indices,
322 bool createWireframe) :
357 LOGD(
"Update polygons");
364 unsigned int polygonSize = polygons[0].vertices.size();
366 polygons_.resize(polygons.size() * polygonSize);
371 for(
unsigned int i=0; i<polygons.size(); ++i)
374 for(
unsigned int j=0; j<polygonSize; ++j)
385 if(polygonsLowRes.size())
387 unsigned int polygonSize = polygonsLowRes[0].vertices.size();
394 for(
unsigned int i=0; i<polygonsLowRes.size(); ++i)
397 for(
unsigned int j=0; j<polygonSize; ++j)
413 UASSERT(cloud.get() && !cloud->empty());
439 LOGE(
"OpenGL: could not generate vertex buffers\n");
446 if(indices.get() && indices->size())
448 totalPoints = indices->size();
449 vertices.resize(indices->size()*4);
454 for(
unsigned int i=0; i<indices->size(); ++i)
456 const pcl::PointXYZRGB & pt = cloud->at(indices->at(i));
457 vertices[i*4] = pt.x;
458 vertices[i*4+1] = pt.y;
459 vertices[i*4+2] = pt.z;
460 vertices[i*4+3] = pt.rgb;
464 if(cloud->isOrganized())
466 if(indices->at(i)%
LOW_DEC == 0 && (indices->at(i)/cloud->width) %
LOW_DEC == 0)
481 totalPoints = cloud->size();
482 vertices.resize(cloud->size()*4);
487 for(
unsigned int i=0; i<cloud->size(); ++i)
489 const pcl::PointXYZRGB & pt = cloud->at(i);
490 vertices[i*4] = pt.x;
491 vertices[i*4+1] = pt.y;
492 vertices[i*4+2] = pt.z;
493 vertices[i*4+3] = pt.rgb;
497 if(cloud->isOrganized())
514 glBufferData(GL_ARRAY_BUFFER,
sizeof(GLfloat) * (
int)vertices.size(), (
const void *)vertices.data(), GL_STATIC_DRAW);
515 glBindBuffer(GL_ARRAY_BUFFER, 0);
517 GLint error = glGetError();
518 if(error != GL_NO_ERROR)
520 LOGE(
"OpenGL: Could not allocate point cloud (0x%x)\n", error);
525 nPoints_ = totalPoints;
546 bool textureUpdate =
false;
555 textureUpdate =
true;
561 LOGE(
"OpenGL: could not generate vertex buffers\n");
571 LOGE(
"OpenGL: could not generate texture buffers\n");
579 std::vector<pcl::Vertices> polygons = mesh.
polygons;
580 std::vector<pcl::Vertices> polygonsLowRes;
583 if(mesh.
cloud->isOrganized())
587 totalPoints = mesh.
indices->size();
595 vertices = std::vector<float>(mesh.
indices->size()*items);
596 for(
unsigned int i=0; i<mesh.
indices->size(); ++i)
598 const pcl::PointXYZRGB & pt = mesh.
cloud->at(mesh.
indices->at(i));
599 vertices[i*items] = pt.x;
600 vertices[i*items+1] = pt.y;
601 vertices[i*items+2] = pt.z;
604 vertices[i*items+3] = pt.rgb;
609 int index = mesh.
indices->at(i);
610 vertices[i*items+4] = float(index % mesh.
cloud->width)/float(mesh.
cloud->width);
611 vertices[i*items+5] = float(index / mesh.
cloud->width)/float(mesh.
cloud->height);
616 vertices[i*items+6] = mesh.
normals->at(mesh.
indices->at(i)).normal_x;
617 vertices[i*items+7] = mesh.
normals->at(mesh.
indices->at(i)).normal_y;
618 vertices[i*items+8] = mesh.
normals->at(mesh.
indices->at(i)).normal_z;
637 vertices = std::vector<float>(mesh.
indices->size()*items);
638 for(
unsigned int i=0; i<mesh.
indices->size(); ++i)
640 const pcl::PointXYZRGB & pt = mesh.
cloud->at(mesh.
indices->at(i));
641 vertices[i*items] = pt.x;
642 vertices[i*items+1] = pt.y;
643 vertices[i*items+2] = pt.z;
644 vertices[i*items+3] = pt.rgb;
651 vertices[i*items+4] = mesh.
normals->at(mesh.
indices->at(i)).normal_x;
652 vertices[i*items+5] = mesh.
normals->at(mesh.
indices->at(i)).normal_y;
653 vertices[i*items+6] = mesh.
normals->at(mesh.
indices->at(i)).normal_z;
683 vertices = std::vector<float>(mesh.
texCoords.size()*9);
687 uFormat(
"%d vs %d x %d", (
int)mesh.
texCoords.size(), (int)polygons[0].vertices.size(), (int)polygons.size()).c_str());
691 for(
unsigned int i=0; i<polygons.size(); ++i)
693 pcl::Vertices & v = polygons[i];
694 for(
unsigned int j=0; j<v.vertices.size(); ++j)
699 const pcl::PointXYZRGB & pt = mesh.
cloud->at(v.vertices[j]);
701 vertices[oi*items] = pt.x;
702 vertices[oi*items+1] = pt.y;
703 vertices[oi*items+2] = pt.z;
706 vertices[oi*items+3] = pt.rgb;
713 vertices[oi*items+4] = mesh.
texCoords[oi][0];
714 vertices[oi*items+5] = 1.0f-mesh.
texCoords[oi][1];
718 vertices[oi*items+4] = vertices[oi*items+5] = -1.0f;
724 vertices[oi*items+6] = mesh.
normals->at(v.vertices[j]).normal_x;
725 vertices[oi*items+7] = mesh.
normals->at(v.vertices[j]).normal_y;
726 vertices[oi*items+8] = mesh.
normals->at(v.vertices[j]).normal_z;
729 v.vertices[j] = (int)oi;
731 UASSERT(oi < organizedToDenseIndices_.size());
732 organizedToDenseIndices_[oi] = oi;
740 totalPoints = mesh.
cloud->size();
744 vertices = std::vector<float>(mesh.
cloud->size()*items);
745 for(
unsigned int i=0; i<mesh.
cloud->size(); ++i)
747 const pcl::PointXYZRGB & pt = mesh.
cloud->at(i);
749 vertices[i*items] =pt.x;
750 vertices[i*items+1] = pt.y;
751 vertices[i*items+2] = pt.z;
752 vertices[i*items+3] = pt.rgb;
758 vertices[i*items+4] = mesh.
normals->at(i).normal_x;
759 vertices[i*items+5] = mesh.
normals->at(i).normal_y;
760 vertices[i*items+6] = mesh.
normals->at(i).normal_z;
769 glBufferData(GL_ARRAY_BUFFER,
sizeof(GLfloat) * (
int)vertices.size(), (
const void *)vertices.data(), GL_STATIC_DRAW);
770 glBindBuffer(GL_ARRAY_BUFFER, 0);
772 GLint error = glGetError();
773 if(error != GL_NO_ERROR)
775 LOGE(
"OpenGL: Could not allocate point cloud (0x%x)\n", error);
791 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
792 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
793 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
794 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
796 cv::cvtColor(mesh.
texture, rgbImage, CV_BGR2RGBA);
798 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
802 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rgbImage.cols, rgbImage.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbImage.data);
804 GLint error = glGetError();
805 if(error != GL_NO_ERROR)
807 LOGE(
"OpenGL: Could not allocate texture (0x%x)\n", error);
816 nPoints_ = totalPoints;
844 pcl::PointCloud<pcl::PointXYZ> corners;
855 pcl::PointCloud<pcl::PointXYZ> cornersTransformed;
860 for(
unsigned int i=0; i<cornersTransformed.size(); ++i)
872 bool textureRendering,
874 float distanceToCameraSqr,
875 const GLuint & depthTexture,
880 bool packDepthToColorChannel,
881 bool wireFrame)
const 890 if(packDepthToColorChannel || !(meshRendering && textureRendering &&
textures_))
892 textureRendering =
false;
896 if(packDepthToColorChannel)
900 else if(textureRendering)
923 glUseProgram(program);
926 GLuint mvp_handle = glGetUniformLocation(program,
"uMVP");
928 glm::mat4 mvp_mat = projectionMatrix * mv_mat;
931 GLint attribute_vertex = glGetAttribLocation(program,
"aVertex");
932 glEnableVertexAttribArray(attribute_vertex);
933 GLint attribute_color = 0;
934 GLint attribute_texture = 0;
935 GLint attribute_normal = 0;
937 if(packDepthToColorChannel || !textureRendering)
939 GLuint point_size_handle_ = glGetUniformLocation(program,
"uPointSize");
940 glUniform1f(point_size_handle_, pointSize);
944 if(!packDepthToColorChannel)
946 GLuint gainR_handle = glGetUniformLocation(program,
"uGainR");
947 GLuint gainG_handle = glGetUniformLocation(program,
"uGainG");
948 GLuint gainB_handle = glGetUniformLocation(program,
"uGainB");
949 glUniform1f(gainR_handle,
gainR_);
950 glUniform1f(gainG_handle,
gainG_);
951 glUniform1f(gainB_handle,
gainB_);
957 glActiveTexture(GL_TEXTURE1);
959 glBindTexture(GL_TEXTURE_2D, depthTexture);
961 GLuint depth_texture_handle = glGetUniformLocation(program,
"uDepthTexture");
962 glUniform1i(depth_texture_handle, 1);
964 GLuint zNear_handle = glGetUniformLocation(program,
"uNearZ");
965 GLuint zFar_handle = glGetUniformLocation(program,
"uFarZ");
966 glUniform1f(zNear_handle, nearClipPlane);
967 glUniform1f(zFar_handle, farClipPlane);
969 GLuint screenScale_handle = glGetUniformLocation(program,
"uScreenScale");
970 glUniform2f(screenScale_handle, 1.0
f/(
float)screenWidth, 1.0
f/(
float)screenHeight);
975 GLuint n_handle = glGetUniformLocation(program,
"uN");
978 normalMatrix = glm::transpose(normalMatrix);
981 GLuint lightingDirection_handle = glGetUniformLocation(program,
"uLightingDirection");
982 glUniform3f(lightingDirection_handle, 0.0, 0.0, 1.0);
984 attribute_normal = glGetAttribLocation(program,
"aNormal");
985 glEnableVertexAttribArray(attribute_normal);
991 glActiveTexture(GL_TEXTURE0);
995 GLuint texture_handle = glGetUniformLocation(program,
"uTexture");
996 glUniform1i(texture_handle, 0);
998 attribute_texture = glGetAttribLocation(program,
"aTexCoord");
999 glEnableVertexAttribArray(attribute_texture);
1003 attribute_color = glGetAttribLocation(program,
"aColor");
1004 glEnableVertexAttribArray(attribute_color);
1012 glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT,
GL_FALSE, (
hasNormals_?9:6)*
sizeof(GLfloat), 0);
1013 if(textureRendering)
1015 glVertexAttribPointer(attribute_texture, 2, GL_FLOAT,
GL_FALSE, (
hasNormals_?9:6)*
sizeof(GLfloat), (GLvoid*) (4 *
sizeof(GLfloat)));
1017 else if(!packDepthToColorChannel)
1019 glVertexAttribPointer(attribute_color, 3, GL_UNSIGNED_BYTE, GL_TRUE, (
hasNormals_?9:6)*
sizeof(GLfloat), (GLvoid*) (3 *
sizeof(GLfloat)));
1023 glVertexAttribPointer(attribute_normal, 3, GL_FLOAT,
GL_FALSE, 9*
sizeof(GLfloat), (GLvoid*) (6 *
sizeof(GLfloat)));
1028 glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT,
GL_FALSE, (
hasNormals_?7:4)*
sizeof(GLfloat), 0);
1029 if(!packDepthToColorChannel)
1031 glVertexAttribPointer(attribute_color, 3, GL_UNSIGNED_BYTE, GL_TRUE, (
hasNormals_?7:4)*
sizeof(GLfloat), (GLvoid*) (3 *
sizeof(GLfloat)));
1035 glVertexAttribPointer(attribute_normal, 3, GL_FLOAT,
GL_FALSE, 7*
sizeof(GLfloat), (GLvoid*) (4 *
sizeof(GLfloat)));
1041 if(textureRendering)
1060 else if(meshRendering &&
polygons_.size())
1081 if(distanceToCameraSqr>600.0
f)
1085 else if(distanceToCameraSqr>150.0
f)
1091 glDrawArrays(GL_POINTS, 0,
nPoints_);
1096 glDrawArrays(GL_POINTS, 0,
nPoints_);
1101 glDisableVertexAttribArray(0);
1102 glBindBuffer(GL_ARRAY_BUFFER, 0);
const std::string kPointCloudBlendingFragmentShader
static void releaseShaderPrograms()
std::vector< GLuint > polygonLinesLowRes_
std::vector< GLuint > polygons_
const std::string kTextureMeshBlendingFragmentShader
std::vector< GLuint > polygonLines_
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP transformPointCloud(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const Transform &transform)
void setPose(const rtabmap::Transform &pose)
std::vector< GLuint > polygonsLowRes_
void updatePolygons(const std::vector< pcl::Vertices > &polygons, const std::vector< pcl::Vertices > &polygonsLowRes=std::vector< pcl::Vertices >(), bool createWireframe=false)
static const float vertices[]
const std::string kTextureMeshVertexShader
pcl::PointCloud< pcl::Normal >::Ptr normals
std::vector< pcl::Vertices > polygons
glm::mat4 glmFromTransform(const rtabmap::Transform &transform)
Some conversion functions.
GLuint CreateProgram(const char *vertex_source, const char *fragment_source)
void Render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix, bool meshRendering=true, float pointSize=3.0f, bool textureRendering=false, bool lighting=true, float distanceToCamSqr=0.0f, const GLuint &depthTexture=0, int screenWidth=0, int screenHeight=0, float nearClipPlane=0, float farClipPlane=0, bool packDepthToColorChannel=false, bool wireFrame=false) const
pcl::PointCloud< pcl::PointXYZRGB >::Ptr cloud
pcl::PointXYZ aabbMaxWorld_
const std::string kPointCloudLightingVertexShader
void updateCloud(const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, const pcl::IndicesPtr &indices)
const std::string kTextureMeshFragmentShader
std::vector< GLuint > verticesLowRes_
pcl::PointXYZ aabbMinWorld_
std::vector< pcl::Vertices > polygonsLowRes
GLM_FUNC_DECL genType::value_type const * value_ptr(genType const &vec)
const std::string kPointCloudDepthPackingVertexShader
#define UASSERT(condition)
pcl::PointXYZ aabbMinModel_
#define UASSERT_MSG(condition, msg_str)
std::vector< GLuint > verticesLowLowRes_
const std::string kTextureMeshLightingVertexShader
virtual ~PointCloudDrawable()
const std::string kPointCloudDepthPackingFragmentShader
PointCloudDrawable(const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, const pcl::IndicesPtr &indices, float gainR=1.0f, float gainG=1.0f, float gainB=1.0f)
void updateAABBWorld(const rtabmap::Transform &pose)
const std::string kPointCloudFragmentShader
static std::vector< GLuint > shaderPrograms_
std::vector< unsigned int > organizedToDenseIndices_
void updateMesh(const Mesh &mesh, bool createWireframe=false)
pcl::PointXYZ aabbMaxModel_
void updateAABBMinMax(const PointT &pt, pcl::PointXYZ &min, pcl::PointXYZ &max)
void glUniformMatrix4fv(GLuint, int, int, float *)
void CheckGlError(const char *operation)
ULogger class and convenient macros.
static void createShaderPrograms()
std::string UTILITE_EXP uFormat(const char *fmt,...)
const std::string kPointCloudVertexShader
std::vector< Eigen::Vector2f > texCoords
GLM_FUNC_DECL matType< T, P > inverse(matType< T, P > const &m)