所以我在一个简洁的小系统中设置我的框架,将SDL,openGL和box2D一起包装成2D游戏。
现在它是如何工作的,我创建一个“GameObject”类的对象,指定一个“源PNG”,然后它自动创建一个openGL纹理和相同尺寸的box2d体。
现在我担心如果我开始需要在屏幕上渲染许多不同的纹理。
是否可以在运行时加载我的所有精灵表,然后将它们组合成一个纹理?如果是这样,怎么样?什么是实现它的好方法(这样我就不必手动指定任何参数或任何东西)。
我想在运行时而不是预先完成它的原因是我可以轻松地将所有(或大多数)瓷砖,敌人等等一定程度地加载到这一个纹理中,因为每个级别都赢了有同样的敌人。它也使整个创作艺术过程更容易。
可能存在一些用于创建纹理图集的库(最佳打包是一个非常重要的问题)并将旧纹理坐标转换为新纹理坐标。
但是,如果你想自己做,你可能会这样做:
显然你也想检查以确保你没有做一些愚蠢的事情,比如将相同的纹理加载到地图集中两次,但这是一个在此过程之外的问题。
要从源图像“复制”(复制)到目标图像,您可以执行以下操作(假设您将128x128纹理复制到512x512图集纹理,从目标上的(128,0)开始):
unsigned char* source = new unsigned char[ 128 * 128 * 4 ]; // in reality, comes from your texture loader
unsigned char* target = new unsigned char[ 512 * 512 * 4 ];
int targetX = 128;
int targetY = 0;
for(int sourceY = 0; sourceY < 128; ++sourceY) {
for(int sourceX = 0; sourceX < 128; ++sourceX) {
int from = (sourceY * 128 * 4) + (sourceX * 4); // 4 bytes per pixel (assuming RGBA)
int to = ((targetY + sourceY) * 512 * 4) + ((targetX + sourceX) * 4); // same format as source
for(int channel = 0; channel < 4; ++channel) {
target[to + channel] = source[from + channel];
}
}
}
这是一个非常简单的暴力实现:有更快,更简洁和更聪明的方法来复制数组,但想法是你基本上将源纹理的内容复制到给定X和Y的目标纹理中偏移。最后,您将创建一个包含旧纹理的新纹理。
如果索引数学对你没有意义,那么考虑一下how a 2D array is actually indexed inside a 1D space(比如计算机内存)。
请原谅任何错误。这不是生产代码,而是我编写的内容,而不检查它是否编译或运行。
既然你正在使用SDL,我应该提到它有一个很好的功能,可以帮助你:SDL_BlitSurface
。您可以完全在SDL中创建SDL_Surface
,只需使用SDL_BlitSurface
将源表面复制到其中,然后使用convert the atlas surface into a GL texture。
它会处理所有数学运算,也可以为您进行格式转换。