Fix UTF-8 shader path support

Work around osg::Shader::loadShaderFromSourceFile ’s lack of UTF-8
support by loading using our own istream, and then setting the text
directly.
This commit is contained in:
James Turner 2020-03-14 20:32:03 +00:00
parent 72af950573
commit c3a169319c

View File

@ -81,6 +81,8 @@
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/props/vectorPropTemplates.hxx> #include <simgear/props/vectorPropTemplates.hxx>
#include <simgear/io/iostreams/sgstream.hxx>
namespace simgear namespace simgear
{ {
using namespace std; using namespace std;
@ -97,6 +99,25 @@ void UniformFactoryImpl::reset()
uniformCache.clear(); 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<Uniform> UniformFactoryImpl::getUniform( Effect * effect, ref_ptr<Uniform> UniformFactoryImpl::getUniform( Effect * effect,
const string & name, const string & name,
Uniform::Type uniformType, Uniform::Type uniformType,
@ -829,7 +850,7 @@ void reload_shaders()
Shader *shader = sitr->second.get(); Shader *shader = sitr->second.get();
string fileName = SGModelLib::findDataFile(sitr->first.first); string fileName = SGModelLib::findDataFile(sitr->first.first);
if (!fileName.empty()) { if (!fileName.empty()) {
shader->loadShaderSourceFromFile(fileName); loadShaderFromUTF8File(shader, fileName);
} }
else else
SG_LOG(SG_INPUT, SG_ALERT, "Could not locate shader: " << fileName); SG_LOG(SG_INPUT, SG_ALERT, "Could not locate shader: " << fileName);
@ -953,7 +974,7 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
} else { } else {
ref_ptr<Shader> shader = new Shader(stype); ref_ptr<Shader> shader = new Shader(stype);
shader->setName(fileName); shader->setName(fileName);
if (shader->loadShaderSourceFromFile(fileName)) { if (loadShaderFromUTF8File(shader, fileName)) {
program->addShader(shader.get()); program->addShader(shader.get());
shaderMap.insert(ShaderMap::value_type(skey, shader)); shaderMap.insert(ShaderMap::value_type(skey, shader));
} }