ANDROID “call to opengl es api with no current context”错误的解决

1,背景:android pad项目中使用到google实景(panorama)的项目,该项目中应用到opengl的一些底层,该问题就是opengl底层出现问题时的表现。

2,症状:在项目中有两个activity(a,b,b为实景,通过a来启动),如果a,b在AndroidManifest.xml均关闭硬件加速( android:hardwareAccelerated="false")则实景可用,但a开硬件加速,b关闭硬件加速的话,则b中的实景不可用,表现为只展示图片,不能随着角度滚动展示。

3,问题的解释:

 (1)question:   am new to both openGL and android development so please forgive me if my question is very trivial.

I am trying to build a simple little app that takes input from the user in three EditTexts representing a 0 - 100% value for each component of a RGB color to be displayed in a GLSurfaceView.

The catch is that I need this to use openGL ES 2.0 and I need to pass the data into the shading program using a uniform value so that once I get it working I can move on to what I am really trying to accomplish.

Upon running what I have written I can get the GLSurfaceView to correctly display the first solid color, but whenever I change any of the values and make calls to rebuild the uniform slot in the shading program I get this error in the LogCat:

ERROR/libEGL(14316): call to OpenGL ES API with no current context (logged once per thread)

and of course the GLSurfaceView remains the initial color.

I've been searching all over for a solution to this problem and as best I can tell I might need to be setting up an EGLContext somewhere before setting my renderer. However, I don't see anything in the API demos about this, and the only information I can find online was written before GLSurfaceView was even available.

Do I need to set up an EGLContext still or have I missed something else? 

Additional info that may help:

-used an XML file to set up the UI (and as far as I can tell doing it in code doesn't help)

-having the same trouble when I try to load in a new texture from the sd card in a seperate program. I can get the first texture to work fine, but when using the same method to load the second I get the same error and nothing changes.

answer: You're not calling it from the OpenGL thread. If a different thread is trying to do something with OpenGL, queue that up and call it during your OpenGL thread instead.

 

(2)

这里使用到了线程局部存储机制,这是一个什么东东呢?

概念:线程局部存储(Thread Local Storage,TLS)用来将数据与一个正在执行的指定线程关联起来。

进程中的全局变量与函数内定义的静态(static)变量,是各个线程都可以访问的共享变量。在一个线程修改的内存内容,对所有线程都生效。这是一个优点也是一个缺点。说它是优点,线程的数据交换变得非常快捷。说它是缺点,一个线程死掉了,其它线程也性命不保; 多个线程访问共享数据,需要昂贵的同步开销,也容易造成同步相关的BUG。

如果需要在一个线程内部的各个函数调用都能访问、但其它线程不能访问的变量(被称为static memory local to a thread 线程局部静态变量),就需要新的机制来实现。这就是TLS。

功能:它主要是为了避免多个线程同时访存同一全局变量或者静态变量时所导致的冲突,尤其是多个线程同时需要修改这一变量时。为了解决这个问题,我们可以通过TLS机制,为每一个使用该全局变量的线程都提供一个变量值的副本,每一个线程均可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。而从全局变量的角度上来看,就好像一个全局变量被克隆成了多份副本,而每一份副本都可以被一个线程独立地改变。

 

好了,介绍完毕,下面介绍系统中代码如何体现的:

由于OpenGL是一个其于上下文Context 环境开发的,所以每个线程需要保存自已的运行环境,如果没有的话则会报错:

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

4,解决办法:

在com.android.panoramagl.iphone.EAGLContext文件中修改红色位置,然后重新jar在项目中引用。

public static boolean setCurrentContext(EAGLContext context)
{
try
{
EGL10 egl = (EGL10)EGLContext.getEGL();
if(context == null)
egl.eglMakeCurrent(currentContext == null ? egl.eglGetCurrentDisplay() : currentContext.getDisplay(), EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
else //if(currentContext != context)
{
egl.eglMakeCurrent(context.getDisplay(), context.getSurface(), context.getSurface(), context.getContext());
currentContext = context;
}
return true;
}
catch(Exception ex)
{
Log.e("setCurrentContext", "Error can't setCurrentContext:" + ex.getMessage());
}
return false;
}

5,个人解释:

出错的地方时因为调用setCurrentContext(EAGLContext context)这个方法,第一次调用没问题,第二次调用有问题。可能是因为context在多线程环境中,第一次调用中context发生了改变,需要在以后调用前重新设置context。总之个人解释是猜测,好歹问题已解决,具体缘由望高手解答。

 

转载于:https://www.cnblogs.com/weiwelcome0/archive/2012/08/09/2630179.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
声明:这些内容是逐步总结过来的,所以可能有当时的理解不正确,只希望大家能做个参考: 内容如下: 目录 一句话总结汇总: Copy project into workspace 和add project into work set 的含义 数字签名总结 JNI 基础及注意: Ndk的使用方法: Ant 与 android update project 命令行只有在非根盘符上才能运行 android Launcher Android 运行环境搭建 Android:name什么时候加”.” Activity class {package/class} does not exist 问题的解决 Activity 中两次调用OnCreate的原因 ByteBuffer 和 FloatBuffer 的直接分配和非直接分配 Application的使用小总结 “call to OpenGL ES API with no current context (logged once per thread” 问题的解决 2013年9月7日19:15:33:我的平板分辨率很高可是运行public void onSurfaceChanged(GL10 gl, int width, int height)函数时,分辨率只有 455*320,这是为什么? 关于android添加第三方字体的方法 android-apt-compiler: [t1] res\layout\LinearLayout.xml: Invalid file name: must contain only [a-z0-9_.] Buttons in button bars should be borderless android 支持的距离单位 使用adb shell命令进入手机后使用ls命令提示: opendir failed permission denied 使用adb pull 命令提示permission denied Button 中的setLayoutParams使用注意: layout文件夹和raw文件下面的文件读取 Matrix方法中的set方法和post方法 android 中调用drawBitmap时理解dip(屏幕密度)和px(像素)的区别 SQLiteDatabase 的setTransactionSuccessful作用 终于弄明白 paddingleft margineleft layout_gravity 和gravity之间的区别 自定义控件时要注意的问题。 obtainMessage 的作用: FrameLayout 需要注意的地方: EditText 禁止弹出按键盘: 获取控件屏幕位置和窗口位置: 为什么MyAdapater的getView没有被调用 XmlSerializer使用总结: ListView中的Item自定义点击后的背景色的方法。 drawable各个分辨率 fragment 的几种创建方式 fragment第一次使用遇到的问题 activity变身对话框 onMeasure 中的AT_MOST EXACTLY UNSPECIFIED MotionEvent的触发记录 对于Drawable 的 getIntrinsicHeight 和getIntrinsicWidth的理解 IntentService 使用总结: 文件读写总结: AES 解密失败: XML中的include标签加入后崩溃 Button的background标签使图像拉伸的问题 SharedPreferences 的getString 的陷阱 TextView 中的EMS和Maxlength
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值