Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用面向对象的方法加载着色器_C++_String_Opengl - Fatal编程技术网

C++ 使用面向对象的方法加载着色器

C++ 使用面向对象的方法加载着色器,c++,string,opengl,C++,String,Opengl,我的应用程序将是一个OpenGL游戏,使用OpenGL4.2、GLFW和GLEW。问题在于如何从文件加载GLSL着色器。对于所有与着色器相关的任务,我使用名为ShadersObject的类 class ShadersObject { public: // ... private: // ... void LoadFile(string Name, string Path); string FolderPath; Shaders ShaderList; };

我的应用程序将是一个OpenGL游戏,使用
OpenGL4.2
GLFW
GLEW
。问题在于如何从文件加载GLSL着色器。对于所有与着色器相关的任务,我使用名为
ShadersObject
的类

class ShadersObject
{
public:
    // ...
private:
    // ...
    void LoadFile(string Name, string Path);
    string FolderPath;
    Shaders ShaderList;
};
该类使用
ShaderObject
s的映射来存储着色器

enum ShaderType{ Vertex = GL_VERTEX_SHADER,
                 Geometry = GL_GEOMETRY_SHADER,
                 Fragment = GL_FRAGMENT_SHADER };

struct ShaderObject
{
    const GLchar* File;
    ShaderType Type;
    GLuint Shader;
    // ...
};

typedef map<string, ShaderObject> Shaders;
我希望使用
ShaderList[Name].File中的值的另一种方法,使用
glShaderSource
glCompileShader
加载和编译着色器。其中,
glShaderSource
需要指向保存源代码的
const GLchar*
的指针。在我的例子中,这将是
&ShaderList[Name].File

不久前,我使用了
ShaderList[Name].File=Output.c_str()而不是现在不编译的行。结果是,只有指针保存在
着色器列表中
,方法退出后,源代码就消失了。这就是为什么我尝试使用
strcpy
,但此函数不接受
const GLchar*
作为参数类型


如何将读取的文件保存到类成员中?

这不是一个复杂的问题:存储字符串。将
输出
存储在
着色器对象
类中。当需要调用
glShaderSource
时,使用
string::c_str
将其转换为
const GLchar*


或者更好;不要存储它们中的任何一个;OpenGL将在着色器对象中保留着色器字符串。可以通过API从OpenGL查询着色器字符串。因此,在着色器对象中存储OpenGL已经存储的内容是毫无意义的。

这不是一个复杂的问题:存储字符串。将
输出
存储在
着色器对象
类中。当需要调用
glShaderSource
时,使用
string::c_str
将其转换为
const GLchar*


或者更好;不要存储它们中的任何一个;OpenGL将在着色器对象中保留着色器字符串。可以通过API从OpenGL查询着色器字符串。因此,在着色器对象中存储OpenGL已经存储的内容是毫无意义的。

为什么不在
ShaderObject
中将其存储为
std::string
,并在必要时使用
c_str()
?如果您想使用
strcpy()
您需要为
.File
分配内存,并将其设为非
const
。谢谢,我不明白为什么我以前没有尝试过它?!简单的解决方案。为什么不将其存储为
std::string
中的
ShaderObject
并在必要时使用
c_str()
?如果您想使用
strcpy()
您需要为
.File
分配内存,并将其设为非
const
。谢谢,我不明白为什么我以前没有尝试过它?!简单的解决方案。OpenGL是否也存储着色器的类型以便我可以查询它?@sharethis:可以。谢谢,所以我只需要存储字符串名称和OpenGL int名称以及着色器是否处于活动状态。再次感谢你!编辑:我想存储源代码,以便打开和关闭着色器。如果这很聪明,你能给我一个建议吗?@sharethis:存储源代码不会有帮助。链接程序后,除非重新链接该程序,否则对构成该程序的着色器所做的操作是无关的。而且很贵。所以没有。通过绑定/解除绑定着色器程序来打开和关闭着色器程序。如果将着色器类和程序类分开,则可以使用OpenGL API允许的功能,并将单个着色器链接到多个程序中,其中每个程序可能由一组不同的着色器组成。例如,对于使用相同的顶点变换,但使用不同的片段着色器(阴影缓冲区计算,与最终渲染过程或类似过程)来说,这很有用。OpenGL是否也存储着色器的类型,以便我可以查询它?@sharethis:可以。谢谢,因此,我只需要存储字符串名称和OpenGL int名称,以及着色器是否处于活动状态。再次感谢你!编辑:我想存储源代码,以便打开和关闭着色器。如果这很聪明,你能给我一个建议吗?@sharethis:存储源代码不会有帮助。链接程序后,除非重新链接该程序,否则对构成该程序的着色器所做的操作是无关的。而且很贵。所以没有。通过绑定/解除绑定着色器程序来打开和关闭着色器程序。如果将着色器类和程序类分开,则可以使用OpenGL API允许的功能,并将单个着色器链接到多个程序中,其中每个程序可能由一组不同的着色器组成。例如,对于使用相同的顶点变换,但使用不同的片段着色器(阴影缓冲区计算,与最终渲染过程或类似过程)非常有用。
void ShadersObject::LoadFile(string Name, string Path)
{
    string FilePath = FolderPath + Path;
    ifstream Stream(FilePath);

    if(Stream.is_open())
    {
        cout << "Loading Shader from " << FilePath << endl;

        string Output;
        Stream.seekg(0, ios::end);   
        Output.reserve(Stream.tellg());
        Stream.seekg(0, ios::beg);
        Output.assign((istreambuf_iterator<char>(Stream)),istreambuf_iterator<char>());

        // this line doesn't compile
        strcpy(ShaderList[Name].File, Output.c_str());
    }
    else cout << "Can not load Shader from " << FilePath << endl;
}