c++ - 解耦自定义用户数据

标签 c++ design-patterns shader decoupling

我有一个自定义着色器生成:

class My_UniformInt { public:
    std::string idName;
    int glsl_id;  //<-- userData-like field
};
class My_Shader{ public:
    My_UniformInt textureCoordinate;
    public: My_Shader(){
        textureCoordinate.idName="textureCoordinate";
    }
};
void registerUniform( My_Shader& shader, My_UniformInt & uniInt){
    uniInt.glsl_id=5; 
    //vec3.glsl_id=glGetUniformLocation(uniInt.idName);
}
void passUniformInt( My_Shader& shader, My_UniformInt & uniInt,int k){
    std::cout<<"successfully pass name="<<uniInt.idName<<" va="<<k<<std::endl;
    //glUniform1i(uniInt.glsl_id,k);
}

我可以生成着色器并像这样使用它:

int main(){
    My_Shader shader;
    registerUniform( shader , shader.textureCoordinate ) ;
    //.. several frame later
    passUniformInt( shader , shader.textureCoordinate ,  5 ) ;
    return 0;
}

它运行速度很快(MCVE),但存在不良耦合。
1. My_UniformInt缓存 glsl 特定变量 ( glsl_id )。
2. My_UniformInt也对glGetUniformLocation情有独钟.

如何制作My_UniformInt在不牺牲速度的情况下更独立?

我有几个案例有类似的问题。不幸的是,最明显的选择通常似乎是添加更多类似 userData 的字段。它增加了耦合。

我糟糕的解决方案:

  1. 制作glsl_id作为void* userData , 然后分配 userData=new int()
    不酷+有一点成本+需要稍后删除。

  2. 创建 map std::map<My_UniformInt*,int glsl_id> .不过我负担不起。

最佳答案

这是我的评论作为回答:

我认为您应该尝试将使用 API 的代码包装在自己的空间中,以便以后可以轻松交换 - 创建一个为您访问 API 的类,如果您想切换后端,只需调整该类.以不使用任何特定于 API 的代码或变量的方式构建其余代码,而是使用包装器与其交互。

我认为这通常是处理任何类型的库或任何东西的好方法。它允许您通过不依赖它们提供的任何类型的接口(interface),而仅依赖于您自己的接口(interface)来快速适应其中的变化。挑战在于以提供良好抽象的方式编写包装器,这样您就可以理想地使用另一个使用完全不同接口(interface)的后端,同时尽量做到原生以确保低开销。

关于c++ - 解耦自定义用户数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57439614/

相关文章:

c++ - 线程不刷新数据,无法从标准输入获取所有数据

c++ - 为什么 new (*)[2] 被禁止?

c++ - c/c++中用函数指针模仿OO,如何存储?

python - 按照设计,属性 getter 是否应该在 python 中抛出异常?

ipad - 顶点着色器中的纹理查找在 iPad 设备和 iPad 模拟器上的行为不同 - OpenGL ES 2.0

c++ - 不同硬件上的不同 OpenGL 行为

c++ - 内存集的功能

java - 根据类型检索随机值的方法

opengl - 优化 OpenGL 片段着色器

c++ - 在 C++ 中使用映射器处理派生类创建