很多大纹理很慢。最好的加速方式?

时间:2013-06-26 12:59:13

标签: opengl freeglut

我正在编写一个地形引擎,它在高度图上覆盖了很多大纹理。这些纹理是通过渲染一堆东西然后使用glCopyTexSubImage2D命令几次生成的。

一切都很好(在速度和质量方面),但是当我制作了很多(> 45千像素)时,我的帧速率从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);

1 个答案:

答案 0 :(得分:1)

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

  

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

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

我看到的快速列表:

  • 使用glColor
  • 修复了管道状态
  • 没有使用VBO /与已弃用的glVertexPointer
  • 结合使用
  • 也许最初应该使用FBO来填充纹理?