我在golang中成功制作了一个opengl 3.x动画。然而;只有在渲染20k纹理后,逐帧更新才会明显变慢。所有的精灵都只是从屏幕的左侧移动到右侧。请记住,他们都是彼此之上的,因为我太懒了,无法随机定位。
我有一台更新的PC可以在高设置下运行GTA5,但是在opengl3环境中无法显示20k精灵(带纹理的四边形)?
我必须在这里做错事。也许我需要将所有顶点打包在一个VBO而不是每个对象的新vbo中?我也绑定了每个对象。我不确定是什么导致了这个瓶颈。有人可以帮忙,因为我不确定从哪里开始?
我已经附加了我的代码作为参考,可以提供一些关于加速在opengl3中渲染20k精灵的提示: http://pastebin.com/SHQtRPn7
答案 0 :(得分:2)
不看源代码,你应该使用一个VBO,并为所有共享纹理的精灵组合几何,并使用一个绘制调用绘制它们。
答案 1 :(得分:2)
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()
}
答案 2 :(得分:1)
我看到的一个问题是你每帧都在创造一个vbo。我不确定你要做什么。如果您尝试更新vbo,请改用glBufferSubData()。每次调用glBufferData()时都会创建一个新的缓冲区,因此它肯定比glBufferSubData()更昂贵。 glBufferSubData()只是修改/更新你的vbo。这应该可以提升你的fps。