【发布时间】:2014-08-07 01:49:07
【问题描述】:
我需要做的是在移动设备(OpenGL ES2.0,Android 4.2)上渲染一个比较大的等轴测图。我将 1 个 VBO 用于地形,1 个 VBO 用于阴影层,1 个 VBO 用于对象层。 性能是问题,即使是第一个 VBO。
这里,我有填充VBO的数据类型:
typedef struct _ovlndVertex
{
GLshort x;
GLshort y;
} ovlndVertex;
typedef struct _ovlndTexture {
GLfloat u;
GLfloat v;
} ovlndTexture;
typedef struct _TexturedVertex
{
ovlndVertex vertices;
ovlndTexture texCoords;
GLshort textureId;
} TexturedVertex;
假设我们正在渲染一个 256x256 大小的地图,每个图块 4 个顶点,这在 VBO 中为我们提供了 256x256x4 = 262144 个顶点。给定 sizeof(TexturedVertex) == 16,这是 4194304 字节的原始 VBO 数据(大约 4MB)。
主要的渲染工作在着色器中完成。这是他们的代码:
顶点着色器:
attribute vec4 a_position;
attribute vec2 a_texCoord;
//attribute vec4 a_color;
attribute vec2 a_textureId;
uniform mat4 u_MVPMatrix;
#ifdef GL_ES
//varying lowp vec4 v_fragmentColor;
varying lowp vec2 v_texCoord;
#else
//varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
varying float v_textureId;
void main()
{
gl_Position = u_MVPMatrix * a_position;
// v_fragmentColor = a_color;
v_texCoord = a_texCoord;
v_textureId = a_textureId.x;
}
片段着色器:
#ifdef GL_ES
precision lowp float;
precision lowp int;
precision lowp sampler2D;
#endif
//varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
//uniform sampler2D u_texture0, u_texture1, u_texture2;
uniform sampler2D u_textures[16];
varying float v_textureId;
uniform int u_idxOffset;
void main()
{
// strange enough, but binary search below works WAY faster than
// plain texture array referencing by index like:
// int idx = int(v_textureId) - u_idxOffset;
// gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[idx], v_texCoord);
int index = int(v_textureId) - u_idxOffset;
if(index < 8) //0-7
{
if(index < 4) // 0-4
{
if(index < 2) //0-1
{
if(index < 1)
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[0], v_texCoord);
}
else
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[1], v_texCoord);
}
} else // 2-3
{
if(index < 3)
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[2], v_texCoord);
}
else
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[3], v_texCoord);
}
}
} else //4-7
{
if(index < 6) //4-5
{
if(index < 5)
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[4], v_texCoord);
}
else
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[5], v_texCoord);
}
} else // 6-7
{
if(index < 7)
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[6], v_texCoord);
}
else
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[7], v_texCoord);
}
}
}
} else //8-15
{
if(index < 12) //8-11
{
if(index < 10) //8-9
{
if(index < 9)
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[8], v_texCoord);
}
else
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[9], v_texCoord);
}
} else // 10-11
{
if(index < 11)
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[10], v_texCoord);
}
else
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[11], v_texCoord);
}
}
} else //12-15
{
if(index < 14) //12-13
{
if(index < 13)
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[12], v_texCoord);
}
else
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[13], v_texCoord);
}
} else // 14-15
{
if(index < 15)
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[14], v_texCoord);
}
else
{
gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[15], v_texCoord);
}
}
}
}
}
是的,我知道 OpenGL ES 剔除视口外的顶点,而且效果很好。在高缩放级别上,它可以流畅地在设备上显示 60FPS,但是,如果我缩小以查看所有地图(这是主要点),即使没有对象渲染,FPS 也会下降到 20-30,而使用对象时下降到 4-5渲染(另外 2 个类似的 VBO)。
以下是典型渲染缓慢帧的 ADT OpenGL ES Tracer 输出: (挂钟时间:0.49 毫秒,线程时间 0.37 毫秒)
glClear(mask = 16640)
glUseProgram(program = 22)
glBindTexture(target = GL_TEXTURE_2D, texture = 2)
glActiveTexture(texture = GL_TEXTURE1)
glActiveTexture(texture = GL_TEXTURE2)
glActiveTexture(texture = GL_TEXTURE3)
glActiveTexture(texture = GL_TEXTURE4)
glActiveTexture(texture = GL_TEXTURE5)
glActiveTexture(texture = GL_TEXTURE6)
glActiveTexture(texture = GL_TEXTURE7)
glActiveTexture(texture = GL_TEXTURE8)
glActiveTexture(texture = GL_TEXTURE9)
glActiveTexture(texture = GL_TEXTURE10)
glActiveTexture(texture = GL_TEXTURE11)
glActiveTexture(texture = GL_TEXTURE12)
glUniform1i(location = 1, x = 0)
glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 123)
glVertexAttribPointer(indx = 0, size = 2, type = GL_SHORT, normalized = false, stride = 16, ptr = 0x0)
glEnableVertexAttribArray(index = 1)
glEnableVertexAttribArray(index = 2)
glEnableVertexAttribArray(index = 0)
glEnableVertexAttribArray(index = 3)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 16, ptr = 0x0)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 16, ptr = 0x4)
glVertexAttribPointer(indx = 3, size = 1, type = GL_SHORT, normalized = false, stride = 16, ptr = 0xc)
glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 124)
glDrawElements(mode = GL_TRIANGLES, count = 469374, type = GL_UNSIGNED_INT, indices = 0x0)
glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 0)
glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 0)
glActiveTexture(texture = GL_TEXTURE0)
glUseProgram(program = 7)
glDisableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x775470c0)
glVertexAttribPointer(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x775470e0)
glVertexAttribPointerData(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 8, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 16, ptr = 0x??, minIndex = 0, maxIndex = 4)
glBlendFunc(sfactor = GL_SRC_ALPHA, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUseProgram(program = 1)
glBlendFunc(sfactor = GL_LINES, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glBindTexture(target = GL_TEXTURE_2D, texture = 0)
glEnableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77530800)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77530810)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x7753080c)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x775295f8)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529608)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77529604)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529878)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529888)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77529884)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
eglSwapBuffers
仅供参考,这是典型的快速渲染 GUI 框架(实际上是主菜单,它给了我 60FPS): (挂钟时间:1.10MS,线程时间0.70MS)
glClear(mask = 16640)
glUseProgram(program = 7)
glDisableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x77538880)
glVertexAttribPointer(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x775388a0)
glBlendFunc(sfactor = GL_SRC_ALPHA, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glVertexAttribPointerData(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 8, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 16, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUseProgram(program = 1)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, 0.093229175, -0.17300725, 0.0, 1.0])
glBlendFunc(sfactor = GL_LINES, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glBindTexture(target = GL_TEXTURE_2D, texture = 1)
glEnableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77546f08)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77546f18)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77546f14)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.23489577, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538cb0)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538cc0)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77538cbc)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.20677078, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538f00)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538f10)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77538f0c)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.15572912, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77539150)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77539160)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x7753915c)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.1057291, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x775393a0)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x775393b0)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x775393ac)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.0567708, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77537bc0)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77537bd0)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77537bcc)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.020312428, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77537e10)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77537e20)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77537e1c)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, 0.02239585, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538060)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538070)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x7753806c)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUseProgram(program = 7)
glDisableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x77533090)
glVertexAttribPointerData(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 8, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 16, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x775330b0)
glBlendFunc(sfactor = GL_SRC_ALPHA, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUseProgram(program = 1)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -1.0, -1.0, 0.0, 1.0])
glBlendFunc(sfactor = GL_LINES, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glBindTexture(target = GL_TEXTURE_2D, texture = 0)
glEnableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77530800)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77530810)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x7753080c)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x775295f8)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529608)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77529604)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529878)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529888)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77529884)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
eglSwapBuffers
这使得 OpenGL Tracers 对我来说毫无用处,因为更快的渲染帧显示的时间(包括挂钟和线程)比慢速帧更多。这是否意味着问题隐藏在着色器的某个地方?我如何分析他们?
到目前为止我尝试了什么:
- 将所有 GLuint 更改为 GLshort 以最小化缓冲区大小(给了我 28 到 16 字节的顶点结构 sizeof 优化)
- 使用 GL_DYNAMIC_DRAW/GL_STATIC_DRAW 方法将数据发送到 VBO(对我来说没有区别)
- 尽我所能尝试使用 lowp
- 尝试了单纹理渲染(没有区别,这让我觉得着色器做得很好)
- 将 OpenGL 调用降至最低(您可以查看上面的 OGL 调用日志)
- 删除了所有可能破坏管道渲染的 glGet* 函数
有什么建议可以优化吗?
【问题讨论】:
-
缩小时无法“mip map”(下采样)?即,创建(重复)低至 1x1 的半比例版本。从底部到顶部渲染,直到时间用完,然后停止。如果您有足够的时间,这会使渲染的 VBO 总数增加 1/3 (1+1/4+1/4*1/4+1/4*1/4*1/4+... = 1+ 1/3),否则会给你快速的帧......可能会弹出一些,不知道。
-
从片段着色器的角度缩小时神奇地选择mipmap的技术是什么? OpenGL ES 不支持 textureLod() 函数。
-
我认为你需要优化你的片段着色器。你有大量的分支,着色器中的分支可能对性能非常不利。
-
我完全同意 Niklas。 SIMD 操作不能很好地处理分歧,因为同一 warp 中的单独并行任务不能同时执行不同的语句。为了避免这种情况,warp 中的每个实例都将执行片段着色器的每个分支(无论结果如何),并在事后选择正确的分支结果。我看到二进制搜索方法更快的唯一方法是由于一些编译器优化删除了您的分支语句并用便宜的算术运算替换它们,这比您以前的方法更快。
标签: android c++ optimization opengl-es-2.0 vbo