diff options
Diffstat (limited to 'src/mbgl/gl')
-rw-r--r-- | src/mbgl/gl/context.cpp | 38 | ||||
-rw-r--r-- | src/mbgl/gl/context.hpp | 21 | ||||
-rw-r--r-- | src/mbgl/gl/texture.hpp | 19 | ||||
-rw-r--r-- | src/mbgl/gl/types.hpp | 3 |
4 files changed, 81 insertions, 0 deletions
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index ae50e64cbc..ded7936feb 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -124,6 +124,44 @@ void Context::uploadBuffer(BufferType type, size_t size, void* data) { MBGL_CHECK_ERROR(glBufferData(static_cast<GLenum>(type), size, data, GL_STATIC_DRAW)); } +UniqueTexture +Context::createTexture(uint16_t width, uint16_t height, const void* data, TextureUnit unit) { + auto obj = createTexture(); + activeTexture = unit; + texture[unit] = obj; + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + MBGL_CHECK_ERROR( + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)); + return obj; +} + +void Context::bindTexture(Texture& obj, + TextureUnit unit, + TextureFilter filter, + TextureMipMap mipmap) { + if (filter != obj.filter || mipmap != obj.mipmap) { + activeTexture = unit; + texture[unit] = obj.texture; + MBGL_CHECK_ERROR(glTexParameteri( + GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + filter == TextureFilter::Linear + ? (mipmap == TextureMipMap::Yes ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR) + : (mipmap == TextureMipMap::Yes ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST))); + MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + filter == TextureFilter::Linear ? GL_LINEAR : GL_NEAREST)); + obj.filter = filter; + obj.mipmap = mipmap; + } else if (texture[unit] != obj.texture) { + // We are checking first to avoid setting the active texture without a subsequent + // texture bind. + activeTexture = unit; + texture[unit] = obj.texture; + } +} + void Context::reset() { std::copy(pooledTextures.begin(), pooledTextures.end(), std::back_inserter(abandonedTextures)); pooledTextures.resize(0); diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 04089c2000..0ec846033a 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -3,6 +3,7 @@ #include <mbgl/gl/object.hpp> #include <mbgl/gl/state.hpp> #include <mbgl/gl/value.hpp> +#include <mbgl/gl/texture.hpp> #include <mbgl/util/noncopyable.hpp> #include <memory> @@ -28,6 +29,23 @@ public: void uploadBuffer(BufferType, size_t, void*); + // Create a texture from an image with data. + template <typename Image> + Texture createTexture(const Image& image, TextureUnit unit = 0) { + return { {{ image.width, image.height }}, + createTexture(image.width, image.height, image.data.get(), unit) }; + } + + // Creates an empty texture with the specified dimensions. + Texture createTexture(const std::array<uint16_t, 2>& size, TextureUnit unit = 0) { + return { size, createTexture(size[0], size[1], nullptr, unit) }; + } + + void bindTexture(Texture&, + TextureUnit = 0, + TextureFilter = TextureFilter::Nearest, + TextureMipMap = TextureMipMap::No); + // Actually remove the objects we marked as abandoned with the above methods. // Only call this while the OpenGL context is exclusive to this thread. void performCleanup(); @@ -80,6 +98,9 @@ public: State<value::BindVertexArray> vertexArrayObject; private: + UniqueTexture createTexture(uint16_t width, uint16_t height, const void* data, TextureUnit); + +private: friend detail::ProgramDeleter; friend detail::ShaderDeleter; friend detail::BufferDeleter; diff --git a/src/mbgl/gl/texture.hpp b/src/mbgl/gl/texture.hpp new file mode 100644 index 0000000000..49e1323095 --- /dev/null +++ b/src/mbgl/gl/texture.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include <mbgl/gl/object.hpp> + +#include <array> + +namespace mbgl { +namespace gl { + +class Texture { +public: + std::array<uint16_t, 2> size; + UniqueTexture texture; + TextureFilter filter = TextureFilter::Nearest; + TextureMipMap mipmap = TextureMipMap::No; +}; + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 8578a11f66..e9d14e4807 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -27,6 +27,9 @@ enum class BufferType : uint32_t { Element = 0x8893 }; +enum class TextureMipMap : bool { No = false, Yes = true }; +enum class TextureFilter : bool { Nearest = false, Linear = true }; + enum class StencilTestFunction : uint32_t { Never = 0x0200, Less = 0x0201, |