如何一次性渲染大量彩色、旋转、缩放和平移的四边形?
我们这里讨论的是 2D 精灵,因此每个精灵有 4 个顶点(8 个 GLint)和 4 个纹理坐标(另外 8 个 GLint)。我有一个排序例程,它会输出可以一次渲染的精灵列表(它们具有相同的混合和相同的纹理,blablabla)。然而,每个精灵也有平移、旋转、缩放等。
我目前这样做(伪代码):
cdef int *vertices
cdef int *texcoords
bind_texture(texture)
set_blending_mode_and_other_blablabla(spritelist)
vertices = alloc_mem(len(sprites) * 8 * sizeof(GLint))
texcoords = alloc_mem(len(sprites) * 8 * sizeof(GLint))
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
glTexCoordPointer(2, GL_INT, 0, texcoords)
glVertexPointer(2, GL_INT, 0, vertices)
load_vertices(sprites, vertices)
load_texcoords(sprites, texcoords)
for index, sprite in spritelist:
glPushMatrix()
glColor4f(sprite.red, sprite.green, sprite.blue, sprite.alpha)
glTranslatef(int(sprite.x), int(sprite.y), 0.0)
glRotatef(sprite.rotation, 0.0, 0.0, 1.0)
glScalef(sprite.scale_x, sprite.scale_y, 1.0)
glTranslatef(-int(sprite.anchor_x), -int(sprite.anchor_y), 0.0)
glDrawArrays(GL_QUADS, 4 * i, 4)
glPopMatrix()
现在,正如您可以猜到的,这并不是很快。我想一次性把所有东西都画出来。我真的不知道如何将平移、旋转等数据传递到 OpenGL 中。如果有人能指出一两个有效的渲染路径,那就太好了。
每个精灵的确切唯一数据为:
- 颜色(红、绿、蓝、alpha)
- 比例(x 和 y 因子)
- 平移(x 和 y)
- 旋转
- Texcoords(8 个 GLint)
- 顶点(8
GLint
's)
请温柔一点,我是 OpenGL 新手。
We are talking 2D sprites here, so I have 4 vertices for each sprite (8 GLint
's) and 4 texcoords (another 8 GLint
's). I have a sorting routine which spits out lists of sprites that can be rendered in one pass (they have the same blending and same texture, blablabla). However, each sprite also has a translation, rotation, scale, etc.
I currently do this (pseudocode):
cdef int *vertices
cdef int *texcoords
bind_texture(texture)
set_blending_mode_and_other_blablabla(spritelist)
vertices = alloc_mem(len(sprites) * 8 * sizeof(GLint))
texcoords = alloc_mem(len(sprites) * 8 * sizeof(GLint))
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
glTexCoordPointer(2, GL_INT, 0, texcoords)
glVertexPointer(2, GL_INT, 0, vertices)
load_vertices(sprites, vertices)
load_texcoords(sprites, texcoords)
for index, sprite in spritelist:
glPushMatrix()
glColor4f(sprite.red, sprite.green, sprite.blue, sprite.alpha)
glTranslatef(int(sprite.x), int(sprite.y), 0.0)
glRotatef(sprite.rotation, 0.0, 0.0, 1.0)
glScalef(sprite.scale_x, sprite.scale_y, 1.0)
glTranslatef(-int(sprite.anchor_x), -int(sprite.anchor_y), 0.0)
glDrawArrays(GL_QUADS, 4 * i, 4)
glPopMatrix()
Now, as you can guess, this isn't terribly fast. I'd like to draw everything in one pass. I really have no idea how to pass the translation, rotation, etc data into OpenGL. If someone could point out an efficient render path or two that would be very nice.
The exact per-sprite unique data is:
- Color (red, green, blue, alpha)
- Scale (x and y factor)
- Translation (x and y)
- Rotation
- Texcoords (8
GLint
's) - Vertices (8
GLint
's)
Please be gentle, I'm new to OpenGL.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
将精灵信息粘贴到顶点属性中,并将它们应用到顶点着色器中。
或者,您可以将缩放、平移和旋转计算移至 CPU 上,并将每帧预变换的顶点缓冲区传递给 GPU。这将减少 GL API 调用,但代价是增加 CPU 使用率。我推荐 Eigen 或
glm
用于重型矩阵提升。编辑:着色器解决方案:
Stick your sprite info in a vertex attribute(s) and apply them in your vertex shader.
Alternatively you can move the scaling, translation, and rotation computation onto the CPU and just pass off the pre-transformed vertex buffer off to the GPU each frame. This will cut way down on GL API calls, at the cost of increased CPU usage. I'd recommend Eigen or
glm
for the heavy matrix lifting.EDIT: Shader solution: