2015-02-12 88 views
3

我正在學習OpenGL ES,尤其是在OpenGL ES 3.1中計算着色器,特別是在Android 5.0.1中。在Android 5中使用計算着色器(Open GL ES 3.1)

我定義了3個着色器(計算,頂點和片段)並附加到兩個不同的程序,一個用於計算着色器,另一個用於頂點和片段着色器。

我時,我只用了頂點和片段着色器沒有問題,但現在我加入了計算着色器,我得到了以下錯誤:

02-11 20:02:10.375 13243-13264/com.example.daan.daggl2 I/VERSION﹕ OpenGL ES 3.1 NVIDIA 349.00 
02-11 20:02:10.472 13243-13264/com.example.daan.daggl2 A/libc﹕ Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 13264 (GLThread 9847) 

我試圖找出什麼我失蹤但我對這個主題很陌生,我不確定從哪裏開始尋找問題。

該對象的構造是:

public Triangle() { 
     buffers = new int[1]; 
     GLES31.glGenBuffers(1, buffers, 0); 
     gVBO = buffers[0]; 

     // set up the vertex and fragment shaders 
     int vertexShader = MyGLRenderer.loadShader(
      GLES31.GL_VERTEX_SHADER, vertexShaderCode); 
     int fragmentShader = MyGLRenderer.loadShader(
      GLES31.GL_FRAGMENT_SHADER, fragmentShaderCode); 

     program = GLES31.glCreateProgram();  
     GLES31.glAttachShader(program, vertexShader); 
     GLES31.glAttachShader(program, fragmentShader); 
     GLES31.glLinkProgram(program); 
     checkGLError("LinkProgram/program"); 

     // set up the compute shader 
     int computeShader = MyGLRenderer.loadShader(
      GLES31.GL_COMPUTE_SHADER, computeShaderCode); 
     computeProgram = GLES31.glCreateProgram(); 
     GLES31.glAttachShader(computeProgram, computeShader); 
     GLES31.glLinkProgram(computeProgram); 
     checkGLError("LinkProgram/computeProgram"); 
    } 

繪製函數:

public void draw(float[] mvpMatrix, float[] color) { 

     GLES31.glUseProgram(computeProgram); 
     checkGLError("UseProgram/computeProgram"); 
     int radiusId = GLES31.glGetUniformLocation(
      computeProgram, "radius"); 
     indexBufferBinding = 0; 
     GLES31.glUniform1f(radiusId, (float) radius); 
     GLES31.glBindBufferBase(
      GLES31.GL_SHADER_STORAGE_BUFFER, indexBufferBinding, gVBO); 
     checkGLError("glBindBuffer/gVBO"); 
     GLES31.glDispatchCompute(2, 2, 1); 
     GLES31.glBindBufferBase(
      GLES31.GL_SHADER_STORAGE_BUFFER, indexBufferBinding, 0); 
     // See note 1 below 
     //GLES31.glMemoryBarrier(
     // GLES31.GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT); 
     GLES31.glMemoryBarrier(
      GLES31.GL_SHADER_STORAGE_BARRIER_BIT); 
     checkGLError("glMemoryBarrier/1"); 
     GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, gVBO); 
     checkGLError("glBindBuffer/gVBO"); 

     GLES31.glUseProgram(program); 

     int posId = GLES31.glGetAttribLocation(
      program, "a_v4Position"); 
     int fillId = GLES31.glGetAttribLocation(
      program, "a_v4FillColor"); 
     int mvpMatrixId = GLES31.glGetUniformLocation(
      program, "mvp_matrix"); 

     GLES31.glEnableVertexAttribArray(posId); 
     GLES31.glEnableVertexAttribArray(fillId); 
     GLES31.glUniformMatrix4fv(mvpMatrixId, 1, false, mvpMatrix, 0); 
     // See note 2 below 
     GLES31.glDrawArrays(GLES31.GL_POINTS, 0, 3); 
    } 

作爲參考,着色器在所述柱的端部。

注:

  1. 我找不到Android文檔中GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT。它不應該在那裏嗎? documentation mentions it
  2. 繪圖調用會使應用程序崩潰。直到glDrawArrays()之前一切似乎都很好。

任何關於如何尋找的想法都是值得讚賞的。

頂點着色器:

private final String vertexShaderCode = 
      "uniform mat4 mvp_matrix;" + 
      "attribute vec4 a_v4Position;" + 
      "attribute vec4 a_v4FillColor;" + 
      "varying vec4 v_v4FillColor;" + 
      "void main(void) {" + 
      " v_v4FillColor = a_v4FillColor;" + 
      " gl_Position = mvp_matrix * a_v4Position;" + 
      "}"; 

片段着色器:

private final String fragmentShaderCode = 
      "precision mediump float;" + 
      "varying vec4 v_v4FillColor;" + 
      "void main(void) {" + 
      " gl_FragColor = v_v4FillColor;" + 
      "}"; 

計算着色器:

private final String computeShaderCode = 
      "#version 310 es" + 
      "\n" + 
      "uniform float radius;" + 
      "struct Vector3f { float x; float y; float z; float w; };" + 
      "struct AttribData { Vector3f v; Vector3f c; };" + 
      "layout(std140, binding = 0) buffer destBuffer { AttribData data[]; } outBuffer;" + 
      "layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;" + 
      "void main() {" + 
      " ivec2 storePos = ivec2(gl_GlobalInvocationID.xy);" + 
      " uint gWidth = gl_WorkGroupSize.x * gl_NumWorkGroups.x;" + 
      " uint gHeigth = gl_WorkGroupSize.y * gl_NumWorkGroups.y;" + 
      " uint gSize = uint(gWidth) * uint(gHeigth);" + 
      " uint offset = uint(storePos.y)*gWidth + uint(storePos.x);" + 
      " float alpha = 2.0 * 3.1159265359 * (float(offset)/float(gSize));" + 
      " outBuffer.data[offset].v.x = float(sin(alpha)) * float(radius);" + 
      " outBuffer.data[offset].v.y = float(cos(alpha)) * float(radius);" + 
      " outBuffer.data[offset].v.z = 0.0;" + 
      " outBuffer.data[offset].v.w = 1.0;" + 
      " outBuffer.data[offset].c.x = float(storePos.x)/float(gWidth);" + 
      " outBuffer.data[offset].c.y = 0.0;" + 
      " outBuffer.data[offset].c.z = 1.0;" + 
      " outBuffer.data[offset].c.w = 1.0;" + 
      "}"; 

回答

2

是,GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT缺少在Android的Java綁定。 Android中Java OpenGL綁定的傳統是不完整的。還有一些從3.0綁定中遺漏的東西。

在這種情況下,因爲它只是一個枚舉值,您可以通過定義值本身來輕鬆解決它。在C/C++的定義是:

#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 

所以在Java中,你可以這樣定義添加到您的代碼:

static final int GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT = 0x00000001; 

至於崩潰,我不能完全肯定。我注意到在發佈的代碼中沒有glVertexAttribPointer()調用。如果他們確實不在你的代碼中,那肯定會成爲問題。