Windows 英特尔驱动程序上没有日志消息的程序链接错误
注意:我将首先明确地说出我的问题,然后我将更好地解释我的情况 在我的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
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
有趣的是,似乎不相关的修改会使程序正确链接,到目前为止,我发现了一些:
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;
};