Tôi muốn viết một trình bao bọc RAII đơn giản cho các đối tượng OpenGL (kết cấu, bộ đệm khung hình, v.v.) Tôi đã nhận thấy rằng tất cả các hàm glGen*
và glDelete*
đều có cùng chữ ký, vì vậy lần thử đầu tiên của tôi giống như thế này :RAII wrapper cho các đối tượng OpenGL
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;
Nó hoạt động tốt cho kết cấu, nhưng không cho bộ đệm khung: glGenFramebuffers
và glDeleteFramebuffers
địa chỉ chức năng không được biết đến tại thời gian biên dịch, và không thể được sử dụng như các đối số mẫu. Vì vậy, tôi đã thực hiện phiên bản thứ hai:
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) {}
};
Nhưng tôi không thích vì tôi phải lưu trữ con trỏ hàm del trong mỗi trường hợp sẽ không thay đổi trong thời gian chạy.
Làm cách nào để tạo lớp trình bao bọc chỉ lưu trữ tên đối tượng trong mỗi trường hợp mà không cần phải tạo một loạt các lớp được sao chép gần như sao chép?
tôi có thể làm một cái gì đó như thế này:
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) {}
};
bất cứ ai có thể đề xuất giải pháp thanh lịch hơn?
IMHO, API OpenGL có lẽ không hoàn toàn hợp nhất cho loại tiếp cận chung này rất thành công. Các thế hệ tính năng khác nhau đã sử dụng các phương pháp thiết kế API khác nhau. – Trillian
@Trillian: Vô nghĩa. Trong số 12 loại đối tượng OpenGL, [chỉ có 3 sử dụng methadologies không phá hủy/tạo tiêu chuẩn] (http://www.opengl.org/wiki/OpenGL_Object#Non-standard_objects). Đây là một ý tưởng tồi vì những lý do khác, nhưng không phải vì lý do đó. –
@NicolBolas: Hết sức tò mò: Điều gì khiến ý tưởng này trở nên tồi tệ? Và bạn có trả lời do đó một phần của quyết định xấu này hay bạn sẽ giới thiệu nó? – Skalli