<legend id='cZjr1'><style id='cZjr1'><dir id='cZjr1'><q id='cZjr1'></q></dir></style></legend>

    <small id='cZjr1'></small><noframes id='cZjr1'>

    1. <tfoot id='cZjr1'></tfoot>
        <bdo id='cZjr1'></bdo><ul id='cZjr1'></ul>

        <i id='cZjr1'><tr id='cZjr1'><dt id='cZjr1'><q id='cZjr1'><span id='cZjr1'><b id='cZjr1'><form id='cZjr1'><ins id='cZjr1'></ins><ul id='cZjr1'></ul><sub id='cZjr1'></sub></form><legend id='cZjr1'></legend><bdo id='cZjr1'><pre id='cZjr1'><center id='cZjr1'></center></pre></bdo></b><th id='cZjr1'></th></span></q></dt></tr></i><div id='cZjr1'><tfoot id='cZjr1'></tfoot><dl id='cZjr1'><fieldset id='cZjr1'></fieldset></dl></div>

      1. OpenGL 对象的 RAII 包装器

        时间:2023-09-18

      2. <legend id='r39Cq'><style id='r39Cq'><dir id='r39Cq'><q id='r39Cq'></q></dir></style></legend>

          <i id='r39Cq'><tr id='r39Cq'><dt id='r39Cq'><q id='r39Cq'><span id='r39Cq'><b id='r39Cq'><form id='r39Cq'><ins id='r39Cq'></ins><ul id='r39Cq'></ul><sub id='r39Cq'></sub></form><legend id='r39Cq'></legend><bdo id='r39Cq'><pre id='r39Cq'><center id='r39Cq'></center></pre></bdo></b><th id='r39Cq'></th></span></q></dt></tr></i><div id='r39Cq'><tfoot id='r39Cq'></tfoot><dl id='r39Cq'><fieldset id='r39Cq'></fieldset></dl></div>

            • <bdo id='r39Cq'></bdo><ul id='r39Cq'></ul>

              • <tfoot id='r39Cq'></tfoot>

                <small id='r39Cq'></small><noframes id='r39Cq'>

                    <tbody id='r39Cq'></tbody>
                  本文介绍了OpenGL 对象的 RAII 包装器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  我想为我注意到的 OpenGL 对象(纹理、帧缓冲区等)编写一个简单的 RAII 包装器,所有 glGen*glDelete* 函数共享相同的签名,所以我的第一次尝试是这样的:

                  I want to write a simple RAII wrapper for OpenGL objects (textures, frame buffers, etc.) I have noticed, that all glGen* and glDelete* functions share the same signature, so my first attempt was like this:

                  typedef void (__stdcall *GLGenFunction)(GLsizei, GLuint *);
                  typedef void (__stdcall *GLDelFunction)(GLsizei, const GLuint *);
                  
                  template <GLGenFunction glGenFunction, GLDelFunction glDelFunction>
                  class GLObject
                  {
                      GLuint m_name;
                  public:
                      GLObject() 
                      {  
                          glGenFunction(1, &m_name);
                      }
                  
                      ~GLObject()
                      {
                          glDelFunction(1, &m_name);
                      }
                  
                      GLuint getName() {return m_name;}
                  };
                  
                  typedef GLObject<glGenTextures, glDeleteTextures> GLTexture;
                  

                  它适用于纹理,但不适用于帧缓冲区:glGenFramebuffersglDeleteFramebuffers 函数地址在编译时未知,不能用作模板参数.所以我做了第二个版本:

                  It works fine for textures, but fails for frame buffers: glGenFramebuffers and glDeleteFramebuffers function addresses are not known at compile time, and cannot be used as template arguments. So I made second version:

                  class GLObjectBase
                  {
                      GLuint m_name;
                      GLDelFunction m_delFunction;
                  
                  public:
                      GLObjectBase(GLGenFunction genFunc, GLDelFunction delFunction)
                          : m_delFunction(delFunction)
                      {
                          genFunc(1, &m_name);
                      }
                  
                      GLuint getName()
                      {
                          return m_name;
                      }
                  
                  protected:
                      ~GLObjectBase()
                      {
                          m_delFunction(1, &m_name);
                      }
                  };
                  
                  class GLFrameBuffer : public GLObjectBase
                  {
                  public:
                      GLFrameBuffer() : GLObjectBase(glGenFramebuffers, glDeleteFramebuffers) {}
                  };
                  

                  但我不喜欢它,因为我必须在每个实例中存储在运行时不会改变的 del 函数指针.

                  But I don't like it since I have to store del function pointer in each instance that will not change at run-time.

                  如何制作仅在每个实例中存储对象名称的包装类,而无需创建一堆几乎复制粘贴的类?

                  How do I make wrapper class that stores only object name in each instance without resorting to create a bunch of almost copy-pasted classes?

                  我可以这样做:

                  template <int N>
                  class GLObject2
                  {
                      GLuint m_name;
                      static GLDelFunction glDelFunction;
                  public:
                      GLObject2(GLGenFunction genFunction, GLDelFunction delFunc)
                      {  
                          genFunction(1, &m_name);
                          if ( glDelFunction == nullptr )
                              glDelFunction = delFunc;
                          ASSERT(glDelFunction == delFunc);
                      }
                  
                      GLuint getName() {return m_name;}
                  
                  protected:
                      ~GLObject2()
                      {
                          glDelFunction(1, &m_name);
                      }
                  };
                  
                  template <int N>
                  GLDelFunction GLObject2<N>::glDelFunction = nullptr;
                  
                  class GLTexture: public GLObject2<1>
                  {
                  public:
                      GLTexture(): GLObject2<1>(glGenTextures, glDeleteTextures) {}
                  };
                  
                  class GLRenderBuffer: public GLObject2<2>
                  {
                  public:
                      GLRenderBuffer(): GLObject2<2>(glGenRenderbuffers, glDeleteRenderbuffers) {}
                  };
                  

                  谁能提出更优雅的解决方案?

                  Can anyone suggest more elegant solution?

                  推荐答案

                  真的,您会像 C 程序员一样思考这个问题.您正在使用 C++,因此请按照 C++ 程序员的方式解决它.使用特征类:

                  Really, you're thinking about this like a C programmer. You're using C++, so solve it the way a C++ programmer would. With a traits class:

                  struct VertexArrayObjectTraits
                  {
                    typedef GLuint value_type;
                    static value_type Create();
                    static void Destroy(value_type);
                  };
                  

                  就像一个适当的 C++ 特征类,我们让每个对象声明它自己的 value_type.这将允许您使其适应不使用 GLuint 的 OpenGL 对象,例如 同步对象(尽管创建/销毁界面无论如何都不适合它们,所以你可能不应该打扰).

                  Like a proper C++ traits class, we have each object declare it's own value_type. This will allow you to adapt it to OpenGL objects that don't use GLuints, like sync objects (though the Create/Destroy interface wouldn't be good for them anyway, so you probably shouldn't bother).

                  因此,您为每种类型的 OpenGL 对象编写了一个特征类.您的 CreateDestroy 函数会将调用适当地转发到 C API.

                  So you write one traits class for each type of OpenGL object. Your Create and Destroy functions will forward the calls on to the C API appropriately.

                  这样做之后,您只需要一个围绕那些接口的 RAII 包装器:

                  After doing that, all you need is a RAII-wrapper around those interfaces:

                  template<typename T>
                  class OpenGLObject
                  {
                  public:
                    OpenGLObject() : m_obj(T::Create()) {}
                    ~OpenGLObject() {T::Destroy(m_obj);}
                  
                    operator typename T::value_type() {return m_obj;}
                  
                  private:
                    typename T::value_type m_obj;
                  };
                  

                  OpenGLObject 将持有 VAO.

                  这篇关于OpenGL 对象的 RAII 包装器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:在 OpenGL 中可视化 4D 对象 下一篇:如何将 std::string 传递给 glShaderSource?

                  相关文章

                  最新文章

                        <bdo id='h0uHj'></bdo><ul id='h0uHj'></ul>
                    1. <i id='h0uHj'><tr id='h0uHj'><dt id='h0uHj'><q id='h0uHj'><span id='h0uHj'><b id='h0uHj'><form id='h0uHj'><ins id='h0uHj'></ins><ul id='h0uHj'></ul><sub id='h0uHj'></sub></form><legend id='h0uHj'></legend><bdo id='h0uHj'><pre id='h0uHj'><center id='h0uHj'></center></pre></bdo></b><th id='h0uHj'></th></span></q></dt></tr></i><div id='h0uHj'><tfoot id='h0uHj'></tfoot><dl id='h0uHj'><fieldset id='h0uHj'></fieldset></dl></div>
                    2. <tfoot id='h0uHj'></tfoot>

                      <legend id='h0uHj'><style id='h0uHj'><dir id='h0uHj'><q id='h0uHj'></q></dir></style></legend>

                      <small id='h0uHj'></small><noframes id='h0uHj'>