@@ -1514,22 +1514,75 @@ void GLShaderManager::SaveShaderBinary( ShaderProgramDescriptor* descriptor ) {
15141514 cacheSaveCount++;
15151515}
15161516
1517+ std::string GLShaderManager::RemoveUniformsFromShaderText ( const std::string& shaderText, const std::vector<GLUniform*>& uniforms ) {
1518+ std::istringstream shaderTextStream ( shaderText );
1519+ std::string shaderMain;
1520+
1521+ std::string line;
1522+ /* Remove local uniform declarations, but avoid removing uniform / storage blocks;
1523+ * their values will be sourced from a buffer instead
1524+ * Global uniforms (like u_ViewOrigin) will still be set as regular uniforms */
1525+ while ( std::getline ( shaderTextStream, line, ' \n ' ) ) {
1526+ bool skip = false ;
1527+ if ( line.find ( " uniform" ) < line.find ( " //" ) && line.find ( " ;" ) != std::string::npos ) {
1528+ for ( GLUniform* uniform : uniforms ) {
1529+ const size_t pos = line.find ( uniform->_name );
1530+ if ( pos != std::string::npos && !Str::cisalpha ( line[pos + uniform->_name .size ()] ) ) {
1531+ skip = true ;
1532+ break ;
1533+ }
1534+ }
1535+ }
1536+
1537+ if ( skip ) {
1538+ continue ;
1539+ }
1540+
1541+ shaderMain += line + " \n " ;
1542+ }
1543+
1544+ return shaderMain;
1545+ }
1546+
1547+ void GLShaderManager::GenerateUniformStructDefinesText ( const std::vector<GLUniform*>& uniforms, const uint32_t padding,
1548+ const uint32_t paddingCount, const std::string& definesName,
1549+ std::string& uniformStruct, std::string& uniformDefines ) {
1550+ for ( GLUniform* uniform : uniforms ) {
1551+ uniformStruct += " " + ( uniform->_isTexture ? " uvec2" : uniform->_type ) + " " + uniform->_name ;
1552+
1553+ if ( uniform->_components ) {
1554+ uniformStruct += " [" + std::to_string ( uniform->_components ) + " ]" ;
1555+ }
1556+ uniformStruct += " ;\n " ;
1557+
1558+ uniformDefines += " #define " ;
1559+ uniformDefines += uniform->_name ;
1560+
1561+ if ( uniform->_isTexture ) {
1562+ uniformDefines += " _initial" ;
1563+ }
1564+
1565+ uniformDefines += " " + definesName + " ." ;
1566+ uniformDefines += uniform->_name ;
1567+
1568+ uniformDefines += " \n " ;
1569+ }
1570+
1571+ // Array of structs is aligned to the largest member of the struct
1572+ for ( uint32_t i = 0 ; i < padding; i++ ) {
1573+ uniformStruct += " int uniform_padding" + std::to_string ( i + paddingCount );
1574+ uniformStruct += " ;\n " ;
1575+ }
1576+
1577+ uniformDefines += " \n " ;
1578+ }
1579+
15171580// This will generate all the extra code for material system shaders
15181581std::string GLShaderManager::ShaderPostProcess ( GLShader *shader, const std::string& shaderText, const uint32_t offset ) {
15191582 if ( !shader->std430Size ) {
15201583 return shaderText;
15211584 }
15221585
1523- std::string newShaderText;
1524- std::string materialStruct = " \n struct Material {\n " ;
1525- // 6 kb for materials
1526- const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD430Size ();
1527- std::string materialBlock = " layout(std140, binding = "
1528- + std::to_string ( BufferBind::MATERIALS )
1529- + " ) uniform materialsUBO {\n "
1530- " Material materials[" + std::to_string ( count ) + " ]; \n "
1531- " };\n\n " ;
1532-
15331586 std::string texBuf = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ?
15341587 " layout(std140, binding = "
15351588 + std::to_string ( BufferBind::TEX_DATA )
@@ -1569,7 +1622,6 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str
15691622 " };\n\n "
15701623 " #define u_LightMap_initial lightMapData[( baseInstance >> 24 ) & 0xFF].u_LightMap\n "
15711624 " #define u_DeluxeMap_initial lightMapData[( baseInstance >> 24 ) & 0xFF].u_DeluxeMap\n\n " ;
1572- std::string materialDefines;
15731625
15741626 /* Generate the struct and defines in the form of:
15751627 * struct Material {
@@ -1582,62 +1634,24 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str
15821634 * #define uniformx materials[baseInstance].uniformx
15831635 */
15841636
1585- for ( GLUniform* uniform : shader->_materialSystemUniforms ) {
1586- materialStruct += " " + uniform->_type + " " + uniform->_name ;
1587-
1588- if ( uniform->_components ) {
1589- materialStruct += " [" + std::to_string ( uniform->_components ) + " ]" ;
1590- }
1591- materialStruct += " ;\n " ;
1592-
1593- materialDefines += " #define " ;
1594- materialDefines += uniform->_name ;
1595-
1596- materialDefines += " materials[baseInstance & 0xFFF]." ;
1597- materialDefines += uniform->_name ;
1598-
1599- materialDefines += " \n " ;
1600- }
1601-
1602- // Array of structs is aligned to the largest member of the struct
1603- for ( uint i = 0 ; i < shader->padding ; i++ ) {
1604- materialStruct += " int material_padding" + std::to_string ( i );
1605- materialStruct += " ;\n " ;
1606- }
1637+ std::string materialStruct = " \n struct Material {\n " ;
1638+ std::string materialDefines;
1639+ GenerateUniformStructDefinesText ( shader->_materialSystemUniforms , shader->padding ,
1640+ 0 , " materials[baseInstance & 0xFFF]" , materialStruct, materialDefines );
16071641
16081642 materialStruct += " };\n\n " ;
1609- materialDefines += " \n " ;
16101643
1611- std::istringstream shaderTextStream ( shaderText );
1612- std::string shaderMain;
1613-
1614- std::string line;
1615-
1616- /* Remove local uniform declarations, but avoid removing uniform / storage blocks;
1617- * their values will be sourced from a buffer instead
1618- * Global uniforms (like u_ViewOrigin) will still be set as regular uniforms */
1619- while ( std::getline ( shaderTextStream, line, ' \n ' ) ) {
1620- bool skip = false ;
1621- if ( line.find ( " uniform" ) < line.find ( " //" ) && line.find ( " ;" ) != std::string::npos ) {
1622- for ( GLUniform* uniform : shader->_materialSystemUniforms ) {
1623- const size_t pos = line.find ( uniform->_name );
1624- if ( pos != std::string::npos && !Str::cisalpha ( line[pos + strlen ( uniform->_name .c_str () )] ) ) {
1625- skip = true ;
1626- break ;
1627- }
1628- }
1629- }
1630-
1631- if ( skip ) {
1632- continue ;
1633- }
1634-
1635- shaderMain += line + " \n " ;
1636- }
1644+ // 6 kb for materials
1645+ const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD430Size ();
1646+ std::string materialBlock = " layout(std140, binding = "
1647+ + std::to_string ( BufferBind::MATERIALS )
1648+ + " ) uniform materialsUBO {\n "
1649+ " Material materials[" + std::to_string ( count ) + " ]; \n "
1650+ " };\n\n " ;
16371651
1638- materialDefines += " \n " ;
1652+ std::string shaderMain = RemoveUniformsFromShaderText ( shaderText, shader-> _materialSystemUniforms ) ;
16391653
1640- newShaderText = " #define USE_MATERIAL_SYSTEM\n " + materialStruct + materialBlock + texDataBlock + materialDefines;
1654+ std::string newShaderText = " #define USE_MATERIAL_SYSTEM\n " + materialStruct + materialBlock + texDataBlock + materialDefines;
16411655 shaderMain.insert ( offset, newShaderText );
16421656 return shaderMain;
16431657}
0 commit comments