texture_cache.cpp
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // Copyright (c) 2014, Southwest Research Institute® (SwRI®)
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Southwest Research Institute® (SwRI®) nor the
14 // names of its contributors may be used to endorse or promote products
15 // derived from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 // *****************************************************************************
29 
30 #include <tile_map/texture_cache.h>
31 
32 #include <cmath>
33 
34 #include <boost/make_shared.hpp>
35 
36 #include <GL/glew.h>
37 #include <GL/gl.h>
38 #include <GL/glu.h>
39 
40 #include <ros/ros.h>
41 
42 #include <QGLWidget>
43 #include <QImage>
44 
46 
47 namespace tile_map
48 {
49  Texture::Texture(int32_t texture_id, size_t hash) :
50  id(texture_id),
51  url_hash(hash)
52  {
53  }
54 
56  {
57  //ROS_ERROR("==== DELETING TEXTURE: %d ====", id);
58  // The texture will automatically be freed from the GPU memory when it goes
59  // out of scope. This is effectively when it is no longer in the texture
60  // cache or being referenced for a render.
61  GLuint ids[1];
62  ids[0] = id;
63  glDeleteTextures(1, &ids[0]);
64  }
65 
66  TextureCache::TextureCache(ImageCachePtr image_cache, size_t size) :
67  cache_(size),
68  image_cache_(image_cache)
69  {
70 
71  }
72 
73  TexturePtr TextureCache::GetTexture(size_t url_hash, const QString& url, bool& failed, int priority)
74  {
75  TexturePtr texture;
76 
77  failed = false;
78 
79  TexturePtr* texture_ptr = cache_.take(url_hash);
80  if (texture_ptr)
81  {
82  texture = *texture_ptr;
83  delete texture_ptr;
84  }
85 
86  if (!texture)
87  {
88  ImagePtr image = image_cache_->GetImage(url_hash, url, priority);
89 
90  if (image)
91  {
92  failed = image->Failed();
93  boost::shared_ptr<QImage> image_ptr = image->GetImage();
94  if (image_ptr)
95  {
96  // All of the OpenGL calls need to occur on the main thread and so
97  // can't be done in the background. The QImage calls could
98  // potentially be done in a background thread by the image cache.
99  QImage qimage = *image_ptr;
100 
101  GLuint ids[1];
102  uint32_t check = 9999999;
103  ids[0] = check;
104 
105  glGenTextures(1, &ids[0]);
106 
107  if (check == ids[0])
108  {
109  ROS_ERROR("FAILED TO CREATE TEXTURE");
110 
111  GLenum err = glGetError();
112  const GLubyte *errString = gluErrorString(err);
113  ROS_ERROR("GL ERROR(%u): %s", err, errString);
114  return texture;
115  }
116 
117  texture_ptr = new TexturePtr(boost::make_shared<Texture>(ids[0], url_hash));
118  texture = *texture_ptr;
119 
120  float max_dim = std::max(qimage.width(), qimage.height());
121  int32_t dimension = swri_math_util::Round(
122  std::pow(2, std::ceil(std::log(max_dim) / std::log(2.0f))));
123 
124  if (qimage.width() != dimension || qimage.height() != dimension)
125  {
126  qimage = qimage.scaled(dimension, dimension, Qt::IgnoreAspectRatio, Qt::FastTransformation);
127  }
128 
129  glBindTexture(GL_TEXTURE_2D, texture->id);
130  glTexImage2D(
131  GL_TEXTURE_2D,
132  0,
133  GL_RGBA,
134  dimension,
135  dimension,
136  0,
137  GL_RGBA,
138  GL_UNSIGNED_BYTE,
139  QGLWidget::convertToGLFormat(qimage).bits());
140 
141  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
142  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
143 
144  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
145  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
146 
147  cache_.insert(url_hash, texture_ptr);
148  }
149  }
150  }
151 
152  return texture;
153  }
154 
156  {
157  if (texture)
158  {
159  TexturePtr* texture_ptr = new TexturePtr(texture);
160  cache_.insert(texture->url_hash, texture_ptr);
161  }
162  }
163 
165  {
166  image_cache_->Clear();
167  cache_.clear();
168  }
169 }
ROSCPP_DECL bool check()
f
TextureCache(ImageCachePtr image_cache, size_t size=512)
void AddTexture(const TexturePtr &texture)
QCache< size_t, TexturePtr > cache_
Definition: texture_cache.h:63
const int32_t id
Definition: texture_cache.h:45
Texture(int32_t texture_id, size_t hash)
double Round(double value)
ImageCachePtr image_cache_
Definition: texture_cache.h:65
boost::shared_ptr< Texture > TexturePtr
Definition: texture_cache.h:50
#define ROS_ERROR(...)
TexturePtr GetTexture(size_t url_hash, const QString &url, bool &failed, int priority)


tile_map
Author(s): Marc Alban
autogenerated on Fri Mar 19 2021 02:44:47