GLSL 着色器编译因不存在的字符而失败

问题描述 投票:0回答:1

我一直在关注 LearnOpenGL.com 的 C++ 教程,但由于我不喜欢将着色器手动硬编码到代码中,所以我编写了一个从文件中读取着色器的函数:

const char* ReadShader(const char* p_ShaderLocation)
{
    std::ifstream ShaderStream;
    std::stringstream Buffer;

    ShaderStream.open(p_ShaderLocation);

    if (!ShaderStream)
    {
        std::cout << "File: " << p_ShaderLocation << " can't be opened!" << '\n';
        return 0;
    }

    if (ShaderStream.is_open())
    {
        Buffer << ShaderStream.rdbuf();
        ShaderStream.close();
        return Buffer.str().c_str();
    }
    else if (!ShaderStream.is_open())
    {
        std::cout << "File: " << p_ShaderLocation << " can't be read!" << '\n';
        return 0;
    }
}

我第一次尝试它,它给了我这个编译错误:

ERROR: Vertex Shader Compilaton Failed
ERROR: 0:2: 'Ç' : unexpected token
ERROR: 0:2: '' : compilation terminated
ERROR: 2 compilation errors.  No code generated.


ERROR: Fragment Shader Compilaton Failed
ERROR: 0:2: '' :  syntax error, unexpected IDENTIFIER
ERROR: 1 compilation errors.  No code generated.

我不知道是什么原因造成的,但我认为这与 ReadShader 函数有关。 此外,着色器与教程中的着色器完全相同。

c++ glsl
1个回答
0
投票

而不是

const char* ReadShader(const char* p_ShaderLocation) 
{
    return Buffer.str().c_str();
}

std::string ReadShader(const char* p_ShaderLocation)
{
    return { Buffer.str() };
}

另请参阅 https://en.cppreference.com/w/cpp/io/basic_stringstream/str

注释

str
返回的基础字符串的副本是一个临时对象,将在表达式末尾被破坏,因此直接对
c_str()
的结果调用
str()
(例如在
auto *ptr = out.str().c_str();
中)会导致悬空指针。

将着色器代码作为字符串对象后,您可以将代码传递给 gl 函数,如下所示:

auto shader_src = ReadShader();
GLint shader_src_length = shader_src.length();
const char *shader_src_str = shader_src.c_str();
glShaderSource(shader, 1, &shader_src_str, &shader_src_length /* or nullptr */);
© www.soinside.com 2019 - 2024. All rights reserved.