Add Texture2D and use it in PatternAtlas (#1183)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -153,6 +153,8 @@ list(APPEND INCLUDE_FILES
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/uniform_block.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/uniform_buffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/vertex_attribute.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/texture2d.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/types.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/background_layer_factory.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/circle_layer_factory.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/fill_extrusion_layer_factory.hpp
|
||||
@@ -394,7 +396,6 @@ list(APPEND SRC_FILES
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/shader_registry.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/stencil_mode.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/types.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/uniform.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/uniform_block.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/uniform_buffer.cpp
|
||||
@@ -929,6 +930,7 @@ if(MLN_WITH_OPENGL)
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/uniform_block_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/uniform_buffer_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/vertex_attribute_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/texture2d.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/layermanager/location_indicator_layer_factory.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/platform/gl_functions.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/change_request.hpp
|
||||
@@ -1010,6 +1012,7 @@ if(MLN_WITH_OPENGL)
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/state.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/texture.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/texture_resource.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/texture_resource.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/types.hpp
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mbgl/util/identity.hpp>
|
||||
#include <mbgl/util/traits.hpp>
|
||||
#include <mbgl/gfx/texture2d.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
@@ -30,6 +31,20 @@ using DrawPriority = int64_t;
|
||||
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
|
||||
|
||||
class Drawable {
|
||||
public:
|
||||
struct TextureAttachment {
|
||||
/// @brief A Texture2D instance
|
||||
std::shared_ptr<gfx::Texture2D> texture{nullptr};
|
||||
/// @brief A sampler location to bind the texture to
|
||||
int32_t location{0};
|
||||
|
||||
TextureAttachment() = delete;
|
||||
TextureAttachment(std::shared_ptr<gfx::Texture2D> tex, int32_t loc)
|
||||
: texture(std::move(tex)),
|
||||
location(loc) {}
|
||||
};
|
||||
using Textures = std::vector<TextureAttachment>;
|
||||
|
||||
protected:
|
||||
Drawable(std::string name);
|
||||
|
||||
@@ -73,6 +88,23 @@ public:
|
||||
int32_t getLineWidth() const { return lineWidth; }
|
||||
void setLineWidth(int32_t value) { lineWidth = value; }
|
||||
|
||||
/// @brief Remove an attached texture from this drawable at the given sampler location
|
||||
/// @param location Texture sampler location
|
||||
void removeTexture(int32_t location);
|
||||
|
||||
/// @brief Return the textures attached to this drawable
|
||||
/// @return Texture and sampler location pairs
|
||||
const Textures& getTextures() const { return textures; };
|
||||
|
||||
/// @brief Set the collection of textures bound to this drawable
|
||||
/// @param textures_ A Textures collection to set
|
||||
void setTextures(const Textures& textures_) noexcept { textures = textures_; }
|
||||
|
||||
/// @brief Attach the given texture to this drawable at the given sampler location.
|
||||
/// @param texture Texture2D instance
|
||||
/// @param location A sampler location in the shader being used with this drawable.
|
||||
void setTexture(std::shared_ptr<gfx::Texture2D>& texture, int32_t location);
|
||||
|
||||
/// not used for anything yet
|
||||
DrawPriority getDrawPriority() const { return drawPriority; }
|
||||
void setDrawPriority(DrawPriority value) { drawPriority = value; }
|
||||
@@ -141,6 +173,7 @@ protected:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
|
||||
Textures textures;
|
||||
std::vector<DrawableTweakerPtr> tweakers;
|
||||
};
|
||||
|
||||
|
||||
@@ -108,6 +108,11 @@ public:
|
||||
void setVertexAttrName(std::string value) { vertexAttrName = std::move(value); }
|
||||
void setColorAttrName(std::string value) { colorAttrName = std::move(value); }
|
||||
|
||||
/// @brief Attach the given texture at the given sampler location.
|
||||
/// @param texture Texture2D instance
|
||||
/// @param location A sampler location in the shader being used.
|
||||
void setTexture(const std::shared_ptr<gfx::Texture2D>& texture, int32_t location);
|
||||
|
||||
/// Set the matrix applied to new drawables
|
||||
void setMatrix(mat4 value) { matrix = value; }
|
||||
|
||||
@@ -169,6 +174,7 @@ protected:
|
||||
std::vector<UniqueDrawable> drawables;
|
||||
ColorAttrMode colorAttrMode = ColorAttrMode::PerVertex;
|
||||
VertexAttributeArray vertexAttrs;
|
||||
gfx::Drawable::Textures textures;
|
||||
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
|
||||
85
include/mbgl/gfx/texture2d.hpp
Normal file
85
include/mbgl/gfx/texture2d.hpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
#include <mbgl/gfx/types.hpp>
|
||||
#include <mbgl/util/image.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Size;
|
||||
|
||||
namespace gfx {
|
||||
|
||||
constexpr int32_t MaxActiveTextureUnits = 8;
|
||||
|
||||
class Context;
|
||||
class UploadPass;
|
||||
class TextureResource;
|
||||
|
||||
class Texture2D {
|
||||
public:
|
||||
struct SamplerState {
|
||||
/// Minification filter within a single mip level
|
||||
TextureFilterType minification{TextureFilterType::Nearest};
|
||||
/// Magnification filter within a single mip level
|
||||
TextureFilterType magnification{TextureFilterType::Nearest};
|
||||
/// Wrapping behavior along U coordinate
|
||||
TextureWrapType wrapU{TextureWrapType::Clamp};
|
||||
/// Wrapping behavior along V coordinate
|
||||
TextureWrapType wrapV{TextureWrapType::Clamp};
|
||||
};
|
||||
|
||||
public:
|
||||
virtual ~Texture2D() = default;
|
||||
|
||||
/// @brief Set the sampler configuration to be used for shader access of this
|
||||
/// texture.
|
||||
/// @param samplerState Sampler state configuration
|
||||
/// @return this
|
||||
virtual Texture2D& setSamplerConfiguration(const SamplerState& samplerState) noexcept = 0;
|
||||
|
||||
/// @brief Set the texture pixel and data format
|
||||
/// @param pixelFormat Pixel format to use
|
||||
/// @param channelType Data type of each color channel
|
||||
/// @return this
|
||||
virtual Texture2D& setFormat(TexturePixelType pixelFormat, TextureChannelDataType channelType) noexcept = 0;
|
||||
|
||||
/// @brief Set the size of the texture
|
||||
/// @param size_ Size of the texture
|
||||
/// @return this
|
||||
virtual Texture2D& setSize(Size size_) noexcept = 0;
|
||||
|
||||
/// @brief Determine the size of the buffer backing this texture
|
||||
/// as configured, in bytes.
|
||||
/// @return Size in bytes
|
||||
virtual size_t getDataSize() const noexcept = 0;
|
||||
|
||||
/// @brief Returns the size, in bytes, of a pixel in the texture.
|
||||
/// @return Size of a pixel, in bytes
|
||||
virtual size_t getPixelStride() const noexcept = 0;
|
||||
|
||||
/// @brief Returns the number of color channels in the texture.
|
||||
/// @return Channel count
|
||||
virtual size_t numChannels() const noexcept = 0;
|
||||
|
||||
/// @brief Create the texture using the provided buffer.
|
||||
/// @param pixelData Buffer of bytes to initialize the texture with
|
||||
virtual void create(const std::vector<uint8_t>& pixelData, gfx::UploadPass& uploadPass) noexcept = 0;
|
||||
|
||||
/// @brief Create the texture with default initialized memory.
|
||||
virtual void create() noexcept = 0;
|
||||
|
||||
/// @brief Upload image data to the texture resource
|
||||
/// @param image Image data to transfer
|
||||
/// @param uploadPass Upload pass to orchestrate upload
|
||||
virtual void upload(const PremultipliedImage& image, gfx::UploadPass& uploadPass) const noexcept = 0;
|
||||
|
||||
/// @brief Get the underlying GL texture resource
|
||||
/// @note: Compat with legacy textures, to be refactored
|
||||
/// @return gfx::TextureResource
|
||||
virtual gfx::TextureResource& getResource() = 0;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
@@ -26,6 +26,7 @@ using UniqueVertexBufferResource = std::unique_ptr<gfx::VertexBufferResource>;
|
||||
|
||||
namespace gl {
|
||||
|
||||
class Texture2D;
|
||||
class VertexArray;
|
||||
|
||||
class DrawableGL : public gfx::Drawable {
|
||||
@@ -62,6 +63,9 @@ protected:
|
||||
private:
|
||||
void bindUniformBuffers() const;
|
||||
void unbindUniformBuffers() const;
|
||||
|
||||
void bindTextures() const;
|
||||
void unbindTextures() const;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
70
include/mbgl/gl/texture2d.hpp
Normal file
70
include/mbgl/gl/texture2d.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/texture2d.hpp>
|
||||
#include <mbgl/platform/gl_functions.hpp>
|
||||
#include <mbgl/util/image.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace gl {
|
||||
|
||||
class Context;
|
||||
|
||||
class Texture2D : public gfx::Texture2D {
|
||||
public:
|
||||
Texture2D(gl::Context& context_);
|
||||
~Texture2D() override;
|
||||
|
||||
public: // gfx::Texture2D
|
||||
Texture2D& setSamplerConfiguration(const SamplerState& samplerState) noexcept override;
|
||||
|
||||
Texture2D& setFormat(gfx::TexturePixelType pixelFormat, gfx::TextureChannelDataType channelType) noexcept override;
|
||||
|
||||
Texture2D& setSize(Size size_) noexcept override;
|
||||
|
||||
size_t getDataSize() const noexcept override;
|
||||
|
||||
size_t getPixelStride() const noexcept override;
|
||||
|
||||
size_t numChannels() const noexcept override;
|
||||
|
||||
void create(const std::vector<uint8_t>& pixelData, gfx::UploadPass& uploadPass) noexcept override;
|
||||
void create() noexcept override;
|
||||
|
||||
void upload(const PremultipliedImage& image, gfx::UploadPass& uploadPass) const noexcept override;
|
||||
|
||||
gfx::TextureResource& getResource() override { return *textureResource; }
|
||||
|
||||
public:
|
||||
/// @brief Get the OpenGL handle ID for the underlying resource
|
||||
/// @return GLuint
|
||||
platform::GLuint getTextureID() const noexcept;
|
||||
|
||||
/// @brief Bind this texture to the specified texture unit
|
||||
/// @param location Location index of texture sampler in a shader
|
||||
/// @param textureUnit Unit to bind to. A maximum of gl::MaxActiveTextureUnits
|
||||
/// texture units are available for binding.
|
||||
void bind(int32_t location, int32_t textureUnit) noexcept;
|
||||
|
||||
/// @brief Unbind the texture, if it was bound
|
||||
void unbind() noexcept;
|
||||
|
||||
private:
|
||||
gl::Context& context;
|
||||
std::unique_ptr<gfx::TextureResource> textureResource{nullptr};
|
||||
|
||||
SamplerState samplerState{};
|
||||
gfx::TexturePixelType pixelFormat;
|
||||
gfx::TextureChannelDataType channelType;
|
||||
|
||||
Size size{0, 0};
|
||||
mutable bool samplerStateDirty{false};
|
||||
|
||||
int32_t boundTextureUnit{-1};
|
||||
int32_t boundLocation{-1};
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -29,5 +29,24 @@ void Drawable::setCullFaceMode(const gfx::CullFaceMode& value) {
|
||||
impl->cullFaceMode = value;
|
||||
}
|
||||
|
||||
void Drawable::setTexture(std::shared_ptr<gfx::Texture2D>& texture, int32_t location) {
|
||||
for (auto& tex : textures) {
|
||||
if (tex.location == location) {
|
||||
tex.texture = texture;
|
||||
return;
|
||||
}
|
||||
}
|
||||
textures.emplace_back(texture, location);
|
||||
}
|
||||
|
||||
void Drawable::removeTexture(int32_t location) {
|
||||
for (auto it = textures.begin(); it != textures.end(); ++it) {
|
||||
if (it->location == location) {
|
||||
textures.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -50,6 +50,7 @@ void DrawableBuilder::flush() {
|
||||
draw->setCullFaceMode(impl->cullFaceMode);
|
||||
draw->setShader(shader);
|
||||
draw->setMatrix(matrix);
|
||||
draw->setTextures(textures);
|
||||
|
||||
if (auto drawAttrs = getVertexAttributes().clone()) {
|
||||
vertexAttrs.observeAttributes([&](const std::string& iName, const VertexAttribute& iAttr) {
|
||||
@@ -102,6 +103,16 @@ void DrawableBuilder::resetDrawPriority(DrawPriority value) {
|
||||
}
|
||||
}
|
||||
|
||||
void DrawableBuilder::setTexture(const std::shared_ptr<gfx::Texture2D>& texture, int32_t location) {
|
||||
for (auto& tex : textures) {
|
||||
if (tex.location == location) {
|
||||
tex.texture = texture;
|
||||
return;
|
||||
}
|
||||
}
|
||||
textures.emplace_back(texture, location);
|
||||
}
|
||||
|
||||
void DrawableBuilder::addTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2) {
|
||||
const auto n = static_cast<uint16_t>(impl->vertices.elements());
|
||||
impl->vertices.emplace_back(Impl::VT({{{x0, y0}}}));
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <mbgl/gfx/index_buffer.hpp>
|
||||
#include <mbgl/gfx/texture.hpp>
|
||||
#include <mbgl/util/size.hpp>
|
||||
#include <mbgl/util/image.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
@@ -15,6 +16,7 @@
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
class Texture2D;
|
||||
class VertexAttributeArray;
|
||||
|
||||
using AttributeBindingArray = std::vector<std::optional<gfx::AttributeBinding>>;
|
||||
@@ -107,7 +109,7 @@ public:
|
||||
updateTextureResourceSub(texture.getResource(), offsetX, offsetY, image.size, image.data.get(), format, type);
|
||||
}
|
||||
|
||||
protected:
|
||||
public:
|
||||
virtual std::unique_ptr<TextureResource> createTextureResource(Size,
|
||||
const void* data,
|
||||
TexturePixelType,
|
||||
@@ -121,6 +123,8 @@ protected:
|
||||
const void* data,
|
||||
TexturePixelType,
|
||||
TextureChannelDataType) = 0;
|
||||
|
||||
virtual std::shared_ptr<gfx::Texture2D> createTexture2D(const PremultipliedImage& image) = 0;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <mbgl/gl/uniform_buffer_gl.hpp>
|
||||
#include <mbgl/gl/texture_resource.hpp>
|
||||
#include <mbgl/gl/texture.hpp>
|
||||
#include <mbgl/gl/texture2d.hpp>
|
||||
#include <mbgl/gl/offscreen_texture.hpp>
|
||||
#include <mbgl/gl/debugging_extension.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/texture.hpp>
|
||||
#include <mbgl/gfx/texture2d.hpp>
|
||||
#include <mbgl/gfx/draw_mode.hpp>
|
||||
#include <mbgl/gfx/depth_mode.hpp>
|
||||
#include <mbgl/gfx/stencil_mode.hpp>
|
||||
@@ -122,7 +123,7 @@ public:
|
||||
State<value::BindFramebuffer> bindFramebuffer;
|
||||
State<value::Viewport> viewport;
|
||||
State<value::ScissorTest> scissorTest;
|
||||
std::array<State<value::BindTexture>, 2> texture;
|
||||
std::array<State<value::BindTexture>, gfx::MaxActiveTextureUnits> texture;
|
||||
State<value::Program> program;
|
||||
State<value::BindVertexBuffer> vertexBuffer;
|
||||
|
||||
@@ -157,10 +158,12 @@ private:
|
||||
|
||||
std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture(Size, gfx::TextureChannelDataType) override;
|
||||
|
||||
public:
|
||||
std::unique_ptr<gfx::TextureResource> createTextureResource(Size,
|
||||
gfx::TexturePixelType,
|
||||
gfx::TextureChannelDataType) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<gfx::RenderbufferResource> createRenderbufferResource(gfx::RenderbufferPixelType,
|
||||
Size size) override;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <mbgl/gl/drawable_gl.hpp>
|
||||
|
||||
#include <mbgl/gl/drawable_gl_impl.hpp>
|
||||
#include <mbgl/gl/texture2d.hpp>
|
||||
#include <mbgl/gl/upload_pass.hpp>
|
||||
#include <mbgl/gl/vertex_array.hpp>
|
||||
#include <mbgl/gl/vertex_attribute_gl.hpp>
|
||||
@@ -49,6 +49,7 @@ void DrawableGL::draw(const PaintParameters& parameters) const {
|
||||
context.setCullFaceMode(gfx::CullFaceMode::disabled());
|
||||
|
||||
bindUniformBuffers();
|
||||
bindTextures();
|
||||
|
||||
auto& glContext = static_cast<gl::Context&>(parameters.context);
|
||||
const auto saveVertexArray = glContext.bindVertexArray.getCurrentValue();
|
||||
@@ -64,6 +65,7 @@ void DrawableGL::draw(const PaintParameters& parameters) const {
|
||||
|
||||
glContext.bindVertexArray = saveVertexArray;
|
||||
|
||||
unbindTextures();
|
||||
unbindUniformBuffers();
|
||||
}
|
||||
|
||||
@@ -173,5 +175,18 @@ void DrawableGL::upload(gfx::Context& context, gfx::UploadPass& uploadPass) {
|
||||
}
|
||||
}
|
||||
|
||||
void DrawableGL::bindTextures() const {
|
||||
int32_t unit = 0;
|
||||
for (const auto& tex : textures) {
|
||||
std::static_pointer_cast<gl::Texture2D>(tex.texture)->bind(tex.location, unit++);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawableGL::unbindTextures() const {
|
||||
for (const auto& tex : textures) {
|
||||
std::static_pointer_cast<gl::Texture2D>(tex.texture)->unbind();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
|
||||
151
src/mbgl/gl/texture2d.cpp
Normal file
151
src/mbgl/gl/texture2d.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#include <mbgl/gl/texture2d.hpp>
|
||||
#include <mbgl/gl/context.hpp>
|
||||
#include <mbgl/gl/defines.hpp>
|
||||
#include <mbgl/gl/enum.hpp>
|
||||
#include <mbgl/platform/gl_functions.hpp>
|
||||
|
||||
#include <mbgl/gl/texture_resource.hpp>
|
||||
#include <mbgl/gfx/texture.hpp>
|
||||
#include <mbgl/gfx/upload_pass.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
Texture2D::Texture2D(gl::Context& context_)
|
||||
: context(context_) {}
|
||||
|
||||
Texture2D::~Texture2D() {}
|
||||
|
||||
Texture2D& Texture2D::setSamplerConfiguration(const SamplerState& samplerState_) noexcept {
|
||||
samplerState = samplerState_;
|
||||
samplerStateDirty = textureResource != nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Texture2D& Texture2D::setFormat(gfx::TexturePixelType pixelFormat_, gfx::TextureChannelDataType channelType_) noexcept {
|
||||
pixelFormat = pixelFormat_;
|
||||
channelType = channelType_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Texture2D& Texture2D::setSize(mbgl::Size size_) noexcept {
|
||||
size = size_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t Texture2D::getDataSize() const noexcept {
|
||||
return size.width * size.height * getPixelStride();
|
||||
}
|
||||
|
||||
size_t Texture2D::getPixelStride() const noexcept {
|
||||
switch (channelType) {
|
||||
case gfx::TextureChannelDataType::UnsignedByte:
|
||||
return 1 * numChannels();
|
||||
case gfx::TextureChannelDataType::HalfFloat:
|
||||
return 2 * numChannels();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t Texture2D::numChannels() const noexcept {
|
||||
switch (pixelFormat) {
|
||||
case gfx::TexturePixelType::RGBA:
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Texture2D::create(const std::vector<uint8_t>& pixelData, gfx::UploadPass& uploadPass) noexcept {
|
||||
assert(!textureResource);
|
||||
textureResource = uploadPass.createTextureResource(size, pixelData.data(), pixelFormat, channelType);
|
||||
}
|
||||
|
||||
void Texture2D::create() noexcept {
|
||||
assert(!textureResource);
|
||||
textureResource = context.createTextureResource(size, pixelFormat, channelType);
|
||||
}
|
||||
|
||||
platform::GLuint Texture2D::getTextureID() const noexcept {
|
||||
return static_cast<gl::TextureResource&>(*textureResource).texture;
|
||||
}
|
||||
|
||||
void Texture2D::bind(int32_t location, int32_t textureUnit) noexcept {
|
||||
using namespace platform;
|
||||
|
||||
assert(gfx::MaxActiveTextureUnits > textureUnit);
|
||||
if (gfx::MaxActiveTextureUnits > textureUnit) return;
|
||||
|
||||
context.activeTextureUnit = static_cast<uint8_t>(textureUnit);
|
||||
context.texture[static_cast<size_t>(textureUnit)] = getTextureID();
|
||||
|
||||
boundTextureUnit = textureUnit;
|
||||
|
||||
// Update the sampler state if it was changed after resource creation
|
||||
if (samplerStateDirty) {
|
||||
samplerStateDirty = false;
|
||||
|
||||
MBGL_CHECK_ERROR(
|
||||
glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_MIN_FILTER,
|
||||
samplerState.minification == gfx::TextureFilterType::Nearest ? GL_NEAREST : GL_LINEAR));
|
||||
MBGL_CHECK_ERROR(
|
||||
glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_MAG_FILTER,
|
||||
samplerState.magnification == gfx::TextureFilterType::Nearest ? GL_NEAREST : GL_LINEAR));
|
||||
MBGL_CHECK_ERROR(
|
||||
glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_S,
|
||||
samplerState.wrapU == gfx::TextureWrapType::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
|
||||
MBGL_CHECK_ERROR(
|
||||
glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_T,
|
||||
samplerState.wrapV == gfx::TextureWrapType::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
|
||||
}
|
||||
|
||||
// Link the bound texture unit with the requested sampler in the active shader
|
||||
glUniform1i(location, textureUnit);
|
||||
}
|
||||
|
||||
void Texture2D::unbind() noexcept {
|
||||
using namespace platform;
|
||||
|
||||
// Unlink the texture from the last used texture unit
|
||||
if (boundTextureUnit != -1) {
|
||||
context.activeTextureUnit = boundTextureUnit;
|
||||
context.texture[static_cast<size_t>(boundTextureUnit)] = 0;
|
||||
boundTextureUnit = -1;
|
||||
}
|
||||
|
||||
// And clear the uniform value linking a sampler to the texture unit
|
||||
// Default back to GL_TEXTURE0
|
||||
if (boundLocation != -1) {
|
||||
glUniform1i(boundLocation, 0);
|
||||
boundLocation = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void Texture2D::upload(const PremultipliedImage& image, gfx::UploadPass& uploadPass) const noexcept {
|
||||
assert(textureResource);
|
||||
assert(image.size == size);
|
||||
if (image.size != size) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(image.channels == numChannels());
|
||||
if (image.channels != numChannels()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// note: images are always unsigned bytes
|
||||
assert(image.channels == getPixelStride());
|
||||
if (image.channels != getPixelStride()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uploadPass.updateTextureResource(*textureResource, size, &image.data[0], pixelFormat, channelType);
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <mbgl/gl/vertex_buffer_resource.hpp>
|
||||
#include <mbgl/gl/index_buffer_resource.hpp>
|
||||
#include <mbgl/gl/texture_resource.hpp>
|
||||
#include <mbgl/gl/texture2d.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -209,6 +210,16 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
return {};
|
||||
}
|
||||
|
||||
std::shared_ptr<gfx::Texture2D> UploadPass::createTexture2D(const PremultipliedImage& image) {
|
||||
auto tex = std::make_shared<gl::Texture2D>(commandEncoder.context);
|
||||
tex->setSize(image.size)
|
||||
.setFormat(image.channels == 4 ? gfx::TexturePixelType::RGBA : gfx::TexturePixelType::Alpha,
|
||||
gfx::TextureChannelDataType::UnsignedByte)
|
||||
.create();
|
||||
tex->upload(image, *this);
|
||||
return tex;
|
||||
}
|
||||
|
||||
void UploadPass::pushDebugGroup(const char* name) {
|
||||
commandEncoder.pushDebugGroup(name);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace gl {
|
||||
class CommandEncoder;
|
||||
class Context;
|
||||
class VertexArray;
|
||||
class Texture2D;
|
||||
|
||||
class UploadPass final : public gfx::UploadPass {
|
||||
public:
|
||||
@@ -56,6 +57,8 @@ public:
|
||||
gfx::TexturePixelType,
|
||||
gfx::TextureChannelDataType) override;
|
||||
|
||||
std::shared_ptr<gfx::Texture2D> createTexture2D(const PremultipliedImage& image) override;
|
||||
|
||||
private:
|
||||
gl::CommandEncoder& commandEncoder;
|
||||
const gfx::DebugGroup<gfx::CommandEncoder> debugGroup;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <mbgl/renderer/pattern_atlas.hpp>
|
||||
#include <mbgl/gfx/upload_pass.hpp>
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/gfx/texture2d.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -87,19 +88,29 @@ Size PatternAtlas::getPixelSize() const {
|
||||
}
|
||||
|
||||
void PatternAtlas::upload(gfx::UploadPass& uploadPass) {
|
||||
if (!atlasTexture) {
|
||||
atlasTexture = uploadPass.createTexture(atlasImage);
|
||||
// @note: This is what we should be doing, but will fail a ton of render tests until we update them all
|
||||
// if (atlasImage.size.isEmpty()) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!atlasTexture2D) {
|
||||
atlasTexture2D = uploadPass.createTexture2D(atlasImage);
|
||||
} else if (dirty) {
|
||||
uploadPass.updateTexture(*atlasTexture, atlasImage);
|
||||
atlasTexture2D->upload(atlasImage, uploadPass);
|
||||
}
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
// @note: Deprecated
|
||||
gfx::TextureBinding PatternAtlas::textureBinding() const {
|
||||
assert(atlasTexture);
|
||||
assert(atlasTexture2D);
|
||||
assert(!dirty);
|
||||
return {atlasTexture->getResource(), gfx::TextureFilterType::Linear};
|
||||
return {atlasTexture2D->getResource(), gfx::TextureFilterType::Linear};
|
||||
}
|
||||
|
||||
const std::shared_ptr<gfx::Texture2D>& PatternAtlas::texture() const {
|
||||
return atlasTexture2D;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -15,6 +15,7 @@ template <class T>
|
||||
class Actor;
|
||||
|
||||
namespace gfx {
|
||||
class Texture2D;
|
||||
class UploadPass;
|
||||
} // namespace gfx
|
||||
|
||||
@@ -29,7 +30,8 @@ public:
|
||||
std::optional<ImagePosition> addPattern(const style::Image::Impl&);
|
||||
void removePattern(const std::string&);
|
||||
|
||||
gfx::TextureBinding textureBinding() const;
|
||||
gfx::TextureBinding textureBinding() const; // @TODO: Migrate
|
||||
const std::shared_ptr<gfx::Texture2D>& texture() const;
|
||||
|
||||
void upload(gfx::UploadPass&);
|
||||
Size getPixelSize() const;
|
||||
@@ -46,7 +48,7 @@ private:
|
||||
mapbox::ShelfPack shelfPack;
|
||||
std::unordered_map<std::string, Pattern> patterns;
|
||||
PremultipliedImage atlasImage;
|
||||
std::optional<gfx::Texture> atlasTexture;
|
||||
std::shared_ptr<gfx::Texture2D> atlasTexture2D{nullptr};
|
||||
bool dirty = true;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user