最近,我决定在OpenGL对象中添加一些RAII,直到我意识到这是徒劳的,并且与OpenGL作为一个国家系统的设置方式相矛盾。现在,我实际上想为涉及OpenGL对象的游戏实现一个类,如下所示:
class RenderTarget: public boost::noncopyable{
public:
virtual ~RenderTarget();
protected:
clear(const ColorSet& color);
copy_to(const RenderTarget& target) = 0;
copy_from(const RenderTarget& target) = 0;
attach(const RenderTarget& target);
detach(const RenderTarget& target);
private:
//set of opengl framebuffers/renderbuffers/etc. ?
};正如您可以看到的,我希望这个抽象包含一组opengl框架缓冲区,但是问题是,由于opengl是一台状态机,每当我想调用任何成员函数时,我都必须这样做:假设成员框架缓冲区绑定(坏),每次调用函数时调用绑定/取消绑定(昂贵),或者公开绑定()/unbind()接口(丑陋,公开OpenGL语义)。我被困在这里了。我是不是想错了?
发布于 2014-01-21 23:52:06
实际上,我的设计与您为我的一个项目讨论的类似,只是没有使用全局数组,而是有一个类作为状态机的接口,并提供了一些类似于不推荐的状态堆栈的功能。
示例绑定状态:
class FrameBufferBindState {
friend class eTB_RenderContext;
protected:
FrameBufferBindState (void) {
reset ();
}
void reset (void) {
bound = NULL;
swap_count = 0;
req_count = 0;
}
void bind (eTB_FrameBuffer* fbo);
void push (void);
void pop (void);
eTB_FrameBuffer* bound;
int swap_count;
int req_count;
std::stack <eTB_FrameBuffer *> stack;
};我有一个名为eTB_RenderContext的类,它包含引擎可以绑定的每个基本对象类的类实例(请注意,其中一些类也包含绑定本身,例如程序对象有绑定到它们的着色器对象)。
我跟踪bind (...)被调用的次数(req_count)与实际更改绑定次数(swap_count)的次数,以衡量批处理效率。我也有一个堆栈机制的绑定和状态,以使一些算法更容易。
绑定类:
VertexArrayBindState vertex_array_;
ProgramBindState program_;
FrameBufferBindState framebuffer_;
SamplerBindState* samplers_; // Minimum: 80 in GL4
TextureBindState* texture_images_; // Minimum: 80 in GL4发布于 2014-01-21 23:58:00
RAII仍然适合OpenGL中的资源管理(纹理需要in等,如果您达到游戏中的下一个级别并加载新的资产,则应该释放这些in )。这些任务很少执行,面向对象的开销对响应性的影响最小。
但是对于单个渲染和中间帧状态管理,封装造成了许多低效率(例如,为每个对象上传颜色和纹理绑定),而良好的OpenGL性能需要最小化状态变化。即使是检测和排除冗余状态变化也没有多大帮助,您需要按照排序顺序提交几何学,而不是按照某些抽象对象模型分组。
https://stackoverflow.com/questions/21270830
复制相似问题