2013-07-01 43 views
10

Tôi đang gặp sự cố rất khó khăn khi tạo chương trình đổ bóng trên Android. khi tôi gọi glCreateShader hoặc glCreateProgram mỗi luôn trả về 0.glCreateShader và glCreateProgram thất bại trên android

tôi đã bao gồm tất cả các căn cứ của tôi liên quan đến xử lý sự cố:

  • Tôi đã kiểm tra để chắc chắn rằng tôi đã có một bối cảnh OGL (tôi làm, tôi thử nghiệm điều này bằng cách xóa bộ đệm khung với các màu khác nhau, đã hoạt động).

  • tôi đã cố gắng glGetError nhưng nó lại không có gì (GL_NO_ERROR)

Tôi không phải là một chuyên gia OpenGL hoặc android vì vậy tôi không biết về bất kỳ điều gì khác mà có thể gây ra điều này.

Tôi đã chạy ứng dụng của mình trên máy tính bảng Nexus 7 và tôi sử dụng OpenGL ES 2.0 và tôi nhắm mục tiêu phiên bản Android mới nhất (phiên bản 17).

Cuối cùng, tôi có mã của tôi để hiển thị cũng như:

Đây là mã soạn sẵn của tôi rằng thiết lập các ứng dụng:

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); 
    } 
} 

và đây là hoạt động chính:

public class MainActivity extends Activity { 

    private Game game; 
    private Platform platform; 

    public MainActivity() { 
     platform = new Platform(); 
     game = new Game(); 
    } 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     platform.link(this); 
     game.link(platform.root); 
     game.onStart(); 
    } 

    public void onDestroy() { 
     super.onDestroy(); 
     game.onStop(); 
     game.unlink(platform.root); 
     platform.unlink(this); 
    } 
} 

và đây là mã tạo trình tạo bóng và chương trình:

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; 
} 

bất kỳ trợ giúp hoặc đề xuất nào sẽ được đánh giá cao.

+3

bạn sẽ gọi đâu 'createProgram() 'tại của bạn mã? Tôi biết thực tế là 'createProgram()' trả về 0 khi được gọi bên ngoài sợi GL. – Reigertje

+0

@Brianberg Nó được gọi trong phương thức onStart() của lớp Game, do đó nó được gọi trong phương thức onCreate() của MainActivity. – Jim

+9

Có, đó là ngoài chủ đề GL. Hãy chắc chắn rằng tất cả các phương pháp từ GLES20 được gọi trong chủ đề GL - nếu không chúng không hoạt động. Đó là trong 'onSurfaceChanged()', 'onSurfaceCreated()' và/hoặc 'onDrawFrame()'. – Reigertje

Trả lời

23

Đối với những người đang tìm kiếm câu trả lời, nó được ẩn trong các nhận xét. Tôi đang đọc @Reigertje từ các bình luận.

cuộc gọi Shader nên trong một chủ đề GL đó là onSurfaceChanged(), onSurfaceCreated() hoặc onDrawFrame()

Các vấn đề liên quan