【发布时间】:2019-09-13 11:48:23
【问题描述】:
这是一个Mesh类:
// Mesh.h
class Mesh
{
std::array<float, 144> m_CanvasVertices;
std::array<unsigned short, 36> m_CanvasIndices;
std::array<float, 24> m_SquareVertices;
std::array<unsigned short, 6> m_SquareIndices;
std::array<glm::vec2, 32> m_SquareOffsets;
Buffers::VertexBuffer* Canvas_VBO;
public:
Mesh();
void InitialiseMembers();
};
// Mesh.cpp:
Mesh::Mesh()
: m_CanvasVertices(), m_CanvasIndices(), m_SquareVertices(),
m_SquareIndices(), m_SquareOffsets(), Canvas_VBO()
{
InitialiseMembers();
Buffers::VertexBuffer aVBO(m_CanvasVertices);
Canvas_VBO = &aVBO;
}
void Mesh::InitialiseMembers()
{
m_CanvasVertices = { ... };
m_CanvasIndices = { ... };
m_SquareVertices = { ... };
m_SquareIndices = { ... };
m_SquareOffsets = { ... };
}
这是一个VertexBuffer类:
class VertexBuffer
{
unsigned int m_VBO;
public:
template<typename T, unsigned short int N>
VertexBuffer(const std::array<T, N>& data, int draw_method = GL_STATIC_DRAW)
: m_VBO(0)
{
GLFunctionCall(glGenBuffers(1, &m_VBO));
GLFunctionCall(glBindBuffer(GL_ARRAY_BUFFER, m_VBO));
if (draw_method == GL_STATIC_DRAW)
{
GLFunctionCall(glNamedBufferData(m_VBO, sizeof(data), &data, draw_method));
}
else if (draw_method == GL_DYNAMIC_DRAW)
{
GLFunctionCall(glNamedBufferData(m_VBO, sizeof(data), &data, draw_method));
}
}
template<typename T, unsigned short int N>
void UpdateDynamicData(std::array<T, N>& data) const
{
GLFunctionCall(glNamedBufferData(m_VBO, sizeof(data), &data, GL_DYNAMIC_DRAW));
}
~VertexBuffer();
void Bind() const;
void Unbind() const;
unsigned int GetBufferID() const;
};
我想在我的 Mesh 类中创建一个 VertexBuffer 对象。 Mesh 成员 Canvas_VBO 是一个 VertexBuffer 对象,因此不能在减速时实例化(我的意思是我不能在类字段)。例如,如果我想在 main.cpp 中创建对象,我可以这样做:
int main()
{
std::array<float, 144> canvas_vertices = { ... };
Buffers::VertexBuffer Canvas_VBO(canvas_vertices);
// ^ buffer generated, 'canvas_vertices' inputted to buffer data, etc...
}
但是因为Canvas_VBO是类成员,我不能用这种方式实例化对象。
在 Mesh 构造函数中,我找到了一种解决方法,我创建了一个临时对象('aVBO'),然后将成员 Canvas_VBO 的内存地址设置为这个新的创建临时对象。这似乎工作正常,但我有一种琐碎的感觉,这可能不是一个好的做法,所以在这方面寻找一些建议,即这是不好的做法吗?还有其他解决方法吗?等等等等。
【问题讨论】:
-
这是直接的未定义行为。构造函数结束后,
aVBO死亡,您的Canvas_VBO指针指向已删除的对象。new/delete可以提供帮助,但只需存储std::unique_ptr<Buffer::VertexBuffer>即可。 -
Canvas_VBO必须是指针是否有特殊原因?我在您的代码中看不到任何理由为什么它不能像其他人一样成为普通成员...... -
@Max Langhof 不,我把它变成了一个指针,因为这样可以方便地从临时对象中传输内存地址,但是正如您所指出的,当临时对象时,内存将被释放超出范围,因此此方法无用。
-
您可以将移动 ctor 和移动赋值运算符添加到
VertexBuffer,以便它可以有效地处理自身移动(如果甚至需要)。也许你应该展示一下VertexBuffer的样子? -
使它成为普通成员(非指针)的问题是我看不到任何可以在对象上调用 VertexBuffer 构造函数的方法,看到好像 m_CanvasVertices 需要作为参数传递。
标签: c++ object opengl instantiation