软件架构:OpenGL着色器创建和编译
Software Architecture: OpenGL Shader creation and compilation
我即将重构渲染引擎的某些部分,并且想知道shader是否应该真正知道它的OpenGL上下文。目前,每个着色器都有一个bind()和compileShader()方法——它们除了为实际任务调用OpenGL上下文之外什么都不做。
在着色器中实现这些方法似乎很常见-但这真的是很好的实践吗?让上下文创建、编译和绑定着色器不是更好吗?一个shader必须知道它的上下文吗?下面是一些代码片段。这里你看到shader只是调用上下文方法,因此编译可能是上下文的关注点,而不是shader本身。
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);
}
说到OpenGL和OOP编程,没有明确的答案。由于OpenGL API混合了全局状态,某些对象类型限制在单一上下文中,而其他对象类型可在多个上下文中共享,因此很难将OpenGL完美地映射到OOP模型中。
让上下文创建、编译和绑定着色器不是更好吗?
是的!事实上,OpenGL上下文作为OpenGL对象的工厂是很有意义的。
一个shader必须知道它的上下文吗?
事实上,每个OpenGL对象都应该知道与它相关的上下文。我建议通过一个专门的抽象上下文引用类来实现这一点;从这个类派生出一个单一上下文引用,它是由不可共享的对象实例化的(着色器,程序,framebuffer对象,VAOs,…)和一个共享上下文引用,它是由是共享的对象实例化的(图像,纹理,缓冲区对象,…)。
然后你应该以某种方式实现一种方法来跟踪上下文共享设置并将其映射到共享上下文引用
相关文章:
- 此代码编译良好,但文件未创建?请指出错误
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- 在VS Code中编译C / C ++时如何禁用自动创建EXE文件?
- 从编译时已知的日历日期创建"std::chrono::time_point"
- 编译时生成应在构造函数中创建的非 constexpr 对象数组
- 在编译时从 c++ 文件创建枚举
- 在编译时而不是运行时创建一个由两个字节组成的值
- 我可以在不创建项目的情况下在Visual Studio 2019中编译和运行HelloWorld.cpp吗?
- 如何在C++中创建自己的编译密钥
- 从"<Base>std::unique_ptr"创建"ClassType<std::unique_ptr>"时出现编译错误<Derived>
- 使用成员函数创建std::函数不会编译
- 有没有办法在 C++17 中创建编译时类型映射以进行类型检查?
- C++ - 我可以创建编译时变量对象吗?
- 如何为多个C++类型创建编译时检查
- 为什么和如何C++允许使用动态值创建编译时数组
- 使用整数模板参数创建编译时双精度
- 如何使用模板使用fibonacci编号创建编译时的模板/数组/矢量
- 使用 SFINAE 但不创建编译错误
- 使用可变参数模板创建编译时布尔表达式
- Visual Studio 2010创建编译代码的应用程序