0

私のアプリケーションはOpenGL 4.2GLFWとを使用した OpenGL ゲームになりGLEWます。問題は、ファイルから GLSL シェーダーをロードすることです。ShadersObjectシェーダー関連のすべてのタスクに名前を付けたクラスを使用します。

class ShadersObject
{
public:
    // ...
private:
    // ...
    void LoadFile(string Name, string Path);
    string FolderPath;
    Shaders ShaderList;
};

このクラスは、 のマップを使用しShaderObjectてシェーダーを格納します。

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;

次の方法では、GLSL シェーダーのソース コードをファイルから .ini にロードする必要がありShaderObjectますShaderList。したがって、マップ内の文字列キーに名前が付けられているPathため、ファイルとNameシェーダーの を使用します。ShaderList

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;
}

別の方法として、 からの値を使用して、およびShaderList[Name].Fileを使用してシェーダーをロードおよびコンパイルします。ソースコードを保持するへのポインターが必要な場所。私の場合、これは.glShaderSourceglCompileShaderglShaderSourceconst GLchar*&ShaderList[Name].File

少し前にShaderList[Name].File = Output.c_str();、現在コンパイルされていない行の代わりに使用しました。その結果、ポインターのみが に保存されShaderList、メソッドが終了した後、ソース コードはなくなりました。というわけで使ってみたのですが、この関数は引数の型としてstrcpy受け付けません。const GLchar*

読み取ったファイルをクラス メンバーに保存するにはどうすればよいですか?

4

1 に答える 1

3

これは複雑な問題ではありません: string を保存します。クラスに保存Outputします。ShadersObjectを呼び出す必要がある場合は、 withglShaderSourceに変換します。const GLchar*string::c_str

またはさらに良いです。どちらも保存しないでください。OpenGL は、シェーダー オブジェクトにシェーダー文字列を保持します。API を介して OpenGL からシェーダー文字列を照会できます。したがって、OpenGL が既に保存しているものをシェーダー オブジェクトに保存しても意味がありません。

于 2012-08-26T12:03:43.687 に答える