texture_cache.cpp
Go to the documentation of this file.
00001 // *****************************************************************************
00002 //
00003 // Copyright (c) 2014, Southwest Research Institute® (SwRI®)
00004 // All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that the following conditions are met:
00008 //     * Redistributions of source code must retain the above copyright
00009 //       notice, this list of conditions and the following disclaimer.
00010 //     * Redistributions in binary form must reproduce the above copyright
00011 //       notice, this list of conditions and the following disclaimer in the
00012 //       documentation and/or other materials provided with the distribution.
00013 //     * Neither the name of Southwest Research Institute® (SwRI®) nor the
00014 //       names of its contributors may be used to endorse or promote products
00015 //       derived from this software without specific prior written permission.
00016 //
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020 // ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //
00028 // *****************************************************************************
00029 
00030 #include <tile_map/texture_cache.h>
00031 
00032 #include <cmath>
00033 
00034 #include <boost/make_shared.hpp>
00035 
00036 #include <GL/glew.h>
00037 #include <GL/gl.h>
00038 #include <GL/glu.h>
00039 
00040 #include <ros/ros.h>
00041 
00042 #include <QGLWidget>
00043 #include <QImage>
00044 
00045 #include <swri_math_util/math_util.h>
00046 
00047 namespace tile_map
00048 {
00049   Texture::Texture(int32_t texture_id, size_t hash) :
00050     id(texture_id),
00051     url_hash(hash)
00052   {
00053   }
00054 
00055   Texture::~Texture()
00056   {
00057     //ROS_ERROR("==== DELETING TEXTURE: %d ====", id);
00058     // The texture will automatically be freed from the GPU memory when it goes
00059     // out of scope.  This is effectively when it is no longer in the texture
00060     // cache or being referenced for a render.
00061     GLuint ids[1];
00062     ids[0] = id;
00063     glDeleteTextures(1, &ids[0]);
00064   }
00065 
00066   TextureCache::TextureCache(ImageCachePtr image_cache, size_t size) :
00067     cache_(size),
00068     image_cache_(image_cache)
00069   {
00070 
00071   }
00072 
00073   TexturePtr TextureCache::GetTexture(size_t url_hash, const QString& url, bool& failed, int priority)
00074   {
00075     TexturePtr texture;
00076 
00077     failed = false;
00078 
00079     TexturePtr* texture_ptr = cache_.take(url_hash);
00080     if (texture_ptr)
00081     {
00082       texture = *texture_ptr;
00083       delete texture_ptr;
00084     }
00085 
00086     if (!texture)
00087     {
00088       ImagePtr image = image_cache_->GetImage(url_hash, url, priority);
00089 
00090       if (image)
00091       {
00092         failed = image->Failed();
00093         boost::shared_ptr<QImage> image_ptr = image->GetImage();
00094         if (image_ptr)
00095         {
00096           // All of the OpenGL calls need to occur on the main thread and so
00097           // can't be done in the background.  The QImage calls could
00098           // potentially be done in a background thread by the image cache.
00099           QImage qimage = *image_ptr;
00100 
00101           GLuint ids[1];
00102           uint32_t check = 9999999;
00103           ids[0] = check;
00104 
00105           glGenTextures(1, &ids[0]);
00106 
00107           if (check == ids[0])
00108           {
00109             ROS_ERROR("FAILED TO CREATE TEXTURE");
00110 
00111             GLenum err = glGetError();
00112             const GLubyte *errString = gluErrorString(err);
00113             ROS_ERROR("GL ERROR(%u): %s", err, errString);
00114             return texture;
00115           }
00116 
00117           texture_ptr = new TexturePtr(boost::make_shared<Texture>(ids[0], url_hash));
00118           texture = *texture_ptr;
00119 
00120           float max_dim = std::max(qimage.width(), qimage.height());
00121           int32_t dimension = swri_math_util::Round(
00122             std::pow(2, std::ceil(std::log(max_dim) / std::log(2.0f))));
00123 
00124           if (qimage.width() != dimension || qimage.height() != dimension)
00125           {
00126             qimage = qimage.scaled(dimension, dimension, Qt::IgnoreAspectRatio, Qt::FastTransformation);
00127           }
00128 
00129           glBindTexture(GL_TEXTURE_2D, texture->id);
00130           glTexImage2D(
00131             GL_TEXTURE_2D,
00132             0,
00133             GL_RGBA,
00134             dimension,
00135             dimension,
00136             0,
00137             GL_RGBA,
00138             GL_UNSIGNED_BYTE,
00139             QGLWidget::convertToGLFormat(qimage).bits());
00140 
00141           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00142           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00143 
00144           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00145           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00146 
00147           cache_.insert(url_hash, texture_ptr);
00148         }
00149       }
00150     }
00151 
00152     return texture;
00153   }
00154 
00155   void TextureCache::AddTexture(const TexturePtr& texture)
00156   {
00157     if (texture)
00158     {
00159       TexturePtr* texture_ptr = new TexturePtr(texture);
00160       cache_.insert(texture->url_hash, texture_ptr);
00161     }
00162   }
00163 
00164   void TextureCache::Clear()
00165   {
00166     image_cache_->Clear();
00167     cache_.clear();
00168   }
00169 }


tile_map
Author(s): Marc Alban
autogenerated on Thu Jun 6 2019 18:51:19