使用OpenGL的2D精灵动画技术
2D Sprite animation techniques with OpenGL
我目前正在尝试使用 OpenGL 4 设置一个 2D 精灵动画。例如,我设计了一个与Gimp一起平稳旋转的球。大约有 32 帧(4 行 8 帧)。
我的目标是在 2D 纹理中创建精灵图集,并将我的精灵数据存储在缓冲区 (VBO) 中。我的精灵矩形总是相同的(即 rect(0,0,32,32) ),但每次帧索引递增时,我的纹理坐标都会改变。
我想知道如何修改坐标。
- 由于精灵图块存储在几行上,如果看起来很难在着色器中管理它。
- 使用 glBufferSubData() 修改缓冲区内的精灵纹理坐标?
我花了很多时间在OpenGL 1.x上。几个月前我回到OpenGL,我意识到很多事情都发生了变化。不过,我会尝试几种选择,但欢迎您的建议和经验。
由于精灵图块存储在几行上,如果看起来像 很难在着色器中管理它。
不是真的,你所有的精灵都是相同的大小,所以你会得到一个完美的统一网格,从一些 1D 索引到 2D 只是一个除法和模的问题。不是很难。
但是,为什么还要将单个帧存储在 m
x n
网格中?现在,您可以将它们仅存储在一行中。但是,在现代 GL 中,我们有数组纹理。这些基本上是一组独立的 2D 图层,大小都相同。您只需通过 3D 坐标访问它们,第三个坐标是从 o 到 n-1 的图层。这非常适合您的用例,并且可以消除边界处纹理过滤/出血的任何问题,并且还可以很好地与 mipmap 配合使用(如果需要的话)。当引入数组纹理时,实现需要支持的最小层数是 64(现在要高得多),因此即使对于旧的 GPU 来说,32 帧也是小菜一碟。
一百万种方式做到这一点,但我要提出一个天真的解决方案:
创建一个具有 32(框架正方形)*2(三角形每帧正方形)*3(三角形顶点)*5(x,y,z,u,v 每个顶点)= 960 个浮点空间的 VBO。用所有精灵的顶点以每帧 2 个三角形的方式填充它。
现在根据glDrawArrays的文档,您可以指定从哪里开始以及渲染多长时间。使用此功能,您可以指定以下内容:
int indicesPerFrame = 960/32;
int indexToStart = indicesPerFrame*currentBallFrame;
glDrawArrays( GL_TRIANGLES, indexToStart, indicesPerFrame);
无需修改 VBO。现在从我的角度来看,一次只渲染 32 帧 1 帧是矫枉过正的。这个问题有更好的解决方案,但这是学习OpenGL4最简单的方法。
在 OpenGL 2.1 中,我使用的是您的第二个选项:
void setActiveRegion(int regionIndex)
{
UVs.clear();
int numberOfRegions = (int) textureSize / spriteWidth;
float uv_x = (regionIndex % numberOfRegions)/numberOfRegions;
float uv_y = (regionIndex / numberOfRegions)/numberOfRegions;
glm::vec2 uv_up_left = glm::vec2( uv_x , uv_y );
glm::vec2 uv_up_right = glm::vec2( uv_x+1.0f/numberOfRegions, uv_y );
glm::vec2 uv_down_right = glm::vec2( uv_x+1.0f/numberOfRegions, (uv_y + 1.0f/numberOfRegions) );
glm::vec2 uv_down_left = glm::vec2( uv_x , (uv_y + 1.0f/numberOfRegions) );
UVs.push_back(uv_up_left );
UVs.push_back(uv_down_left );
UVs.push_back(uv_up_right );
UVs.push_back(uv_down_right);
UVs.push_back(uv_up_right);
UVs.push_back(uv_down_left);
glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
glBufferSubData(GL_ARRAY_BUFFER, 0, UVs.size() * sizeof(glm::vec2), &UVs[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
资料来源:http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-11-2d-text/
他实现它来渲染 2D 文本,但它是相同的概念!
我希望有所帮助!
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 使用 GLUT 使用键停止动画?
- 在 Windows 8/10 技术中完全实时的屏幕捕获,没有延迟
- C++ 关于指针取消引用的技术问题
- 使用对象数组对 SFML 进行动画处理
- (SFML)按下键时,播放器构造函数未使用正确的动画进行更新
- 是否有技术原因阻止 Java 中的 final C++ 像 const 一样严格?
- 如何减慢从 BVH 文件读取的 opengl 动画?
- 如何检测是否在缓冲绘画动画中绘制最后一帧?
- 如何在 SEAL 3.1 中使用 CRT 批处理技术Microsoft?
- 从精灵表在 sfml 中为精灵制作动画
- 暴力破解技术解决以下问题
- std::complex<> in C++ 数学特殊函数:技术规范或提案
- Qt3D 骨骼动画
- ASCII 旋转光标 (TUI) 动画出现问题
- 带有 std::cout 的多线程控制台文本动画
- 使用OpenGL的2D精灵动画技术
- 什么是好的网格动画技术
- WIN32上"iPhone"风格动画的最佳2D动画库/技术?