我正在编写一个地形引擎,它有很多大的纹理覆盖在高度图上。这些纹理是通过渲染一堆东西然后使用glCopyTexSubImage2D
命令几次生成的。
一切都很好(在速度和质量方面),但是当我制作很多(> 45 1Mpixel)时,我的帧率从60急剧下降到2左右。我的第一个想法是,有些东西(GPU或CPU)有每次渲染每个纹理时都要拉动所有百万像素,这肯定会减慢它的速度,所以我尝试了我认为的解决方案:实现 mipmapping。
因此,我将所有 rgb 值拉入一个数组并将其重新传递到gluBuild2DMipmaps
. (这不是浪费吗?我要了一些数据,然后马上把它还给我?有没有更好的方法来用我所拥有的东西来做到这一点(见下文))。
现在,中远纹理看起来很糟糕而且平淡无奇,我在速度方面也好不到哪里去。
有没有什么方法可以在加快渲染速度的同时获得更远纹理的更多细节?请记住,我使用的是 freeglut,因此仅限于 opengl 2。
[编辑:一些代码示例]
纹理的生成:
//Only executes once as then the texture is defined.
if (TextureNumber == -1)
{
glGenTextures (1, &TextureNumber);
glBindTexture(GL_TEXTURE_2D, TextureNumber);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR );
// ... Other not directly related stuff
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, TEXTURE_SIZE, TEXTURE_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
}
//The texture is built up a little bit at a time, over a number of calls.
// Do some rendering
// ...
glBindTexture(GL_TEXTURE_2D, TextureNumber);
//And copy it into the big texture
glCopyTexSubImage2D (GL_TEXTURE_2D, 0, texX * _patch_size, texY * _patch_size, 0, 0, _patch_size, _patch_size);
最后,运行一次:
unsigned char* dat = new unsigned char [TEXTURE_SIZE*TEXTURE_SIZE*3];
glBindTexture(GL_TEXTURE_2D, TextureNumber);
glGetTexImage(GL_TEXTURE_2D,0,GL_RGB,GL_UNSIGNED_BYTE,dat);
gluBuild2DMipmaps(GL_TEXTURE_2D,3,TEXTURE_SIZE,TEXTURE_SIZE,GL_RGB,GL_UNSIGNED_BYTE,dat);
finishedTexture = true;
delete[] dat;
渲染:
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glColor3f(1,1,1);
glVertexPointer( 3, GL_FLOAT, 0, VertexData);
glTexCoordPointer(2, GL_FLOAT, 0, TextureData);
glBindTexture(GL_TEXTURE_2D, TextureNumber);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glDrawElements( GL_TRIANGLES, //mode
numTri[detail], //count, ie. how many indices
GL_UNSIGNED_INT, //type of the index array
TriangleData[detail]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);