mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-09-11 05:20:14 -04:00
Reduce string usage in ShaderManager
This commit is contained in:
parent
924d591158
commit
ecbc3a7b9e
@ -3,44 +3,47 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <components/debug/debuglog.hpp>
|
|
||||||
#include <components/files/conversion.hpp>
|
|
||||||
#include <components/misc/strings/algorithm.hpp>
|
|
||||||
#include <components/misc/strings/conversion.hpp>
|
|
||||||
#include <components/misc/strings/format.hpp>
|
|
||||||
#include <components/settings/settings.hpp>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <osg/Program>
|
|
||||||
#include <osgViewer/Viewer>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <osg/Program>
|
||||||
|
#include <osgViewer/Viewer>
|
||||||
|
|
||||||
|
#include <components/debug/debuglog.hpp>
|
||||||
|
#include <components/files/conversion.hpp>
|
||||||
|
#include <components/misc/pathhelpers.hpp>
|
||||||
|
#include <components/misc/strings/algorithm.hpp>
|
||||||
|
#include <components/misc/strings/conversion.hpp>
|
||||||
|
#include <components/misc/strings/format.hpp>
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
osg::Shader::Type getShaderType(const std::string& templateName)
|
osg::Shader::Type getShaderType(const std::string& templateName)
|
||||||
{
|
{
|
||||||
auto ext = std::filesystem::path(templateName).extension();
|
std::string_view ext = Misc::getFileExtension(templateName);
|
||||||
|
|
||||||
if (ext == ".vert")
|
if (ext == "vert")
|
||||||
return osg::Shader::VERTEX;
|
return osg::Shader::VERTEX;
|
||||||
if (ext == ".frag")
|
if (ext == "frag")
|
||||||
return osg::Shader::FRAGMENT;
|
return osg::Shader::FRAGMENT;
|
||||||
if (ext == ".geom")
|
if (ext == "geom")
|
||||||
return osg::Shader::GEOMETRY;
|
return osg::Shader::GEOMETRY;
|
||||||
if (ext == ".comp")
|
if (ext == "comp")
|
||||||
return osg::Shader::COMPUTE;
|
return osg::Shader::COMPUTE;
|
||||||
if (ext == ".tese")
|
if (ext == "tese")
|
||||||
return osg::Shader::TESSEVALUATION;
|
return osg::Shader::TESSEVALUATION;
|
||||||
if (ext == ".tesc")
|
if (ext == "tesc")
|
||||||
return osg::Shader::TESSCONTROL;
|
return osg::Shader::TESSCONTROL;
|
||||||
|
|
||||||
throw std::runtime_error("unrecognized shader template name: " + templateName);
|
throw std::runtime_error("unrecognized shader template name: " + templateName);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getRootPrefix(const std::string& path)
|
std::string_view getRootPrefix(std::string_view path)
|
||||||
{
|
{
|
||||||
if (path.starts_with("lib"))
|
if (path.starts_with("lib"))
|
||||||
return "lib";
|
return "lib";
|
||||||
@ -48,8 +51,26 @@ namespace
|
|||||||
return "compatibility";
|
return "compatibility";
|
||||||
else if (path.starts_with("core"))
|
else if (path.starts_with("core"))
|
||||||
return "core";
|
return "core";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
int getLineNumber(std::string_view source, std::size_t foundPos, int lineNumber, int offset)
|
||||||
|
{
|
||||||
|
constexpr std::string_view tag = "#line";
|
||||||
|
std::size_t lineDirectivePosition = source.rfind(tag, foundPos);
|
||||||
|
if (lineDirectivePosition != std::string_view::npos)
|
||||||
|
{
|
||||||
|
std::size_t lineNumberStart = lineDirectivePosition + tag.size() + 1;
|
||||||
|
std::size_t lineNumberEnd = source.find_first_not_of("0123456789", lineNumberStart);
|
||||||
|
std::string_view lineNumberString = source.substr(lineNumberStart, lineNumberEnd - lineNumberStart);
|
||||||
|
lineNumber = Misc::StringUtils::toNumeric<int>(lineNumberString, 2) + offset;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return "";
|
{
|
||||||
|
lineDirectivePosition = 0;
|
||||||
|
}
|
||||||
|
lineNumber += std::count(source.begin() + lineDirectivePosition, source.begin() + foundPos, '\n');
|
||||||
|
return lineNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,21 +106,7 @@ namespace Shader
|
|||||||
if (foundPos == std::string::npos)
|
if (foundPos == std::string::npos)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
size_t lineDirectivePosition = source.rfind("#line", foundPos);
|
int lineNumber = getLineNumber(source, foundPos, 1, -1);
|
||||||
int lineNumber;
|
|
||||||
if (lineDirectivePosition != std::string::npos)
|
|
||||||
{
|
|
||||||
size_t lineNumberStart = lineDirectivePosition + std::string("#line ").length();
|
|
||||||
size_t lineNumberEnd = source.find_first_not_of("0123456789", lineNumberStart);
|
|
||||||
std::string lineNumberString = source.substr(lineNumberStart, lineNumberEnd - lineNumberStart);
|
|
||||||
lineNumber = Misc::StringUtils::toNumeric<int>(lineNumberString, 2) - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lineDirectivePosition = 0;
|
|
||||||
lineNumber = 1;
|
|
||||||
}
|
|
||||||
lineNumber += std::count(source.begin() + lineDirectivePosition, source.begin() + foundPos, '\n');
|
|
||||||
|
|
||||||
source.replace(foundPos, 0, "#line " + std::to_string(lineNumber) + "\n");
|
source.replace(foundPos, 0, "#line " + std::to_string(lineNumber) + "\n");
|
||||||
|
|
||||||
@ -154,21 +161,7 @@ namespace Shader
|
|||||||
std::filesystem::path includePath = shaderPath / includeFilename;
|
std::filesystem::path includePath = shaderPath / includeFilename;
|
||||||
|
|
||||||
// Determine the line number that will be used for the #line directive following the included source
|
// Determine the line number that will be used for the #line directive following the included source
|
||||||
size_t lineDirectivePosition = source.rfind("#line", foundPos);
|
int lineNumber = getLineNumber(source, foundPos, 0, -1);
|
||||||
int lineNumber;
|
|
||||||
if (lineDirectivePosition != std::string::npos)
|
|
||||||
{
|
|
||||||
size_t lineNumberStart = lineDirectivePosition + std::string("#line ").length();
|
|
||||||
size_t lineNumberEnd = source.find_first_not_of("0123456789", lineNumberStart);
|
|
||||||
std::string lineNumberString = source.substr(lineNumberStart, lineNumberEnd - lineNumberStart);
|
|
||||||
lineNumber = Misc::StringUtils::toNumeric<int>(lineNumberString, 2) - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lineDirectivePosition = 0;
|
|
||||||
lineNumber = 0;
|
|
||||||
}
|
|
||||||
lineNumber += std::count(source.begin() + lineDirectivePosition, source.begin() + foundPos, '\n');
|
|
||||||
|
|
||||||
// Include the file recursively
|
// Include the file recursively
|
||||||
std::ifstream includeFstream;
|
std::ifstream includeFstream;
|
||||||
@ -202,7 +195,8 @@ namespace Shader
|
|||||||
|
|
||||||
bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos)
|
bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos)
|
||||||
{
|
{
|
||||||
size_t iterNameStart = foundPos + strlen("$foreach") + 1;
|
constexpr std::string_view directiveStart = "$foreach";
|
||||||
|
size_t iterNameStart = foundPos + directiveStart.size() + 1;
|
||||||
size_t iterNameEnd = source.find_first_of(" \n\r()[].;,", iterNameStart);
|
size_t iterNameEnd = source.find_first_of(" \n\r()[].;,", iterNameStart);
|
||||||
if (iterNameEnd == std::string::npos)
|
if (iterNameEnd == std::string::npos)
|
||||||
{
|
{
|
||||||
@ -218,46 +212,32 @@ namespace Shader
|
|||||||
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string list = source.substr(listStart, listEnd - listStart);
|
std::string_view list = std::string_view(source).substr(listStart, listEnd - listStart);
|
||||||
std::vector<std::string> listElements;
|
std::vector<std::string> listElements;
|
||||||
if (list != "")
|
if (!list.empty())
|
||||||
Misc::StringUtils::split(list, listElements, ",");
|
Misc::StringUtils::split(list, listElements, ",");
|
||||||
|
|
||||||
size_t contentStart = source.find_first_not_of("\n\r", listEnd);
|
size_t contentStart = source.find_first_not_of("\n\r", listEnd);
|
||||||
size_t contentEnd = source.find("$endforeach", contentStart);
|
constexpr std::string_view directiveEnd = "$endforeach";
|
||||||
|
size_t contentEnd = source.find(directiveEnd, contentStart);
|
||||||
if (contentEnd == std::string::npos)
|
if (contentEnd == std::string::npos)
|
||||||
{
|
{
|
||||||
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string content = source.substr(contentStart, contentEnd - contentStart);
|
std::string_view content = std::string_view(source).substr(contentStart, contentEnd - contentStart);
|
||||||
|
|
||||||
size_t overallEnd = contentEnd + std::string("$endforeach").length();
|
size_t overallEnd = contentEnd + directiveEnd.size();
|
||||||
|
|
||||||
size_t lineDirectivePosition = source.rfind("#line", overallEnd);
|
int lineNumber = getLineNumber(source, overallEnd, 2, 0);
|
||||||
int lineNumber;
|
|
||||||
if (lineDirectivePosition != std::string::npos)
|
|
||||||
{
|
|
||||||
size_t lineNumberStart = lineDirectivePosition + std::string("#line ").length();
|
|
||||||
size_t lineNumberEnd = source.find_first_not_of("0123456789", lineNumberStart);
|
|
||||||
std::string lineNumberString = source.substr(lineNumberStart, lineNumberEnd - lineNumberStart);
|
|
||||||
lineNumber = Misc::StringUtils::toNumeric<int>(lineNumberString, 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lineDirectivePosition = 0;
|
|
||||||
lineNumber = 2;
|
|
||||||
}
|
|
||||||
lineNumber += std::count(source.begin() + lineDirectivePosition, source.begin() + overallEnd, '\n');
|
|
||||||
|
|
||||||
std::string replacement;
|
std::string replacement;
|
||||||
for (std::vector<std::string>::const_iterator element = listElements.cbegin(); element != listElements.cend();
|
for (const std::string& element : listElements)
|
||||||
element++)
|
|
||||||
{
|
{
|
||||||
std::string contentInstance = content;
|
std::string contentInstance(content);
|
||||||
size_t foundIterator;
|
size_t foundIterator;
|
||||||
while ((foundIterator = contentInstance.find(iteratorName)) != std::string::npos)
|
while ((foundIterator = contentInstance.find(iteratorName)) != std::string::npos)
|
||||||
contentInstance.replace(foundIterator, iteratorName.length(), *element);
|
contentInstance.replace(foundIterator, iteratorName.length(), element);
|
||||||
replacement += contentInstance;
|
replacement += contentInstance;
|
||||||
}
|
}
|
||||||
replacement += "\n#line " + std::to_string(lineNumber);
|
replacement += "\n#line " + std::to_string(lineNumber);
|
||||||
@ -327,7 +307,7 @@ namespace Shader
|
|||||||
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string directive = source.substr(foundPos + 1, endPos - (foundPos + 1));
|
std::string_view directive = std::string_view(source).substr(foundPos + 1, endPos - (foundPos + 1));
|
||||||
if (directive == "foreach")
|
if (directive == "foreach")
|
||||||
{
|
{
|
||||||
if (!parseForeachDirective(source, templateName, foundPos))
|
if (!parseForeachDirective(source, templateName, foundPos))
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define OPENMW_COMPONENTS_SHADERMANAGER_H
|
#define OPENMW_COMPONENTS_SHADERMANAGER_H
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <filesystem>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
@ -9,11 +10,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <osg/ref_ptr>
|
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <osg/Program>
|
#include <osg/Program>
|
||||||
#include <osg/Shader>
|
#include <osg/Shader>
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
namespace osgViewer
|
namespace osgViewer
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user