使用顶点缓冲区对象进行 OpenGL 快速纹理绘制。这是这样做的方法吗?
我正在用 OpenGL 制作 2D 游戏。我想通过使用 VBO 来加快纹理绘制速度。
目前我使用的是立即模式。当我旋转和缩放纹理时,我正在生成自己的坐标。我还具有圆化纹理角的功能,使用多边形图元来绘制这些角。
我在想,制作一个带有纹理侧面顶点且不包含偏移的 VBO 是不是最快,这样我就可以使用 glTranslate、glScale 和 glRotate 来移动纹理的绘制位置。然后我可以使用相同的 VBO 而不做任何更改来每次绘制纹理。当我需要添加圆角坐标时,我只能更改 VBO。
这是最好的方法吗?做的过程中需要注意哪些事项呢?在现代显卡中使用 GL_TRIANGLES 代替 GL_QUADS 真的是最快吗?
感谢您的任何答复。
I am making a 2D game with OpenGL. I would like to speed up my texture drawing by using VBOs.
Currently I am using the immediate mode. I am generating my own coordinates when I rotate and scale a texture. I also have the functionality of rounding the corners of a texture, using the polygon primitive to draw those.
I was thinking, would it be fastest to make a VBO with vertices for the sides of the texture with no offset included so I can then use glTranslate, glScale and glRotate to move the drawing position for my texture. Then I can use the same VBO with no changes to draw the texture each time. I could only change the VBO when I need to add coordinates for the rounded corners.
Is that the best way to do this? What things should I look out for while doing it? Is it really fastest to use GL_TRIANGLES instead of GL_QUADS in modern graphics cards?
Thank you for any answer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了获得更好的性能,您不应使用立即模式渲染,而应使用顶点缓冲区(在 CPU 或 GPU 上)并使用 glDrawArrays 等类似方法进行绘制。通过修改纹理矩阵乘数来缩放/旋转纹理坐标不是性能问题,您只需为整个网格设置一些小值即可。这里最重要的瓶颈是将每个顶点数据(例如颜色、位置和纹理坐标)传输到 GPU,这就是 GPU 上的顶点缓冲区对象可以提供很大帮助的地方。
如果要绘制到屏幕上的网格是静态的,即设置一次并且以后不需要修改(部分)它,则只需为整个网格(包括所有角)生成一次纹理坐标。您稍后可以使用纹理矩阵乘法器修改整个网格的纹理坐标。但是,如果您想使用不同的变换来修改网格的不同部分,则必须将网格划分为多个部分。根据您的描述,我了解到您想要绘制一个圆角矩形,其中包含内部图片,这可以使用单个静态网格(每个顶点数据的列表)来完成。
最后,GL_QUADS 在现代 OpenGL 规范中也已被弃用。无论如何,它们不提供太多功能,因此您应该将 QUADS 切换为三角形或三角形条/扇形。
For better performance, you should not use immediate mode rendering, but instead use vertex buffer (on CPU or GPU) and draw using glDrawArrays etc like methods. Scaling/rotating the texture coordinates by modifying texture matrix multiplier is not a performance issue, you just set some small values for the entire mesh. The most important bottleneck here is to transfer per-vertex data (such as color, position AND texture coordinate(s)) to GPU, and that's what vertex buffer objects on the GPU can greatly help.
If the mesh that you want to draw to screen is static, that is, you set it once and do not need to modify (parts of) it later, you can generate the texture coordinates for the entire mesh, including all corners) only once. You can later modify texture coordinates for the entire mesh using texture matrix multiplier. However, if you want to modify different parts of the mesh using different transformations, you will have to divide the mesh into parts. From what you have described, I understand that you want to draw a rounded-corner rectangle which holds a picture inside, which can be accomplished using a single static mesh (a list of per-vertex data).
Lastly, GL_QUADS are also deprecated in modern OpenGL specifications. They do not offer much functionality anyway, so you should switch QUADS to triangles or triangle strips/fans.
如果要使用 VBO 绘制纹理多边形,则不仅需要为顶点创建缓冲区,还需要为纹理坐标(每个顶点一个 UV 坐标)创建缓冲区,如果要进行顶点照明(使用 glColor相反,如果没有)。在绑定预期纹理之前使用 glClientActiveTexture(GL_TEXTUREn)。在发出渲染调用之前,不要忘记对正在使用的每种缓冲区类型使用 glEnableClientState()。
If you want to draw a textured polygon using VBOs, you need to create buffers not only for the vertices, but also for the texture coordinates (one UV coordinate per vertex) and for the vertex colors if you want to do vertex lighting (use glColor instead if not). Use glClientActiveTexture(GL_TEXTUREn) before binding the intended texture. Don't forget to use glEnableClientState() for each buffer type you are using before issuing the render call.