在 C++ 中覆盖 OpenGL 的纹理包装器

Overwriting a texture wrapper for OpenGL in C++

我正在尝试为 C++ 中的纹理包装器创建赋值运算符,但我有太多问题,我不确定该怎么做。

结构如下所示:

class Texture
{

    protected:
        GLuint textureID;   //!< OpenGL name of the texture
        GLuint target;      //!< Target of the texture (e.g GL_TEXTURE_2D)

        int color_format;   //!< The color format of the texture (e.g GL_RGBA)
        int width;          //!< width of the texture
        int height;         //!< height of the texture

        std::string file;

    public:

        Texture(){}
        Texture(std::string file_path, GLuint target);
        ~Texture();

};

还有一些内容,但并不重要。

问题具体来自 textureID 字段。该值是由 glGenTextures 返回的值,它本质上是一个用于所有给定目的的指针。

复制纹理时,我不能只复制 textureID 字段。如果我这样做,当其他对象被删除时,当前对象也会被删除,这将导致意外行为、错误、段错误和所有不好的事情。

但是,每次复制纹理非常慢,而且非常痛苦,因为您必须手动复制每个 mipmap 级别等等。 我非常关心效率,所以我尽量避免实际复制数据。

我有一个 "bad" 解决方案。大多数时候我不需要保留旧副本,因为我主要只是重新实例化纹理的值。

换句话说:

Texture t;
t = Texture(file1, target1);
t = Texture(file2, target2);

所以我的想法是在复制之前将右值中的 textureID 字段设置为 0 (nullptr)。

本质上,这通过使先前的对象无效来防止浅拷贝。这很快,可以让我做我需要的大部分事情,很容易实现。但这是非常误导的,因为声明

Texture t1, t2;

t1=t2;

也在默默地使 t2 成为无效对象。

我该怎么办?

删除复制构造函数和复制赋值运算符。定义适当的移动操作。

添加 ResetRebind 成员以用新纹理替换现有纹理

t.Reset(file1, target1);

避免创建一个临时对象 copied/moved 然后销毁。