1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-09 21:42:13 +00:00
OpenMW/apps/openmw_test_suite/nifosg/testnifloader.cpp
Alexei Kotov 116ef1c62b Depth flag handling fixes (bug #7380)
Properly disable depth test while allowing depth writes to happen
Remove NiStencilProperty interaction
Don't set up depth flags for BSShaderPPLightingProperty
2023-11-06 02:19:56 +03:00

299 lines
8.3 KiB
C++

#include "../nif/node.hpp"
#include <components/nif/node.hpp>
#include <components/nif/property.hpp>
#include <components/nifosg/nifloader.hpp>
#include <components/resource/imagemanager.hpp>
#include <components/sceneutil/serialize.hpp>
#include <components/vfs/manager.hpp>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <osgDB/Registry>
#include <array>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
namespace
{
using namespace testing;
using namespace NifOsg;
using namespace Nif::Testing;
struct BaseNifOsgLoaderTest
{
VFS::Manager mVfs;
Resource::ImageManager mImageManager{ &mVfs, 0 };
const osgDB::ReaderWriter* mReaderWriter = osgDB::Registry::instance()->getReaderWriterForExtension("osgt");
osg::ref_ptr<osgDB::Options> mOptions = new osgDB::Options;
BaseNifOsgLoaderTest()
{
SceneUtil::registerSerializers();
if (mReaderWriter == nullptr)
throw std::runtime_error("osgt reader writer is not found");
mOptions->setPluginStringData("fileType", "Ascii");
mOptions->setPluginStringData("WriteImageHint", "UseExternal");
}
std::string serialize(const osg::Node& node) const
{
std::stringstream stream;
mReaderWriter->writeNode(node, stream, mOptions);
std::string result;
for (std::string line; std::getline(stream, line);)
{
if (line.starts_with('#'))
continue;
line.erase(line.find_last_not_of(" \t\n\r\f\v") + 1);
result += line;
result += '\n';
}
return result;
}
};
struct NifOsgLoaderTest : Test, BaseNifOsgLoaderTest
{
};
TEST_F(NifOsgLoaderTest, shouldLoadFileWithDefaultNode)
{
Nif::NiAVObject node;
init(node);
Nif::NIFFile file("test.nif");
file.mRoots.push_back(&node);
auto result = Loader::load(file, &mImageManager);
EXPECT_EQ(serialize(*result), R"(
osg::Group {
UniqueID 1
DataVariance STATIC
UserDataContainer TRUE {
osg::DefaultUserDataContainer {
UniqueID 2
UDC_UserObjects 1 {
osg::StringValueObject {
UniqueID 3
Name "fileHash"
}
}
}
}
Children 1 {
osg::Group {
UniqueID 4
DataVariance STATIC
UserDataContainer TRUE {
osg::DefaultUserDataContainer {
UniqueID 5
UDC_UserObjects 1 {
osg::UIntValueObject {
UniqueID 6
Name "recIndex"
Value 4294967295
}
}
}
}
}
}
}
)");
}
std::string formatOsgNodeForBSShaderProperty(std::string_view shaderPrefix)
{
std::ostringstream oss;
oss << R"(
osg::Group {
UniqueID 1
DataVariance STATIC
UserDataContainer TRUE {
osg::DefaultUserDataContainer {
UniqueID 2
UDC_UserObjects 1 {
osg::StringValueObject {
UniqueID 3
Name "fileHash"
}
}
}
}
Children 1 {
osg::Group {
UniqueID 4
DataVariance STATIC
UserDataContainer TRUE {
osg::DefaultUserDataContainer {
UniqueID 5
UDC_UserObjects 3 {
osg::UIntValueObject {
UniqueID 6
Name "recIndex"
Value 4294967295
}
osg::StringValueObject {
UniqueID 7
Name "shaderPrefix"
Value ")"
<< shaderPrefix << R"("
}
osg::BoolValueObject {
UniqueID 8
Name "shaderRequired"
Value TRUE
}
}
}
}
StateSet TRUE {
osg::StateSet {
UniqueID 9
}
}
}
}
}
)";
return oss.str();
}
std::string formatOsgNodeForBSLightingShaderProperty(std::string_view shaderPrefix)
{
std::ostringstream oss;
oss << R"(
osg::Group {
UniqueID 1
DataVariance STATIC
UserDataContainer TRUE {
osg::DefaultUserDataContainer {
UniqueID 2
UDC_UserObjects 1 {
osg::StringValueObject {
UniqueID 3
Name "fileHash"
}
}
}
}
Children 1 {
osg::Group {
UniqueID 4
DataVariance STATIC
UserDataContainer TRUE {
osg::DefaultUserDataContainer {
UniqueID 5
UDC_UserObjects 3 {
osg::UIntValueObject {
UniqueID 6
Name "recIndex"
Value 4294967295
}
osg::StringValueObject {
UniqueID 7
Name "shaderPrefix"
Value ")"
<< shaderPrefix << R"("
}
osg::BoolValueObject {
UniqueID 8
Name "shaderRequired"
Value TRUE
}
}
}
}
StateSet TRUE {
osg::StateSet {
UniqueID 9
ModeList 1 {
GL_DEPTH_TEST ON
}
AttributeList 1 {
osg::Depth {
UniqueID 10
}
Value OFF
}
}
}
}
}
}
)";
return oss.str();
}
struct ShaderPrefixParams
{
unsigned int mShaderType;
std::string_view mExpectedShaderPrefix;
};
struct NifOsgLoaderBSShaderPrefixTest : TestWithParam<ShaderPrefixParams>, BaseNifOsgLoaderTest
{
static constexpr std::array sParams = {
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_Default), "bs/default" },
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_NoLighting), "bs/nolighting" },
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSShaderType::ShaderType_Tile), "bs/default" },
ShaderPrefixParams{ std::numeric_limits<unsigned int>::max(), "bs/default" },
};
};
TEST_P(NifOsgLoaderBSShaderPrefixTest, shouldAddShaderPrefix)
{
Nif::NiAVObject node;
init(node);
Nif::BSShaderPPLightingProperty property;
property.recType = Nif::RC_BSShaderPPLightingProperty;
property.mTextureSet = nullptr;
property.mController = nullptr;
property.mType = GetParam().mShaderType;
node.mProperties.push_back(Nif::RecordPtrT<Nif::NiProperty>(&property));
Nif::NIFFile file("test.nif");
file.mRoots.push_back(&node);
auto result = Loader::load(file, &mImageManager);
EXPECT_EQ(serialize(*result), formatOsgNodeForBSShaderProperty(GetParam().mExpectedShaderPrefix));
}
INSTANTIATE_TEST_SUITE_P(Params, NifOsgLoaderBSShaderPrefixTest, ValuesIn(NifOsgLoaderBSShaderPrefixTest::sParams));
struct NifOsgLoaderBSLightingShaderPrefixTest : TestWithParam<ShaderPrefixParams>, BaseNifOsgLoaderTest
{
static constexpr std::array sParams = {
ShaderPrefixParams{
static_cast<unsigned int>(Nif::BSLightingShaderType::ShaderType_Default), "bs/default" },
ShaderPrefixParams{ static_cast<unsigned int>(Nif::BSLightingShaderType::ShaderType_Cloud), "bs/default" },
ShaderPrefixParams{ std::numeric_limits<unsigned int>::max(), "bs/default" },
};
};
TEST_P(NifOsgLoaderBSLightingShaderPrefixTest, shouldAddShaderPrefix)
{
Nif::NiAVObject node;
init(node);
Nif::BSLightingShaderProperty property;
property.recType = Nif::RC_BSLightingShaderProperty;
property.mTextureSet = nullptr;
property.mController = nullptr;
property.mType = GetParam().mShaderType;
property.mShaderFlags1 |= Nif::BSShaderFlags1::BSSFlag1_DepthTest;
property.mShaderFlags2 |= Nif::BSShaderFlags2::BSSFlag2_DepthWrite;
node.mProperties.push_back(Nif::RecordPtrT<Nif::NiProperty>(&property));
Nif::NIFFile file("test.nif");
file.mRoots.push_back(&node);
auto result = Loader::load(file, &mImageManager);
EXPECT_EQ(serialize(*result), formatOsgNodeForBSLightingShaderProperty(GetParam().mExpectedShaderPrefix));
}
INSTANTIATE_TEST_SUITE_P(
Params, NifOsgLoaderBSLightingShaderPrefixTest, ValuesIn(NifOsgLoaderBSLightingShaderPrefixTest::sParams));
}