From 40e1eba6c489e11a4c9b8865ddcd3ec3d9f83818 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 2 Jul 2018 15:49:48 +0300 Subject: [PATCH] Allow the maximum mipmap level of a texture to be specified This doubles as a way to specify the number of mipmap levels to allocate when the tetxure image is loaded from a Graphics::Image. --- source/texture.cpp | 15 +++++++++++++++ source/texture.h | 7 ++++++- source/texture1d.cpp | 2 +- source/texture2d.cpp | 2 +- source/texture3d.cpp | 2 +- source/texturecube.cpp | 2 +- 6 files changed, 25 insertions(+), 5 deletions(-) diff --git a/source/texture.cpp b/source/texture.cpp index 820dd10f..719d4a56 100644 --- a/source/texture.cpp +++ b/source/texture.cpp @@ -63,6 +63,7 @@ Texture::Texture(GLenum t, ResourceManager *m): ifmt(RGB), min_filter(NEAREST_MIPMAP_LINEAR), mag_filter(LINEAR), + mipmap_levels(0), max_anisotropy(1.0f), wrap_s(REPEAT), wrap_t(REPEAT), @@ -178,6 +179,8 @@ void Texture::update_parameter(int mask) const glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4); } } + if(mask&MIPMAP_LEVELS) + set_parameter_i(GL_TEXTURE_MAX_LEVEL, (mipmap_levels ? mipmap_levels-1 : 1000)); } void Texture::set_parameter_i(GLenum param, int value) const @@ -214,6 +217,12 @@ void Texture::set_filter(TextureFilter f) set_mag_filter(f==NEAREST ? NEAREST : LINEAR); } +void Texture::set_mipmap_levels(unsigned l) +{ + mipmap_levels = l; + update_parameter(MIPMAP_LEVELS); +} + void Texture::set_max_anisotropy(float a) { if(a<1.0f) @@ -403,6 +412,7 @@ void Texture::Loader::init() add("mag_filter", &Loader::mag_filter); add("max_anisotropy", &Loader::max_anisotropy); add("min_filter", &Loader::min_filter); + add("mipmap_levels", &Loader::mipmap_levels); add("wrap", &Loader::wrap); add("wrap_r", &Loader::wrap_r); add("wrap_s", &Loader::wrap_s); @@ -452,6 +462,11 @@ void Texture::Loader::min_filter(TextureFilter f) obj.set_min_filter(f); } +void Texture::Loader::mipmap_levels(unsigned l) +{ + obj.set_mipmap_levels(l); +} + void Texture::Loader::wrap(TextureWrap w) { obj.set_wrap(w); diff --git a/source/texture.h b/source/texture.h index ffc5e1a4..94614c45 100644 --- a/source/texture.h +++ b/source/texture.h @@ -88,6 +88,7 @@ protected: void mag_filter(TextureFilter); void max_anisotropy(float); void min_filter(TextureFilter); + void mipmap_levels(unsigned); void wrap(TextureWrap); void wrap_r(TextureWrap); void wrap_s(TextureWrap); @@ -105,7 +106,8 @@ protected: COMPARE = 64, COMPARE_FUNC = 128, MAX_ANISOTROPY = 256, - FORMAT_SWIZZLE = 512 + FORMAT_SWIZZLE = 512, + MIPMAP_LEVELS = 1024 }; enum FormatSwizzle @@ -121,6 +123,7 @@ protected: FormatSwizzle swizzle; TextureFilter min_filter; TextureFilter mag_filter; + unsigned mipmap_levels; float max_anisotropy; TextureWrap wrap_s; TextureWrap wrap_t; @@ -154,6 +157,8 @@ public: is not applicable to magnification, LINEAR is used instead. */ void set_filter(TextureFilter); + void set_mipmap_levels(unsigned); + void set_max_anisotropy(float); /** Sets the wrapping mode for all coordinates. */ diff --git a/source/texture1d.cpp b/source/texture1d.cpp index a1ee418b..7466a9ef 100644 --- a/source/texture1d.cpp +++ b/source/texture1d.cpp @@ -108,7 +108,7 @@ void Texture1D::image(const Graphics::Image &img, bool srgb) PixelFormat fmt = pixelformat_from_graphics(img.get_format()); if(width==0) { - unsigned l = (is_mipmapped(min_filter) ? 0 : 1); + unsigned l = (is_mipmapped(min_filter) ? mipmap_levels ? mipmap_levels : 0 : 1); storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, l); } else if(w!=width) diff --git a/source/texture2d.cpp b/source/texture2d.cpp index 44ee6406..45c2e665 100644 --- a/source/texture2d.cpp +++ b/source/texture2d.cpp @@ -141,7 +141,7 @@ void Texture2D::image(const Graphics::Image &img, bool srgb, bool from_buffer) PixelFormat fmt = pixelformat_from_graphics(img.get_format()); if(width==0) { - unsigned l = (is_mipmapped(min_filter) ? 0 : 1); + unsigned l = (is_mipmapped(min_filter) ? mipmap_levels ? mipmap_levels : 0 : 1); storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, h, l); } else if(w!=width || h!=height) diff --git a/source/texture3d.cpp b/source/texture3d.cpp index 36fdfa0f..ed5619cb 100644 --- a/source/texture3d.cpp +++ b/source/texture3d.cpp @@ -188,7 +188,7 @@ void Texture3D::image(const Graphics::Image &img, bool srgb) PixelFormat fmt = pixelformat_from_graphics(img.get_format()); if(width==0) { - unsigned l = (is_mipmapped(min_filter) ? 0 : 1); + unsigned l = (is_mipmapped(min_filter) ? mipmap_levels ? mipmap_levels : 0 : 1); storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, h, d, l); } else if(w!=width || h!=height || d!=depth) diff --git a/source/texturecube.cpp b/source/texturecube.cpp index ee8c71c5..03e65167 100644 --- a/source/texturecube.cpp +++ b/source/texturecube.cpp @@ -161,7 +161,7 @@ void TextureCube::image(const Graphics::Image &img, bool srgb) PixelFormat fmt = pixelformat_from_graphics(img.get_format()); if(size==0) { - unsigned l = (is_mipmapped(min_filter) ? 0 : 1); + unsigned l = (is_mipmapped(min_filter) ? mipmap_levels ? mipmap_levels : 0 : 1); storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, l); } else if(w!=size || h!=size) -- 2.45.2