1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-31 15:32:45 +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)
, mUpdateTimer(0.f)
{
mPreviewTexture.reset(new osgMyGUI::OSGTexture(mPreview->getTexture()));
mPreviewTexture.reset(new osgMyGUI::OSGTexture(mPreview->getTexture(), mPreview->getTextureStateSet()));
mPreview->rebuild();
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);

View File

@ -138,7 +138,7 @@ namespace MWGui
mPreview->rebuild();
mPreview->setAngle (mCurrentAngle);
mPreviewTexture.reset(new osgMyGUI::OSGTexture(mPreview->getTexture()));
mPreviewTexture.reset(new osgMyGUI::OSGTexture(mPreview->getTexture(), mPreview->getTextureStateSet()));
mPreviewImage->setRenderItemTexture(mPreviewTexture.get());
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->setFilter(osg::Texture::MIN_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;
// hints that the camera is not relative to the master camera

View File

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

View File

@ -4,10 +4,8 @@
#include <MyGUI_Timer.h>
#include <osg/Drawable>
#include <osg/BlendFunc>
#include <osg/Texture2D>
#include <osg/TexMat>
#include <osg/ValueObject>
#include <osgViewer/Viewer>
@ -17,8 +15,6 @@
#include <components/shader/shadermanager.hpp>
#include <components/sceneutil/nodecallback.hpp>
#include <components/debug/debuglog.hpp>
#include "myguicompat.h"
#include "myguitexture.hpp"
@ -465,23 +461,17 @@ void RenderManager::doRender(MyGUI::IVertexBuffer *buffer, MyGUI::ITexture *text
batch.mVertexBuffer = static_cast<OSGVertexBuffer*>(buffer)->getVertexBuffer();
batch.mArray = static_cast<OSGVertexBuffer*>(buffer)->getVertexArray();
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)
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)
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);
}

View File

@ -3,6 +3,7 @@
#include <stdexcept>
#include <osg/Texture2D>
#include <osg/StateSet>
#include <components/debug/debuglog.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)
, mTexture(texture)
, mInjectState(injectState)
, mFormat(MyGUI::PixelFormat::Unknow)
, mUsage(MyGUI::TextureUsage::Default)
, mNumElemBytes(0)

View File

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