所以我正在开发一款游戏,我需要绘制很多相同的对象。相同的形状,相同的尺寸,相同的颜色,只是不同的位置。
现在我的设置是这样的。
我有一些类Renderer
,其中想要在屏幕上绘制的对象可以调用static void addVertex(float x, float y, float z);
,它将顶点存储到std::vector
。当每个人都完成时,static void draw();
中的Renderer
被调用,其中所有内容都被填充到VBO中并被绘制到屏幕上。
绘制看起来像这样:
void Renderer::draw() {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, _quadID);
glBufferSubDataARB(GL_QUADS, 0, _vertexBuffer.dataSize(), _vertexBuffer.toArray());
glColorPointer(4, GL_FLOAT, 0, _colorBuffer.toArray());
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, _vertexBuffer.toArray());
glDrawArrays(GL_QUADS, 0, (_vertexBuffer.size() / 3));
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
_vertexBuffer.clear();
_colorBuffer.clear();
}
其中_vertexBuffer
和_colorBuffer
属于template <class T> Buffer
类,而我的目的或多或少是托管std::vector<T>
。
通过这种设置,我可以在开始放慢速度之前在屏幕上获得大约300个内容。现在一切都是GL_QUAD。请记住,我对OpenGL有点新鲜,如果上述内容令人尴尬,我很抱歉。
如何根据类似的多边形进行改进?
答案 0 :(得分:21)
在〜现代硬件上,instancing是可行的方法。
您的想法是将几何体发送到GPU一次(一次绘制调用),指定要绘制的实例数(primCount
参数)。
然后在顶点着色器中,您可以使用内部输入变量gl_InstanceID
来了解正在渲染的实例,然后对其使用适当的变换。这种方法意味着您应该在顶点着色器中为所有实例提供转换,例如在Uniform Buffer Object中。
编辑:glVertexAttribDivisor
功能与实例化非常有用;它基本上允许一些每顶点属性和一些每个实例属性。
答案 1 :(得分:1)
OpenGL中有一些很棒的东西,名为Display list。 NeHe的制作有tutorial,应提供所有必要的信息和示例。但基本上是:
GLuint displayList; // This should be class attribute
displayList = glGenLists(1);
glNewList(displayList,GL_COMPILE);
Renderer::draw();
glEndList();
在真正的抽奖方法中:
glCallList( displayList);
每次添加/删除某些内容时,请不要忘记实现预编译的显示列表。