2020-05-01 21:03:13 +00:00
# include <components/shader/shadermanager.hpp>
2022-05-25 19:16:26 +00:00
# include <fstream>
2020-05-01 21:03:13 +00:00
# include <gtest/gtest.h>
2022-05-24 20:31:29 +00:00
# include "../testing_util.hpp"
2020-05-01 21:03:13 +00:00
namespace
{
using namespace testing ;
using namespace Shader ;
struct ShaderManagerTest : Test
{
ShaderManager mManager ;
ShaderManager : : DefineMap mDefines ;
ShaderManagerTest ( )
{
mManager . setShaderPath ( " . " ) ;
}
template < class F >
void withShaderFile ( const std : : string & content , F & & f )
{
withShaderFile ( " " , content , std : : forward < F > ( f ) ) ;
}
template < class F >
void withShaderFile ( const std : : string & suffix , const std : : string & content , F & & f )
{
2022-06-19 11:28:33 +00:00
auto path = TestingOpenMW : : outputFilePath (
2022-05-24 20:31:29 +00:00
std : : string ( UnitTest : : GetInstance ( ) - > current_test_info ( ) - > name ( ) ) + suffix + " .glsl " ) ;
2020-05-01 21:03:13 +00:00
{
2022-05-24 20:31:29 +00:00
std : : ofstream stream ( path ) ;
2020-05-01 21:03:13 +00:00
stream < < content ;
stream . close ( ) ;
}
f ( path ) ;
}
} ;
TEST_F ( ShaderManagerTest , get_shader_with_empty_content_should_succeed )
{
const std : : string content ;
2022-06-19 11:28:33 +00:00
withShaderFile ( content , [ this ] ( const std : : filesystem : : path & templateName ) {
EXPECT_TRUE ( mManager . getShader ( templateName . string ( ) , { } , osg : : Shader : : VERTEX ) ) ; //TODO(Project579): This will probably break in windows with unicode paths
2020-05-01 21:03:13 +00:00
} ) ;
}
TEST_F ( ShaderManagerTest , get_shader_should_not_change_source_without_template_parameters )
{
const std : : string content =
" #version 120 \n "
" void main() {} \n " ;
2022-06-19 11:28:33 +00:00
withShaderFile ( content , [ & ] ( const std : : filesystem : : path & templateName ) {
const auto shader = mManager . getShader ( templateName . string ( ) , mDefines , osg : : Shader : : VERTEX ) ; //TODO(Project579): This will probably break in windows with unicode paths
2020-05-01 21:03:13 +00:00
ASSERT_TRUE ( shader ) ;
EXPECT_EQ ( shader - > getShaderSource ( ) , content ) ;
} ) ;
}
TEST_F ( ShaderManagerTest , get_shader_should_replace_includes_with_content )
{
const std : : string content0 =
" void foo() {} \n " ;
2022-06-19 11:28:33 +00:00
withShaderFile ( " _0 " , content0 , [ & ] ( const std : : filesystem : : path & templateName0 ) {
2020-05-01 21:03:13 +00:00
const std : : string content1 =
2022-06-19 11:28:33 +00:00
" #include \" " + templateName0 . string ( ) + " \" \n " //TODO(Project579): This will probably break in windows with unicode paths
2020-05-01 21:03:13 +00:00
" void bar() { foo() } \n " ;
2022-06-19 11:28:33 +00:00
withShaderFile ( " _1 " , content1 , [ & ] ( const std : : filesystem : : path & templateName1 ) {
2020-05-01 21:03:13 +00:00
const std : : string content2 =
" #version 120 \n "
2022-06-19 11:28:33 +00:00
" #include \" " + templateName1 . string ( ) + " \" \n " //TODO(Project579): This will probably break in windows with unicode paths
2020-05-01 21:03:13 +00:00
" void main() { bar() } \n " ;
2022-06-19 11:28:33 +00:00
withShaderFile ( content2 , [ & ] ( const std : : filesystem : : path & templateName2 ) {
const auto shader = mManager . getShader ( templateName2 . string ( ) , mDefines , osg : : Shader : : VERTEX ) ; //TODO(Project579): This will probably break in windows with unicode paths
2020-05-01 21:03:13 +00:00
ASSERT_TRUE ( shader ) ;
const std : : string expected =
" #version 120 \n "
" #line 0 1 \n "
" #line 0 2 \n "
" void foo() {} \n "
" \n "
" #line 0 0 \n "
" \n "
" void bar() { foo() } \n "
" \n "
2020-10-03 12:22:34 +00:00
" #line 1 0 \n "
2020-05-01 21:03:13 +00:00
" \n "
" void main() { bar() } \n " ;
EXPECT_EQ ( shader - > getShaderSource ( ) , expected ) ;
} ) ;
} ) ;
} ) ;
}
TEST_F ( ShaderManagerTest , get_shader_should_replace_defines )
{
const std : : string content =
" #version 120 \n "
" #define FLAG @flag \n "
" void main() {} \n "
;
2022-06-19 11:28:33 +00:00
withShaderFile ( content , [ & ] ( const std : : filesystem : : path & templateName ) {
2020-05-01 21:03:13 +00:00
mDefines [ " flag " ] = " 1 " ;
2022-06-19 11:28:33 +00:00
const auto shader = mManager . getShader ( templateName . string ( ) , mDefines , osg : : Shader : : VERTEX ) ; //TODO(Project579): This will probably break in windows with unicode paths
2020-05-01 21:03:13 +00:00
ASSERT_TRUE ( shader ) ;
const std : : string expected =
" #version 120 \n "
" #define FLAG 1 \n "
" void main() {} \n " ;
EXPECT_EQ ( shader - > getShaderSource ( ) , expected ) ;
} ) ;
}
TEST_F ( ShaderManagerTest , get_shader_should_expand_loop )
{
const std : : string content =
" #version 120 \n "
" @foreach index @list \n "
" varying vec4 foo@index; \n "
" @endforeach \n "
" void main() {} \n "
;
2022-06-19 11:28:33 +00:00
withShaderFile ( content , [ & ] ( const std : : filesystem : : path & templateName ) {
2020-05-01 21:03:13 +00:00
mDefines [ " list " ] = " 1,2,3 " ;
2022-06-19 11:28:33 +00:00
const auto shader = mManager . getShader ( templateName . string ( ) , mDefines , osg : : Shader : : VERTEX ) ; //TODO(Project579): This will probably break in windows with unicode paths
2020-05-01 21:03:13 +00:00
ASSERT_TRUE ( shader ) ;
const std : : string expected =
" #version 120 \n "
" varying vec4 foo1; \n "
" varying vec4 foo2; \n "
" varying vec4 foo3; \n "
" \n "
" #line 5 \n "
" void main() {} \n " ;
EXPECT_EQ ( shader - > getShaderSource ( ) , expected ) ;
} ) ;
}
TEST_F ( ShaderManagerTest , get_shader_should_replace_loops_with_conditions )
{
const std : : string content =
" #version 120 \n "
" @foreach index @list \n "
" varying vec4 foo@index; \n "
" @endforeach \n "
" void main() \n "
" { \n "
" #ifdef BAR \n "
" @foreach index @list \n "
" foo@index = vec4(1.0); \n "
" @endforeach \n "
" #elif BAZ \n "
" @foreach index @list \n "
" foo@index = vec4(2.0); \n "
" @endforeach \n "
" #else \n "
" @foreach index @list \n "
" foo@index = vec4(3.0); \n "
" @endforeach \n "
" #endif \n "
" } \n "
;
2022-06-19 11:28:33 +00:00
withShaderFile ( content , [ & ] ( const std : : filesystem : : path & templateName ) {
2020-05-01 21:03:13 +00:00
mDefines [ " list " ] = " 1,2,3 " ;
2022-06-19 11:28:33 +00:00
const auto shader = mManager . getShader ( templateName . string ( ) , mDefines , osg : : Shader : : VERTEX ) ; //TODO(Project579): This will probably break in windows with unicode paths
2020-05-01 21:03:13 +00:00
ASSERT_TRUE ( shader ) ;
const std : : string expected =
" #version 120 \n "
" varying vec4 foo1; \n "
" varying vec4 foo2; \n "
" varying vec4 foo3; \n "
" \n "
" #line 5 \n "
" void main() \n "
" { \n "
" #ifdef BAR \n "
" foo1 = vec4(1.0); \n "
" foo2 = vec4(1.0); \n "
" foo3 = vec4(1.0); \n "
" \n "
" #line 11 \n "
" #elif BAZ \n "
" #line 12 \n "
" foo1 = vec4(2.0); \n "
" foo2 = vec4(2.0); \n "
" foo3 = vec4(2.0); \n "
" \n "
" #line 15 \n "
" #else \n "
" #line 16 \n "
" foo1 = vec4(3.0); \n "
" foo2 = vec4(3.0); \n "
" foo3 = vec4(3.0); \n "
" \n "
" #line 19 \n "
" #endif \n "
" #line 20 \n "
" } \n " ;
EXPECT_EQ ( shader - > getShaderSource ( ) , expected ) ;
} ) ;
}
TEST_F ( ShaderManagerTest , get_shader_should_fail_on_absent_template_parameters_in_single_line_comments )
{
const std : : string content =
" #version 120 \n "
" // #define FLAG @flag \n "
" void main() {} \n "
;
2022-06-19 11:28:33 +00:00
withShaderFile ( content , [ & ] ( const std : : filesystem : : path & templateName ) {
EXPECT_FALSE ( mManager . getShader ( templateName . string ( ) , mDefines , osg : : Shader : : VERTEX ) ) ; //TODO(Project579): This will probably break in windows with unicode paths
2020-05-01 21:03:13 +00:00
} ) ;
}
TEST_F ( ShaderManagerTest , get_shader_should_fail_on_absent_template_parameter_in_multi_line_comments )
{
const std : : string content =
" #version 120 \n "
" /* #define FLAG @flag */ \n "
" void main() {} \n "
;
2022-06-19 11:28:33 +00:00
withShaderFile ( content , [ & ] ( const std : : filesystem : : path & templateName ) {
EXPECT_FALSE ( mManager . getShader ( templateName . string ( ) , mDefines , osg : : Shader : : VERTEX ) ) ; //TODO(Project579): This will probably break in windows with unicode paths
2020-05-01 21:03:13 +00:00
} ) ;
}
}