gpt4 book ai didi

c - OpenGL ES 2.0 + 开罗 : HUD

转载 作者:太空狗 更新时间:2023-10-29 17:25:01 26 4
gpt4 key购买 nike

我正在尝试在 ARM Linux 平台上通过用 C 语言编写的 OpenGL ES 2.0 应用程序渲染 HUD。

我目前正在使用靠近近裁剪平面放置的 2 个三角形,并将纹理平铺到它们上面。纹理是屏幕的大小,除了我渲染文本的部分外,大部分是透明的。纹理是使用Pango/Cairo生成的

如果我打开 HUD(取消对 render_ui 调用的注释),我目前会受到 50% 的性能影响(从 60fps 到 30fps)。

这是渲染 HUD 的代码:

void render_ui(OGL_STATE_T *state) {

glUseProgram(state->uiHandle);

matIdentity(modelViewMatrix);
matTranslate(modelViewMatrix, 0, 0, -0.51);

const GLfloat *mvMat2 = modelViewMatrix;

glViewport(0,0,state->screen_width, state->screen_height);

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);

glBindBuffer(GL_ARRAY_BUFFER, state->uiVB);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, state->uiIB);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, state->uiTex);
glUniform1i(_uiTexUniform, 0);

glUniformMatrix4fv(_uiProjectionUniform, 1, 0, pMat);
glUniformMatrix4fv(_uiModelViewUniform, 1, 0, mvMat2);

glVertexAttribPointer(_uiPositionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(_uiColorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(GLvoid *) (sizeof(GLfloat) * 3));
glVertexAttribPointer(_uiTexCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
(GLvoid *) (sizeof(GLfloat) * 7));

glEnableVertexAttribArray(_uiPositionSlot);
glEnableVertexAttribArray(_uiColorSlot);
glEnableVertexAttribArray(_uiTexCoordSlot);

glDrawElements(GL_TRIANGLES, uiIndicesArraySize / uiIndicesElementSize,
GL_UNSIGNED_BYTE, 0);

glDisableVertexAttribArray(_uiTexCoordSlot);
glDisable(GL_BLEND);

GLenum err;

if ((err = glGetError()) != GL_NO_ERROR)
printf("There was an error");
}

必须有更明智的方法来做到这一点。

最佳答案

在移动设备上,GPU 对混合非常敏感,这有多种原因:

  • 混合会消耗更多带宽(需要读取当前像素以将其与新像素混合)
  • 混合可以打破隐藏表面去除优化
  • 混合还可以打破基于图 block 的延迟渲染优化

简而言之,移动 GPU 喜欢不透明的多边形,讨厌透明的

请注意,屏幕上透明多边形占据的总表面也非常重要,因为大多数移动 GPU 具有“基于图 block ”的特性(当图 block / block 被透明多边形覆盖时,您可以为此失去了一些 GPU 优化)。

另外,既然你说你从 60fps 急剧下降到 30fps,我会得出结论,你的设备 GPU 正在阻塞,等待屏幕 60Hz 垂直同步交换,所以这意味着你的帧 DT 只能是16 毫秒,因此您可能只能获得 fps 值,例如:60、30、15、7.5,...

因此,如果您的帧率为 60fps,但在您的应用程序主循环中添加一些内容,这会将理论 fps 降至仅 57fps,然后由于垂直同步等待,您将突然变为 30fps。可以禁用 VSync,或者可以使用三重缓冲等技术来缓解这种情况,但是对于 OpenGLES,这样做的方式是特定于您正在使用的操作系统和硬件的……没有“官方的工作方式”在所有设备上”。

所以,了解所有这些后,我们提出了一些恢复到 60fps 的建议:

  1. 使用降低的分辨率,例如:1280x720 而不是 1920x1080,这将减少带宽使用和片段处理。当然不理想,但这可以用作确认您有带宽或片段问题的测试(如果在降低分辨率后恢复 60fps,则说明您有此类问题)
  2. 使用 16 位 (R5G6B5) 后备缓冲区而不是 32 位后备缓冲区 (R8G8B8A8),这可以减少带宽使用,但会损失一些视觉质量
  3. 减少混合表面的面积:在您的情况下,这意味着您应该按“ block ”组织文本,每个 block 尽可能适合文本,如 IOS 图片中的文本 docs : enter image description here
  4. 想办法在您的设备上禁用垂直同步/使用三重缓冲。如果您可以访问 Vivante GPU 文档(我没有),这可能会在里面进行描述。

第 3 点是最好的做法(这是我开发的大多数手机游戏所做的),但是这需要一些不可忽略的额外工作。第 1、2 和 3 点更直接,但只是“一半的解决方案”。

关于c - OpenGL ES 2.0 + 开罗 : HUD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32345164/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com