Android OpenGL Cannot create GL program: 0 & GL error: 1282

Android OpenGL create GL program: 0 & GL error: 1282

快速解决

1. 使用GLSurfaceView的话

请在继承类中合适的地方(一般是构造函数里面)设置当前的clientversion 为 2
具体代码:

setEGLContextClientVersion(2);

2. 使用自己构建的opengl环境的话

请在创建glContext的时传入的参数中配置 int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2 , EGL10.EGL_NONE };
具体代码如下,注意 attrib_list 中的第二个元素写为 2

//注意 :int EGL_CONTEXT_CLIENT_VERSION = 0x3098
int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
EGLContext glContext = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT,attrib_list);

注意,int EGL_CONTEXT_CLIENT_VERSION = 0x3098。到此,是同样的问题的话,应该得到了解决,可以继续搬砖了。

有兴趣的继续往下看:

出错代码鉴赏

        int shader = GLES20.glCreateShader(type);

        // add the source code to the shader and compile it
        GLES20.glShaderSource(shader, shaderCode);
        checkError();
        GLES20.glCompileShader(shader);
        checkError();


        int program = GLES20.glCreateProgram();
        checkError();

该段代码一般是封装为一个叫loadShader的函数中,本身是无误,但达不到期望的效果,如果在checkError里面抛出异常,那么就挂掉了。

通过上面的解决方法和代码,问题的原因就明显了:
GLES20.xxx() 和open环境不一致。即 opengl的环境不是2.0,却使用了2.0的接口 ,所以将opengl的版本指定(初始化)为 2。

有些朋友可能直接提问 loadShader出错,实际上的代码是上面的代码片段。

GLSurfaceView 部分代码分享

GLSurfaceView 源码是API level 30.

  1. GLSurfaceView中 mEGLContextClientVersion 外部没有设置的话,默认是0
  2. DefaultContextFactory 具体实现
 private class DefaultContextFactory implements EGLContextFactory {
        private int EGL_CONTEXT_CLIENT_VERSION = 0x3098;

        public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) {
            int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, mEGLContextClientVersion,
                    EGL10.EGL_NONE };

            return egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT,
                    mEGLContextClientVersion != 0 ? attrib_list : null);
        }

        public void destroyContext(EGL10 egl, EGLDisplay display,
                EGLContext context) {
            if (!egl.eglDestroyContext(display, context)) {
                Log.e("DefaultContextFactory", "display:" + display + " context: " + context);
                if (LOG_THREADS) {
                    Log.i("DefaultContextFactory", "tid=" + Thread.currentThread().getId());
                }
                EglHelper.throwEglException("eglDestroyContex", egl.eglGetError());
            }
        }
    }

从createContext 中代码可看出,mEGLContextClientVersion 为0 的时候 ,egl.eglCreateContext的最后一个参数传入的是null。同时mEGLContextClientVersion 又是 attrib_list 数组第二个元素,版本openGl2.0就是通过这个参数确定的。

  1. setEGLContextClientVersion
    精简了函数的注释,可以从注释上面得到一些启发, Pick an OpenGL ES 2.0 context

/**
     * Inform the default EGLContextFactory and default EGLConfigChooser
     * which EGLContext client version to pick.
     * <p>Use this method to create an OpenGL ES 2.0-compatible context.
     * Example:
     * <pre class="prettyprint">
     *     public MyView(Context context) {
     *         super(context);
     *         setEGLContextClientVersion(2); // Pick an OpenGL ES 2.0 context.
     *         setRenderer(new MyRenderer());
     *     }
     * </pre>
     */
    public void setEGLContextClientVersion(int version) {
        checkRenderThreadState();
        mEGLContextClientVersion = version;
    }

综合起来使用GLSurfaceView的opengl便利的情况下要使用2.0,优先调用setEGLContextClientVersion(2)

基于TextureView 或SufaceView创建openglcontext

最终的要调用的代码如下:

int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
EGLContext glContext = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT,attrib_list);

version 可以根据需要进行指定。

补充:
自定义 GLSurfaceView 的 setEGLContextFactory 是提供自定义创建opengl环境的接口,只要根据上面两个关键调用实现EGLContextFactory 就可以,GLSurfaceView的默认实现就是DefaultContextFactory。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值