Windows 英特尔驱动程序上没有日志消息的程序链接错误

Windows 英特尔驱动程序上没有日志消息的程序链接错误,windows,visual-c++,opengl,glsl,Windows,Visual C++,Opengl,Glsl,注意:我将首先明确地说出我的问题,然后我将更好地解释我的情况 在我的windows上,使用我的英特尔驱动程序。我可以编译这两个(分别是顶点着色器和片段着色器),但无法链接它们: attribute vec4 vertex; void main(void) { gl_Position = vertex; } , 我在链接上出错(链接状态为false),但信息日志为空 问题是,这个着色器在使用相同GPU的Linux中运行良好,在NVIDIA中运行良好。只有在使用英特尔驱动程序的win

注意:我将首先明确地说出我的问题,然后我将更好地解释我的情况

在我的windows上,使用我的英特尔驱动程序。我可以编译这两个(分别是顶点着色器和片段着色器),但无法链接它们:

attribute vec4 vertex;
void main(void) {
       gl_Position = vertex;
}
,

我在链接上出错(链接状态为false),但信息日志为空

问题是,这个着色器在使用相同GPU的Linux中运行良好,在NVIDIA中运行良好。只有在使用英特尔驱动程序的windows中,我才会遇到这个问题。My OpenGL通知以下有关驱动程序的信息:

GL_VENDOR Intel
GL_RENDERER Intel(R) HD Graphics Family
GL_VERSION 3.0.0 - Build 8.15.10.2253
GL_SHADING_LANGUAGE_VERSION 1.30  - Intel Build 8.15.10.2253
有趣的是,似乎不相关的修改会使程序正确链接,到目前为止,我发现了一些:

  • 如果第二个函数没有收到任何参数,它就工作了
  • 如果main()直接调用第三个函数,它就会工作
  • 如果统一不是一个数组,而是一个元素,那么它就可以工作
  • 如果不是将sampler2D从第二个传递到第三个,而是传递一个第三个将用于访问纹理的索引,那么它会起作用
  • 我的问题是如何使它工作,但保持相同的语义?我需要三个函数,我需要
    third
    main
    函数不使用制服,我需要只有
    second
    函数知道制服。另外,我需要
    second
    third
    函数接收参数。在我的真实场景中,第二个和第三个函数使用它接收到的值做了很多事情

    为了澄清,我所做的需要:

    在我正在开发的框架中,使用了三种不同的片段着色器。第一个(
    main
    (在我的参考代码中))是用户提供的,这个可以调用框架中定义的函数(
    second
    )。第三级也是用户提供的,但着色器只编译一次,不知道将使用多少次,也不知道使用了哪些值,
    second
    负责分配正确数量的缓冲区,并为每个缓冲区调用
    third

    以下是我用来测试着色器的代码:

    #include <SDL.h>
    #include <GL/glew.h>
    #include <iostream>
    #include <vector>
    #include <cassert>
    #include <sstream>
    #include <stdexcept>
    
    #define WIDTH 800
    #define HEIGHT 640
    
    void warn(const std::exception& e) {
    #ifndef NDEBUG
        std::cerr << "Warning: " << e.what() << std::endl;
    #endif
    };
    
    namespace {
    std::string tostr(unsigned a) { 
        std::stringstream ss;
        ss << a;
        return ss.str();
    }
    
    std::string errorname(unsigned a) {
        switch(a) {
        case GL_NO_ERROR:                      return "GL_NO_ERROR";
        case GL_INVALID_ENUM:                  return "GL_INVALID_ENUM";
        case GL_INVALID_VALUE:                 return "GL_INVALID_VALUE";
        case GL_INVALID_OPERATION:             return "GL_INVALID_OPERATION";
        case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
        case GL_OUT_OF_MEMORY:                 return "GL_OUT_OF_MEMORY";
        }
        return "";
    }
    
    }
    
    void checkGlErrorImpl(unsigned line, const char* file) {
        GLenum curerr = glGetError();
        if( curerr == GL_NO_ERROR )
            return;
    
        auto err = std::runtime_error(std::string("OpenGL ")+errorname(curerr)+" error on "+file+":"+tostr(line));
        warn(err);
        throw err;
    }
    
    #define checkGlError() checkGlErrorImpl(__LINE__,__FILE__)
    
    int create_shader(unsigned type, const char* shaderSource) {
        unsigned id = glCreateShader(type);
    
        const char* shaderSources[2] = {"#version 130\n",shaderSource};
        glShaderSource(id,2,shaderSources,NULL);
    
        glCompileShader(id);
        GLint compileStatus;
        glGetShaderiv(id, GL_COMPILE_STATUS, &compileStatus);
            int msgLength;
            glGetShaderiv(id, GL_INFO_LOG_LENGTH, &msgLength);
    
            char* msg = new char[msgLength];
            glGetShaderInfoLog(id, msgLength, &msgLength, msg);
    
            std::cout << "(" << id << ") " << msg << std::endl;
    
            std::runtime_error except(std::string("Error on compiling shader:\n")+msg);
            delete[] msg;
            if( compileStatus == GL_FALSE ) {
                warn(except);
                throw except;
            }
    
        checkGlError();
    
        return id;
    };
    
    int create_program(const std::vector<int>& shaders) {
        int id = glCreateProgram();
        checkGlError();
        for( unsigned int i=0; i< shaders.size(); ++i ) {
            glAttachShader(id,shaders[i]);
        }
    
        glLinkProgram(id);
        GLint linkStatus=-1;
        glGetProgramiv(id, GL_LINK_STATUS, &linkStatus);
        assert(linkStatus != -1);
        checkGlError();
        if( linkStatus == GL_FALSE ) {
            int msgLength=-1;
            glGetProgramiv(id, GL_INFO_LOG_LENGTH, &msgLength);
            assert( msgLength != -1 );
    
            char* msg = new char[msgLength+1];
            msg[0] = '\0';
            std::cout << "Buffer(" << msgLength+1 << ")" << msg << std::endl;
            glGetProgramInfoLog(id, msgLength+1, &msgLength, msg);
            std::cout << "Second length " << msgLength << std::endl;
            std::cout << "Log " << msg << std::endl;
            std::string errormsg("Error on linking shader: ");
            errormsg += msg;
    //      delete[] msg;
    
            auto err = std::runtime_error(errormsg);
            warn(err);
            throw err;
        }
    
        checkGlError();
    
        return id;
    }
    
    int main(int argc, char** argv) {
        if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
            throw __LINE__;
        }
    
        int video_flags;
        video_flags = SDL_OPENGL;
        video_flags |= SDL_GL_DOUBLEBUFFER;
        video_flags |= SDL_HWSURFACE;
        video_flags |= SDL_HWACCEL;
        SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
        SDL_Surface* surface = SDL_SetVideoMode( WIDTH, HEIGHT, 24, video_flags );
        if( surface == NULL )
            throw __LINE__;
    
        unsigned width = WIDTH;
        unsigned height = HEIGHT;
    
        GLenum err = glewInit();
        if (GLEW_OK != err) {
            std::cerr << "Error: " << glewGetErrorString(err) << std::endl;
            throw __LINE__;
        }
    
        std::vector<int> shaders;
        shaders.push_back( create_shader(GL_VERTEX_SHADER,
            "attribute vec4 vertex;\n"
            "void main(void) {\n"
            "   gl_Position = vertex;\n"
            "}\n"
        ));
        shaders.push_back( create_shader(GL_FRAGMENT_SHADER,
            "uniform sampler2D textures[2];\n"
            "vec4 third(sampler2D texture) {\n"
            "   return texture2D(texture,vec2(0.5,0.5));\n"
            "}\n"
            "vec4 second(float a) {\n"
            "   return third(textures[0]);\n"
            "}\n"
            "\n"
            "void main(void) {\n"
            "   gl_FragColor = second(0.0);\n"
            "}\n"
        ));
    
        int program = create_program(shaders);
    
        try {
            while( true ) {
                SDL_Event event;
                while( SDL_PollEvent(&event) ) {
                    switch( event.type ) {
                    case SDL_QUIT:
                        throw 0;
                    break;
                    }
                }
                SDL_Delay(10);
            }
        } catch( int returnal) {
            return returnal;
        }
        return 0;
    };
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #定义宽度800
    #定义高度640
    无效警告(const std::exception&e){
    #ifndef NDEBUG
    
    要解释我的问题和我试图实现的目标有点困难,如果仍然不清楚,请发表评论。“分别是几何体和碎片着色器”这不是几何体着色器。你不能在几何体着色器中使用
    属性
    。如果你想让OpenGL正常工作,而不会遇到驱动程序错误,不要混淆驱动程序。不要做不常用的事情,比如将同一着色器阶段的多个着色器链接到同一个程序中。这不是一个好主意。@Nicolasgh我原来的问题出现在多个着色器中,我在这里发布的代码对每个阶段只使用一个着色器。GL_供应商英特尔GL_渲染器英特尔(R)HD图形系列GL_版本3.0.0-Build 8.15.10.2253 GL_SHADING_语言版本1.30-英特尔Build 8.15.10.2253
    #include <SDL.h>
    #include <GL/glew.h>
    #include <iostream>
    #include <vector>
    #include <cassert>
    #include <sstream>
    #include <stdexcept>
    
    #define WIDTH 800
    #define HEIGHT 640
    
    void warn(const std::exception& e) {
    #ifndef NDEBUG
        std::cerr << "Warning: " << e.what() << std::endl;
    #endif
    };
    
    namespace {
    std::string tostr(unsigned a) { 
        std::stringstream ss;
        ss << a;
        return ss.str();
    }
    
    std::string errorname(unsigned a) {
        switch(a) {
        case GL_NO_ERROR:                      return "GL_NO_ERROR";
        case GL_INVALID_ENUM:                  return "GL_INVALID_ENUM";
        case GL_INVALID_VALUE:                 return "GL_INVALID_VALUE";
        case GL_INVALID_OPERATION:             return "GL_INVALID_OPERATION";
        case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
        case GL_OUT_OF_MEMORY:                 return "GL_OUT_OF_MEMORY";
        }
        return "";
    }
    
    }
    
    void checkGlErrorImpl(unsigned line, const char* file) {
        GLenum curerr = glGetError();
        if( curerr == GL_NO_ERROR )
            return;
    
        auto err = std::runtime_error(std::string("OpenGL ")+errorname(curerr)+" error on "+file+":"+tostr(line));
        warn(err);
        throw err;
    }
    
    #define checkGlError() checkGlErrorImpl(__LINE__,__FILE__)
    
    int create_shader(unsigned type, const char* shaderSource) {
        unsigned id = glCreateShader(type);
    
        const char* shaderSources[2] = {"#version 130\n",shaderSource};
        glShaderSource(id,2,shaderSources,NULL);
    
        glCompileShader(id);
        GLint compileStatus;
        glGetShaderiv(id, GL_COMPILE_STATUS, &compileStatus);
            int msgLength;
            glGetShaderiv(id, GL_INFO_LOG_LENGTH, &msgLength);
    
            char* msg = new char[msgLength];
            glGetShaderInfoLog(id, msgLength, &msgLength, msg);
    
            std::cout << "(" << id << ") " << msg << std::endl;
    
            std::runtime_error except(std::string("Error on compiling shader:\n")+msg);
            delete[] msg;
            if( compileStatus == GL_FALSE ) {
                warn(except);
                throw except;
            }
    
        checkGlError();
    
        return id;
    };
    
    int create_program(const std::vector<int>& shaders) {
        int id = glCreateProgram();
        checkGlError();
        for( unsigned int i=0; i< shaders.size(); ++i ) {
            glAttachShader(id,shaders[i]);
        }
    
        glLinkProgram(id);
        GLint linkStatus=-1;
        glGetProgramiv(id, GL_LINK_STATUS, &linkStatus);
        assert(linkStatus != -1);
        checkGlError();
        if( linkStatus == GL_FALSE ) {
            int msgLength=-1;
            glGetProgramiv(id, GL_INFO_LOG_LENGTH, &msgLength);
            assert( msgLength != -1 );
    
            char* msg = new char[msgLength+1];
            msg[0] = '\0';
            std::cout << "Buffer(" << msgLength+1 << ")" << msg << std::endl;
            glGetProgramInfoLog(id, msgLength+1, &msgLength, msg);
            std::cout << "Second length " << msgLength << std::endl;
            std::cout << "Log " << msg << std::endl;
            std::string errormsg("Error on linking shader: ");
            errormsg += msg;
    //      delete[] msg;
    
            auto err = std::runtime_error(errormsg);
            warn(err);
            throw err;
        }
    
        checkGlError();
    
        return id;
    }
    
    int main(int argc, char** argv) {
        if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
            throw __LINE__;
        }
    
        int video_flags;
        video_flags = SDL_OPENGL;
        video_flags |= SDL_GL_DOUBLEBUFFER;
        video_flags |= SDL_HWSURFACE;
        video_flags |= SDL_HWACCEL;
        SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
        SDL_Surface* surface = SDL_SetVideoMode( WIDTH, HEIGHT, 24, video_flags );
        if( surface == NULL )
            throw __LINE__;
    
        unsigned width = WIDTH;
        unsigned height = HEIGHT;
    
        GLenum err = glewInit();
        if (GLEW_OK != err) {
            std::cerr << "Error: " << glewGetErrorString(err) << std::endl;
            throw __LINE__;
        }
    
        std::vector<int> shaders;
        shaders.push_back( create_shader(GL_VERTEX_SHADER,
            "attribute vec4 vertex;\n"
            "void main(void) {\n"
            "   gl_Position = vertex;\n"
            "}\n"
        ));
        shaders.push_back( create_shader(GL_FRAGMENT_SHADER,
            "uniform sampler2D textures[2];\n"
            "vec4 third(sampler2D texture) {\n"
            "   return texture2D(texture,vec2(0.5,0.5));\n"
            "}\n"
            "vec4 second(float a) {\n"
            "   return third(textures[0]);\n"
            "}\n"
            "\n"
            "void main(void) {\n"
            "   gl_FragColor = second(0.0);\n"
            "}\n"
        ));
    
        int program = create_program(shaders);
    
        try {
            while( true ) {
                SDL_Event event;
                while( SDL_PollEvent(&event) ) {
                    switch( event.type ) {
                    case SDL_QUIT:
                        throw 0;
                    break;
                    }
                }
                SDL_Delay(10);
            }
        } catch( int returnal) {
            return returnal;
        }
        return 0;
    };