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/components_tests/fx/technique.cpp

205 lines
6.8 KiB
C++

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <components/files/configurationmanager.hpp>
#include <components/fx/technique.hpp>
#include <components/resource/imagemanager.hpp>
#include <components/settings/settings.hpp>
#include <components/testing/util.hpp>
namespace
{
constexpr VFS::Path::NormalizedView techniquePropertiesPath("shaders/technique_properties.omwfx");
TestingOpenMW::VFSTestFile techniqueProperties(R"(
fragment main {}
vertex main {}
technique {
passes = main;
version = "0.1a";
description = "description";
author = "author";
glsl_version = 330;
glsl_profile = "compatability";
glsl_extensions = GL_EXT_gpu_shader4, GL_ARB_uniform_buffer_object;
flags = disable_sunglare;
hdr = true;
}
)");
constexpr VFS::Path::NormalizedView rendertargetPropertiesPath("shaders/rendertarget_properties.omwfx");
TestingOpenMW::VFSTestFile rendertargetProperties{ R"(
render_target rendertarget {
width_ratio = 0.5;
height_ratio = 0.5;
internal_format = r16f;
source_type = float;
source_format = red;
mipmaps = true;
wrap_s = clamp_to_edge;
wrap_t = repeat;
min_filter = linear;
mag_filter = nearest;
}
fragment downsample2x(target=rendertarget) {
omw_In vec2 omw_TexCoord;
void main()
{
omw_FragColor.r = omw_GetLastShader(omw_TexCoord).r;
}
}
fragment main { }
technique { passes = downsample2x, main; }
)" };
constexpr VFS::Path::NormalizedView uniformPropertiesPath("shaders/uniform_properties.omwfx");
TestingOpenMW::VFSTestFile uniformProperties{ R"(
uniform_vec4 uVec4 {
default = vec4(0,0,0,0);
min = vec4(0,1,0,0);
max = vec4(0,0,1,0);
step = 0.5;
header = "header";
static = true;
description = "description";
}
fragment main { }
technique { passes = main; }
)" };
constexpr VFS::Path::NormalizedView missingSamplerSourcePath("shaders/missing_sampler_source.omwfx");
TestingOpenMW::VFSTestFile missingSamplerSource{ R"(
sampler_1d mysampler1d { }
fragment main { }
technique { passes = main; }
)" };
constexpr VFS::Path::NormalizedView repeatedSharedBlockPath("shaders/repeated_shared_block.omwfx");
TestingOpenMW::VFSTestFile repeatedSharedBlock{ R"(
shared {
float myfloat = 1.0;
}
shared {}
fragment main { }
technique { passes = main; }
)" };
using namespace testing;
using namespace fx;
struct TechniqueTest : Test
{
std::unique_ptr<VFS::Manager> mVFS;
Resource::ImageManager mImageManager;
std::unique_ptr<Technique> mTechnique;
TechniqueTest()
: mVFS(TestingOpenMW::createTestVFS({
{ techniquePropertiesPath, &techniqueProperties },
{ rendertargetPropertiesPath, &rendertargetProperties },
{ uniformPropertiesPath, &uniformProperties },
{ missingSamplerSourcePath, &missingSamplerSource },
{ repeatedSharedBlockPath, &repeatedSharedBlock },
}))
, mImageManager(mVFS.get(), 0)
{
}
void compile(const std::string& name)
{
mTechnique = std::make_unique<Technique>(*mVFS.get(), mImageManager, name, 1, 1, true, true);
mTechnique->compile();
}
};
TEST_F(TechniqueTest, technique_properties)
{
std::unordered_set<std::string> targetExtensions = { "GL_EXT_gpu_shader4", "GL_ARB_uniform_buffer_object" };
compile("technique_properties");
EXPECT_EQ(mTechnique->getVersion(), "0.1a");
EXPECT_EQ(mTechnique->getDescription(), "description");
EXPECT_EQ(mTechnique->getAuthor(), "author");
EXPECT_EQ(mTechnique->getGLSLVersion(), 330);
EXPECT_EQ(mTechnique->getGLSLProfile(), "compatability");
EXPECT_EQ(mTechnique->getGLSLExtensions(), targetExtensions);
EXPECT_EQ(mTechnique->getFlags(), Technique::Flag_Disable_SunGlare);
EXPECT_EQ(mTechnique->getHDR(), true);
EXPECT_EQ(mTechnique->getPasses().size(), 1);
EXPECT_EQ(mTechnique->getPasses().front()->getName(), "main");
}
TEST_F(TechniqueTest, rendertarget_properties)
{
compile("rendertarget_properties");
EXPECT_EQ(mTechnique->getRenderTargetsMap().size(), 1);
const std::string_view name = mTechnique->getRenderTargetsMap().begin()->first;
auto& rt = mTechnique->getRenderTargetsMap().begin()->second;
auto& texture = rt.mTarget;
EXPECT_EQ(name, "rendertarget");
EXPECT_EQ(rt.mMipMap, true);
EXPECT_EQ(rt.mSize.mWidthRatio, 0.5f);
EXPECT_EQ(rt.mSize.mHeightRatio, 0.5f);
EXPECT_EQ(texture->getWrap(osg::Texture::WRAP_S), osg::Texture::CLAMP_TO_EDGE);
EXPECT_EQ(texture->getWrap(osg::Texture::WRAP_T), osg::Texture::REPEAT);
EXPECT_EQ(texture->getFilter(osg::Texture::MIN_FILTER), osg::Texture::LINEAR);
EXPECT_EQ(texture->getFilter(osg::Texture::MAG_FILTER), osg::Texture::NEAREST);
EXPECT_EQ(texture->getSourceType(), static_cast<GLenum>(GL_FLOAT));
EXPECT_EQ(texture->getSourceFormat(), static_cast<GLenum>(GL_RED));
EXPECT_EQ(texture->getInternalFormat(), static_cast<GLint>(GL_R16F));
EXPECT_EQ(mTechnique->getPasses().size(), 2);
EXPECT_EQ(mTechnique->getPasses()[0]->getTarget(), "rendertarget");
}
TEST_F(TechniqueTest, uniform_properties)
{
compile("uniform_properties");
EXPECT_EQ(mTechnique->getUniformMap().size(), 1);
const auto& uniform = mTechnique->getUniformMap().front();
EXPECT_TRUE(uniform->mStatic);
EXPECT_DOUBLE_EQ(uniform->mStep, 0.5);
EXPECT_EQ(uniform->getDefault<osg::Vec4f>(), osg::Vec4f(0, 0, 0, 0));
EXPECT_EQ(uniform->getMin<osg::Vec4f>(), osg::Vec4f(0, 1, 0, 0));
EXPECT_EQ(uniform->getMax<osg::Vec4f>(), osg::Vec4f(0, 0, 1, 0));
EXPECT_EQ(uniform->mHeader, "header");
EXPECT_EQ(uniform->mDescription, "description");
EXPECT_EQ(uniform->mName, "uVec4");
}
TEST_F(TechniqueTest, fail_with_missing_source_for_sampler)
{
internal::CaptureStdout();
compile("missing_sampler_source");
std::string output = internal::GetCapturedStdout();
Log(Debug::Error) << output;
EXPECT_THAT(output, HasSubstr("sampler_1d 'mysampler1d' requires a filename"));
}
TEST_F(TechniqueTest, fail_with_repeated_shared_block)
{
internal::CaptureStdout();
compile("repeated_shared_block");
std::string output = internal::GetCapturedStdout();
Log(Debug::Error) << output;
EXPECT_THAT(output, HasSubstr("repeated 'shared' block"));
}
}