在opengl线程上运行处理程序

时间:2016-11-15 08:02:04

标签: android opengl-es opengl-es-2.0

我试图每秒重新创建一个GL_POINTS场景,我尝试使用处理程序:

myocamlbuild.ml

我在onSufraceCreated方法中使用 private Handler handler = new Handler(); private Runnable runnable = new Runnable() { @Override public void run() { createRandomGridPoints(); mPoint = new Point(pointCoords,colorCoords); handler.postDelayed(this, 1000); } }; 。 这些点被创建,但我在屏幕上什么都没有,我在logcat中有这个错误:handler.postDelayed(runnable, 1000);

我认为问题可能是runnl没有在opengl线程上运行。有可能解决这个问题吗?

积分课程:

call to OpenGL ES API with no current context (logged once per thread)

1 个答案:

答案 0 :(得分:0)

openGL上下文旨在使用多线程。在单独的线程上使用openGL执行某些操作时,您应该在该线程上有另一个上下文并将其设置为当前。这意味着必须在要使用openGL的每个线程上设置上下文。可以在多个线程上使用相同的上下文,但除非您确定自己在做什么,否则我建议您不要这样做;因为你在屏幕上绘制它绝对不是使用相同上下文的情况。

现在要在上下文之间共享资源,您需要拥有一个应该是上下文构造函数之一的共享上下文。您需要将主要上下文插入其中。当您需要在背景中加载大数据时使用此选项,例如纹理。

但你的情况有点具体。您创建的数据未绑定到openGL,因此没有理由在此线程上设置上下文,也不创建新的上下文。你应该以某种方式回到你的主要openGL线程并绘制点。

所以最简单的解决方案是从主线程上的线程调用draw方法。但根据您的具体情况,有多种方法可以实现您的目标:

  1. 如果场景设计为按需重绘(这意味着它不会每秒执行几次,但仅当您调用redraw等方法时):您需要在线程上显式调用此方法旨在在屏幕上显示内容(您的主要OpenGL线程)。您可以将这些点传递给绘制方法drawPoints(points)或将其分配给负责绘图的类mainEngine.points = points; mainEngine.redraw();
  2. 如果场景不断重绘,则重绘已经在主线程上。在这种情况下,解决方案非常简单。引擎应该有绘制点的逻辑,所以在你的onDraw方法中应该有一些逻辑,比如foreach (point in this.points) drawPoint(point)然后你需要做的就是设置完成后的新点,线程不会有影响mainEngine.points = points应该做的。
  3. 如果场景没有线程依赖,并且您正在进行一些数据处理,则可以在整个线程中移动逻辑。这绝不适合屏幕绘图,但更适合绘制到FBO。在这种情况下,只要你打开线程并在新线程上将上下文设置为current,同时从上一个线程中删除当前上下文,就需要转发上下文。
相关问题