2015-02-09 60 views
1

我將頂點和片段着色器附加到程序對象,然後嘗試鏈接所述程序。 GL_LINK_STATUS返回false。我查看信息日誌,這是一堆亂碼字符。我檢查了GL_INFO_LOG_LENGTH,它是0.如何調試這種情況?無法將着色器鏈接到OpenGL中的程序對象,無法調試

//this is the end of my LoadBasicShaders function 
glAttachShader(program, vertShader); 
glAttachShader(program, fragShader); 

glLinkProgram(program); 

GLint status; 

glGetProgramiv(program, GL_LINK_STATUS, &status); 

if (status == GL_FALSE) 
{ 
    GLint logLength = 0; 
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); 
    std::vector<GLchar> log(logLength + 1); 
    glGetProgramInfoLog(program, logLength, &logLength, &log[0]); 

    fprintf(stderr, "%s\n\n", log); 
    //logLength returns 0, log returns seemingly random chars 

    return -3;//just my error code 
} 

我的着色器是最簡單的着色器,因爲我剛開始。 這裏的頂點着色器:

#version 330 

layout(location = 0) in vec4 position; 
void main() 
{ 
    gl_Position = position; 
} 

而這裏的片段着色器:

#version 330 

out vec4 outputColor; 
void main() 
{ 
    outputColor = vec4(1.0, 1.0, 1.0, 1.0); 
} 

我用GLFW創建OpenGL窗口,並GLEW加載功能:

if (!glfwInit()) 
{/*error checking*/} 

    window = glfwCreateWindow(800, 600, "Swash", NULL, NULL); 

if (!window) 
{/*more error checking*/} 

glfwMakeContextCurrent(window); 
glfwSwapInterval(1); 
glfwSetKeyCallback(window, key_callback); 

if (glewInit() != GLEW_OK) 
{/*you guessed it*/} 
//don't call anything that involves nonstandard OpenGL functions before this point 

GLuint shaderProgram; 

int shaderLoadResult = LoadBasicShaders(shaderProgram, "../res/vert.shader", "../res/frag.shader"); 
+0

發佈包含着色器和上下文創建的[MCVE](http://stackoverflow.com/help/mcve)。 – genpfault 2015-02-09 19:30:04

+0

@genpfault我假設你的意思是OpenGL上下文的創建,也應該包括我如何從着色器文件讀取? – Yago 2015-02-09 20:32:19

+0

是的,窗口/上下文創建。您可以使用類似[this](http://stackoverflow.com/a/13874526/44729)的內容將着色器文本內聯到字符串中。使用[在上下文中](http://stackoverflow.com/questions/17602130/cant-draw-triangle-using-opengl/17604206#17604206)。 – genpfault 2015-02-09 20:33:21

回答

0

對不起,對於非常緩慢的更新,我一直在忙於其他事情。

不管怎麼說,問題是,在編寫代碼,我已經包括了線

program = glCreateProgram(); 

但在某些時候,同時整理,我不小心刪除了它。這就是着色器編譯但未鏈接的原因,它們沒有鏈接到程序對象。

0

總之請求明確的GL版本和配置文件(核心/兼容)(這是我的意思是通過發佈MCVE):

#include <GL/glew.h> 
#include <GLFW/glfw3.h> 
#include <iostream> 
#include <cstdlib> 

struct GlDebugOutput 
{ 
    static void Install() 
    { 
     if(!glewIsSupported("GL_ARB_debug_output")) 
     { 
      std::cerr << "GL_ARB_debug_output not supported" << std::endl; 
      return; 
     } 
     glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); 
     glDebugMessageCallbackARB(DebugCallback, 0); 
     glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE); 
    } 

private: 
    static const char* Source(GLenum source) 
    { 
     switch(source) 
     { 
     case GL_DEBUG_SOURCE_API_ARB    : return "API"; 
     case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB  : return "WINDOW_SYSTEM"; 
     case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB : return "SHADER_COMPILER"; 
     case GL_DEBUG_SOURCE_THIRD_PARTY_ARB  : return "THIRD_PARTY"; 
     case GL_DEBUG_SOURCE_APPLICATION_ARB  : return "APPLICATION"; 
     case GL_DEBUG_SOURCE_OTHER_ARB    : return "OTHER"; 
     default          : return "Unknown source"; 
     } 
    } 

    static const char* Type(GLenum type) 
    { 
     switch(type) 
     { 
     case GL_DEBUG_TYPE_ERROR_ARB    : return "ERROR"; 
     case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB : return "DEPRECATED_BEHAVIOR"; 
     case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB : return "UNDEFINED_BEHAVIOR"; 
     case GL_DEBUG_TYPE_PORTABILITY_ARB   : return "PORTABILITY"; 
     case GL_DEBUG_TYPE_PERFORMANCE_ARB   : return "PERFORMANCE"; 
     case GL_DEBUG_TYPE_OTHER_ARB    : return "OTHER"; 
     default          : return "Unknown type"; 
     } 
    } 

    static const char* Severity(GLenum severity) 
    { 
     switch(severity) 
     { 
     case GL_DEBUG_SEVERITY_HIGH_ARB  : return "HIGH"; 
     case GL_DEBUG_SEVERITY_MEDIUM_ARB : return "MEDIUM"; 
     case GL_DEBUG_SEVERITY_LOW_ARB  : return "LOW"; 
     default        : return "Unknown severity"; 
     } 
    } 

    static void APIENTRY DebugCallback 
     (
     GLenum source, 
     GLenum type, 
     GLuint id, 
     GLenum severity, 
     GLsizei length, 
     const GLchar* message, 
     const void* userParam 
     ) 
    { 
     std::cerr << "GL_DEBUG" 
      << ": " << Source(source) 
      << ": " << Type(type) 
      << ": " << Severity(severity) 
      << ": " << message 
      << std::endl; 
    } 
}; 

struct Program 
{ 
    static GLuint Load(const char* vert, const char* geom, const char* frag) 
    { 
     GLuint prog = glCreateProgram(); 
     if(vert) AttachShader(prog, GL_VERTEX_SHADER, vert); 
     if(geom) AttachShader(prog, GL_GEOMETRY_SHADER, geom); 
     if(frag) AttachShader(prog, GL_FRAGMENT_SHADER, frag); 
     glLinkProgram(prog); 
     CheckStatus(prog); 
     return prog; 
    } 

private: 
    static void CheckStatus(GLuint obj) 
    { 
     GLint status = GL_FALSE; 
     if(glIsShader(obj)) glGetShaderiv(obj, GL_COMPILE_STATUS, &status); 
     if(glIsProgram(obj)) glGetProgramiv(obj, GL_LINK_STATUS, &status); 
     if(status == GL_TRUE) return; 
     GLchar log[ 1 << 15 ] = { 0 }; 
     if(glIsShader(obj)) glGetShaderInfoLog(obj, sizeof(log), NULL, log); 
     if(glIsProgram(obj)) glGetProgramInfoLog(obj, sizeof(log), NULL, log); 
     std::cerr << log << std::endl; 
     exit(EXIT_FAILURE); 
    } 

    static void AttachShader(GLuint program, GLenum type, const char* src) 
    { 
     GLuint shader = glCreateShader(type); 
     glShaderSource(shader, 1, &src, NULL); 
     glCompileShader(shader); 
     CheckStatus(shader); 
     glAttachShader(program, shader); 
     glDeleteShader(shader); 
    } 
}; 

#define GLSL(version, shader) "#version " #version "\n" #shader 

const char* vert = GLSL 
( 
    330, 
    layout(location = 0) in vec4 position; 
    void main() 
    { 
     gl_Position = position; 
    } 
); 

const char* frag = GLSL 
( 
    330, 
    out vec4 outputColor; 
    void main() 
    { 
     outputColor = vec4(1.0, 1.0, 1.0, 1.0); 
    } 
); 

GLuint VAO; 
GLuint VBO; 
GLuint prog; 
void init() 
{ 
    glGenVertexArrays(1, &VAO); 
    glBindVertexArray(VAO); 

    glGenBuffers(1,&VBO); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    float verts[] = 
    { 
     -1.0, -1.0, 
     1.0, -1.0, 
     0.0, 1.0, 
    }; 
    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); 

    prog = Program::Load(vert, NULL, frag); 
    glUseProgram(prog); 

    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); 
} 

void display() 
{ 
    glClearColor(0, 0, 0, 1); 
    glClear(GL_COLOR_BUFFER_BIT); 

    glUseProgram(prog); 
    glBindVertexArray(VAO); 
    glDrawArrays(GL_TRIANGLES, 0, 3); 
} 

void glfwErrorCallback(int error, const char* description) 
{ 
    std::cerr << "GLFW error: " << description << std::endl; 
} 

int main(int argc, char** argv) 
{ 
    glfwSetErrorCallback(glfwErrorCallback); 

    if(GL_FALSE == glfwInit()) 
    { 
     return EXIT_FAILURE; 
    } 
    std::cout << "GLFW version : " << glfwGetVersionString() << std::endl; 

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE); 
    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); 
    GLFWwindow* window = glfwCreateWindow(640, 480, "Test", NULL, NULL); 
    if(NULL == window) 
    { 
     glfwTerminate(); 
     return EXIT_FAILURE; 
    } 
    glfwMakeContextCurrent(window); 

    glfwSwapInterval(1); 

    glewExperimental = GL_TRUE; 
    const GLenum glewErr = glewInit(); 
    if(GLEW_OK != glewErr) 
    { 
     std::cerr << "glewInit() failed: " << glewGetErrorString(glewErr) << std::endl; 
     glfwTerminate(); 
     return EXIT_FAILURE; 
    } 
    // consume spurious GL error from GLEW init 
    glGetError(); 

    GlDebugOutput::Install(); 

    init(); 

    while(!glfwWindowShouldClose(window)) 
    { 
     glfwPollEvents(); 

     int w, h; 
     glfwGetFramebufferSize(window, &w, &h); 
     glViewport(0, 0, w, h); 

     display(); 

     glfwSwapBuffers(window); 
    } 

    return EXIT_SUCCESS; 
} 

如果您的OpenGL實現和/或着色器甚至有一點點關閉,程序應該將血腥謀殺尖叫爲stderr並退出。

+0

我的userParams參數爲const之前,你的代碼不工作。但是它有很大的幫助,所以謝謝 – Yago 2015-02-28 10:48:42

+0

@Yago:對不起,我正在使用過時的GLEW,它有'GLDEBUGPROCARB'函數簽名錯誤。 – genpfault 2015-03-11 14:42:28

相關問題