From c3a169319c0a21f24a599a23631a4acc00509322 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sat, 14 Mar 2020 20:32:03 +0000 Subject: [PATCH] Fix UTF-8 shader path support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Work around osg::Shader::loadShaderFromSourceFile ’s lack of UTF-8 support by loading using our own istream, and then setting the text directly. --- simgear/scene/material/Effect.cxx | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index 44f15a7f..57f6ac29 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -81,6 +81,8 @@ #include #include +#include + namespace simgear { using namespace std; @@ -97,6 +99,25 @@ void UniformFactoryImpl::reset() uniformCache.clear(); } +// work around the fact osg::Shader::loadShaderFromSourceFile does not +// respect UTF8 paths, even when OSG_USE_UTF8_FILENAME is set :( +bool loadShaderFromUTF8File(osg::Shader* shader, const std::string& fileName) +{ + sg_ifstream inStream(SGPath::fromUtf8(fileName), std::ios::in | std::ios::binary); + if (!inStream.is_open()) + return false; + + string shaderSource; + while (!inStream.eof()) { + char bytes[8192]; + inStream.read(bytes, 8192); + shaderSource.append(bytes, inStream.gcount()); + } + inStream.close(); + shader->setShaderSource(shaderSource); + return true; +} + ref_ptr UniformFactoryImpl::getUniform( Effect * effect, const string & name, Uniform::Type uniformType, @@ -829,7 +850,7 @@ void reload_shaders() Shader *shader = sitr->second.get(); string fileName = SGModelLib::findDataFile(sitr->first.first); if (!fileName.empty()) { - shader->loadShaderSourceFromFile(fileName); + loadShaderFromUTF8File(shader, fileName); } else SG_LOG(SG_INPUT, SG_ALERT, "Could not locate shader: " << fileName); @@ -953,7 +974,7 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass, } else { ref_ptr shader = new Shader(stype); shader->setName(fileName); - if (shader->loadShaderSourceFromFile(fileName)) { + if (loadShaderFromUTF8File(shader, fileName)) { program->addShader(shader.get()); shaderMap.insert(ShaderMap::value_type(skey, shader)); }