From c05db9e2c7deb75b72098b3f0e1214f33c755ece Mon Sep 17 00:00:00 2001 From: Peter Schaefer Date: Tue, 28 Jun 2016 03:36:04 +0200 Subject: [PATCH] MipMap and Sampling Qualities --- Weave/Events.cpp | 32 ++++++- Weave/Graphix/Textures/Texture.cpp | 137 +++++++++++++++++++++++++++-- Weave/Graphix/Textures/Texture.h | 54 +++++++++++- Weave/Graphix/Textures/tImage.cpp | 3 +- Weave/Scene/Scene.cpp | 4 +- 5 files changed, 215 insertions(+), 15 deletions(-) diff --git a/Weave/Events.cpp b/Weave/Events.cpp index 949544f..abadd2f 100644 --- a/Weave/Events.cpp +++ b/Weave/Events.cpp @@ -2,6 +2,7 @@ #include #include "Graphix\Graphix.h" +#include "Graphix\Textures\Texture.h" #include "Game.h" #include "GLM.h" @@ -14,6 +15,9 @@ using std::endl; void message(std::string title, bool onoff); +unsigned int toggle_MIPMAP = 0; + + void Events::processEvents() { SDL_Event sdl_event; @@ -124,10 +128,34 @@ void Events::KeyDown(int _key) message("WireFrame", !key_toggle[SDLK_F3]); break; case SDLK_F4: - //TEXTURE SAMPLING QUALITY + //TEXTURE SAMPLING QUALITY: Nearest Neighbor/Bilinear + if (key_toggle[SDLK_F4]) + Texture::setMaxSamplingQuality(TSQ_LINEAR); + else + Texture::setMaxSamplingQuality(TSQ_NEAREST_NEIGHBOR); + Message::info((string)"Texture Sampling Quality: " + ((!key_toggle[SDLK_F4]) ? "Nearest Neighbor" : "Bilinear")); + break; case SDLK_F5: - //MIPMAP QUALITY + //MIPMAP QUALITY: Off/Nearest Neighbor/Linear + switch (toggle_MIPMAP) + { + default: + case 0: + Texture::setMaxSamplingQuality(MMQ_OFF); + Message::info("MipMap Quality: Off"); + toggle_MIPMAP = 0; + break; + case 1: + Texture::setMaxSamplingQuality(MMQ_NEAREST_NEIGHBOR); + Message::info("MipMap Quality: Nearest Neighbor"); + break; + case 2: + Texture::setMaxSamplingQuality(MMQ_LINEAR); + Message::info("MipMap Quality: Linear"); + break; + } + toggle_MIPMAP++; break; case SDLK_F6: //??? BoundingBox diff --git a/Weave/Graphix/Textures/Texture.cpp b/Weave/Graphix/Textures/Texture.cpp index 3da4465..e2d32c2 100644 --- a/Weave/Graphix/Textures/Texture.cpp +++ b/Weave/Graphix/Textures/Texture.cpp @@ -8,14 +8,18 @@ using std::string; using std::unordered_map; +using std::unordered_set; string bindTargets[] = {"uColorTexture", "uBlendTexture", "uPointLightXP", "uPointLightXM", "uPointLightYP", "uPointLightYM", "uPointLightZP", "uPointLightZM", "uBlurVec" }; + Texture::Texture(texTarget _target, unsigned int _type) - : texture_target(_type) + : texture_target(_type), texture_MMQ(MMQ_OFF), texture_TSQ(TSQ_LINEAR) { glGenTextures(1, &handle); + + texture_List.insert(this); switch (_target) { @@ -42,6 +46,7 @@ Texture::Texture(texTarget _target, unsigned int _type) Texture::~Texture() { glDeleteTextures(1, &handle); + texture_List.erase(this); } Texture* Texture::newTImage(const string& _path, const vec4& _material) @@ -83,6 +88,54 @@ unsigned int Texture::getTTarget() const return texture_target; } +void Texture::setMaxSamplingQuality(sampTarget _mTSQ, bool _bind) +{ + if (max_tex_TSQ == _mTSQ) + return; + + max_tex_TSQ = _mTSQ; + + for (auto i = texture_List.begin(); i != texture_List.end(); i++) + (*i)->setSamplingQuality(_bind); +} + +void Texture::setMaxSamplingQuality(mmTarget _mMMQ, bool _bind) +{ + if (max_tex_MMQ == _mMMQ) + return; + + max_tex_MMQ = _mMMQ; + + for (auto i = texture_List.begin(); i != texture_List.end(); i++) + (*i)->setSamplingQuality(_bind); +} + +void Texture::updateMxSamplingQuality() +{ + switch (getMxMmTarget()) + { + case MMQ_OFF: + if(getMxSampTarget()) + texture_quality = GL_LINEAR; + else + texture_quality = GL_NEAREST; + break; + default: + case MMQ_NEAREST_NEIGHBOR: + if (getMxSampTarget()) + texture_quality = GL_NEAREST_MIPMAP_LINEAR; + else + texture_quality = GL_NEAREST_MIPMAP_NEAREST; + break; + case MMQ_LINEAR: + if (getMxSampTarget()) + texture_quality = GL_LINEAR_MIPMAP_LINEAR; + else + texture_quality = GL_LINEAR_MIPMAP_NEAREST; + break; + } +} + Texture::operator unsigned int() const { @@ -97,12 +150,11 @@ void Texture::bindTexture(unsigned int _width, unsigned int _height, bool shadow height = _height; } + updateMxSamplingQuality(); + glBindTexture(texture_target, handle); - if(data!=nullptr) - glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - else - glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, texture_quality); glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -129,6 +181,8 @@ void Texture::bindTexture(unsigned int _width, unsigned int _height, bool shadow //else glTexImage2D(texture_target, 0, texture_internal, width, height, 0, texture_format, texture_type, data); + if (getMxMmTarget()) + glGenerateMipmap(texture_target); } void Texture::unbindTexture() @@ -169,14 +223,79 @@ void Texture::updateSize(unsigned int _width, unsigned int _height) glTexImage2D(texture_target, 0, texture_internal, width, height, 0, texture_format, texture_type, data); } -void Texture::downscale(unsigned int _lvl) +void Texture::setSamplingQuality(sampTarget _TSQ, mmTarget _MMQ, bool _bind) +{ + texture_TSQ = _TSQ; + texture_MMQ = _MMQ; + updateMxSamplingQuality(); + + if (_bind) + glBindTexture(texture_target, handle); + + if (getMxMmTarget()) + glGenerateMipmap(texture_target); + + glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, texture_quality); +} +void Texture::setSamplingQuality(mmTarget _MMQ, bool _bind) +{ + texture_MMQ = _MMQ; + updateMxSamplingQuality(); + + if (_bind) + glBindTexture(texture_target, handle); + + if (getMxMmTarget()) + glGenerateMipmap(texture_target); + + glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, texture_quality); +} +void Texture::setSamplingQuality(sampTarget _TSQ, bool _bind) +{ + texture_TSQ = _TSQ; + updateMxSamplingQuality(); + + if (_bind) + glBindTexture(texture_target, handle); + + glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, texture_quality); +} +void Texture::setSamplingQuality(bool _bind) +{ + updateMxSamplingQuality(); + + if (_bind) + glBindTexture(texture_target, handle); + + if (getMxMmTarget()) + glGenerateMipmap(texture_target); + + glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, texture_quality); +} + +void Texture::setMipMapLVL(unsigned int _lvl) { glBindTexture(texture_target, handle); + + glTexParameteri(texture_target, GL_TEXTURE_BASE_LEVEL, mipmap_lvl); +} + +void Texture::updateMipMap(bool _bind) +{ + if (!getMxMmTarget()) + return; + + if (_bind) + glBindTexture(texture_target, handle); + glGenerateMipmap(texture_target); - glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - //glTexParameteri(texture_target, GL_TEXTURE_BASE_LEVEL, _lvl); } unordered_map Texture::texture_Map; -unordered_map Texture::handle_Map; \ No newline at end of file +unordered_map Texture::handle_Map; + +unordered_set Texture::texture_List; + +sampTarget Texture::max_tex_TSQ = TSQ_LINEAR; +mmTarget Texture::max_tex_MMQ = MMQ_LINEAR; \ No newline at end of file diff --git a/Weave/Graphix/Textures/Texture.h b/Weave/Graphix/Textures/Texture.h index 8f058af..a3fc735 100644 --- a/Weave/Graphix/Textures/Texture.h +++ b/Weave/Graphix/Textures/Texture.h @@ -5,6 +5,7 @@ #include #include +#include class tImage; @@ -26,6 +27,20 @@ enum bindTarget { uBLURVEC = 8 }; //Don't forget to assign the correct name in bindTargets at the beginning of Texture.cpp! +#define BIT(x) (1<<(x)) +#define BIT0(x) (0<<(x)) + +enum sampTarget { + TSQ_NEAREST_NEIGHBOR = 0, + TSQ_LINEAR = 1 +}; + +enum mmTarget { + MMQ_OFF = 0, + MMQ_NEAREST_NEIGHBOR = 1, + MMQ_LINEAR = 2 +}; + class Texture { public: @@ -42,13 +57,28 @@ public: static void leaveTexture(bindTarget = uCOLOR); virtual void updateSize(unsigned int width = 0, unsigned int height = 0); - virtual void downscale(unsigned int lvl); + + virtual void setMipMapLVL(unsigned int lvl=0); + virtual void updateMipMap(bool = true); + + virtual void setSamplingQuality(sampTarget, mmTarget, bool = true); + virtual void setSamplingQuality(mmTarget, bool = true); + virtual void setSamplingQuality(sampTarget, bool = true); + virtual void setSamplingQuality(bool = true); virtual operator unsigned int() const; unsigned int getTTarget() const; + static void setMaxSamplingQuality(sampTarget, bool = true); + static void setMaxSamplingQuality(mmTarget, bool = true); + protected: + + static sampTarget max_tex_TSQ; + static mmTarget max_tex_MMQ; + + unsigned int handle; unsigned int texture_target; @@ -56,11 +86,29 @@ protected: unsigned int texture_format; unsigned int texture_type; + + sampTarget texture_TSQ; + mmTarget texture_MMQ; + unsigned int texture_quality; + + inline sampTarget getMxSampTarget() + { + return max_tex_TSQ texture_Map; static std::unordered_map handle_Map; + + static std::unordered_set texture_List; }; \ No newline at end of file diff --git a/Weave/Graphix/Textures/tImage.cpp b/Weave/Graphix/Textures/tImage.cpp index f230422..a26cebc 100644 --- a/Weave/Graphix/Textures/tImage.cpp +++ b/Weave/Graphix/Textures/tImage.cpp @@ -29,6 +29,8 @@ tImage::tImage(const string& _path, const vec4& _material) : Texture(texT_IMAGE) } loadImage(path); + + texture_MMQ = MMQ_LINEAR; } @@ -41,7 +43,6 @@ void tImage::bindTexture(unsigned int _width, unsigned int _height, bool shadow) { Texture::bindTexture(); - glGenerateMipmap(texture_target); } diff --git a/Weave/Scene/Scene.cpp b/Weave/Scene/Scene.cpp index 5a51e35..3c80da6 100644 --- a/Weave/Scene/Scene.cpp +++ b/Weave/Scene/Scene.cpp @@ -443,13 +443,15 @@ void Scene::draw() const glClear(GL_COLOR_BUFFER_BIT); //glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - lastScreen->getTexture()->downscale(1); + lastScreen->getTexture()->setSamplingQuality(MMQ_NEAREST_NEIGHBOR); Shader::getShader(SH_FILTER_BRIGHT)->useShader(); Shader::getShader(SH_ACTIVE)->setUniformLocation("uFilterThreshold",1.2f); lastScreen->getTexture()->useTexture(); Model::getPlaneModel()->drawModel(mat4(1.f)); + //lastScreen->getTexture()->setMipMap(-1); + horizontal_blurPP = !horizontal_blurPP; blurPingPong[!horizontal_blurPP]->useBuffer(); -- 2.47.3