我最近發現glDrawArrays在每一幀都分配和釋放大量內存。 我懷疑它與openGL profiler報告的「初始化之外的着色器編譯問題」有關。這發生在每一幀!是否應該只有一次,並且在着色器編譯之後消失?glDrawArrays在每一幀上分配內存
編輯:我也雙重檢查,我的頂點正確對齊。所以我很困惑內存驅動需要在每一幀上分配哪些內存。編輯#2:我使用VBO的和退化的三角形帶來渲染精靈和。我在每幀上傳遞幾何(GL_STREAM_DRAW)。
編輯#3:
我想我接近發行,但仍然未能解決。 如果我將相同的紋理ID值傳遞給着色器,問題會消失(請參閱源代碼註釋)。不知何故,這個問題與我認爲的片段着色器有關。
在我的sprite批處理中,我有精靈列表,我通過紋理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();
}
編輯#4:我試圖在iOS 6和Iphone5的分配和配置文件的應用程序都大得多。但是在這種情況下方法是不同的。我附上了新的截圖。
你能展示一些代碼嗎?你有沒有機會......在初始化之外編譯着色器?不要說明顯然,但着色器只需要編譯一次。 VBO還是VAO?我真的不會期待太多的內存分配回事下去,但我懷疑它更可能與在那裏你推到頂點的圖形流水線的每幀VAO。 –
我使用其他信息編輯了我的問題。我在初始化的第一步加載着色器(在任何gl調用之前)。 –
你能發表評論「setUniform」功能的代碼嗎? –