Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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/gl.h>
00037 #include <GL/glu.h>
00038
00039 #include <ros/ros.h>
00040
00041 #include <QGLWidget>
00042 #include <QImage>
00043
00044 #include <swri_math_util/math_util.h>
00045
00046 namespace tile_map
00047 {
00048 Texture::Texture(int32_t texture_id, size_t hash) :
00049 id(texture_id),
00050 url_hash(hash)
00051 {
00052 }
00053
00054 Texture::~Texture()
00055 {
00056
00057
00058
00059
00060 GLuint ids[1];
00061 ids[0] = id;
00062 glDeleteTextures(1, &ids[0]);
00063 }
00064
00065 TextureCache::TextureCache(ImageCachePtr image_cache, size_t size) :
00066 cache_(size),
00067 image_cache_(image_cache)
00068 {
00069
00070 }
00071
00072 TexturePtr TextureCache::GetTexture(size_t url_hash, const QString& url, bool& failed)
00073 {
00074 TexturePtr texture;
00075
00076 failed = false;
00077
00078 TexturePtr* texture_ptr = cache_.take(url_hash);
00079 if (texture_ptr)
00080 {
00081 texture = *texture_ptr;
00082 delete texture_ptr;
00083 }
00084
00085 if (!texture)
00086 {
00087 ImagePtr image = image_cache_->GetImage(url_hash, url);
00088
00089 if (image)
00090 {
00091 failed = image->Failed();
00092 boost::shared_ptr<QImage> image_ptr = image->GetImage();
00093 if (image_ptr)
00094 {
00095
00096
00097
00098 QImage qimage = *image_ptr;
00099
00100 GLuint ids[1];
00101 uint32_t check = 9999999;
00102 ids[0] = check;
00103
00104 glGenTextures(1, &ids[0]);
00105
00106 if (check == ids[0])
00107 {
00108 ROS_ERROR("FAILED TO CREATE TEXTURE");
00109
00110 GLenum err = glGetError();
00111 const GLubyte *errString = gluErrorString(err);
00112 ROS_ERROR("GL ERROR(%u): %s", err, errString);
00113 return texture;
00114 }
00115
00116 texture_ptr = new TexturePtr(boost::make_shared<Texture>(ids[0], url_hash));
00117 texture = *texture_ptr;
00118
00119 float max_dim = std::max(qimage.width(), qimage.height());
00120 int32_t dimension = swri_math_util::Round(
00121 std::pow(2, std::ceil(std::log(max_dim) / std::log(2.0f))));
00122
00123 if (qimage.width() != dimension || qimage.height() != dimension)
00124 {
00125 qimage = qimage.scaled(dimension, dimension, Qt::IgnoreAspectRatio, Qt::FastTransformation);
00126 }
00127
00128 glBindTexture(GL_TEXTURE_2D, texture->id);
00129 glTexImage2D(
00130 GL_TEXTURE_2D,
00131 0,
00132 3,
00133 dimension,
00134 dimension,
00135 0,
00136 GL_RGBA,
00137 GL_UNSIGNED_BYTE,
00138 QGLWidget::convertToGLFormat(qimage).bits());
00139
00140 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00142
00143 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00145
00146 cache_.insert(url_hash, texture_ptr);
00147 }
00148 }
00149 }
00150
00151 return texture;
00152 }
00153
00154 void TextureCache::AddTexture(const TexturePtr& texture)
00155 {
00156 if (texture)
00157 {
00158 TexturePtr* texture_ptr = new TexturePtr(texture);
00159 cache_.insert(texture->url_hash, texture_ptr);
00160 }
00161 }
00162
00163 void TextureCache::Clear()
00164 {
00165 image_cache_->Clear();
00166 cache_.clear();
00167 }
00168 }