私はHLSLを使用していた頃に少しのシェーダシステムを開発しました。データを使ってすべてのパラメータを指定できるので、パラメータリストとシェーダを含むXMLファイルを編集できますコードを保存した後、エンジンは自動的に再読み込みし、すべてのパラメータを再バインドします。
これはUDKのものと何も比較できませんが、かなり便利です。
私はそれは、ここにいくつかのものがあります。まず、あなたはこれらの線に沿って何かを抽象シェーダパラメータの取り扱い(結合、設定、など)にクラスを作成する必要があります。
class IShaderParameter
{
protected:
IShaderParameter(const std::string & name)
: m_Uniform(-1)
, m_Name(name)
{}
GLuint m_Uniform;
std::string m_Name;
public:
virtual void Set(GLuint program) = 0;
};
次に、静的パラメータのために、あなたは、単にこのような過負荷を作成することができます。
template < typename Type >
class StaticParameter
: public IShaderParameter
{
public:
StaticParameter(const std::string & name, const Type & value)
: IShaderParameter(name)
, m_Value(value)
{}
virtual void Set(GLuint program)
{
if (m_Uniform == -1)
m_Uniform = glGetUniformLocation(program, m_Name.c_str());
this->SetUniform(m_Value);
}
protected:
Type m_Value;
void SetUniform(float value) { glUniform1f(m_Uniform, value); }
// write all SetUniform specializations that you need here
// ...
};
同じ考え方で、「ダイナミックシェーダパラメータ」タイプを作成できます。たとえば、ライトのパラメータをシェーダにバインドできるようにするには、特殊なパラメータのタイプを作成します。そのコンストラクターで、ライトのIDを渡して、Setメソッドでライトを取得する方法を知るようにします。少しの作業では、あなたはその後、自動的にエンジンの実体に結合することができ、パラメータの全体の束(など材料パラメータ、ライトパラメータ、)
行うには最後のものは少しカスタムファイルを作成しているを持つことができますさまざまなパラメータを定義するための形式(xmlを使用)、およびローダーです。例えば、私の場合、それはこのように見えた:
<shader>
<param type="vec3" name="lightPos">light_0_position</param>
<param type="vec4" name="diffuse">material_10_diffuse</param>
<vertexShader>
... a CDATA containing your shader code
</vertexShader>
</shader>
を私のエンジンでは、「light_0_positionは、」光のパラメータを意味し、0は光のIDであり、位置が取得するためのパラメータです。パラメータと実際の値との間のバインディングはローディング時に行われ、オーバーヘッドはあまりありませんでした。
とにかく質問に答えても、これらのサンプルコードをあまり重視しないでください(HLSLとOpenGLシェーダは全く違った働きをしていますが、OpenGLの専門家はいません^^)が、うまくいけばあなたにいくつかのリードを与える:
ありがとうございました。あなたの実装(XMLの方法)は、CryEngineの人がマテリアルシステムを構築する方法と非常によく似ています。 – Raymond