在OpenGL中使用着色器绘制精灵表的技术
Techniques for drawing spritesheets in OpenGL with shaders
我现在正在学习OpenGL,我想从精灵表中绘制一些精灵到屏幕。我不确定我这样做是否正确。
我想做的是用瓷砖建造一个世界(la Terraria)。这意味着所有构建我的世界的贴图都是1x1,但我以后可能会想要2x1、1x2、2x2等实体。
我现在做的是,我有一个名为"Tile"的类,其中包含Tile的变换矩阵和指向其缓冲区的指针。非常简单:
Tile::Tile(glm::vec2 position, GLuint* vbo)
{
transformMatrix = glm::translate(transformMatrix, glm::vec3(position, 0.0f));
buffer = vbo;
}
然后当我绘制贴图时,我只需绑定缓冲区并更新着色器的uv坐标和顶点位置。之后,我将贴图的变换矩阵传递给着色器,并使用glDrawElements:
绘制它。glEnableVertexAttribArray(positionAttrib);
glEnableVertexAttribArray(textureAttrib);
for(int i = 0; i < 5; i++)
{
glBindBuffer(GL_ARRAY_BUFFER, *tiles[i].buffer);
glVertexAttribPointer(positionAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
glVertexAttribPointer(textureAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
glUniformMatrix4fv(transformMatrixLoc, 1, GL_FALSE, value_ptr(tiles[i].transformMatrix));
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
}
glDisableVertexAttribArray(positionAttrib);
glDisableVertexAttribArray(textureAttrib);
我能更有效率地做这件事吗?我在想,我可以有一个缓冲1x1瓷砖,一个缓冲2x1瓷砖等,然后只是有瓷砖类包含UVpos和UVsize,然后只是把它们发送到着色器,但我不确定我怎么做。
我认为我所描述的为1x1和2x1分别设置一个缓冲区听起来会快得多。
我能更有效率地做这件事吗?
我不认为你可以做更有效率。你为每个四元绑定了一个完整的缓冲区对象。然后你上传一个矩阵。
平铺图绘制的方式(只有map,而不是实体)通常是构建一个包含可见屏幕平铺图的一部分的缓冲对象。空的空间被渲染成透明的贴图。然后在一个绘图调用中呈现屏幕该区域的所有贴片。您为该区域中的所有瓷砖提供一个矩阵。通常情况下,您将有一些这样的可见区域,以便在该区域更改时轻松更新该区域的tile。离开屏幕的区域被重新用于出现在屏幕上的区域,因此您可以用新的平铺数据填充它们。
相关文章:
- OpenGL 着色器不绘制任何东西 - 糟糕的精灵类
- 绘制精灵会导致分割错误
- OpenGL 2D游戏只绘制第二个精灵纹理而不是第一个
- 为什么该代码不绘制精灵C++ SFML
- 仅使用精灵绘制
- 在绘制循环中绘制精灵
- OpenGL精灵绘制质量低
- OpenGL-快速精灵绘制-需要一些指导
- 如何在cocos2d-x3测试版中围绕精灵绘制边界框
- 尝试绘制精灵地图时出现 SFML 错误
- C++SFML精灵没有绘制,但是没有出现错误
- 未在指定位置绘制的精灵
- 在 cocos2d-x v3 中绘制并向场景添加大量精灵(~200)的最佳方法是什么?
- 无法从 Direct2D png 使用 DirectX9 绘制图像精灵
- OpenGL没有绘制我的纹理精灵
- 精灵批次只绘制第一个精灵
- 使用 directX 10 绘制大型精灵时性能低下
- SFML在另一个类中绘制移动精灵
- c++ SFML精灵不能通过类绘制
- SFML只绘制一些精灵