You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/apps/openmw_test_suite/nifosg/testnifloader.cpp

231 lines
6.7 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{ false };
Resource::ImageManager mImageManager{ &mVfs };
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::Node 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 formatOsgNodeForShaderProperty(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();
}
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::Node node;
init(node);
Nif::BSShaderPPLightingProperty property;
property.recType = Nif::RC_BSShaderPPLightingProperty;
property.textureSet = nullptr;
property.controller = nullptr;
property.type = GetParam().mShaderType;
node.props.push_back(Nif::RecordPtrT<Nif::Property>(&property));
Nif::NIFFile file("test.nif");
file.mRoots.push_back(&node);
auto result = Loader::load(file, &mImageManager);
EXPECT_EQ(serialize(*result), formatOsgNodeForShaderProperty(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::Node node;
init(node);
Nif::BSLightingShaderProperty property;
property.recType = Nif::RC_BSLightingShaderProperty;
property.mTextureSet = nullptr;
property.controller = nullptr;
property.type = GetParam().mShaderType;
node.props.push_back(Nif::RecordPtrT<Nif::Property>(&property));
Nif::NIFFile file("test.nif");
file.mRoots.push_back(&node);
auto result = Loader::load(file, &mImageManager);
EXPECT_EQ(serialize(*result), formatOsgNodeForShaderProperty(GetParam().mExpectedShaderPrefix));
}
INSTANTIATE_TEST_SUITE_P(
Params, NifOsgLoaderBSLightingShaderPrefixTest, ValuesIn(NifOsgLoaderBSLightingShaderPrefixTest::sParams));
}