2017-11-19 9 views
0

私はこのロードブロックを打つまで、個人的なプロジェクトのためにネイティブアクティビティとGLES 3.0を試したかったのです。シェーダはロードされず、コンパイルされません。 OPENGLのログは存在しないので、確かに。ここでAndroidネイティブアクティビティ、GLES 3.0シェーダのコンパイルが失敗する

は私のシェーダの両方がある:

static const char glVertexShader[] = 
"#version 300 es\n" 
"in vec4 vPosition;\n" 
"void main()\n" 
"{\n" 
" gl_Position = vPosition;\n" 
"}\n\0"; 

static const char glFragmentShader[] = 
"#version 300 es\n" 
"precision mediump float;\n" 
"void main()\n" 
"{\n" 
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" 
"}\n\0"; 

そして、ここでは私のシェーダのロードとプログラム作成機能は以下のとおりです。

GLuint loadShader(GLenum shaderType, const char* shaderSource) 
{ 
    GLuint shader = glCreateShader(shaderType); 
    if (shader) 
    { 
     glShaderSource(shader, 1, &shaderSource, NULL); 
     glCompileShader(shader); 
     GLint compiled = 0; 
     glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 
     if (!compiled) 
     { 
      GLint infoLen = 0; 
      glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 
      if (infoLen) 
      { 
       char * buf = new char[infoLen]; 
       if (buf) 
       { 
        glGetShaderInfoLog(shader, infoLen, NULL, buf); 
        log.log_error("Could not Compile Shader %d:\n%s\n", shaderType, buf); 
        delete[] buf; 
       } 
       glDeleteShader(shader); 
       shader = 0; 
      } 
     } 
    } 
    return shader; 
} 

GLuint createProgram(const char* vertexSource, const char * fragmentSource) 
{ 
    log.log_info("Loading vertex shader"); 
    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexSource); 
    if (!vertexShader) 
    { 
     log.log_info("Vertex shader load failure!"); 
     return 0; 
    } 
    log.log_info("Loading fragment shader"); 
    GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentSource); 
    if (!fragmentShader) 
    { 
     log.log_info("Fragment shader load failure!"); 
     return 0; 
    } 
    GLuint program = glCreateProgram(); 

    if (program) 
    { 
     glAttachShader(program, vertexShader); 
     glAttachShader(program, fragmentShader); 
     glLinkProgram(program); 
     GLint linkStatus = GL_FALSE; 
     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 

     if (linkStatus != GL_TRUE) 
     { 
      GLint bufLength = 0; 
      glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 
      if (bufLength) 
      { 
       char* buf = new char[bufLength]; 
       if (buf) 
       { 
        glGetProgramInfoLog(program, bufLength, NULL, buf); 
        log.log_error("Could not link program:\n%s\n", buf); 
        delete[] buf; 
       } 
      } 
      glDeleteProgram(program); 
      program = 0; 
     } 
    } 
    return program; 
} 

私も私のセットアップコードを含め、以下のコードを描画されます:

セットアップコード:

GLuint simpleTriangleProgram; 
GLuint vPosition; 
bool setupGraphics(int w, int h) 
{ 
    simpleTriangleProgram = createProgram(glVertexShader, glFragmentShader); 
    if (!simpleTriangleProgram) 
    { 
     log.log_error("Could not create program"); 
     return false; 
    } 
    vPosition = glGetAttribLocation(simpleTriangleProgram, "vPosition"); 
    glViewport(0, 0, w, h); 
    return true; 
} 

描画コード:

//------------------------------- 
const GLfloat triangleVertices[] = { 
    0.0f, 1.0f, 
    -1.0f, -1.0f, 
    1.0f, -1.0f 
}; 
//------------------------------- 


/** 
* Just the current frame in the display. 
*/ 
static void engine_draw_frame(struct engine* engine) { 
    if (engine->display == NULL) { 
     // No display. 
     return; 
    } 

    // Just fill the screen with a color. 
    glClearColor(((float)engine->state.x)/engine->width, engine->state.angle, 
     ((float)engine->state.y)/engine->height, 1); 
    glClear(GL_COLOR_BUFFER_BIT); 

    //--------------------------------------------------- 
    glUseProgram(simpleTriangleProgram); 
    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, triangleVertices); 
    glEnableVertexAttribArray(vPosition); 
    glDrawArrays(GL_TRIANGLES, 0, 3); 
    //--------------------------------------------------- 

    eglSwapBuffers(engine->display, engine->surface); 
} 

そして、はい、GLESコンテキストが正しく作成されています。 しかし、私もそのコードを投稿すべきかどうかを教えてください。

/** 
* Initialize an EGL context for the current display. 
*/ 
static int engine_init_display(struct engine* engine) { 
    // initialize OpenGL ES and EGL 

    /* 
    * Here specify the attributes of the desired configuration. 
    * Below, we select an EGLConfig with at least 8 bits per color 
    * component compatible with on-screen windows 
    */ 
    const EGLint attribs[] = { 
     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 
     EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 
     EGL_BLUE_SIZE, 8, 
     EGL_GREEN_SIZE, 8, 
     EGL_RED_SIZE, 8, 
     EGL_NONE 
    }; 
    EGLint w, h, format; 
    EGLint numConfigs; 
    EGLConfig config; 
    EGLSurface surface; 
    EGLContext context; 

    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 

    eglInitialize(display, 0, 0); 

    /* Here, the application chooses the configuration it desires. 
    * find the best match if possible, otherwise use the very first one 
    */ 
    eglChooseConfig(display, attribs, NULL, 0, &numConfigs); 
    std::unique_ptr<EGLConfig[]> supportedConfigs(new EGLConfig[numConfigs]); 
    assert(supportedConfigs); 
    eglChooseConfig(display, attribs, supportedConfigs.get(), numConfigs, &numConfigs); 
    assert(numConfigs); 
    auto i = 0; 
    for (; i < numConfigs; i++) { 
     auto& cfg = supportedConfigs[i]; 
     EGLint r, g, b, d; 
     if (eglGetConfigAttrib(display, cfg, EGL_RED_SIZE, &r) && 
      eglGetConfigAttrib(display, cfg, EGL_GREEN_SIZE, &g) && 
      eglGetConfigAttrib(display, cfg, EGL_BLUE_SIZE, &b) && 
      eglGetConfigAttrib(display, cfg, EGL_DEPTH_SIZE, &d) && 
      r == 8 && g == 8 && b == 8 && d == 0) { 

      config = supportedConfigs[i]; 
      break; 
     } 
    } 
    if (i == numConfigs) { 
     config = supportedConfigs[0]; 
    } 

    EGLint AttribList[] = 
    { 
     EGL_CONTEXT_CLIENT_VERSION, 3, 
     EGL_NONE 
    }; 

    /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is 
    * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). 
    * As soon as we picked a EGLConfig, we can safely reconfigure the 
    * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ 
    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); 
    surface = eglCreateWindowSurface(display, config, engine->app->window, NULL); 
    context = eglCreateContext(display, config, NULL, AttribList); 

    if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { 
     log.log_warning("Unable to eglMakeCurrent"); 
     return -1; 
    } 

    eglQuerySurface(display, surface, EGL_WIDTH, &w); 
    eglQuerySurface(display, surface, EGL_HEIGHT, &h); 

    engine->display = display; 
    engine->context = context; 
    engine->surface = surface; 
    engine->width = w; 
    engine->height = h; 
    engine->state.angle = 0; 

    // Check openGL on the system 
    auto opengl_info = { GL_VENDOR, GL_RENDERER, GL_VERSION, GL_EXTENSIONS }; 
    for (auto name : opengl_info) { 
     auto info = glGetString(name); 
     log.log_info("OpenGL Info: %s", info); 
    } 
    // Initialize GL state. 
    // glEnable(GL_CULL_FACE); 
    // glEnable(GL_DEPTH_TEST); 

    return 0; 
} 

全ログ:

は、ここに私のコンテキストを作成するコードです Log pic

注:私のロガークラス__android_log_vprint()ための単なるラッパーです。私はそれがほんの少しでも関係がないので、それを含めなかった。

+2

コードをデバッグしましたか? – Rabbid76

+0

はい、ヌルポインタも何もありません。 OpenGLが私にログを与えていないので、シェーダがコンパイル/リンクしないことを除いて、すべてうまく動作します。 – AquaBytez

+0

どのビットが失敗しますか?それは 'コンパイルされた'は偽ですか? – Columbo

答えて

0

投稿されたログに基づいて、glCreateShaderはコンテキストが有効でない場合にのみ0を返します。

ログのタイムスタンプを見ると、OpenGLESコンテキストを作成する前にシェーダをロードしているように見えます。

+0

Whoa。私はそれを知らなかった。 'void android_main(struct android_app * state)'のコンテキストを初期化するのではなく、むしろ 'cmd == APP_CMD_INIT_WINDOW'のときに' void engine_handle_cmd(struct android_app * app、int32_t cmd) 'に書かなければなりません。 つまり、コンテキストの初期化は、 'main()'で毎回発生する必要はありません。それは私が慣れ親しんだこととはちょっと違うのですが、なぜそれがAndroidではなくWindows上で動作するのかを説明します。 – AquaBytez

1

この:

#version 300 es 
attribute vec4 vPosition; 
void main() 
{ 
    gl_Position = vPosition; 
} 

は...法的ESSLバージョン300シェーダではありませんので、あなたのプラットフォーム上で、コンパイラによって返され、コンパイル・エラー・ログを取得する必要があります。あなたのlog_infoログチャンネルから何も取得していませんか?

attributeinに置き換えてシェーダを有効にします。

+0

'属性'を 'in'に置き換えて質問を更新しましたが、まだ何も表示されていません – AquaBytez

関連する問題