opengl3 20k 精灵帧率慢?
opengl3 20k sprites slow framerate?
我在golang中成功制作了一个opengl 3.x动画。然而;只有在渲染 20k 纹理后,逐帧更新才明显变慢。所有精灵所做的只是从屏幕的左侧移动到右侧。请记住,它们都在彼此之上,因为我懒得随机分配位置。
我有一台更新的 PC,可以 运行 GTA5 在高设置下但不能在 opengl3 环境中显示 20k 精灵(带纹理的四边形)??
我一定是哪里做错了。也许我需要将所有顶点打包到一个 VBO 中,而不是为每个对象打包一个新的 vbo?我也绑定了每个对象。我不太确定是什么导致了这个瓶颈。有人可以帮忙吗,因为我不确定从这里到哪里去?
我附上了我的代码作为参考,任何人都可以提供一些关于在 opengl3 中加速渲染 20k 精灵的提示:
http://pastebin.com/SHQtRPn7
在不查看源代码的情况下,您应该使用一个 VBO 并为共享纹理的所有精灵组合几何图形,并使用一次绘制调用绘制它们。
我看到的一个问题是您在每一帧创建一个 vbo。我不确定您要做什么。如果您尝试更新 vbo,请改用 glBufferSubData()。每次调用 glBufferData() 都会创建一个新缓冲区,因此它肯定会比 glBufferSubData() 更昂贵。 glBufferSubData() 只是 modifies/updates 你的 vbo。这应该可以提高您的 fps。
OpenGL 调用很昂贵。你在每一帧中都做了很多一万次。相反,如果可能的话,你想做一个大的抽奖电话。如果不是,每个纹理 + 程序组合一个绘制调用。
您可以为绘制的每个对象传递一个矩阵,而不是将矩阵作为统一传递。
这段代码并不尽如人意,但它的性能比你的好几个数量级。
func (drawer *SpriteDrawer) Draw(sprites []Sprite) {
if len(sprites) == 0 {
return
}
drawer.Use()
drawer.Texture.Bind(gl.TEXTURE_2D_ARRAY)
tmp := drawer.GetTransform().To32()
drawer.camera_uniform.UniformMatrix2x3f(false, &tmp)
vertexbuffer := gl.GenBuffer()
defer vertexbuffer.Delete()
vertexbuffer.Bind(gl.ARRAY_BUFFER)
stride := int(unsafe.Sizeof(sprites[0]))
gl.BufferData(gl.ARRAY_BUFFER, stride*len(sprites), sprites, gl.STREAM_DRAW)
var transform1, transform2, texcoords, texlevel gl.AttribLocation
transform1 = 0
transform2 = 1
texcoords = 2
texlevel = 3
transform1.AttribPointer(3, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].Transform))
transform2.AttribPointer(3, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].Transform)+unsafe.Sizeof(sprites[0].Transform[0])*3)
texcoords.AttribPointer(4, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].TextureLeft))
texlevel.AttribPointer(1, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].Layer))
transform1.EnableArray()
transform2.EnableArray()
texcoords.EnableArray()
texlevel.EnableArray()
gl.DrawArrays(gl.POINTS, 0, len(sprites))
transform1.DisableArray()
transform2.DisableArray()
texcoords.DisableArray()
texlevel.DisableArray()
}
我在golang中成功制作了一个opengl 3.x动画。然而;只有在渲染 20k 纹理后,逐帧更新才明显变慢。所有精灵所做的只是从屏幕的左侧移动到右侧。请记住,它们都在彼此之上,因为我懒得随机分配位置。
我有一台更新的 PC,可以 运行 GTA5 在高设置下但不能在 opengl3 环境中显示 20k 精灵(带纹理的四边形)??
我一定是哪里做错了。也许我需要将所有顶点打包到一个 VBO 中,而不是为每个对象打包一个新的 vbo?我也绑定了每个对象。我不太确定是什么导致了这个瓶颈。有人可以帮忙吗,因为我不确定从这里到哪里去?
我附上了我的代码作为参考,任何人都可以提供一些关于在 opengl3 中加速渲染 20k 精灵的提示: http://pastebin.com/SHQtRPn7
在不查看源代码的情况下,您应该使用一个 VBO 并为共享纹理的所有精灵组合几何图形,并使用一次绘制调用绘制它们。
我看到的一个问题是您在每一帧创建一个 vbo。我不确定您要做什么。如果您尝试更新 vbo,请改用 glBufferSubData()。每次调用 glBufferData() 都会创建一个新缓冲区,因此它肯定会比 glBufferSubData() 更昂贵。 glBufferSubData() 只是 modifies/updates 你的 vbo。这应该可以提高您的 fps。
OpenGL 调用很昂贵。你在每一帧中都做了很多一万次。相反,如果可能的话,你想做一个大的抽奖电话。如果不是,每个纹理 + 程序组合一个绘制调用。
您可以为绘制的每个对象传递一个矩阵,而不是将矩阵作为统一传递。
这段代码并不尽如人意,但它的性能比你的好几个数量级。
func (drawer *SpriteDrawer) Draw(sprites []Sprite) {
if len(sprites) == 0 {
return
}
drawer.Use()
drawer.Texture.Bind(gl.TEXTURE_2D_ARRAY)
tmp := drawer.GetTransform().To32()
drawer.camera_uniform.UniformMatrix2x3f(false, &tmp)
vertexbuffer := gl.GenBuffer()
defer vertexbuffer.Delete()
vertexbuffer.Bind(gl.ARRAY_BUFFER)
stride := int(unsafe.Sizeof(sprites[0]))
gl.BufferData(gl.ARRAY_BUFFER, stride*len(sprites), sprites, gl.STREAM_DRAW)
var transform1, transform2, texcoords, texlevel gl.AttribLocation
transform1 = 0
transform2 = 1
texcoords = 2
texlevel = 3
transform1.AttribPointer(3, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].Transform))
transform2.AttribPointer(3, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].Transform)+unsafe.Sizeof(sprites[0].Transform[0])*3)
texcoords.AttribPointer(4, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].TextureLeft))
texlevel.AttribPointer(1, gl.FLOAT, false, stride, unsafe.Offsetof(sprites[0].Layer))
transform1.EnableArray()
transform2.EnableArray()
texcoords.EnableArray()
texlevel.EnableArray()
gl.DrawArrays(gl.POINTS, 0, len(sprites))
transform1.DisableArray()
transform2.DisableArray()
texcoords.DisableArray()
texlevel.DisableArray()
}