point_cloud_drawable.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007     * Redistributions of source code must retain the above copyright
00008       notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright
00010       notice, this list of conditions and the following disclaimer in the
00011       documentation and/or other materials provided with the distribution.
00012     * Neither the name of the Universite de Sherbrooke nor the
00013       names of its contributors may be used to endorse or promote products
00014       derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
00020 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 */
00027 
00028 #include <sstream>
00029 
00030 #include "point_cloud_drawable.h"
00031 #include "rtabmap/utilite/ULogger.h"
00032 #include "rtabmap/utilite/UTimer.h"
00033 #include "rtabmap/utilite/UConversion.h"
00034 #include <opencv2/imgproc/imgproc.hpp>
00035 #include "util.h"
00036 #include "pcl/common/transforms.h"
00037 
00038 #include <GLES2/gl2.h>
00039 
00040 #define LOW_DEC 2
00041 #define LOWLOW_DEC 4
00042 
00043 enum PointCloudShaders
00044 {
00045         kPointCloud = 0,
00046         kPointCloudBlending = 1,
00047         kPointCloudLighting = 2,
00048         kPointCloudLightingBlending = 3,
00049 
00050         kTexture = 4,
00051         kTextureBlending = 5,
00052         kTextureLighting = 6,
00053         kTextureLightingBlending = 7,
00054 
00055         kDepthPacking = 8
00056 };
00057 
00058 // PointCloud shaders
00059 const std::string kPointCloudVertexShader =
00060     "precision mediump float;\n"
00061     "precision mediump int;\n"
00062     "attribute vec3 aVertex;\n"
00063     "attribute vec3 aColor;\n"
00064 
00065     "uniform mat4 uMVP;\n"
00066     "uniform float uPointSize;\n"
00067 
00068     "varying vec3 vColor;\n"
00069     "varying float vLightWeighting;\n"
00070 
00071     "void main() {\n"
00072     "  gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n"
00073     "  gl_PointSize = uPointSize;\n"
00074         "  vLightWeighting = 1.0;\n"
00075     "  vColor = aColor;\n"
00076     "}\n";
00077 const std::string kPointCloudLightingVertexShader =
00078     "precision mediump float;\n"
00079     "precision mediump int;\n"
00080     "attribute vec3 aVertex;\n"
00081         "attribute vec3 aNormal;\n"
00082     "attribute vec3 aColor;\n"
00083 
00084     "uniform mat4 uMVP;\n"
00085         "uniform mat3 uN;\n"
00086         "uniform vec3 uLightingDirection;\n"
00087     "uniform float uPointSize;\n"
00088 
00089     "varying vec3 vColor;\n"
00090     "varying float vLightWeighting;\n"
00091 
00092     "void main() {\n"
00093     "  gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n"
00094     "  gl_PointSize = uPointSize;\n"
00095         "  vec3 transformedNormal = uN * aNormal;\n"
00096         "  vLightWeighting = max(dot(transformedNormal, uLightingDirection)*0.5+0.5, 0.0);\n"
00097         "  if(vLightWeighting<0.5)"
00098         "    vLightWeighting=0.5;\n"
00099     "  vColor = aColor;\n"
00100     "}\n";
00101 
00102 const std::string kPointCloudFragmentShader =
00103     "precision mediump float;\n"
00104     "precision mediump int;\n"
00105         "uniform float uGainR;\n"
00106         "uniform float uGainG;\n"
00107         "uniform float uGainB;\n"
00108     "varying vec3 vColor;\n"
00109         "varying float vLightWeighting;\n"
00110     "void main() {\n"
00111     "  vec4 textureColor = vec4(vColor.z, vColor.y, vColor.x, 1.0);\n"
00112         "  gl_FragColor = vec4(textureColor.r * uGainR * vLightWeighting, textureColor.g * uGainG * vLightWeighting, textureColor.b * uGainB * vLightWeighting, textureColor.a);\n"
00113     "}\n";
00114 const std::string kPointCloudBlendingFragmentShader =
00115     "precision highp float;\n"
00116     "precision mediump int;\n"
00117         "uniform float uGainR;\n"
00118         "uniform float uGainG;\n"
00119         "uniform float uGainB;\n"
00120         "uniform float uNearZ;\n"
00121         "uniform float uFarZ;\n"
00122         "uniform sampler2D uDepthTexture;\n"
00123         "uniform vec2 uScreenScale;\n"
00124     "varying vec3 vColor;\n"
00125         "varying float vLightWeighting;\n"
00126     "void main() {\n"
00127     "  vec4 textureColor = vec4(vColor.z, vColor.y, vColor.x, 1.0);\n"
00128         "  float alpha = 1.0;\n"
00129         "  vec2 coord = uScreenScale * gl_FragCoord.xy;\n;"
00130         "  float depth = texture2D(uDepthTexture, coord).r;\n"
00131         "  float num =  (2.0 * uNearZ * uFarZ);\n"
00132         "  float diff = (uFarZ - uNearZ);\n"
00133         "  float add = (uFarZ + uNearZ);\n"
00134         "  float ndcDepth = depth * 2.0 - 1.0;\n" // Back to NDC
00135         "  float linearDepth = num / (add - ndcDepth * diff);\n" // inverse projection matrix
00136         "  float ndcFragz = gl_FragCoord.z * 2.0 - 1.0;\n" // Back to NDC
00137         "  float linearFragz = num / (add - ndcFragz * diff);\n" // inverse projection matrix
00138         "  if(linearFragz > linearDepth + 0.05)\n"
00139         "    alpha=0.0;\n"
00140         "  gl_FragColor = vec4(textureColor.r * uGainR * vLightWeighting, textureColor.g * uGainG * vLightWeighting, textureColor.b * uGainB * vLightWeighting, alpha);\n"
00141     "}\n";
00142 
00143 const std::string kPointCloudDepthPackingVertexShader =
00144     "precision mediump float;\n"
00145     "precision mediump int;\n"
00146     "attribute vec3 aVertex;\n"
00147     "uniform mat4 uMVP;\n"
00148     "uniform float uPointSize;\n"
00149     "void main() {\n"
00150     "  gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n"
00151     "  gl_PointSize = uPointSize;\n"
00152     "}\n";
00153 const std::string kPointCloudDepthPackingFragmentShader =
00154     "precision highp float;\n"
00155     "precision mediump int;\n"
00156     "void main() {\n"
00157         "  float toFixed = 255.0/256.0;\n"
00158         "  vec4 enc = vec4(1.0, 255.0, 65025.0, 160581375.0) * toFixed * gl_FragCoord.z;\n"
00159         "  enc = fract(enc);\n"
00160         "  gl_FragColor = enc;\n"
00161     "}\n";
00162 
00163 // Texture shaders
00164 const std::string kTextureMeshVertexShader =
00165     "precision mediump float;\n"
00166     "precision mediump int;\n"
00167     "attribute vec3 aVertex;\n"
00168     "attribute vec2 aTexCoord;\n"
00169 
00170     "uniform mat4 uMVP;\n"
00171 
00172     "varying vec2 vTexCoord;\n"
00173     "varying float vLightWeighting;\n"
00174 
00175     "void main() {\n"
00176     "  gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n"
00177 
00178         "  if(aTexCoord.x < 0.0) {\n"
00179         "    vTexCoord.x = 1.0;\n"
00180         "    vTexCoord.y = 1.0;\n" // bottom right corner
00181         "  } else {\n"
00182     "    vTexCoord = aTexCoord;\n"
00183     "  }\n"
00184 
00185     "  vLightWeighting = 1.0;\n"
00186     "}\n";
00187 const std::string kTextureMeshLightingVertexShader =
00188     "precision mediump float;\n"
00189     "precision mediump int;\n"
00190     "attribute vec3 aVertex;\n"
00191         "attribute vec3 aNormal;\n"
00192     "attribute vec2 aTexCoord;\n"
00193 
00194     "uniform mat4 uMVP;\n"
00195     "uniform mat3 uN;\n"
00196     "uniform vec3 uLightingDirection;\n"
00197 
00198     "varying vec2 vTexCoord;\n"
00199     "varying float vLightWeighting;\n"
00200 
00201     "void main() {\n"
00202     "  gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n"
00203 
00204         "  if(aTexCoord.x < 0.0) {\n"
00205         "    vTexCoord.x = 1.0;\n"
00206         "    vTexCoord.y = 1.0;\n" // bottom right corner
00207         "  } else {\n"
00208     "    vTexCoord = aTexCoord;\n"
00209     "  }\n"
00210 
00211     "  vec3 transformedNormal = uN * aNormal;\n"
00212     "  vLightWeighting = max(dot(transformedNormal, uLightingDirection)*0.5+0.5, 0.0);\n"
00213     "  if(vLightWeighting<0.5) \n"
00214     "    vLightWeighting=0.5;\n"
00215     "}\n";
00216 const std::string kTextureMeshFragmentShader =
00217     "precision mediump float;\n"
00218     "precision mediump int;\n"
00219         "uniform sampler2D uTexture;\n"
00220         "uniform float uGainR;\n"
00221         "uniform float uGainG;\n"
00222         "uniform float uGainB;\n"
00223     "varying vec2 vTexCoord;\n"
00224         "varying float vLightWeighting;\n"
00225         ""
00226     "void main() {\n"
00227     "  vec4 textureColor = texture2D(uTexture, vTexCoord);\n"
00228         "  gl_FragColor = vec4(textureColor.r * uGainR * vLightWeighting, textureColor.g * uGainG * vLightWeighting, textureColor.b * uGainB * vLightWeighting, textureColor.a);\n"
00229     "}\n";
00230 const std::string kTextureMeshBlendingFragmentShader =
00231     "precision highp float;\n"
00232     "precision mediump int;\n"
00233         "uniform sampler2D uTexture;\n"
00234     "uniform sampler2D uDepthTexture;\n"
00235         "uniform float uGainR;\n"
00236         "uniform float uGainG;\n"
00237         "uniform float uGainB;\n"
00238         "uniform vec2 uScreenScale;\n"
00239         "uniform float uNearZ;\n"
00240         "uniform float uFarZ;\n"
00241     "varying vec2 vTexCoord;\n"
00242         "varying float vLightWeighting;\n"
00243         ""
00244     "void main() {\n"
00245     "  vec4 textureColor = texture2D(uTexture, vTexCoord);\n"
00246     "  float alpha = 1.0;\n"
00247         "  vec2 coord = uScreenScale * gl_FragCoord.xy;\n;"
00248         "  float depth = texture2D(uDepthTexture, coord).r;\n"
00249         "  float num =  (2.0 * uNearZ * uFarZ);\n"
00250         "  float diff = (uFarZ - uNearZ);\n"
00251         "  float add = (uFarZ + uNearZ);\n"
00252         "  float ndcDepth = depth * 2.0 - 1.0;\n" // Back to NDC
00253         "  float linearDepth = num / (add - ndcDepth * diff);\n" // inverse projection matrix
00254         "  float ndcFragz = gl_FragCoord.z * 2.0 - 1.0;\n" // Back to NDC
00255         "  float linearFragz = num / (add - ndcFragz * diff);\n" // inverse projection matrix
00256         "  if(linearFragz > linearDepth + 0.05)\n"
00257         "    alpha=0.0;\n"
00258         "  gl_FragColor = vec4(textureColor.r * uGainR * vLightWeighting, textureColor.g * uGainG * vLightWeighting, textureColor.b * uGainB * vLightWeighting, alpha);\n"
00259     "}\n";
00260 
00261 std::vector<GLuint> PointCloudDrawable::shaderPrograms_;
00262 
00263 void PointCloudDrawable::createShaderPrograms()
00264 {
00265         if(shaderPrograms_.empty())
00266         {
00267                 shaderPrograms_.resize(9);
00268 
00269                 shaderPrograms_[kPointCloud] = tango_gl::util::CreateProgram(kPointCloudVertexShader.c_str(), kPointCloudFragmentShader.c_str());
00270                 UASSERT(shaderPrograms_[kPointCloud] != 0);
00271                 shaderPrograms_[kPointCloudBlending] = tango_gl::util::CreateProgram(kPointCloudVertexShader.c_str(), kPointCloudBlendingFragmentShader.c_str());
00272                 UASSERT(shaderPrograms_[kPointCloudBlending] != 0);
00273                 shaderPrograms_[kPointCloudLighting] = tango_gl::util::CreateProgram(kPointCloudLightingVertexShader.c_str(), kPointCloudFragmentShader.c_str());
00274                 UASSERT(shaderPrograms_[kPointCloudLighting] != 0);
00275                 shaderPrograms_[kPointCloudLightingBlending] = tango_gl::util::CreateProgram(kPointCloudLightingVertexShader.c_str(), kPointCloudBlendingFragmentShader.c_str());
00276                 UASSERT(shaderPrograms_[kPointCloudLightingBlending] != 0);
00277 
00278                 shaderPrograms_[kTexture] = tango_gl::util::CreateProgram(kTextureMeshVertexShader.c_str(), kTextureMeshFragmentShader.c_str());
00279                 UASSERT(shaderPrograms_[kTexture] != 0);
00280                 shaderPrograms_[kTextureBlending] = tango_gl::util::CreateProgram(kTextureMeshVertexShader.c_str(), kTextureMeshBlendingFragmentShader.c_str());
00281                 UASSERT(shaderPrograms_[kTextureBlending] != 0);
00282                 shaderPrograms_[kTextureLighting] = tango_gl::util::CreateProgram(kTextureMeshLightingVertexShader.c_str(), kTextureMeshFragmentShader.c_str());
00283                 UASSERT(shaderPrograms_[kTextureLighting] != 0);
00284                 shaderPrograms_[kTextureLightingBlending] = tango_gl::util::CreateProgram(kTextureMeshLightingVertexShader.c_str(), kTextureMeshBlendingFragmentShader.c_str());
00285                 UASSERT(shaderPrograms_[kTextureLightingBlending] != 0);
00286 
00287                 shaderPrograms_[kDepthPacking] = tango_gl::util::CreateProgram(kPointCloudDepthPackingVertexShader.c_str(), kPointCloudDepthPackingFragmentShader.c_str());
00288                 UASSERT(shaderPrograms_[kDepthPacking] != 0);
00289         }
00290 }
00291 void PointCloudDrawable::releaseShaderPrograms()
00292 {
00293         for(unsigned int i=0; i<shaderPrograms_.size(); ++i)
00294         {
00295                 glDeleteShader(shaderPrograms_[i]);
00296         }
00297         shaderPrograms_.clear();
00298 }
00299 
00300 PointCloudDrawable::PointCloudDrawable(
00301                 const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
00302                 const pcl::IndicesPtr & indices,
00303                 float gainR,
00304                 float gainG,
00305                 float gainB) :
00306                                 vertex_buffers_(0),
00307                                 textures_(0),
00308                                 nPoints_(0),
00309                                 pose_(rtabmap::Transform::getIdentity()),
00310                                 poseGl_(1.0f),
00311                                 visible_(true),
00312                                 hasNormals_(false),
00313                                 gainR_(gainR),
00314                                 gainG_(gainG),
00315                                 gainB_(gainB)
00316 {
00317         updateCloud(cloud, indices);
00318 }
00319 
00320 PointCloudDrawable::PointCloudDrawable(
00321                 const Mesh & mesh,
00322                 bool createWireframe) :
00323                                 vertex_buffers_(0),
00324                                 textures_(0),
00325                                 nPoints_(0),
00326                                 pose_(rtabmap::Transform::getIdentity()),
00327                                 poseGl_(1.0f),
00328                                 visible_(true),
00329                                 hasNormals_(false),
00330                                 gainR_(1.0f),
00331                                 gainG_(1.0f),
00332                                 gainB_(1.0f)
00333 {
00334         updateMesh(mesh, createWireframe);
00335 }
00336 
00337 PointCloudDrawable::~PointCloudDrawable()
00338 {
00339         LOGI("Freeing cloud buffer %d", vertex_buffers_);
00340         if (vertex_buffers_)
00341         {
00342                 glDeleteBuffers(1, &vertex_buffers_);
00343                 tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
00344                 vertex_buffers_ = 0;
00345         }
00346 
00347         if (textures_)
00348         {
00349                 glDeleteTextures(1, &textures_);
00350                 tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
00351                 textures_ = 0;
00352         }
00353 }
00354 
00355 void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polygons, const std::vector<pcl::Vertices> & polygonsLowRes, bool createWireframe)
00356 {
00357         LOGD("Update polygons");
00358         polygons_.clear();
00359         polygonLines_.clear();
00360         polygonsLowRes_.clear();
00361         polygonLinesLowRes_.clear();
00362         if(polygons.size() && organizedToDenseIndices_.size())
00363         {
00364                 unsigned int polygonSize = polygons[0].vertices.size();
00365                 UASSERT(polygonSize == 3);
00366                 polygons_.resize(polygons.size() * polygonSize);
00367                 if(createWireframe)
00368                         polygonLines_.resize(polygons_.size()*2);
00369                 int oi = 0;
00370                 int li = 0;
00371                 for(unsigned int i=0; i<polygons.size(); ++i)
00372                 {
00373                         UASSERT(polygons[i].vertices.size() == polygonSize);
00374                         for(unsigned int j=0; j<polygonSize; ++j)
00375                         {
00376                                 polygons_[oi++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
00377                                 if(createWireframe)
00378                                 {
00379                                         polygonLines_[li++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
00380                                         polygonLines_[li++] = organizedToDenseIndices_.at(polygons[i].vertices[(j+1) % polygonSize]);
00381                                 }
00382                         }
00383                 }
00384 
00385                 if(polygonsLowRes.size())
00386                 {
00387                         unsigned int polygonSize = polygonsLowRes[0].vertices.size();
00388                         UASSERT(polygonSize == 3);
00389                         polygonsLowRes_.resize(polygonsLowRes.size() * polygonSize);
00390                         if(createWireframe)
00391                                 polygonLinesLowRes_.resize(polygonsLowRes_.size()*2);
00392                         int oi = 0;
00393                         int li = 0;
00394                         for(unsigned int i=0; i<polygonsLowRes.size(); ++i)
00395                         {
00396                                 UASSERT(polygonsLowRes[i].vertices.size() == polygonSize);
00397                                 for(unsigned int j=0; j<polygonSize; ++j)
00398                                 {
00399                                         polygonsLowRes_[oi++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
00400                                         if(createWireframe)
00401                                         {
00402                                                 polygonLinesLowRes_[li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
00403                                                 polygonLinesLowRes_[li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[(j+1)%polygonSize]);
00404                                         }
00405                                 }
00406                         }
00407                 }
00408         }
00409 }
00410 
00411 void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::IndicesPtr & indices)
00412 {
00413         UASSERT(cloud.get() && !cloud->empty());
00414         nPoints_ = 0;
00415         polygons_.clear();
00416         polygonsLowRes_.clear();
00417         verticesLowRes_.clear();
00418         verticesLowLowRes_.clear();
00419         aabbMinModel_ = aabbMinWorld_ = pcl::PointXYZ(1000,1000,1000);
00420         aabbMaxModel_ = aabbMaxWorld_ = pcl::PointXYZ(-1000,-1000,-1000);
00421 
00422         if (vertex_buffers_)
00423         {
00424                 glDeleteBuffers(1, &vertex_buffers_);
00425                 tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
00426                 vertex_buffers_ = 0;
00427         }
00428 
00429         if (textures_)
00430         {
00431                 glDeleteTextures(1, &textures_);
00432                 tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
00433                 textures_ = 0;
00434         }
00435 
00436         glGenBuffers(1, &vertex_buffers_);
00437         if(!vertex_buffers_)
00438         {
00439                 LOGE("OpenGL: could not generate vertex buffers\n");
00440                 return;
00441         }
00442 
00443         LOGI("Creating cloud buffer %d", vertex_buffers_);
00444         std::vector<float> vertices;
00445         int totalPoints = 0;
00446         if(indices.get() && indices->size())
00447         {
00448                 totalPoints = indices->size();
00449                 vertices.resize(indices->size()*4);
00450                 verticesLowRes_.resize(cloud->isOrganized()?totalPoints:0);
00451                 verticesLowLowRes_.resize(cloud->isOrganized()?totalPoints:0);
00452                 int oi_low = 0;
00453                 int oi_lowlow = 0;
00454                 for(unsigned int i=0; i<indices->size(); ++i)
00455                 {
00456                         const pcl::PointXYZRGB & pt = cloud->at(indices->at(i));
00457                         vertices[i*4] = pt.x;
00458                         vertices[i*4+1] = pt.y;
00459                         vertices[i*4+2] = pt.z;
00460                         vertices[i*4+3] = pt.rgb;
00461 
00462                         updateAABBMinMax(pt, aabbMinModel_, aabbMaxModel_);
00463 
00464                         if(cloud->isOrganized())
00465                         {
00466                                 if(indices->at(i)%LOW_DEC == 0 && (indices->at(i)/cloud->width) % LOW_DEC == 0)
00467                                 {
00468                                         verticesLowRes_[oi_low++] = i;
00469                                 }
00470                                 if(indices->at(i)%LOWLOW_DEC == 0 && (indices->at(i)/cloud->width) % LOWLOW_DEC == 0)
00471                                 {
00472                                         verticesLowLowRes_[oi_lowlow++] = i;
00473                                 }
00474                         }
00475                 }
00476                 verticesLowRes_.resize(oi_low);
00477                 verticesLowLowRes_.resize(oi_lowlow);
00478         }
00479         else
00480         {
00481                 totalPoints = cloud->size();
00482                 vertices.resize(cloud->size()*4);
00483                 verticesLowRes_.resize(cloud->isOrganized()?totalPoints:0);
00484                 verticesLowLowRes_.resize(cloud->isOrganized()?totalPoints:0);
00485                 int oi_low = 0;
00486                 int oi_lowlow = 0;
00487                 for(unsigned int i=0; i<cloud->size(); ++i)
00488                 {
00489                         const pcl::PointXYZRGB & pt = cloud->at(i);
00490                         vertices[i*4] = pt.x;
00491                         vertices[i*4+1] = pt.y;
00492                         vertices[i*4+2] = pt.z;
00493                         vertices[i*4+3] = pt.rgb;
00494 
00495                         updateAABBMinMax(pt, aabbMinModel_, aabbMaxModel_);
00496 
00497                         if(cloud->isOrganized())
00498                         {
00499                                 if(i%LOW_DEC == 0 && (i/cloud->width) % LOW_DEC == 0)
00500                                 {
00501                                         verticesLowRes_[oi_low++] = i;
00502                                 }
00503                                 if(i%LOWLOW_DEC == 0 && (i/cloud->width) % LOWLOW_DEC == 0)
00504                                 {
00505                                         verticesLowLowRes_[oi_lowlow++] = i;
00506                                 }
00507                         }
00508                 }
00509                 verticesLowRes_.resize(oi_low);
00510                 verticesLowLowRes_.resize(oi_lowlow);
00511         }
00512 
00513         glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
00514         glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW);
00515         glBindBuffer(GL_ARRAY_BUFFER, 0);
00516 
00517         GLint error = glGetError();
00518         if(error != GL_NO_ERROR)
00519         {
00520                 LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error);
00521                 vertex_buffers_ = 0;
00522                 return;
00523         }
00524 
00525         nPoints_ = totalPoints;
00526 }
00527 
00528 void PointCloudDrawable::updateMesh(const Mesh & mesh, bool createWireframe)
00529 {
00530         UASSERT(mesh.cloud.get() && !mesh.cloud->empty());
00531         nPoints_ = 0;
00532         aabbMinModel_ = aabbMinWorld_ = pcl::PointXYZ(1000,1000,1000);
00533         aabbMaxModel_ = aabbMaxWorld_ = pcl::PointXYZ(-1000,-1000,-1000);
00534 
00535         if (vertex_buffers_)
00536         {
00537                 glDeleteBuffers(1, &vertex_buffers_);
00538                 tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
00539                 vertex_buffers_ = 0;
00540         }
00541 
00542         gainR_ = mesh.gains[0];
00543         gainG_ = mesh.gains[1];
00544         gainB_ = mesh.gains[2];
00545 
00546         bool textureUpdate = false;
00547         if(!mesh.texture.empty() && mesh.texture.type() == CV_8UC3)
00548         {
00549                 if (textures_)
00550                 {
00551                         glDeleteTextures(1, &textures_);
00552                         tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
00553                         textures_ = 0;
00554                 }
00555                 textureUpdate = true;
00556         }
00557 
00558         glGenBuffers(1, &vertex_buffers_);
00559         if(!vertex_buffers_)
00560         {
00561                 LOGE("OpenGL: could not generate vertex buffers\n");
00562                 return;
00563         }
00564 
00565         if(textureUpdate)
00566         {
00567                 glGenTextures(1, &textures_);
00568                 if(!textures_)
00569                 {
00570                         vertex_buffers_ = 0;
00571                         LOGE("OpenGL: could not generate texture buffers\n");
00572                         return;
00573                 }
00574         }
00575 
00576         //LOGD("Creating cloud buffer %d", vertex_buffers_);
00577         std::vector<float> vertices;
00578         int totalPoints = 0;
00579         std::vector<pcl::Vertices> polygons = mesh.polygons;
00580         std::vector<pcl::Vertices> polygonsLowRes;
00581         hasNormals_ = mesh.normals.get() && mesh.normals->size() == mesh.cloud->size();
00582         UASSERT(!hasNormals_ || mesh.cloud->size() == mesh.normals->size());
00583         if(mesh.cloud->isOrganized()) // assume organized mesh
00584         {
00585                 polygonsLowRes = mesh.polygonsLowRes; // only in organized we keep the low res
00586                 organizedToDenseIndices_ = std::vector<unsigned int>(mesh.cloud->width*mesh.cloud->height, -1);
00587                 totalPoints = mesh.indices->size();
00588                 verticesLowRes_.resize(totalPoints);
00589                 verticesLowLowRes_.resize(totalPoints);
00590                 int oi_low = 0;
00591                 int oi_lowlow = 0;
00592                 if(textures_ && polygons.size())
00593                 {
00594                         int items = hasNormals_?9:6;
00595                         vertices = std::vector<float>(mesh.indices->size()*items);
00596                         for(unsigned int i=0; i<mesh.indices->size(); ++i)
00597                         {
00598                                 const pcl::PointXYZRGB & pt = mesh.cloud->at(mesh.indices->at(i));
00599                                 vertices[i*items] = pt.x;
00600                                 vertices[i*items+1] = pt.y;
00601                                 vertices[i*items+2] = pt.z;
00602 
00603                                 // rgb
00604                                 vertices[i*items+3] = pt.rgb;
00605 
00606                                 updateAABBMinMax(pt, aabbMinModel_, aabbMaxModel_);
00607 
00608                                 // texture uv
00609                                 int index = mesh.indices->at(i);
00610                                 vertices[i*items+4] = float(index % mesh.cloud->width)/float(mesh.cloud->width); //u
00611                                 vertices[i*items+5] = float(index / mesh.cloud->width)/float(mesh.cloud->height);  //v
00612 
00613                                 if(hasNormals_)
00614                                 {
00615                                         // normal
00616                                         vertices[i*items+6] = mesh.normals->at(mesh.indices->at(i)).normal_x;
00617                                         vertices[i*items+7] = mesh.normals->at(mesh.indices->at(i)).normal_y;
00618                                         vertices[i*items+8] = mesh.normals->at(mesh.indices->at(i)).normal_z;
00619                                 }
00620 
00621                                 organizedToDenseIndices_[mesh.indices->at(i)] = i;
00622 
00623                                 if(mesh.indices->at(i)%LOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOW_DEC == 0)
00624                                 {
00625                                         verticesLowRes_[oi_low++] = i;
00626                                 }
00627                                 if(mesh.indices->at(i)%LOWLOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOWLOW_DEC == 0)
00628                                 {
00629                                         verticesLowLowRes_[oi_lowlow++] = i;
00630                                 }
00631                         }
00632                 }
00633                 else
00634                 {
00635                         //LOGD("Organized mesh");
00636                         int items = hasNormals_?7:4;
00637                         vertices = std::vector<float>(mesh.indices->size()*items);
00638                         for(unsigned int i=0; i<mesh.indices->size(); ++i)
00639                         {
00640                                 const pcl::PointXYZRGB & pt = mesh.cloud->at(mesh.indices->at(i));
00641                                 vertices[i*items] = pt.x;
00642                                 vertices[i*items+1] = pt.y;
00643                                 vertices[i*items+2] = pt.z;
00644                                 vertices[i*items+3] = pt.rgb;
00645 
00646                                 updateAABBMinMax(pt, aabbMinModel_, aabbMaxModel_);
00647 
00648                                 if(hasNormals_)
00649                                 {
00650                                         // normal
00651                                         vertices[i*items+4] = mesh.normals->at(mesh.indices->at(i)).normal_x;
00652                                         vertices[i*items+5] = mesh.normals->at(mesh.indices->at(i)).normal_y;
00653                                         vertices[i*items+6] = mesh.normals->at(mesh.indices->at(i)).normal_z;
00654                                 }
00655 
00656                                 organizedToDenseIndices_[mesh.indices->at(i)] = i;
00657 
00658                                 if(mesh.indices->at(i)%LOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOW_DEC == 0)
00659                                 {
00660                                         verticesLowRes_[oi_low++] = i;
00661                                 }
00662                                 if(mesh.indices->at(i)%LOWLOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOWLOW_DEC == 0)
00663                                 {
00664                                         verticesLowLowRes_[oi_lowlow++] = i;
00665                                 }
00666                         }
00667                 }
00668                 verticesLowRes_.resize(oi_low);
00669                 verticesLowLowRes_.resize(oi_lowlow);
00670         }
00671         else // assume dense mesh with texCoords set to polygons
00672         {
00673                 if(textures_ && polygons.size() && mesh.normals->size())
00674                 {
00675                         //LOGD("Dense mesh with texture (%d texCoords %d points %d polygons %dx%d)",
00676                         //              (int)mesh.texCoords.size(), (int)mesh.cloud->size(), (int)mesh.polygons.size(), texture.cols, texture.rows);
00677 
00678                         // Texturing issue:
00679                         //  tex_coordinates should be linked to points, not
00680                         //  polygon vertices. Points linked to multiple different texCoords (different textures) should
00681                         //  be duplicated.
00682                         totalPoints = mesh.texCoords.size();
00683                         vertices = std::vector<float>(mesh.texCoords.size()*9);
00684                         organizedToDenseIndices_ = std::vector<unsigned int>(totalPoints, -1);
00685 
00686                         UASSERT_MSG(mesh.texCoords.size() == polygons[0].vertices.size()*polygons.size(),
00687                                         uFormat("%d vs %d x %d", (int)mesh.texCoords.size(), (int)polygons[0].vertices.size(), (int)polygons.size()).c_str());
00688 
00689                         int items = hasNormals_?9:6;
00690                         unsigned int oi=0;
00691                         for(unsigned int i=0; i<polygons.size(); ++i)
00692                         {
00693                                 pcl::Vertices & v = polygons[i];
00694                                 for(unsigned int j=0; j<v.vertices.size(); ++j)
00695                                 {
00696                                         UASSERT(oi < mesh.texCoords.size());
00697                                         UASSERT(v.vertices[j] < mesh.cloud->size());
00698 
00699                                         const pcl::PointXYZRGB & pt =  mesh.cloud->at(v.vertices[j]);
00700 
00701                                         vertices[oi*items] = pt.x;
00702                                         vertices[oi*items+1] = pt.y;
00703                                         vertices[oi*items+2] = pt.z;
00704 
00705                                         // rgb
00706                                         vertices[oi*items+3] = pt.rgb;
00707 
00708                                         updateAABBMinMax(pt, aabbMinModel_, aabbMaxModel_);
00709 
00710                                         // texture uv
00711                                         if(mesh.texCoords[oi][0]>=0.0f)
00712                                         {
00713                                                 vertices[oi*items+4] = mesh.texCoords[oi][0]; //u
00714                                                 vertices[oi*items+5] = 1.0f-mesh.texCoords[oi][1];  //v
00715                                         }
00716                                         else
00717                                         {
00718                                                 vertices[oi*items+4] = vertices[oi*items+5] = -1.0f;
00719                                         }
00720 
00721                                         if(hasNormals_)
00722                                         {
00723                                                 // normal
00724                                                 vertices[oi*items+6] = mesh.normals->at(v.vertices[j]).normal_x;
00725                                                 vertices[oi*items+7] = mesh.normals->at(v.vertices[j]).normal_y;
00726                                                 vertices[oi*items+8] = mesh.normals->at(v.vertices[j]).normal_z;
00727                                         }
00728 
00729                                         v.vertices[j] = (int)oi; // new vertex index
00730 
00731                                         UASSERT(oi < organizedToDenseIndices_.size());
00732                                         organizedToDenseIndices_[oi] = oi;
00733 
00734                                         ++oi;
00735                                 }
00736                         }
00737                 }
00738                 else
00739                 {
00740                         totalPoints = mesh.cloud->size();
00741                         //LOGD("Dense mesh");
00742                         int items = hasNormals_?7:4;
00743                         organizedToDenseIndices_ = std::vector<unsigned int>(totalPoints, -1);
00744                         vertices = std::vector<float>(mesh.cloud->size()*items);
00745                         for(unsigned int i=0; i<mesh.cloud->size(); ++i)
00746                         {
00747                                 const pcl::PointXYZRGB & pt =  mesh.cloud->at(i);
00748 
00749                                 vertices[i*items] =pt.x;
00750                                 vertices[i*items+1] = pt.y;
00751                                 vertices[i*items+2] = pt.z;
00752                                 vertices[i*items+3] = pt.rgb;
00753 
00754                                 updateAABBMinMax(pt, aabbMinModel_, aabbMaxModel_);
00755 
00756                                 if(hasNormals_)
00757                                 {
00758                                         vertices[i*items+4] = mesh.normals->at(i).normal_x;
00759                                         vertices[i*items+5] = mesh.normals->at(i).normal_y;
00760                                         vertices[i*items+6] = mesh.normals->at(i).normal_z;
00761                                 }
00762 
00763                                 organizedToDenseIndices_[i] = i;
00764                         }
00765                 }
00766         }
00767 
00768         glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
00769         glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW);
00770         glBindBuffer(GL_ARRAY_BUFFER, 0);
00771 
00772         GLint error = glGetError();
00773         if(error != GL_NO_ERROR)
00774         {
00775                 LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error);
00776                 vertex_buffers_ = 0;
00777                 return;
00778         }
00779 
00780         if(textures_ && textureUpdate)
00781         {
00782                 //GLint maxTextureSize = 0;
00783                 //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
00784                 //LOGI("maxTextureSize=%d", maxTextureSize);
00785                 //GLint maxTextureUnits = 0;
00786                 //glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
00787                 //LOGW("maxTextureUnits=%d", maxTextureUnits);
00788 
00789                 // gen texture from image
00790                 glBindTexture(GL_TEXTURE_2D, textures_);
00791                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00792                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00793                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00794                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00795                 cv::Mat rgbImage;
00796                 cv::cvtColor(mesh.texture, rgbImage, CV_BGR2RGBA);
00797 
00798                 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
00799                 //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00800                 //glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
00801                 //glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
00802                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rgbImage.cols, rgbImage.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbImage.data);
00803 
00804                 GLint error = glGetError();
00805                 if(error != GL_NO_ERROR)
00806                 {
00807                         LOGE("OpenGL: Could not allocate texture (0x%x)\n", error);
00808                         textures_ = 0;
00809 
00810                         glDeleteBuffers(1, &vertex_buffers_);
00811                         vertex_buffers_ = 0;
00812                         return;
00813                 }
00814         }
00815 
00816         nPoints_ = totalPoints;
00817 
00818         if(polygons_.size() != polygons.size())
00819         {
00820                 updatePolygons(polygons, polygonsLowRes, createWireframe);
00821         }
00822 
00823         if(!pose_.isNull())
00824         {
00825                 updateAABBWorld(pose_);
00826         }
00827 }
00828 
00829 void PointCloudDrawable::setPose(const rtabmap::Transform & pose)
00830 {
00831         UASSERT(!pose.isNull());
00832 
00833         if(pose_ != pose)
00834         {
00835                 updateAABBWorld(pose);
00836         }
00837 
00838         pose_ = pose;
00839         poseGl_ = glmFromTransform(pose);
00840 }
00841 
00842 void PointCloudDrawable::updateAABBWorld(const rtabmap::Transform & pose)
00843 {
00844         pcl::PointCloud<pcl::PointXYZ> corners;
00845         corners.resize(8);
00846         corners.at(0) = pcl::PointXYZ(aabbMinModel_.x, aabbMinModel_.y, aabbMinModel_.z);
00847         corners.at(1) = pcl::PointXYZ(aabbMinModel_.x, aabbMinModel_.y, aabbMaxModel_.z);
00848         corners.at(2) = pcl::PointXYZ(aabbMinModel_.x, aabbMaxModel_.y, aabbMinModel_.z);
00849         corners.at(3) = pcl::PointXYZ(aabbMaxModel_.x, aabbMinModel_.y, aabbMinModel_.z);
00850         corners.at(4) = pcl::PointXYZ(aabbMaxModel_.x, aabbMaxModel_.y, aabbMaxModel_.z);
00851         corners.at(5) = pcl::PointXYZ(aabbMaxModel_.x, aabbMaxModel_.y, aabbMinModel_.z);
00852         corners.at(6) = pcl::PointXYZ(aabbMaxModel_.x, aabbMinModel_.y, aabbMaxModel_.z);
00853         corners.at(7) = pcl::PointXYZ(aabbMinModel_.x, aabbMaxModel_.y, aabbMaxModel_.z);
00854 
00855         pcl::PointCloud<pcl::PointXYZ> cornersTransformed;
00856         pcl::transformPointCloud(corners, cornersTransformed, pose.toEigen3f());
00857 
00858         aabbMinWorld_ = pcl::PointXYZ(1000,1000,1000);
00859         aabbMaxWorld_ = pcl::PointXYZ(-1000,-1000,-1000);
00860         for(unsigned int i=0; i<cornersTransformed.size(); ++i)
00861         {
00862                 updateAABBMinMax(cornersTransformed.at(i), aabbMinWorld_, aabbMaxWorld_);
00863         }
00864 }
00865 
00866 
00867 void PointCloudDrawable::Render(
00868                 const glm::mat4 & projectionMatrix,
00869                 const glm::mat4 & viewMatrix,
00870                 bool meshRendering,
00871                 float pointSize,
00872                 bool textureRendering,
00873                 bool lighting,
00874                 float distanceToCameraSqr,
00875                 const GLuint & depthTexture,
00876                 int screenWidth,
00877                 int screenHeight,
00878                 float nearClipPlane,
00879             float farClipPlane,
00880                 bool packDepthToColorChannel,
00881                 bool wireFrame) const
00882 {
00883         if(vertex_buffers_ && nPoints_ && visible_ && !shaderPrograms_.empty())
00884         {
00885                 if(packDepthToColorChannel || !hasNormals_)
00886                 {
00887                         lighting = false;
00888                 }
00889 
00890                 if(packDepthToColorChannel || !(meshRendering && textureRendering && textures_))
00891                 {
00892                         textureRendering = false;
00893                 }
00894 
00895                 GLuint program;
00896                 if(packDepthToColorChannel)
00897                 {
00898                         program = shaderPrograms_[kDepthPacking];
00899                 }
00900                 else if(textureRendering)
00901                 {
00902                         if(lighting)
00903                         {
00904                                 program = shaderPrograms_[depthTexture>0?kTextureLightingBlending:kTextureLighting];
00905                         }
00906                         else
00907                         {
00908                                 program = shaderPrograms_[depthTexture>0?kTextureBlending:kTexture];
00909                         }
00910                 }
00911                 else
00912                 {
00913                         if(lighting)
00914                         {
00915                                 program = shaderPrograms_[depthTexture>0?kPointCloudLightingBlending:kPointCloudLighting];
00916                         }
00917                         else
00918                         {
00919                                 program = shaderPrograms_[depthTexture>0?kPointCloudBlending:kPointCloud];
00920                         }
00921                 }
00922 
00923                 glUseProgram(program);
00924                 tango_gl::util::CheckGlError("Pointcloud::Render() set program");
00925 
00926                 GLuint mvp_handle = glGetUniformLocation(program, "uMVP");
00927                 glm::mat4 mv_mat = viewMatrix * poseGl_;
00928                 glm::mat4 mvp_mat = projectionMatrix * mv_mat;
00929                 glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, glm::value_ptr(mvp_mat));
00930 
00931                 GLint attribute_vertex = glGetAttribLocation(program, "aVertex");
00932                 glEnableVertexAttribArray(attribute_vertex);
00933                 GLint attribute_color = 0;
00934                 GLint attribute_texture = 0;
00935                 GLint attribute_normal = 0;
00936 
00937                 if(packDepthToColorChannel || !textureRendering)
00938                 {
00939                         GLuint point_size_handle_ = glGetUniformLocation(program, "uPointSize");
00940                         glUniform1f(point_size_handle_, pointSize);
00941                 }
00942                 tango_gl::util::CheckGlError("Pointcloud::Render() vertex");
00943 
00944                 if(!packDepthToColorChannel)
00945                 {
00946                         GLuint gainR_handle = glGetUniformLocation(program, "uGainR");
00947                         GLuint gainG_handle = glGetUniformLocation(program, "uGainG");
00948                         GLuint gainB_handle = glGetUniformLocation(program, "uGainB");
00949                         glUniform1f(gainR_handle, gainR_);
00950                         glUniform1f(gainG_handle, gainG_);
00951                         glUniform1f(gainB_handle, gainB_);
00952 
00953                         // blending
00954                         if(depthTexture > 0)
00955                         {
00956                                 // Texture activate unit 1
00957                                 glActiveTexture(GL_TEXTURE1);
00958                                 // Bind the texture to this unit.
00959                                 glBindTexture(GL_TEXTURE_2D, depthTexture);
00960                                 // Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 1.
00961                                 GLuint depth_texture_handle = glGetUniformLocation(program, "uDepthTexture");
00962                                 glUniform1i(depth_texture_handle, 1);
00963 
00964                                 GLuint zNear_handle = glGetUniformLocation(program, "uNearZ");
00965                                 GLuint zFar_handle = glGetUniformLocation(program, "uFarZ");
00966                                 glUniform1f(zNear_handle, nearClipPlane);
00967                                 glUniform1f(zFar_handle, farClipPlane);
00968 
00969                                 GLuint screenScale_handle = glGetUniformLocation(program, "uScreenScale");
00970                                 glUniform2f(screenScale_handle, 1.0f/(float)screenWidth, 1.0f/(float)screenHeight);
00971                         }
00972 
00973                         if(lighting)
00974                         {
00975                                 GLuint n_handle = glGetUniformLocation(program, "uN");
00976                                 glm::mat3 normalMatrix(mv_mat);
00977                                 normalMatrix = glm::inverse(normalMatrix);
00978                                 normalMatrix = glm::transpose(normalMatrix);
00979                                 glUniformMatrix3fv(n_handle, 1, GL_FALSE, glm::value_ptr(normalMatrix));
00980 
00981                                 GLuint lightingDirection_handle = glGetUniformLocation(program, "uLightingDirection");
00982                                 glUniform3f(lightingDirection_handle, 0.0, 0.0, 1.0); // from the camera
00983 
00984                                 attribute_normal = glGetAttribLocation(program, "aNormal");
00985                                 glEnableVertexAttribArray(attribute_normal);
00986                         }
00987 
00988                         if(textureRendering)
00989                         {
00990                                 // Texture activate unit 0
00991                                 glActiveTexture(GL_TEXTURE0);
00992                                 // Bind the texture to this unit.
00993                                 glBindTexture(GL_TEXTURE_2D, textures_);
00994                                 // Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
00995                                 GLuint texture_handle = glGetUniformLocation(program, "uTexture");
00996                                 glUniform1i(texture_handle, 0);
00997 
00998                                 attribute_texture = glGetAttribLocation(program, "aTexCoord");
00999                                 glEnableVertexAttribArray(attribute_texture);
01000                         }
01001                         else
01002                         {
01003                                 attribute_color = glGetAttribLocation(program, "aColor");
01004                                 glEnableVertexAttribArray(attribute_color);
01005                         }
01006                 }
01007                 tango_gl::util::CheckGlError("Pointcloud::Render() common");
01008 
01009                 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
01010                 if(textures_)
01011                 {
01012                         glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, (hasNormals_?9:6)*sizeof(GLfloat), 0);
01013                         if(textureRendering)
01014                         {
01015                                 glVertexAttribPointer(attribute_texture, 2, GL_FLOAT, GL_FALSE, (hasNormals_?9:6)*sizeof(GLfloat), (GLvoid*) (4 * sizeof(GLfloat)));
01016                         }
01017                         else if(!packDepthToColorChannel)
01018                         {
01019                                 glVertexAttribPointer(attribute_color, 3, GL_UNSIGNED_BYTE, GL_TRUE,  (hasNormals_?9:6)*sizeof(GLfloat), (GLvoid*) (3 * sizeof(GLfloat)));
01020                         }
01021                         if(lighting && hasNormals_)
01022                         {
01023                                 glVertexAttribPointer(attribute_normal, 3, GL_FLOAT, GL_FALSE, 9*sizeof(GLfloat), (GLvoid*) (6 * sizeof(GLfloat)));
01024                         }
01025                 }
01026                 else
01027                 {
01028                         glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, (hasNormals_?7:4)*sizeof(GLfloat), 0);
01029                         if(!packDepthToColorChannel)
01030                         {
01031                                 glVertexAttribPointer(attribute_color, 3, GL_UNSIGNED_BYTE, GL_TRUE, (hasNormals_?7:4)*sizeof(GLfloat), (GLvoid*) (3 * sizeof(GLfloat)));
01032                         }
01033                         if(lighting && hasNormals_)
01034                         {
01035                                 glVertexAttribPointer(attribute_normal, 3, GL_FLOAT, GL_FALSE, 7*sizeof(GLfloat), (GLvoid*) (4 * sizeof(GLfloat)));
01036                         }
01037                 }
01038                 tango_gl::util::CheckGlError("Pointcloud::Render() set attribute pointer");
01039 
01040                 UTimer drawTime;
01041                 if(textureRendering)
01042                 {
01043                         if(distanceToCameraSqr<16.0f || polygonsLowRes_.empty())
01044                         {
01045                                 wireFrame = wireFrame && polygonLines_.size();
01046                                 if(wireFrame)
01047                                         glDrawElements(GL_LINES, polygonLines_.size(), GL_UNSIGNED_INT, polygonLines_.data());
01048                                 else
01049                                         glDrawElements(GL_TRIANGLES, polygons_.size(), GL_UNSIGNED_INT, polygons_.data());
01050                         }
01051                         else
01052                         {
01053                                 wireFrame = wireFrame && polygonLinesLowRes_.size();
01054                                 if(wireFrame)
01055                                         glDrawElements(GL_LINES, polygonLinesLowRes_.size(), GL_UNSIGNED_INT, polygonLinesLowRes_.data());
01056                                 else
01057                                         glDrawElements(GL_TRIANGLES, polygonsLowRes_.size(), GL_UNSIGNED_INT, polygonsLowRes_.data());
01058                         }
01059                 }
01060                 else if(meshRendering && polygons_.size())
01061                 {
01062                         if(distanceToCameraSqr<50.0f || polygonsLowRes_.empty())
01063                         {
01064                                 wireFrame = wireFrame && polygonLines_.size();
01065                                 if(wireFrame)
01066                                         glDrawElements(GL_LINES, polygonLines_.size(), GL_UNSIGNED_INT, polygonLines_.data());
01067                                 else
01068                                         glDrawElements(GL_TRIANGLES, polygons_.size(), GL_UNSIGNED_INT, polygons_.data());
01069                         }
01070                         else
01071                         {
01072                                 wireFrame = wireFrame && polygonLinesLowRes_.size();
01073                                 if(wireFrame)
01074                                         glDrawElements(GL_LINES, polygonLinesLowRes_.size(), GL_UNSIGNED_INT, polygonLinesLowRes_.data());
01075                                 else
01076                                         glDrawElements(GL_TRIANGLES, polygonsLowRes_.size(), GL_UNSIGNED_INT, polygonsLowRes_.data());
01077                         }
01078                 }
01079                 else if(!verticesLowRes_.empty())
01080                 {
01081                         if(distanceToCameraSqr>600.0f)
01082                         {
01083                                 glDrawElements(GL_POINTS, verticesLowLowRes_.size(), GL_UNSIGNED_INT, verticesLowLowRes_.data());
01084                         }
01085                         else if(distanceToCameraSqr>150.0f)
01086                         {
01087                                 glDrawElements(GL_POINTS, verticesLowRes_.size(), GL_UNSIGNED_INT, verticesLowRes_.data());
01088                         }
01089                         else
01090                         {
01091                                 glDrawArrays(GL_POINTS, 0, nPoints_);
01092                         }
01093                 }
01094                 else
01095                 {
01096                         glDrawArrays(GL_POINTS, 0, nPoints_);
01097                 }
01098                 //UERROR("drawTime=%fs", drawTime.ticks());
01099                 tango_gl::util::CheckGlError("Pointcloud::Render() draw");
01100 
01101                 glDisableVertexAttribArray(0);
01102                 glBindBuffer(GL_ARRAY_BUFFER, 0);
01103 
01104                 glUseProgram(0);
01105                 tango_gl::util::CheckGlError("Pointcloud::Render() cleaning");
01106         }
01107 }
01108 


rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jun 6 2019 21:59:21