bounty将在5天内到期。回答此问题可获得+100声望奖励。Myles Hollowed正在寻找一个答案从一个有信誉的来源。
我正在尝试为使用GLESv 2的Android应用程序构建一个覆盖层。为了在帧完成之前插入渲染代码,我已经挂接了eglSwapBuffers
。
我可以做一些简单的事情,比如用剪刀测试画一个正方形:
glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, 200, 200);
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
我也用下面的代码成功地绘制了简单的形状,但是一旦我开始使用顶点属性指针,应用程序就停止正确渲染,并显示一个几乎全黑的屏幕,其中一小部分仍然正确显示。我肯定有一些开放的gl状态,我在这里痛击,但我不知道它是什么。我需要在绘制调用之前/之后保存/恢复哪些内容,以允许应用继续使用我的叠加正确渲染?
// Save application state
GLint prev_program;
glGetIntegerv(GL_CURRENT_PROGRAM, &prev_program);
// Do overlay drawing
glUseProgram(program);
glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, RectangleVertices);
glEnableVertexAttribArray(vPosition);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray(vPosition);
// Trying to restore application state here - there are probably more things that I'm missing.
glUseProgram(prevProgram);
2条答案
按热度按时间7rtdyuoh1#
我需要在绘制调用之前/之后保存/恢复哪些内容,以允许应用继续使用我的叠加正确渲染?
你修改过的所有东西...
请注意,对于某些开发人员用例,即使是完整的状态恢复也可能是不够的。通常,这是应用程序中的一个错误(应用程序对对象ID分配进行假设),但在开发工具(如逐字API跟踪重放工具)中也有这样的假设。
p8h8hvxi2#
根据你对我的评论的回应,我相信你正在努力实现这样的效果:
在所示的示例中,首先绘制3D信息,然后使用基于图块的渲染着色器以正交模式绘制左下方的按钮。基于tile的部分不是必需的,但是如果你感兴趣的话,Sprite Tile Maps on GPU有一个很好的例子来说明如何实现。
抱歉,我使用了一些Javaisms(你看到的大多数是手机)
尝试在可能的情况下切换到c++约定。
渲染循环的一般结构如下所示:
在每个几何体组中,我有
draw()
调用来执行该类型几何体的绘制操作,因此我可以收集并保存所有必要的着色器输入、glEnable调用等。一个典型的例子如下所示:下面是一个在属性Pre-和Post-步骤中调用的示例,在本例中是AttributeBuffer
用户界面的绘制调用几乎相同,除了它循环通过MenuElements的树结构(可能有子元素),然后使用正交投影绘制所有这些元素,而不进行深度测试。
作为最后一点,我提供了一些结构选择,因为我发现处理OpenGL绘图的最佳方法之一是将着色器上每个属性或统一的所有必要的PreRender和PostRender步骤分开,为每个对象或对象组记录它们(许多着色器从不更改其大部分输入),在正在绘制的对象之间传递着色器,然后根据需要为每个着色器指定和执行所有PreRender和PostRender更改。这有助于确保您在每次绘制会话后返回到中性状态。