В то время, когда я использовал 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 источника света, а position - параметр, который нужно получить.Связывание между параметром и фактическим значением было выполнено во время загрузки, поэтому не было больших накладных расходов.
В любом случае, я не буду отвечать, если это ответит на ваш вопрос, и не воспринимаю эти примеры кода слишком серьезно (HLSLШейдеры OpenGL работают совершенно по-другому, и я не эксперт по OpenGL ^^) но, надеюсь, это даст вам несколько подсказок:)