2

我正在编写一个地形引擎,它有很多大的纹理覆盖在高度图上。这些纹理是通过渲染一堆东西然后使用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);
4

1 回答 1

1

加速该代码的第一种方法是摆脱 20 年前的所有函数并将其转换为着色器。固定管道在现代硬件上可能非常不理想,并且不断向 GPU 发送数据也可能会降低性能。

请记住,我使用的是 freeglut,因此仅限于 opengl 2。

不,那不是真的。Freeglut 主要关注窗口和上下文创建,您仍然可以使用 GLLoad 或 GLEW 来获取 OGL 3.x 或 4.x 功能。

我看到的东西的快速列表:

  • 使用的固定管道状态glColor
  • 未使用/不推荐使用 VBOglVertexPointer
  • 也许最初应该使用 FBO 来填充纹理?
于 2013-06-26T13:29:05.157 回答