mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 15:26:57 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			196 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
	
		
			6.3 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 "../testing_util.hpp"
 | 
						|
 | 
						|
namespace
 | 
						|
{
 | 
						|
 | 
						|
    TestingOpenMW::VFSTestFile technique_properties(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;
 | 
						|
    }
 | 
						|
)");
 | 
						|
 | 
						|
    TestingOpenMW::VFSTestFile rendertarget_properties{ 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; }
 | 
						|
)" };
 | 
						|
 | 
						|
    TestingOpenMW::VFSTestFile uniform_properties{ 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; }
 | 
						|
)" };
 | 
						|
 | 
						|
    TestingOpenMW::VFSTestFile missing_sampler_source{ R"(
 | 
						|
    sampler_1d mysampler1d { }
 | 
						|
    fragment main { }
 | 
						|
    technique { passes = main; }
 | 
						|
)" };
 | 
						|
 | 
						|
    TestingOpenMW::VFSTestFile repeated_shared_block{ 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({
 | 
						|
                { "shaders/technique_properties.omwfx", &technique_properties },
 | 
						|
                { "shaders/rendertarget_properties.omwfx", &rendertarget_properties },
 | 
						|
                { "shaders/uniform_properties.omwfx", &uniform_properties },
 | 
						|
                { "shaders/missing_sampler_source.omwfx", &missing_sampler_source },
 | 
						|
                { "shaders/repeated_shared_block.omwfx", &repeated_shared_block },
 | 
						|
            }))
 | 
						|
            , 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"));
 | 
						|
    }
 | 
						|
}
 |