Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/195.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java glCreateShader和glCreateProgram在android上失败_Java_Android_Opengl Es 2.0_Shader_Nexus 7 - Fatal编程技术网

Java glCreateShader和glCreateProgram在android上失败

Java glCreateShader和glCreateProgram在android上失败,java,android,opengl-es-2.0,shader,nexus-7,Java,Android,Opengl Es 2.0,Shader,Nexus 7,我在android上创建着色器程序时遇到了一个非常困难的问题。当我调用glCreateShader或glCreateProgram时,每个都始终返回0 我已经介绍了有关故障排除的所有基础知识: 我检查以确保我有一个ogl上下文(我有,我通过用各种颜色清除帧缓冲区来测试它,这很有效) 我尝试了glGetError,但它没有返回任何结果(GL\u NO\u ERROR) 我不是opengl或android专家,所以我不知道还有什么其他原因会导致这种情况 我一直在Nexus7平板电脑上运行我的应用

我在android上创建着色器程序时遇到了一个非常困难的问题。当我调用glCreateShader或glCreateProgram时,每个都始终返回0

我已经介绍了有关故障排除的所有基础知识:

  • 我检查以确保我有一个ogl上下文(我有,我通过用各种颜色清除帧缓冲区来测试它,这很有效)

  • 我尝试了glGetError,但它没有返回任何结果(GL\u NO\u ERROR)

我不是opengl或android专家,所以我不知道还有什么其他原因会导致这种情况

我一直在Nexus7平板电脑上运行我的应用程序,我使用OpenGLES2.0,我的目标是最新版本的Android(版本17)

最后,我还要展示我的代码:

以下是我设置应用程序的样板代码:

public class Platform implements ILinkable<Activity> {
    class GameLoop extends GLSurfaceView implements GLSurfaceView.Renderer {
        class Graphics2D implements IGraphics2D {
            int width  = 0;
            int height = 0;

            public void setWidth (int width ) { this.width = width; }
            public void setHeight(int height) { this.height = height; }

            public int getWidth () { return width;  }
            public int getHeight() { return height; }
        }

        class Time implements ITime {
            float frametime = 0;
            float totaltime = 0;
            long  temptime = 0;
            boolean running = true;

            public void beginTimeCount() {
                temptime = System.nanoTime();
            }

            public void endTimeCount() {
                frametime  = (System.nanoTime() - temptime) / 1000000;
                totaltime += frametime;
            }

            public float getFrameTime() { return frametime; }
            public float getTotalTime() { return totaltime; }
        }

        Graphics2D graphics2d = new Graphics2D();
        Time       time       = new Time();
        boolean    running    = true;

        public GameLoop(Context context) {
            super(context);

            setEGLContextClientVersion(2);
            setRenderer(this);
            //setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
        }

        public void onSurfaceCreated(GL10 unused, EGLConfig config) {
            GLES20.glClearColor(0.5f, 0.0f, 0.5f, 1.0f);
        }

        public void onDrawFrame(GL10 unused) {
            if (running) {
                time.beginTimeCount();

                for (IUpdateable u : Platform.this.root.update)
                    u.onUpdate(time);

                GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
                for (IDrawable2D d : Platform.this.root.draw2d) {
                    d.onDraw2D(graphics2d);
                }

                for (IDrawable3D d : Platform.this.root.draw3d)
                    d.onDraw3D();

                time.endTimeCount();
            }
        }

        public void onSurfaceChanged(GL10 unused, int width, int height) {
            GLES20.glViewport(0,0, width, height);
            graphics2d.setWidth(width);
            graphics2d.setHeight(height);
            for (IDrawable2D d : Platform.this.root.draw2d)
                d.onSize2D(graphics2d);
        }

        public void onPause() {
            super.onPause();
            running = false;
        }

        public void onResume() {
            super.onResume();
            running = true;
        }
    }

    private GameLoop gameloop;
    public Node root;

    public Platform() {
        this.root = new Node();
    }

    public void link(Activity activity) {
        this.gameloop = new GameLoop(activity);
        activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
        activity.setContentView(this.gameloop);
    }

    public void unlink(Activity activity) {
        this.gameloop = null;
        activity.setContentView(null);
    }
}
这是创建着色器和程序的代码:

public static int loadShader(int shaderType, String source) throws FmtException {
    int[] gotVar = new int[]{ 0 };
    int shader = GLES20.glCreateShader(shaderType);

    if (shader == 0)
        throw new FmtException(FmtException.GLES,"could not create shader: %s",getError());

    GLES20.glShaderSource(shader, source);
    GLES20.glCompileShader(shader);

    GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, gotVar, 0);
    if (gotVar[0] == 0) {
        GLES20.glGetShaderiv(shader, GLES20.GL_INFO_LOG_LENGTH, gotVar, 0);
        if (gotVar[0] != 0) {
            GLES20.glDeleteShader(shader);
            throw new FmtException(FmtException.GLES, "could not compile shader %d:\n%s\n",shaderType, GLES20.glGetShaderInfoLog(shader));
        }
    }

    return shader;
}

public static int createProgram(String pVertexSource, String pFragmentSource) throws FmtException {
    int[] gotVar = new int[]{ GLES20.GL_FALSE };
    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, pVertexSource);
    int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, pFragmentSource);

    int program = GLES20.glCreateProgram();
    if (program == 0)
        throw new FmtException(FmtException.GLES, "could not create program: %s",getError());


    GLES20.glAttachShader(program, vertexShader);
    GLES20.glAttachShader(program, pixelShader);
    GLES20.glLinkProgram(program);

    GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, gotVar, 0);
    if (gotVar[0] != GLES20.GL_TRUE) {
        GLES20.glGetProgramiv(program, GLES20.GL_INFO_LOG_LENGTH, gotVar, 0);
        if (gotVar[0] != 0) {
            GLES20.glDeleteProgram(program);
            throw new FmtException(FmtException.GLES, "could not link program:\n%s\n", GLES20.glGetProgramInfoLog(program));
        }
    }

    return program;
}

任何帮助或建议都将不胜感激。

对于那些正在寻找答案的人来说,答案隐藏在评论中。我引用评论中的@Reigertje

着色器调用应该位于surfacechanged()上的GL线程中, onSurfaceCreated()onDrawFrame()


在代码中,您将在哪里调用
createProgram()
?我知道一个事实,
createProgram()
在GL线程外调用时返回0。@Brianberg它在游戏类onStart()方法中被调用,因此它在MainActivity的onCreate()方法中被调用。是的,这在GL线程外。确保GLES20中的所有方法都在GL线程中调用,否则它们将无法工作。这是在
onSurfaceChanged()
onSurfaceCreated()
和/或
onDrawFrame()
@Brianberg()中,谢谢。将初始化代码移到onSurfaceCreated()需要一些时间,因此我现在不尝试这样做,但我以前在windows上遇到过类似的opengl问题,因此我了解opengl如何与多个线程交互。
public static int loadShader(int shaderType, String source) throws FmtException {
    int[] gotVar = new int[]{ 0 };
    int shader = GLES20.glCreateShader(shaderType);

    if (shader == 0)
        throw new FmtException(FmtException.GLES,"could not create shader: %s",getError());

    GLES20.glShaderSource(shader, source);
    GLES20.glCompileShader(shader);

    GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, gotVar, 0);
    if (gotVar[0] == 0) {
        GLES20.glGetShaderiv(shader, GLES20.GL_INFO_LOG_LENGTH, gotVar, 0);
        if (gotVar[0] != 0) {
            GLES20.glDeleteShader(shader);
            throw new FmtException(FmtException.GLES, "could not compile shader %d:\n%s\n",shaderType, GLES20.glGetShaderInfoLog(shader));
        }
    }

    return shader;
}

public static int createProgram(String pVertexSource, String pFragmentSource) throws FmtException {
    int[] gotVar = new int[]{ GLES20.GL_FALSE };
    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, pVertexSource);
    int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, pFragmentSource);

    int program = GLES20.glCreateProgram();
    if (program == 0)
        throw new FmtException(FmtException.GLES, "could not create program: %s",getError());


    GLES20.glAttachShader(program, vertexShader);
    GLES20.glAttachShader(program, pixelShader);
    GLES20.glLinkProgram(program);

    GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, gotVar, 0);
    if (gotVar[0] != GLES20.GL_TRUE) {
        GLES20.glGetProgramiv(program, GLES20.GL_INFO_LOG_LENGTH, gotVar, 0);
        if (gotVar[0] != 0) {
            GLES20.glDeleteProgram(program);
            throw new FmtException(FmtException.GLES, "could not link program:\n%s\n", GLES20.glGetProgramInfoLog(program));
        }
    }

    return program;
}