我即将重构渲染引擎的某些部分,并想知道着色器是否真的应该知道它的OpenGL上下文。目前,每个着色器都有一个bind()和compileShader()方法 - 除了为实际任务调用OpenGL上下文之外别无其他操作。
在着色器中实现这些方法似乎很常见 - 但这是非常好的做法吗?让上下文创建,编译和绑定着色器不应该更好吗?着色器是否必须知道它的背景?
下面的一些代码段。在这里您可以看到着色器只调用上下文方法,因此编译可能是上下文的关注点,而不是着色器本身。
ShaderPtr hdm::shader::fancy_lines_3d_ptr;
fancy_lines_3d_ptr->compileShader( vert_src.c_str(), frag_src.c_str(), vlayout );
void Shader::bind()
{
assert(_shaderObj);
_context.bindShader(_shaderObj);
}
void Shader::compileShader(const string &vertexSrc,
const string &fragmentSrc,
hdm::rendering::VERTEX_LAYOUT vlayout)
{
_context.compileShader(_shaderObj, vertexSrc.c_str(), vertexSrc.length(), SHADER_TYPE::ST_VERTEX);
_context.compileShader(_shaderObj, fragmentSrc.c_str(), fragmentSrc.length(), SHADER_TYPE::ST_FRAGMENT);
_context.bindAttributeLocations(vlayout, _shaderObj);
_context.linkShader(_shaderObj);
}
答案 0 :(得分:1)
对于OpenGL和OOP编程,没有明确的答案。由于OpenGL API混合全局状态的方式,某些对象类型局限于单个上下文和其他可在多个上下文之间共享的对象类型,如果不是不可能将OpenGL完美地映射到OOP模型中,则非常困难。
不应该让上下文创建,编译和绑定着色器更好吗?
是的!事实上,OpenGL上下文成为OpenGL对象的 factory 非常有意义。
着色器是否必须知道它的背景?
事实上,每个OpenGL对象都应该知道它与之相关的上下文。我建议通过专用的抽象上下文引用类来实现它;从该类派生出一个单个上下文引用,它由不可共享的对象(着色器,程序,帧缓冲对象,VAO,...)和共享上下文引用那些 可共享的对象(图像,纹理,缓冲对象......)实现。
然后你应该以某种方式实现跟踪上下文共享设置的方法并将其映射到共享上下文引用。