[英]Framebuffer FBO render to texture is very slow, using OpenGL ES 2.0 on Android, why?
[英]Slow OpenGL ES Render-to-texture ping pong with FBO on Android
我使用Qt進行了渲染到紋理的測試,同時在macOS和Android上運行它。 該測試創建2個紋理和一個FBO,然后在循環中將交替的紋理附加為渲染目標。 在Android上,代碼出奇地慢。 在Samsung Galaxy Tab S上,它的速度比Mac上慢30-40倍,因此我懷疑出現了問題。 片段着色器中的實際代碼似乎無關緊要。
在glBindFramebuffer之后添加glClear會使它更快一些,但仍然很慢。 關於在哪里尋找原因的任何線索?
// create textures
glEnable(GL_TEXTURE_2D);
GLuint tex1, tex2;
// define texture properties
glGenTextures(1, &tex1);
glBindTexture(GL_TEXTURE_2D, tex1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_EXT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER_EXT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1280, 800, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// define texture properties
glGenTextures(1, &tex2);
glBindTexture(GL_TEXTURE_2D, tex2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_EXT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER_EXT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1280, 800, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// create framebuffer
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glClear(GL_COLOR_BUFFER_BIT);
// create program
QGLShaderProgram program;
program.addShaderFromSourceFile(QGLShader::Fragment, ":/shaders/fshader.glsl");
program.addShaderFromSourceFile(QGLShader::Vertex, ":/shaders/vshader.glsl");
program.link();
program.bind();
//
float vertices[16];
int i = 0;
vertices[i++] = 0.0f; vertices[i++] = 0.0f; vertices[i++] = 0.0; vertices[i++] = 1.0;
vertices[i++] = 0.0f; vertices[i++] = 1280.0f; vertices[i++] = 0.0; vertices[i++] = 0.0;
vertices[i++] = 1280.0f; vertices[i++] = 0.0f; vertices[i++] = 1.0; vertices[i++] = 1.0;
vertices[i++] = 1280.0f; vertices[i++] = 1280.0f; vertices[i++] = 1.0; vertices[i++] = 0.0;
int vertexLocation = program.attributeLocation("a_position");
program.enableAttributeArray(vertexLocation);
glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), (const void *)vertices);
int texcoordLocation = program.attributeLocation("a_texcoord");
program.enableAttributeArray(texcoordLocation);
glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), (const void *)(vertices + 2));
QMatrix4x4 textureMatrix, modelViewMatrix;
// do loop test
int count = 10000;
bool swapped = false;
cout << "Start fbo test" << endl;
QTime myTimer;
myTimer.start();
textureMatrix.setToIdentity();
program.setUniformValue("textureMatrix", textureMatrix);
modelViewMatrix.setToIdentity();
program.setUniformValue("modelViewProjectionMatrix", modelViewMatrix);
program.setUniformValue("srcTex", 0);
for(int i = 0; i < count; i++)
{
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, swapped? tex2 : tex1, 0);
// check completeness
GLenum status;
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE:
break;
default:
log("Framebuffer error");
}
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, swapped? tex1 : tex2);
// draw slab
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
swapped = !swapped;
}
這是頂點着色器:
#ifdef GL_ES
// Set default precision to medium
precision mediump int;
precision mediump float;
#endif
uniform mat4 modelViewProjectionMatrix;
uniform mat4 textureMatrix;
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main()
{
// Calculate vertex position in screen space
gl_Position = modelViewProjectionMatrix* a_position;
v_texcoord = vec4(textureMatrix * vec4(a_texcoord, 0.0, 1.0)).xy;
}
和片段着色器:
#ifdef GL_ES
// Set default precision to medium
precision mediump int;
precision mediump float;
#endif
uniform sampler2D srcTex;
varying vec2 v_texcoord;
void main(void)
{
vec4 f = texture2D(srcTex, v_texcoord);
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
使用兩個FBO,每個FBO都綁定到單獨的紋理,而不是在循環內交換。 調用glClear()
后glBindFramebuffer()
循環中,如果你不希望保留在質地的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.