mirror of
https://github.com/OpenMW/openmw.git
synced 2025-11-29 16:04:30 +00:00
Merge branch 'fix-8705' into 'master'
Feature #8705: Use texture-based LUT for moddable global map colors See merge request OpenMW/openmw!4932
This commit is contained in:
commit
f8374f2ff0
3 changed files with 36 additions and 45 deletions
|
|
@ -13,10 +13,15 @@
|
|||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
|
||||
#include <components/resource/imagemanager.hpp>
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
|
||||
#include <components/sceneutil/depth.hpp>
|
||||
#include <components/sceneutil/nodecallback.hpp>
|
||||
#include <components/sceneutil/workqueue.hpp>
|
||||
|
||||
#include <components/vfs/pathutil.hpp>
|
||||
|
||||
#include <components/esm3/globalmap.hpp>
|
||||
#include <components/esm3/loadland.hpp>
|
||||
|
||||
|
|
@ -122,7 +127,7 @@ namespace MWRender
|
|||
{
|
||||
public:
|
||||
CreateMapWorkItem(int width, int height, int minX, int minY, int maxX, int maxY, int cellSize,
|
||||
const MWWorld::Store<ESM::Land>& landStore)
|
||||
const MWWorld::Store<ESM::Land>& landStore, osg::ref_ptr<osg::Image> colorLut)
|
||||
: mWidth(width)
|
||||
, mHeight(height)
|
||||
, mMinX(minX)
|
||||
|
|
@ -131,6 +136,7 @@ namespace MWRender
|
|||
, mMaxY(maxY)
|
||||
, mCellSize(cellSize)
|
||||
, mLandStore(landStore)
|
||||
, mColorLut(colorLut)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -138,11 +144,9 @@ namespace MWRender
|
|||
{
|
||||
osg::ref_ptr<osg::Image> image = new osg::Image;
|
||||
image->allocateImage(mWidth, mHeight, 1, GL_RGB, GL_UNSIGNED_BYTE);
|
||||
unsigned char* data = image->data();
|
||||
|
||||
osg::ref_ptr<osg::Image> alphaImage = new osg::Image;
|
||||
alphaImage->allocateImage(mWidth, mHeight, 1, GL_ALPHA, GL_UNSIGNED_BYTE);
|
||||
unsigned char* alphaData = alphaImage->data();
|
||||
|
||||
for (int x = mMinX; x <= mMaxX; ++x)
|
||||
{
|
||||
|
|
@ -154,53 +158,26 @@ namespace MWRender
|
|||
{
|
||||
for (int cellX = 0; cellX < mCellSize; ++cellX)
|
||||
{
|
||||
int vertexX = static_cast<int>(float(cellX) / float(mCellSize) * 9);
|
||||
int vertexY = static_cast<int>(float(cellY) / float(mCellSize) * 9);
|
||||
int vertexX = (cellX * 9) / mCellSize; // 0..8
|
||||
int vertexY = (cellY * 9) / mCellSize; // 0..8
|
||||
|
||||
int texelX = (x - mMinX) * mCellSize + cellX;
|
||||
int texelY = (y - mMinY) * mCellSize + cellY;
|
||||
|
||||
unsigned char r, g, b;
|
||||
int lutIndex = 0;
|
||||
// Converting [-128; 127] WNAM range to [0; 255] index
|
||||
if (land != nullptr && (land->mDataTypes & ESM::Land::DATA_WNAM))
|
||||
lutIndex = static_cast<int>(land->mWnam[vertexY * 9 + vertexX]) + 128;
|
||||
|
||||
float y2 = 0;
|
||||
if (land && (land->mDataTypes & ESM::Land::DATA_WNAM))
|
||||
y2 = land->mWnam[vertexY * 9 + vertexX] / 128.f;
|
||||
else
|
||||
y2 = SCHAR_MIN / 128.f;
|
||||
if (y2 < 0)
|
||||
{
|
||||
r = static_cast<unsigned char>(14 * y2 + 38);
|
||||
g = static_cast<unsigned char>(20 * y2 + 56);
|
||||
b = static_cast<unsigned char>(18 * y2 + 51);
|
||||
}
|
||||
else if (y2 < 0.3f)
|
||||
{
|
||||
if (y2 < 0.1f)
|
||||
y2 *= 8.f;
|
||||
else
|
||||
{
|
||||
y2 -= 0.1f;
|
||||
y2 += 0.8f;
|
||||
}
|
||||
r = static_cast<unsigned char>(66 - 32 * y2);
|
||||
g = static_cast<unsigned char>(48 - 23 * y2);
|
||||
b = static_cast<unsigned char>(33 - 16 * y2);
|
||||
}
|
||||
else
|
||||
{
|
||||
y2 -= 0.3f;
|
||||
y2 *= 1.428f;
|
||||
r = static_cast<unsigned char>(34 - 29 * y2);
|
||||
g = static_cast<unsigned char>(25 - 20 * y2);
|
||||
b = static_cast<unsigned char>(17 - 12 * y2);
|
||||
}
|
||||
// Use getColor to handle all pixel format conversions automatically
|
||||
osg::Vec4 color = mColorLut->getColor(lutIndex, 0);
|
||||
|
||||
data[texelY * mWidth * 3 + texelX * 3] = r;
|
||||
data[texelY * mWidth * 3 + texelX * 3 + 1] = g;
|
||||
data[texelY * mWidth * 3 + texelX * 3 + 2] = b;
|
||||
// Use setColor to write to output images
|
||||
image->setColor(color, texelX, texelY);
|
||||
|
||||
alphaData[texelY * mWidth + texelX]
|
||||
= (y2 < 0) ? static_cast<unsigned char>(0) : static_cast<unsigned char>(255);
|
||||
// Set alpha based on lutIndex threshold
|
||||
osg::Vec4 alpha(0.0f, 0.0f, 0.0f, lutIndex < 128 ? 0.0f : 1.0f);
|
||||
alphaImage->setColor(alpha, texelX, texelY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -242,6 +219,7 @@ namespace MWRender
|
|||
int mMinX, mMinY, mMaxX, mMaxY;
|
||||
int mCellSize;
|
||||
const MWWorld::Store<ESM::Land>& mLandStore;
|
||||
osg::ref_ptr<osg::Image> mColorLut;
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> mBaseTexture;
|
||||
osg::ref_ptr<osg::Texture2D> mAlphaTexture;
|
||||
|
|
@ -309,8 +287,20 @@ namespace MWRender
|
|||
mWidth = cellSize * (mMaxX - mMinX + 1);
|
||||
mHeight = cellSize * (mMaxY - mMinY + 1);
|
||||
|
||||
mWorkItem
|
||||
= new CreateMapWorkItem(mWidth, mHeight, mMinX, mMinY, mMaxX, mMaxY, cellSize, esmStore.get<ESM::Land>());
|
||||
// Load color LUT texture
|
||||
constexpr VFS::Path::NormalizedView colorLutPath("textures/omw_map_color_palette.dds");
|
||||
auto resourceSystem = MWBase::Environment::get().getResourceSystem();
|
||||
osg::ref_ptr<osg::Image> colorLut = resourceSystem->getImageManager()->getImage(colorLutPath);
|
||||
|
||||
// Validate LUT dimensions
|
||||
if (!colorLut || colorLut->s() != 256 || colorLut->t() != 1)
|
||||
{
|
||||
throw std::runtime_error("Global map color LUT must be 256x1 pixels, got "
|
||||
+ std::to_string(colorLut ? colorLut->s() : 0) + "x" + std::to_string(colorLut ? colorLut->t() : 0));
|
||||
}
|
||||
|
||||
mWorkItem = new CreateMapWorkItem(
|
||||
mWidth, mHeight, mMinX, mMinY, mMaxX, mMaxY, cellSize, esmStore.get<ESM::Land>(), colorLut);
|
||||
mWorkQueue->addWorkItem(mWorkItem);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ if (NOT DEFINED OPENMW_RESOURCES_ROOT)
|
|||
endif()
|
||||
|
||||
set(BUILTIN_DATA_FILES
|
||||
textures/omw_map_color_palette.dds
|
||||
textures/omw_menu_scroll_down.dds
|
||||
textures/omw_menu_scroll_up.dds
|
||||
textures/omw_menu_scroll_left.dds
|
||||
|
|
|
|||
BIN
files/data/textures/omw_map_color_palette.dds
Normal file
BIN
files/data/textures/omw_map_color_palette.dds
Normal file
Binary file not shown.
Loading…
Reference in a new issue