我最近发现glDrawArrays在每个帧上分配和释放大量内存。
我怀疑这与openGL分析器报告的“在初始化之外编译着色器”问题有关。那发生在每一帧!是否应该只有一次,并且在编译着色器后消失?

编辑:我还仔细检查了我的顶点是否正确对齐。所以我真的很困惑在每个帧上需要分配什么内存驱动程序。

编辑#2:我正在使用VBO和退化的三角形条来渲染精灵和。我在每一帧上传递几何图形(GL_STREAM_DRAW)。

编辑#3:

我认为我快要解决问题了,但仍然无法解决。 如果将相同的纹理id值传递给着色器,问题将消失(请参见源代码注释)。我认为这个问题与某种程度上与片段着色器有关。

在我的子画面批处理中,我有一个子画面列表,并通过纹理ID和FIFO队列渲染它们。

这是我的精灵批处理类的源代码:

void spriteBatch::renderInRange(shader& prog, int start, int count){


int curTexture = textures[start];
int startFrom = start;

//Looping through all vertexes and rendering them by texture id's
for(int i=start;i<start+count;++i){
    if(textures[i] != curTexture || i == (start + count) -1){


        //Problem occurs after decommenting this line
       // prog.setUniform("texture", curTexture-1);

         prog.setUniform("texture", 0); // if I pass same texture id everything is OK

        int startVertex = startFrom * vertexesPerSprite;
        int cnt = ((i - startFrom) * vertexesPerSprite);

        //If last one has same texture we just adding it
        //to last render call

        if(i == (start + count) - 1 && textures[i] == curTexture)
            cnt = ((i + 1) - startFrom) * vertexesPerSprite;

        render(vbo, GL_TRIANGLE_STRIP, startVertex+1, cnt-1);

        //if last element has different texture
        //we need to render it separately

        if(i == (start + count) - 1 && textures[i] != curTexture){

         //   prog.setUniform("texture", textures[i]-1);
            render(vbo, GL_TRIANGLE_STRIP, (i * vertexesPerSprite) + 1, 5);
        }


        curTexture = textures[i];
        startFrom = i;
    }
}

}
inline GLint getUniformLocation(GLuint shaderID, const string& name) {
    GLint iLocation = glGetUniformLocation(shaderID, name.data());
    if(iLocation == -1){ // shader variable not found
        stringstream errorText;
        errorText << "Uniform \"" << name << " was not found!";
        throw logic_error(errorText.str());
    }
    return iLocation;
}

void shader::setUniform(const string& name, const matrix& value) {
    GLint location = getUniformLocation(this->programID, name.data());
    glUniformMatrix4fv(location, 1, GL_FALSE, &(value[0]));
}

void shader::setUniform(const string& name, int value) {
    GLint iLocation = getUniformLocation(this->programID, name.data());
            //GLenum error =  glGetError();
    glUniform1i(iLocation, value);
            //    error =  glGetError();
}

EDIT#4:我尝试在IOS 6和Iphone5上分析应用程序,并且分配更大。但是在这种情况下,方法是不同的。我要附加新的屏幕截图。

最佳答案

通过为每个纹理创建单独的着色器,可以解决问题。
看起来驱动程序实现中的错误确实发生在所有IOS设备上(我在IOS 5/6上进行了测试)。但是,在更高型号的iPhone上,它并不那么引人注目。

在iPhone4上,性能指标从60帧/秒提高到38帧非常重要!

07-26 09:42