软件架构:OpenGL Shader 创建和编译

Posted

技术标签:

【中文标题】软件架构:OpenGL Shader 创建和编译【英文标题】:Software Architecture: OpenGL Shader creation and compilation 【发布时间】:2016-10-09 11:19:30 【问题描述】:

我即将重构渲染引擎的某些部分,并且想知道着色器是否真的应该知道它是 OpenGL 上下文。目前,每个着色器都有一个 bind() 和 compileShader() 方法——它们除了为实际任务调用 OpenGL 上下文之外什么都不做。

在着色器中实现这些方法似乎很常见——但这真的是一种好的做法吗?让上下文创建、编译和绑定着色器不是更好吗?着色器是否必须知道它的上下文?

下面是一些代码sn-ps。在这里,您看到着色器只调用上下文方法,因此编译可能是上下文的问题,而不是着色器本身。

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

【问题讨论】:

为什么投反对票? 【参考方案1】:

对于 OpenGL 和 OOP 编程,无法给出明确的答案。由于 OpenGL API 混合全局状态的方式,某些对象类型仅限于单个上下文,而其他对象类型可在多个上下文之间共享,即使不是不可能,也很难将 OpenGL 完美地映射到 OOP 模型中。

让上下文创建、编译和绑定着色器不是更好吗?

是的!事实上,将 OpenGL 上下文作为 OpenGL 对象的 工厂 非常有意义。

着色器是否必须知道它的上下文?

事实上,每个 OpenGL 对象都应该知道与其相关的上下文。我建议通过专用的抽象上下文引用类来实现它;从该类派生一个由不可共享的对象(着色器、程序、帧缓冲区对象、VAO...)实例化的单个上下文引用和一个由以下实例实例化的共享上下文引用 可共享的对象(图像、纹理、缓冲区对象……)。

然后您应该以某种方式实现一种方法来跟踪上下文共享设置并将其映射到共享上下文引用中。

【讨论】:

以上是关于软件架构:OpenGL Shader 创建和编译的主要内容,如果未能解决你的问题,请参考以下文章

初识OpenGL 编译着色器

OpenGL Shader Key Points

android使用GLSurfaceView搭建OpenGL环境

android使用GLSurfaceView搭建OpenGL环境

C#开发的OpenRA的Shader加载编译和设置使用

C#开发的OpenRA的Shader加载编译和设置使用