我正在用OpenGL制作一个简单的2D游戏引擎,而我的SpriteRenderer
类制作使用相同着色器或纹理的批量精灵。一旦我首先按纹理,然后按着色器,然后按深度对它们进行排序,我的uploadData()
类的SpriteRenderer
方法将CPU生成的顶点数据上传到GPU。为此,我使用的是孤立方法,据说比简单的glBufferData
调用更快。
我的问题是,当我有少量的精灵(< 15)时,我的框架有很大的档位,但是数字> 20到10 000它会顺利运行。我将opengl函数包装到c ++类中。如果我用VertexBufferObject::uploadOrphaned()
方法替换VertexBufferObject::upload()
方法,则失速消失。这是我的vbo课程:
//vbo.h
class VertexBufferObject
{
public:
VertexBufferObject();
VertexBufferObject(size_t allocSize);
~VertexBufferObject();
inline ui32 id(){ return (ui32)m_id; }
template <class T>
void addData(const T& data)
{
const byte* convertedData = reinterpret_cast<const byte*>(&data);
size_t size = sizeof(T);
for (ui32 i = 0; i < size; i++)m_data.add(convertedData[i]);
}
void initialize();
void resetData();
void upload(GLenum drawType);
void uploadOrphaned(GLenum drawType);
inline void bind() { ::glBindBuffer(GL_ARRAY_BUFFER, m_id); }
inline void unbind(){ ::glBindBuffer(GL_ARRAY_BUFFER, 0); }
private:
GLuint m_id;
//this is my custom dynamic array class, this is a hobby project
//and I enjoy reinventing the wheel :)
Array<byte> m_data;
以下是cpp文件:
VertexBufferObject::VertexBufferObject() :m_id(0)
{
}
VertexBufferObject::VertexBufferObject(size_t allocSize) : m_id(0), m_data(allocSize)
{
}
VertexBufferObject::~VertexBufferObject()
{
if (m_id != 0) ::glDeleteBuffers(1, &m_id);
}
void VertexBufferObject::initialize()
{
if (m_id == 0) ::glGenBuffers(1, &m_id);
}
void VertexBufferObject::upload(GLenum drawType)
{
glBufferData(GL_ARRAY_BUFFER, m_data.size(), &m_data[0], drawType);
}
void VertexBufferObject::uploadOrphaned(GLenum drawType)
{
glBufferData(GL_ARRAY_BUFFER, m_data.size() * 2, NULL, drawType);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_data.size(), &m_data[0]);
}
void VertexBufferObject::resetData()
{
m_data.strip();
}
我正在学习opengl,所以我的VertexBufferObject类包含了我已经知道的内容。我知道还有其他方法可以上传数据,但我想了解这个简单方法当前问题的原因。我环顾了包括这里在内的各种论坛,没有人发现我发现的类似问题。也许我的班级有一些错误?