java–glClearColor无法正常工作(android opengl)

java–glClearColor无法正常工作(android opengl),第1张

概述我想在运行时更改我的应用程序的背景颜色.所以点击按钮我先打电话:GLES20.glClearColor(color[0],color[1],color[2],color[3]);然后我打电话给:GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT);它什么都不做!它保持当前的背景颜色–不会改变

我想在运行时更改我的应用程序的背景颜色.
所以点击按钮我先打电话:

GLES20.glClearcolor(color[0], color[1], color[2], color[3]);

然后我打电话给:

GLES20.glClear(GLES20.GL_color_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

它什么都不做!它保持当前的背景颜色 – 不会改变它.但是当我暂停我的应用并再次恢复时,背景颜色会发生变化.

编辑:
我发现了一种方法.每个帧我首先调用glClear但我dIDent调用glClearcolor.所以,如果我在调用glClear之前每次调用glClearcolor它都可以工作.但是这对我来说仍然没有意义,我想避免在每一帧调用glClearcolor,认为如果我想改变颜色就调用它就足够了.

解决方法:

您只能在拥有当前OpenGL上下文时进行OpenGL调用.当您使用GLSurfaceVIEw时,上下文处理会得到照顾,所以这一切都神奇地似乎有效.直到出现问题,就像你的情况一样.不要只给你解决方案,让我仍然解释一下发生了什么,以避免未来的惊喜.

在进行任何OpenGL调用之前,需要创建一个OpenGL上下文,并将其设置为当前上下文.在AndroID上,它使用EGL API. GLSurfaceVIEw为您处理,这一切都发生在渲染器上调用onSurfaceCreated()之前.因此,当调用Renderer实现上的方法时,您始终可以依赖于当前上下文,而无需担心它.

然而,关键的方面是当前上下文是每个线程. GLSurfaceVIEw创建一个渲染线程,并在此线程中调用所有Renderer方法.

这样做的结果是您无法从其他线程进行OpenGL调用,因为它们没有当前的OpenGL上下文.其中包括UI线程.这正是你试图做的.如果在响应按钮单击时进行glClearcolor()调用,则表示您处于UI线程中,并且您没有当前的OpenGL上下文.

在这种情况下,您已经找到的解决方法实际上可能是最现实的解决方案. glClearcolor()应该是一个便宜的调用,所以在每个glClear()之前创建它都不会很重要.如果您需要采取的 *** 作更昂贵,您还可以在值更改时设置布尔标志,然后仅在设置标志时在onDrawFrame()中执行相应的工作.

这里有另一个微妙但非常重要的方面:线程安全.只要在一个线程(UI线程)中设置值并在另一个线程(渲染线程)中使用它们,就必须担心这一点.假设您有背景颜色的RGB组件的3个值,并且您逐个在UI线程中设置它们.渲染线程可能在UI线程设置时使用3个值,最后混合使用旧值和新值.

为了说明所有这些,我将使用您的示例,并勾勒出一个工作和线程安全的解决方案.涉及的班级成员可能如下所示:

float mBackRed, mBackGreen, mBackBlue;boolean mBackChanged;Object mBackLock = new Object();

然后在UI线程中设置值的位置:

synchronized(mBackLock) {    mBackRed = ...;    mBackGreen = ...;    mBackBlue = ...;    mBackChanged = true;}

在调用glClear()之前的onDrawFrame()方法中:

Boolean changed = false;float backR = 0.0f, backG = 0.0f, backB = 0.0f;synchronized(mBackLock) {    if (mBackChanged) {        changed = true;        backR = mBackRed;        backG = mBackGreen;        backB = mBackBlue;        mBackChanged = false;    }}if (changed) {    glClearcolor(backR, backG, backB, 0.0f);}

请注意两个线程共享的类成员的所有访问权限都在锁定内.在最后一个代码片段中,还要注意在使用之前如何将颜色值复制到局部变量.对于这个简单的例子,这可能太过分了,但我想说明锁定应该尽可能短暂地保持的总体目标.如果直接使用成员变量,则必须在锁内进行glClearcolor()调用.如果这是一个可能需要很长时间的 *** 作,则UI线程无法更新值,并且可能会等待一段时间等待锁定.

还有一种使用锁的替代方法. GLSurfaceVIEw有一个queueEvent()方法,允许您传入Runnable,然后在渲染线程中执行该Runnable.在GLSurfaceVIEw文档中有一个例子,所以我不会在这里拼出代码.

总结

以上是内存溢出为你收集整理的java – glClearColor无法正常工作(android opengl)全部内容,希望文章能够帮你解决java – glClearColor无法正常工作(android opengl)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1116149.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存