【发布时间】:2010-11-05 15:45:45
【问题描述】:
我正在使用 C++ 开发行星生成工具,目前我正在尝试生成纹理和高度图。
我为此使用了 3d perlian 噪声函数,因此每次生成纹理或高度图时,我都会计算球体表面上每个顶点的噪声函数值。
这些坐标不会改变。最初我是通过使用this method 将立方体映射到球体来计算这些的。
然后我想好,如果我知道这些值每次都相同,为什么不计算一次并将它们输出到可以定义为静态数组的头文件。
我想创建 512x512 的纹理,这意味着 每个面会生成 260,000+ 个坐标 :(
结果坐标存储在一个数组中:
float textureMapSaved[6][512][512][3] = {etc};
由于立方体有 6 个面,每个面512x512 像素 和3 个坐标(x、y 和 z)。
这有望让我在数组中循环获取我感兴趣的 perlian 噪声函数中的值的坐标。
到目前为止,我只是设法将我的电脑变成了一个令人哭泣的烂摊子。
我的问题是:
有可行的方法吗?
在不创建输出文件的情况下,程序需要大约 15 分钟来计算球体。我实际上无法使用标头进行编译,它使我的计算机崩溃了。
然后我尝试了 256x256,效果稍微好一点,但我的电脑仍然卡壳;我猜这是因为它无法有效地为 4D 数组分配内存。
感谢您的快速回复!
目前我正在做以下事情:
std::vector<std::vector<std::vector<std::vector<float>>>> textureFaces = GenerateSphereCoordinates(TEXTURE_MAP);
std::ofstream myfile;
myfile.open ("spheremapping.h");
myfile << "#ifndef _SPHEREMAP \n#define _SPHEREMAP \n\nfloat textureMapSaved[6][" << textureRes << "][" << textureRes << "][3] = {";
for(int i = 0; i < 6; i++)
{
myfile << "{";
for(int j = 0; j < textureRes; j++)
{
myfile << "{";
for(int k = 0; k < textureRes; k++)
{
if(k != textureRes - 1)
{
myfile << "{ " << textureFaces[i][j][k][0] << ", " << textureFaces[i][j][k][1] << ", " << textureFaces[i][j][k][2] << "}, " ;
}
else
{
myfile << "{ " << textureFaces[i][j][k][0] << ", " << textureFaces[i][j][k][1] << ", " << textureFaces[i][j][k][2] << "}" ;
}
}
if(j != textureRes - 1)
{
myfile << "}, \n";
}
else
{
myfile << "} \n";
}
}
if(i != 5)
{
myfile << "}, \n\n";
}
else
{
myfile << "} \n\n";
}
}
myfile << "};\n\n#endif";
myfile.close();
如何将其保存为二进制文件并直接读入内存?
【问题讨论】:
-
这个数组只有大约 16MB 的大小。只要它是静态分配的(使用
static或通过将其放置在命名空间范围内)或动态分配(使用new),并且只要您没有耗尽内存或没有足够大的连续块来容纳它,分配本身不应该成为瓶颈。 -
如果它使您的计算机崩溃,您可能做错了什么。正如詹姆斯所说,这并不是一个真正的大数组。邮政编码。
-
那么,你有没有生成头文件呢?还是仅仅计算纹理贴图就需要 15 分钟?如果花费了这么长时间并且您已经生成并包含了标头,我怀疑预处理器没有很好地处理大量的头文件。
-
那个数组大约有 18M 的内存。 6*512*512*3*sizeof(float) / 1024 /1024 = 18。在堆栈上分配它可能不是一个好主意,因为这样大小的堆栈帧可能存在编译器限制。
-
所以,你想预先计算一些值,将它们存储在一个数组中,然后使用它们。你的问题在哪里?预计算似乎很慢,编译器崩溃时无法使用存储的值,并且您正在通过循环访问这些数组值......所以,我确定我没有正确理解您的问题。 ..
标签: c++ arrays memory-management static floating-point