1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-03 15:09:39 +00:00

refactors premultiplied alpha (#3189)

With this PR we refactor a `premultiplied alpha` user string set by `characterpreview.cpp` into a more flexible mechanism allowing us to assign any state to GUI textures. We can consider these changes more future proof than the previous approach.
This commit is contained in:
Bo Svensson 2021-10-25 07:28:32 +00:00 committed by GitHub
parent 7f9beac3a7
commit 1ff8318a52
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 22 additions and 20 deletions

View file

@ -70,7 +70,7 @@ namespace MWGui
, mTrading(false) , mTrading(false)
, mUpdateTimer(0.f) , mUpdateTimer(0.f)
{ {
mPreviewTexture.reset(new osgMyGUI::OSGTexture(mPreview->getTexture())); mPreviewTexture.reset(new osgMyGUI::OSGTexture(mPreview->getTexture(), mPreview->getTextureStateSet()));
mPreview->rebuild(); mPreview->rebuild();
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize); mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);

View file

@ -138,7 +138,7 @@ namespace MWGui
mPreview->rebuild(); mPreview->rebuild();
mPreview->setAngle (mCurrentAngle); mPreview->setAngle (mCurrentAngle);
mPreviewTexture.reset(new osgMyGUI::OSGTexture(mPreview->getTexture())); mPreviewTexture.reset(new osgMyGUI::OSGTexture(mPreview->getTexture(), mPreview->getTextureStateSet()));
mPreviewImage->setRenderItemTexture(mPreviewTexture.get()); mPreviewImage->setRenderItemTexture(mPreviewTexture.get());
mPreviewImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f)); mPreviewImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f));

View file

@ -190,7 +190,9 @@ namespace MWRender
mTexture->setInternalFormat(GL_RGBA); mTexture->setInternalFormat(GL_RGBA);
mTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); mTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
mTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); mTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
mTexture->setUserValue("premultiplied alpha", true);
mTextureStateSet = new osg::StateSet;
mTextureStateSet->setAttribute(new osg::BlendFunc(osg::BlendFunc::ONE, osg::BlendFunc::ONE_MINUS_SRC_ALPHA));
mCamera = new osg::Camera; mCamera = new osg::Camera;
// hints that the camera is not relative to the master camera // hints that the camera is not relative to the master camera

View file

@ -18,6 +18,7 @@ namespace osg
class Camera; class Camera;
class Group; class Group;
class Viewport; class Viewport;
class StateSet;
} }
namespace MWRender namespace MWRender
@ -41,6 +42,8 @@ namespace MWRender
void rebuild(); void rebuild();
osg::ref_ptr<osg::Texture2D> getTexture(); osg::ref_ptr<osg::Texture2D> getTexture();
/// Get the osg::StateSet required to render the texture correctly, if any.
osg::StateSet* getTextureStateSet() { return mTextureStateSet; }
private: private:
CharacterPreview(const CharacterPreview&); CharacterPreview(const CharacterPreview&);
@ -54,6 +57,7 @@ namespace MWRender
osg::ref_ptr<osg::Group> mParent; osg::ref_ptr<osg::Group> mParent;
Resource::ResourceSystem* mResourceSystem; Resource::ResourceSystem* mResourceSystem;
osg::ref_ptr<osg::Texture2D> mTexture; osg::ref_ptr<osg::Texture2D> mTexture;
osg::ref_ptr<osg::StateSet> mTextureStateSet;
osg::ref_ptr<osg::Camera> mCamera; osg::ref_ptr<osg::Camera> mCamera;
osg::ref_ptr<DrawOnceCallback> mDrawOnceCallback; osg::ref_ptr<DrawOnceCallback> mDrawOnceCallback;

View file

@ -4,10 +4,8 @@
#include <MyGUI_Timer.h> #include <MyGUI_Timer.h>
#include <osg/Drawable> #include <osg/Drawable>
#include <osg/BlendFunc>
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osg/TexMat> #include <osg/TexMat>
#include <osg/ValueObject>
#include <osgViewer/Viewer> #include <osgViewer/Viewer>
@ -17,8 +15,6 @@
#include <components/shader/shadermanager.hpp> #include <components/shader/shadermanager.hpp>
#include <components/sceneutil/nodecallback.hpp> #include <components/sceneutil/nodecallback.hpp>
#include <components/debug/debuglog.hpp>
#include "myguicompat.h" #include "myguicompat.h"
#include "myguitexture.hpp" #include "myguitexture.hpp"
@ -465,23 +461,17 @@ void RenderManager::doRender(MyGUI::IVertexBuffer *buffer, MyGUI::ITexture *text
batch.mVertexBuffer = static_cast<OSGVertexBuffer*>(buffer)->getVertexBuffer(); batch.mVertexBuffer = static_cast<OSGVertexBuffer*>(buffer)->getVertexBuffer();
batch.mArray = static_cast<OSGVertexBuffer*>(buffer)->getVertexArray(); batch.mArray = static_cast<OSGVertexBuffer*>(buffer)->getVertexArray();
static_cast<OSGVertexBuffer*>(buffer)->markUsed(); static_cast<OSGVertexBuffer*>(buffer)->markUsed();
bool premultipliedAlpha = false;
if (texture) if (OSGTexture* osgtexture = static_cast<OSGTexture*>(texture))
{ {
batch.mTexture = static_cast<OSGTexture*>(texture)->getTexture(); batch.mTexture = osgtexture->getTexture();
if (batch.mTexture->getDataVariance() == osg::Object::DYNAMIC) if (batch.mTexture->getDataVariance() == osg::Object::DYNAMIC)
mDrawable->setDataVariance(osg::Object::DYNAMIC); // only for this frame, reset in begin() mDrawable->setDataVariance(osg::Object::DYNAMIC); // only for this frame, reset in begin()
batch.mTexture->getUserValue("premultiplied alpha", premultipliedAlpha); if (!mInjectState && osgtexture->getInjectState())
batch.mStateSet = osgtexture->getInjectState();
} }
if (mInjectState) if (mInjectState)
batch.mStateSet = mInjectState; batch.mStateSet = mInjectState;
else if (premultipliedAlpha)
{
// This is hacky, but MyGUI made it impossible to use a custom layer for a nested node, so state couldn't be injected 'properly'
osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet();
stateSet->setAttribute(new osg::BlendFunc(osg::BlendFunc::ONE, osg::BlendFunc::ONE_MINUS_SRC_ALPHA));
batch.mStateSet = stateSet;
}
mDrawable->addBatch(batch); mDrawable->addBatch(batch);
} }

View file

@ -3,6 +3,7 @@
#include <stdexcept> #include <stdexcept>
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osg/StateSet>
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/resource/imagemanager.hpp> #include <components/resource/imagemanager.hpp>
@ -21,9 +22,10 @@ namespace osgMyGUI
{ {
} }
OSGTexture::OSGTexture(osg::Texture2D *texture) OSGTexture::OSGTexture(osg::Texture2D *texture, osg::StateSet *injectState)
: mImageManager(nullptr) : mImageManager(nullptr)
, mTexture(texture) , mTexture(texture)
, mInjectState(injectState)
, mFormat(MyGUI::PixelFormat::Unknow) , mFormat(MyGUI::PixelFormat::Unknow)
, mUsage(MyGUI::TextureUsage::Default) , mUsage(MyGUI::TextureUsage::Default)
, mNumElemBytes(0) , mNumElemBytes(0)

View file

@ -15,6 +15,7 @@ namespace osg
{ {
class Image; class Image;
class Texture2D; class Texture2D;
class StateSet;
} }
namespace Resource namespace Resource
@ -31,6 +32,7 @@ namespace osgMyGUI
osg::ref_ptr<osg::Image> mLockedImage; osg::ref_ptr<osg::Image> mLockedImage;
osg::ref_ptr<osg::Texture2D> mTexture; osg::ref_ptr<osg::Texture2D> mTexture;
osg::ref_ptr<osg::StateSet> mInjectState;
MyGUI::PixelFormat mFormat; MyGUI::PixelFormat mFormat;
MyGUI::TextureUsage mUsage; MyGUI::TextureUsage mUsage;
size_t mNumElemBytes; size_t mNumElemBytes;
@ -40,9 +42,11 @@ namespace osgMyGUI
public: public:
OSGTexture(const std::string &name, Resource::ImageManager* imageManager); OSGTexture(const std::string &name, Resource::ImageManager* imageManager);
OSGTexture(osg::Texture2D* texture); OSGTexture(osg::Texture2D* texture, osg::StateSet* injectState = nullptr);
virtual ~OSGTexture(); virtual ~OSGTexture();
osg::StateSet* getInjectState() { return mInjectState; }
const std::string& getName() const override { return mName; } const std::string& getName() const override { return mName; }
void createManual(int width, int height, MyGUI::TextureUsage usage, MyGUI::PixelFormat format) override; void createManual(int width, int height, MyGUI::TextureUsage usage, MyGUI::PixelFormat format) override;