mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 19:30:04 +00:00 
			
		
		
		
	Generate multiple texture atlases when first atlas is full
This commit is contained in:
		
							parent
							
								
									7198d1c7af
								
							
						
					
					
						commit
						9766e02f32
					
				
					 10 changed files with 205 additions and 141 deletions
				
			
		|  | @ -23,7 +23,7 @@ static constexpr size_t kNumRectangles        = 1; | |||
| static constexpr size_t kNumTriangles         = kNumRectangles * 2; | ||||
| static constexpr size_t kVerticesPerTriangle  = 3; | ||||
| static constexpr size_t kVerticesPerRectangle = kVerticesPerTriangle * 2; | ||||
| static constexpr size_t kPointsPerVertex      = 10; | ||||
| static constexpr size_t kPointsPerVertex      = 11; | ||||
| static constexpr size_t kBufferLength = | ||||
|    kNumTriangles * kVerticesPerTriangle * kPointsPerVertex; | ||||
| 
 | ||||
|  | @ -147,7 +147,7 @@ void GeoLine::Initialize() | |||
| 
 | ||||
|    // aTexCoord
 | ||||
|    gl.glVertexAttribPointer(2, | ||||
|                             2, | ||||
|                             3, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|  | @ -160,7 +160,7 @@ void GeoLine::Initialize() | |||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(6 * sizeof(float))); | ||||
|                             reinterpret_cast<void*>(7 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(3); | ||||
| 
 | ||||
|    p->dirty_ = true; | ||||
|  | @ -264,6 +264,8 @@ void GeoLine::Impl::Update() | |||
|       const float oy = width_ * 0.5f * sinf(angle_); | ||||
| 
 | ||||
|       // Texture coordinates
 | ||||
|       static constexpr float r = 0.0f; | ||||
| 
 | ||||
|       const float ls = texture_.sLeft_; | ||||
|       const float rs = texture_.sRight_; | ||||
|       const float tt = texture_.tTop_; | ||||
|  | @ -289,12 +291,12 @@ void GeoLine::Impl::Update() | |||
|          {                                   //
 | ||||
|           // Line
 | ||||
|           { | ||||
|              {lx, by, -ox, -oy, ls, bt, mc0, mc1, mc2, mc3}, // BL
 | ||||
|              {lx, by, +ox, +oy, ls, tt, mc0, mc1, mc2, mc3}, // TL
 | ||||
|              {rx, ty, -ox, -oy, rs, bt, mc0, mc1, mc2, mc3}, // BR
 | ||||
|              {rx, ty, -ox, -oy, rs, bt, mc0, mc1, mc2, mc3}, // BR
 | ||||
|              {rx, ty, +ox, +oy, rs, tt, mc0, mc1, mc2, mc3}, // TR
 | ||||
|              {lx, by, +ox, +oy, ls, tt, mc0, mc1, mc2, mc3}  // TL
 | ||||
|              {lx, by, -ox, -oy, ls, bt, r, mc0, mc1, mc2, mc3}, // BL
 | ||||
|              {lx, by, +ox, +oy, ls, tt, r, mc0, mc1, mc2, mc3}, // TL
 | ||||
|              {rx, ty, -ox, -oy, rs, bt, r, mc0, mc1, mc2, mc3}, // BR
 | ||||
|              {rx, ty, -ox, -oy, rs, bt, r, mc0, mc1, mc2, mc3}, // BR
 | ||||
|              {rx, ty, +ox, +oy, rs, tt, r, mc0, mc1, mc2, mc3}, // TR
 | ||||
|              {lx, by, +ox, +oy, ls, tt, r, mc0, mc1, mc2, mc3}  // TL
 | ||||
|           }}; | ||||
| 
 | ||||
|       gl.glBufferData(GL_ARRAY_BUFFER, | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ static constexpr std::size_t kNumTriangles         = kNumRectangles * 2; | |||
| static constexpr std::size_t kVerticesPerTriangle  = 3; | ||||
| static constexpr std::size_t kVerticesPerRectangle = kVerticesPerTriangle * 2; | ||||
| static constexpr std::size_t kPointsPerVertex      = 9; | ||||
| static constexpr std::size_t kPointsPerTexCoord    = 2; | ||||
| static constexpr std::size_t kPointsPerTexCoord    = 3; | ||||
| static constexpr std::size_t kIconBufferLength = | ||||
|    kNumTriangles * kVerticesPerTriangle * kPointsPerVertex; | ||||
| static constexpr std::size_t kTextureBufferLength = | ||||
|  | @ -208,7 +208,7 @@ void PlacefileIcons::Initialize() | |||
| 
 | ||||
|    // aTexCoord
 | ||||
|    gl.glVertexAttribPointer(2, | ||||
|                             2, | ||||
|                             3, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerTexCoord * sizeof(float), | ||||
|  | @ -508,12 +508,12 @@ void PlacefileIcons::Impl::UpdateTextureBuffer() | |||
|             textureBuffer_.end(), | ||||
|             { | ||||
|                // Icon
 | ||||
|                0.0f, 0.0f, // BL
 | ||||
|                0.0f, 0.0f, // TL
 | ||||
|                0.0f, 0.0f, // BR
 | ||||
|                0.0f, 0.0f, // BR
 | ||||
|                0.0f, 0.0f, // TR
 | ||||
|                0.0f, 0.0f  // TL
 | ||||
|                0.0f, 0.0f, 0.0f, // BL
 | ||||
|                0.0f, 0.0f, 0.0f, // TL
 | ||||
|                0.0f, 0.0f, 0.0f, // BR
 | ||||
|                0.0f, 0.0f, 0.0f, // BR
 | ||||
|                0.0f, 0.0f, 0.0f, // TR
 | ||||
|                0.0f, 0.0f, 0.0f  // TL
 | ||||
|             }); | ||||
|          // clang-format on
 | ||||
| 
 | ||||
|  | @ -536,12 +536,12 @@ void PlacefileIcons::Impl::UpdateTextureBuffer() | |||
|             textureBuffer_.end(), | ||||
|             { | ||||
|                // Icon
 | ||||
|                0.0f, 0.0f, // BL
 | ||||
|                0.0f, 0.0f, // TL
 | ||||
|                0.0f, 0.0f, // BR
 | ||||
|                0.0f, 0.0f, // BR
 | ||||
|                0.0f, 0.0f, // TR
 | ||||
|                0.0f, 0.0f  // TL
 | ||||
|                0.0f, 0.0f, 0.0f, // BL
 | ||||
|                0.0f, 0.0f, 0.0f, // TL
 | ||||
|                0.0f, 0.0f, 0.0f, // BR
 | ||||
|                0.0f, 0.0f, 0.0f, // BR
 | ||||
|                0.0f, 0.0f, 0.0f, // TR
 | ||||
|                0.0f, 0.0f, 0.0f  // TL
 | ||||
|             }); | ||||
|          // clang-format on
 | ||||
| 
 | ||||
|  | @ -559,18 +559,19 @@ void PlacefileIcons::Impl::UpdateTextureBuffer() | |||
|       const float rs = ls + icon.scaledWidth_; | ||||
|       const float tt = icon.texture_.tTop_ + iconY; | ||||
|       const float bt = tt + icon.scaledHeight_; | ||||
|       const float r  = static_cast<float>(icon.texture_.layerId_); | ||||
| 
 | ||||
|       // clang-format off
 | ||||
|       textureBuffer_.insert( | ||||
|          textureBuffer_.end(), | ||||
|          { | ||||
|             // Icon
 | ||||
|             ls, bt, // BL
 | ||||
|             ls, tt, // TL
 | ||||
|             rs, bt, // BR
 | ||||
|             rs, bt, // BR
 | ||||
|             rs, tt, // TR
 | ||||
|             ls, tt  // TL
 | ||||
|             ls, bt, r, // BL
 | ||||
|             ls, tt, r, // TL
 | ||||
|             rs, bt, r, // BR
 | ||||
|             rs, bt, r, // BR
 | ||||
|             rs, tt, r, // TR
 | ||||
|             ls, tt, r  // TL
 | ||||
|          }); | ||||
|       // clang-format on
 | ||||
|    } | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ static constexpr std::size_t kNumTriangles         = kNumRectangles * 2; | |||
| static constexpr std::size_t kVerticesPerTriangle  = 3; | ||||
| static constexpr std::size_t kVerticesPerRectangle = kVerticesPerTriangle * 2; | ||||
| static constexpr std::size_t kPointsPerVertex      = 8; | ||||
| static constexpr std::size_t kPointsPerTexCoord    = 2; | ||||
| static constexpr std::size_t kPointsPerTexCoord    = 3; | ||||
| static constexpr std::size_t kImageBufferLength = | ||||
|    kNumTriangles * kVerticesPerTriangle * kPointsPerVertex; | ||||
| static constexpr std::size_t kTextureBufferLength = | ||||
|  | @ -177,7 +177,7 @@ void PlacefileImages::Initialize() | |||
| 
 | ||||
|    // aTexCoord
 | ||||
|    gl.glVertexAttribPointer(2, | ||||
|                             2, | ||||
|                             3, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerTexCoord * sizeof(float), | ||||
|  | @ -367,6 +367,8 @@ void PlacefileImages::Impl::UpdateTextureBuffer() | |||
|                                            currentImageFiles_.cbegin()->second : | ||||
|                                            it->second; | ||||
| 
 | ||||
|       const float r = static_cast<float>(image.texture_.layerId_); | ||||
| 
 | ||||
|       // Limit processing to groups of 3 (triangles)
 | ||||
|       std::size_t numElements = di->elements_.size() - di->elements_.size() % 3; | ||||
|       for (std::size_t i = 0; i < numElements; ++i) | ||||
|  | @ -379,7 +381,7 @@ void PlacefileImages::Impl::UpdateTextureBuffer() | |||
|          const float t = | ||||
|             image.texture_.tTop_ + (image.scaledHeight_ * element.tv_); | ||||
| 
 | ||||
|          textureBuffer_.insert(textureBuffer_.end(), {s, t}); | ||||
|          textureBuffer_.insert(textureBuffer_.end(), {s, t, r}); | ||||
|       } | ||||
|    } | ||||
| } | ||||
|  |  | |||
|  | @ -50,7 +50,7 @@ public: | |||
|    std::shared_mutex textureCacheMutex_ {}; | ||||
|    std::unordered_map<std::string, boost::gil::rgba8_image_t> textureCache_ {}; | ||||
| 
 | ||||
|    boost::gil::rgba8_image_t                          atlas_ {}; | ||||
|    std::vector<boost::gil::rgba8_image_t>             atlasArray_ {}; | ||||
|    std::unordered_map<std::string, TextureAttributes> atlasMap_ {}; | ||||
|    std::shared_mutex                                  atlasMutex_ {}; | ||||
| 
 | ||||
|  | @ -95,7 +95,7 @@ bool TextureAtlas::CacheTexture(const std::string& name, | |||
|    return false; | ||||
| } | ||||
| 
 | ||||
| void TextureAtlas::BuildAtlas(size_t width, size_t height) | ||||
| void TextureAtlas::BuildAtlas(std::size_t width, std::size_t height) | ||||
| { | ||||
|    logger_->debug("Building {}x{} texture atlas", width, height); | ||||
| 
 | ||||
|  | @ -105,11 +105,13 @@ void TextureAtlas::BuildAtlas(size_t width, size_t height) | |||
|       return; | ||||
|    } | ||||
| 
 | ||||
|    std::vector<std::pair< | ||||
|    typedef std::vector<std::pair< | ||||
|       std::string, | ||||
|       std::variant<boost::gil::rgba8_image_t, boost::gil::rgba8_image_t*>>> | ||||
|                            images; | ||||
|    std::vector<stbrp_rect> stbrpRects; | ||||
|       ImageVector; | ||||
| 
 | ||||
|    ImageVector             images {}; | ||||
|    std::vector<stbrp_rect> stbrpRects {}; | ||||
| 
 | ||||
|    // Load images
 | ||||
|    { | ||||
|  | @ -171,104 +173,143 @@ void TextureAtlas::BuildAtlas(size_t width, size_t height) | |||
|       } | ||||
|    } | ||||
| 
 | ||||
|    // Pack images
 | ||||
|    { | ||||
|       logger_->trace("Packing {} images", images.size()); | ||||
| 
 | ||||
|       // Optimal number of nodes = width
 | ||||
|       stbrp_context           stbrpContext; | ||||
|       std::vector<stbrp_node> stbrpNodes(width); | ||||
| 
 | ||||
|       stbrp_init_target(&stbrpContext, | ||||
|                         static_cast<int>(width), | ||||
|                         static_cast<int>(height), | ||||
|                         stbrpNodes.data(), | ||||
|                         static_cast<int>(stbrpNodes.size())); | ||||
| 
 | ||||
|       // Pack loaded textures
 | ||||
|       stbrp_pack_rects( | ||||
|          &stbrpContext, stbrpRects.data(), static_cast<int>(stbrpRects.size())); | ||||
|    } | ||||
| 
 | ||||
|    // Lock atlas
 | ||||
|    std::unique_lock lock(p->atlasMutex_); | ||||
| 
 | ||||
|    // Clear index
 | ||||
|    p->atlasMap_.clear(); | ||||
| 
 | ||||
|    // Clear atlas
 | ||||
|    p->atlas_.recreate(width, height); | ||||
|    boost::gil::rgba8_view_t atlasView = boost::gil::view(p->atlas_); | ||||
|    boost::gil::fill_pixels(atlasView, | ||||
|                            boost::gil::rgba8_pixel_t {255, 0, 255, 255}); | ||||
| 
 | ||||
|    // Populate atlas
 | ||||
|    logger_->trace("Populating atlas"); | ||||
|    // GL_MAX_ARRAY_TEXTURE_LAYERS is guaranteed to be at least 256 in OpenGL 3.3
 | ||||
|    constexpr std::size_t kMaxLayers = 256u; | ||||
| 
 | ||||
|    const float xStep = 1.0f / width; | ||||
|    const float yStep = 1.0f / height; | ||||
|    const float xMin  = xStep * 0.5f; | ||||
|    const float yMin  = yStep * 0.5f; | ||||
| 
 | ||||
|    for (size_t i = 0; i < images.size(); i++) | ||||
|    // Optimal number of nodes = width
 | ||||
|    stbrp_context           stbrpContext; | ||||
|    std::vector<stbrp_node> stbrpNodes(width); | ||||
|    ImageVector             unpackedImages {}; | ||||
|    std::vector<stbrp_rect> unpackedRects {}; | ||||
| 
 | ||||
|    std::vector<boost::gil::rgba8_image_t>             newAtlasArray {}; | ||||
|    std::unordered_map<std::string, TextureAttributes> newAtlasMap {}; | ||||
| 
 | ||||
|    for (std::size_t layer = 0; layer < kMaxLayers; ++layer) | ||||
|    { | ||||
|       // If the image was packed successfully
 | ||||
|       if (stbrpRects[i].was_packed != 0) | ||||
|       logger_->trace("Processing layer {}", layer); | ||||
| 
 | ||||
|       // Pack images
 | ||||
|       { | ||||
|          // Populate the atlas
 | ||||
|          boost::gil::rgba8c_view_t imageView; | ||||
|          logger_->trace("Packing {} images", images.size()); | ||||
| 
 | ||||
|          // Retrieve the image
 | ||||
|          if (std::holds_alternative<boost::gil::rgba8_image_t>( | ||||
|                 images[i].second)) | ||||
|          stbrp_init_target(&stbrpContext, | ||||
|                            static_cast<int>(width), | ||||
|                            static_cast<int>(height), | ||||
|                            stbrpNodes.data(), | ||||
|                            static_cast<int>(stbrpNodes.size())); | ||||
| 
 | ||||
|          // Pack loaded textures
 | ||||
|          stbrp_pack_rects(&stbrpContext, | ||||
|                           stbrpRects.data(), | ||||
|                           static_cast<int>(stbrpRects.size())); | ||||
|       } | ||||
| 
 | ||||
|       // Clear atlas
 | ||||
|       auto& atlas = | ||||
|          newAtlasArray.emplace_back(boost::gil::rgba8_image_t(width, height)); | ||||
|       boost::gil::rgba8_view_t atlasView = boost::gil::view(atlas); | ||||
|       boost::gil::fill_pixels(atlasView, | ||||
|                               boost::gil::rgba8_pixel_t {255, 0, 255, 255}); | ||||
| 
 | ||||
|       // Populate atlas
 | ||||
|       logger_->trace("Populating atlas"); | ||||
| 
 | ||||
|       for (std::size_t i = 0; i < images.size(); ++i) | ||||
|       { | ||||
|          // If the image was packed successfully
 | ||||
|          if (stbrpRects[i].was_packed != 0) | ||||
|          { | ||||
|             imageView = boost::gil::const_view( | ||||
|                std::get<boost::gil::rgba8_image_t>(images[i].second)); | ||||
|             // Populate the atlas
 | ||||
|             boost::gil::rgba8c_view_t imageView; | ||||
| 
 | ||||
|             // Retrieve the image
 | ||||
|             if (std::holds_alternative<boost::gil::rgba8_image_t>( | ||||
|                    images[i].second)) | ||||
|             { | ||||
|                imageView = boost::gil::const_view( | ||||
|                   std::get<boost::gil::rgba8_image_t>(images[i].second)); | ||||
|             } | ||||
|             else if (std::holds_alternative<boost::gil::rgba8_image_t*>( | ||||
|                         images[i].second)) | ||||
|             { | ||||
|                imageView = boost::gil::const_view( | ||||
|                   *std::get<boost::gil::rgba8_image_t*>(images[i].second)); | ||||
|             } | ||||
| 
 | ||||
|             boost::gil::rgba8_view_t atlasSubView = | ||||
|                boost::gil::subimage_view(atlasView, | ||||
|                                          stbrpRects[i].x, | ||||
|                                          stbrpRects[i].y, | ||||
|                                          imageView.width(), | ||||
|                                          imageView.height()); | ||||
| 
 | ||||
|             boost::gil::copy_pixels(imageView, atlasSubView); | ||||
| 
 | ||||
|             // Add texture image to the index
 | ||||
|             const stbrp_coord x = stbrpRects[i].x; | ||||
|             const stbrp_coord y = stbrpRects[i].y; | ||||
| 
 | ||||
|             const float sLeft = x * xStep + xMin; | ||||
|             const float sRight = | ||||
|                sLeft + static_cast<float>(imageView.width() - 1) / width; | ||||
|             const float tTop = y * yStep + yMin; | ||||
|             const float tBottom = | ||||
|                tTop + static_cast<float>(imageView.height() - 1) / height; | ||||
| 
 | ||||
|             newAtlasMap.emplace( | ||||
|                std::piecewise_construct, | ||||
|                std::forward_as_tuple(images[i].first), | ||||
|                std::forward_as_tuple( | ||||
|                   layer, | ||||
|                   boost::gil::point_t {x, y}, | ||||
|                   boost::gil::point_t {imageView.width(), imageView.height()}, | ||||
|                   sLeft, | ||||
|                   sRight, | ||||
|                   tTop, | ||||
|                   tBottom)); | ||||
|          } | ||||
|          else if (std::holds_alternative<boost::gil::rgba8_image_t*>( | ||||
|                      images[i].second)) | ||||
|          else | ||||
|          { | ||||
|             imageView = boost::gil::const_view( | ||||
|                *std::get<boost::gil::rgba8_image_t*>(images[i].second)); | ||||
|             unpackedImages.push_back(std::move(images[i])); | ||||
|             unpackedRects.push_back(stbrpRects[i]); | ||||
|          } | ||||
|       } | ||||
| 
 | ||||
|          boost::gil::rgba8_view_t atlasSubView = | ||||
|             boost::gil::subimage_view(atlasView, | ||||
|                                       stbrpRects[i].x, | ||||
|                                       stbrpRects[i].y, | ||||
|                                       imageView.width(), | ||||
|                                       imageView.height()); | ||||
| 
 | ||||
|          boost::gil::copy_pixels(imageView, atlasSubView); | ||||
| 
 | ||||
|          // Add texture image to the index
 | ||||
|          const stbrp_coord x = stbrpRects[i].x; | ||||
|          const stbrp_coord y = stbrpRects[i].y; | ||||
| 
 | ||||
|          const float sLeft = x * xStep + xMin; | ||||
|          const float sRight = | ||||
|             sLeft + static_cast<float>(imageView.width() - 1) / width; | ||||
|          const float tTop = y * yStep + yMin; | ||||
|          const float tBottom = | ||||
|             tTop + static_cast<float>(imageView.height() - 1) / height; | ||||
| 
 | ||||
|          p->atlasMap_.emplace( | ||||
|             std::piecewise_construct, | ||||
|             std::forward_as_tuple(images[i].first), | ||||
|             std::forward_as_tuple( | ||||
|                boost::gil::point_t {x, y}, | ||||
|                boost::gil::point_t {imageView.width(), imageView.height()}, | ||||
|                sLeft, | ||||
|                sRight, | ||||
|                tTop, | ||||
|                tBottom)); | ||||
|       if (unpackedImages.empty()) | ||||
|       { | ||||
|          // All images have been packed into the texture atlas
 | ||||
|          break; | ||||
|       } | ||||
|       else if (layer == kMaxLayers - 1u) | ||||
|       { | ||||
|          // Some images were unable to be packed into the texture atlas
 | ||||
|          for (auto& image : unpackedImages) | ||||
|          { | ||||
|             logger_->warn("Unable to pack texture: {}", image.first); | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          logger_->warn("Unable to pack texture: {}", images[i].first); | ||||
|          // Swap in unpacked images for processing the next atlas layer
 | ||||
|          images.swap(unpackedImages); | ||||
|          stbrpRects.swap(unpackedRects); | ||||
|          unpackedImages.clear(); | ||||
|          unpackedRects.clear(); | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    // Lock atlas
 | ||||
|    std::unique_lock lock(p->atlasMutex_); | ||||
| 
 | ||||
|    p->atlasArray_.swap(newAtlasArray); | ||||
|    p->atlasMap_.swap(newAtlasMap); | ||||
| 
 | ||||
|    // Mark the need to buffer the atlas
 | ||||
|    ++p->buildCount_; | ||||
| } | ||||
|  | @ -279,19 +320,28 @@ GLuint TextureAtlas::BufferAtlas(gl::OpenGLFunctions& gl) | |||
| 
 | ||||
|    std::shared_lock lock(p->atlasMutex_); | ||||
| 
 | ||||
|    if (p->atlas_.width() > 0u && p->atlas_.height() > 0u) | ||||
|    if (p->atlasArray_.size() > 0u && p->atlasArray_[0].width() > 0 && | ||||
|        p->atlasArray_[0].height() > 0) | ||||
|    { | ||||
|       boost::gil::rgba8_view_t               view = boost::gil::view(p->atlas_); | ||||
|       std::vector<boost::gil::rgba8_pixel_t> pixelData(view.width() * | ||||
|                                                        view.height()); | ||||
|       const std::size_t numLayers = p->atlasArray_.size(); | ||||
|       const std::size_t width     = p->atlasArray_[0].width(); | ||||
|       const std::size_t height    = p->atlasArray_[0].height(); | ||||
|       const std::size_t layerSize = width * height; | ||||
| 
 | ||||
|       boost::gil::copy_pixels( | ||||
|          view, | ||||
|          boost::gil::interleaved_view(view.width(), | ||||
|                                       view.height(), | ||||
|                                       pixelData.data(), | ||||
|                                       view.width() * | ||||
|                                          sizeof(boost::gil::rgba8_pixel_t))); | ||||
|       std::vector<boost::gil::rgba8_pixel_t> pixelData {layerSize * numLayers}; | ||||
| 
 | ||||
|       for (std::size_t i = 0; i < numLayers; ++i) | ||||
|       { | ||||
|          boost::gil::rgba8_view_t view = boost::gil::view(p->atlasArray_[i]); | ||||
| 
 | ||||
|          boost::gil::copy_pixels( | ||||
|             view, | ||||
|             boost::gil::interleaved_view(view.width(), | ||||
|                                          view.height(), | ||||
|                                          pixelData.data() + (i * layerSize), | ||||
|                                          view.width() * | ||||
|                                             sizeof(boost::gil::rgba8_pixel_t))); | ||||
|       } | ||||
| 
 | ||||
|       lock.unlock(); | ||||
| 
 | ||||
|  | @ -308,9 +358,9 @@ GLuint TextureAtlas::BufferAtlas(gl::OpenGLFunctions& gl) | |||
|       gl.glTexImage3D(GL_TEXTURE_2D_ARRAY, | ||||
|                       0, | ||||
|                       GL_RGBA, | ||||
|                       view.width(), | ||||
|                       view.height(), | ||||
|                       1u, | ||||
|                       static_cast<GLsizei>(width), | ||||
|                       static_cast<GLsizei>(height), | ||||
|                       static_cast<GLsizei>(numLayers), | ||||
|                       0, | ||||
|                       GL_RGBA, | ||||
|                       GL_UNSIGNED_BYTE, | ||||
|  | @ -424,6 +474,11 @@ TextureAtlas::Impl::LoadImage(const std::string& imagePath) | |||
|                }); | ||||
|          } | ||||
| 
 | ||||
|          boost::gil::write_view( | ||||
|             fmt::format("gil-{}.png", url.fileName().toStdString()), | ||||
|             image._view, | ||||
|             boost::gil::png_tag()); | ||||
| 
 | ||||
|          stbi_image_free(pixelData); | ||||
|       } | ||||
|       else if (response.status_code == 0) | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ struct TextureAttributes | |||
| { | ||||
|    TextureAttributes() : | ||||
|        valid_ {false}, | ||||
|        layerId_ {}, | ||||
|        position_ {}, | ||||
|        size_ {}, | ||||
|        sLeft_ {}, | ||||
|  | @ -27,13 +28,15 @@ struct TextureAttributes | |||
|    { | ||||
|    } | ||||
| 
 | ||||
|    TextureAttributes(boost::gil::point_t position, | ||||
|    TextureAttributes(std::size_t         layerId, | ||||
|                      boost::gil::point_t position, | ||||
|                      boost::gil::point_t size, | ||||
|                      float               sLeft, | ||||
|                      float               sRight, | ||||
|                      float               tTop, | ||||
|                      float               tBottom) : | ||||
|        valid_ {true}, | ||||
|        layerId_ {layerId}, | ||||
|        position_ {position}, | ||||
|        size_ {size}, | ||||
|        sLeft_ {sLeft}, | ||||
|  | @ -44,6 +47,7 @@ struct TextureAttributes | |||
|    } | ||||
| 
 | ||||
|    bool                valid_; | ||||
|    std::size_t         layerId_; | ||||
|    boost::gil::point_t position_; | ||||
|    boost::gil::point_t size_; | ||||
|    float               sLeft_; | ||||
|  | @ -70,7 +74,7 @@ public: | |||
| 
 | ||||
|    void   RegisterTexture(const std::string& name, const std::string& path); | ||||
|    bool   CacheTexture(const std::string& name, const std::string& path); | ||||
|    void   BuildAtlas(size_t width, size_t height); | ||||
|    void   BuildAtlas(std::size_t width, std::size_t height); | ||||
|    GLuint BufferAtlas(gl::OpenGLFunctions& gl); | ||||
| 
 | ||||
|    TextureAttributes GetTextureAttributes(const std::string& name); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat