2011-12-22 17 views
7

Debo admitir que esta es la primera vez que implementa shaders, anteriormente solo he trabajado con pipeline de funciones fijas; sin embargo, aunque estoy seguro de que todo lo que hice es correcto, debe haber un error.OpenGL glLinkProgram devuelve falso pero el registro de información está vacío; comprobé todo

glLinkProgram(program) - devuelve GL_FALSE cuando se le preguntó por GL_LINK_STATUS. Además, el registro de información está vacío (cuando consulto la longitud del registro, es 1, que es el terminador nulo según los documentos, se retira). Por lo tanto, errores de enlazador y no registros. Además, acababa de descubrir que los problemas del enlazador ocurren tan pronto como utilizo la variable gl_Position en vertex shader, tanto durante la asignación como si la utilizo para los cálculos. Probé todo tipo de variaciones de sombreado, pero produce errores, pero no produce los registros; parece que devuelve GL_FALSE en cualquier momento en que se toca gl_Position. Curiosamente, fragment shader no causa ningún problema.

Los sombreadores de fragmentos y vértices compilan bien sin errores. Cuando introduzco los errores de sintaxis, se detectan, imprimen y el proceso se cancela antes de la creación del programa (por lo que parece funcionar bien). Depuré y me aseguré de que los archivos se cargaran correctamente, la fuente no se finalizó, los tamaños son correctos, verifiqué el número de programas adjuntos después del archivo adjunto y es 2 (número correcto). Se elimina para mayor claridad, tengo el método checkForErrors() que comprueba e imprime los errores de apertura - no se detecta ninguno.

Estoy perplejo, por favor alguien ayuda! He estado perdiendo el sueño por esto durante 2 días ahora ...

Este es el código para cargar el shader:

FILE *file = fopen(fileName.c_str(), "rb"); 

if(file == NULL) 
{ 
    Log::error("file does not exist: \"" + fileName + "\""); 
    return NULL; 
} 

// Calculate file size 
fseek(file , 0 , SEEK_END); 
int size = ftell(file); 
rewind(file); 

// If file size is 0 
if(size == 0) 
{ 
    Log::error("file is empty: \"" + fileName + "\""); 
    return NULL; 
} 

char **source = new char*[1]; 
source[0] = new char[size+1]; 
source[0][size] = '\0'; 

// If we weren't able to read the entire file into memory 
int readSize = fread(source[0], sizeof(char), size, file); 
if(size != readSize) 
{ 
    int fileError = ferror(file); 

    // Free the source, log an error and return false 
    delete source[0]; 
    delete [] source; 
    fclose(file); 
    Log::error("couldn't load file into memory [ferror(" + toString<int>(fileError) + ")]: \"" + fileName + "\" (Size: " + toString<int>(readSize) + "/" + toString<int>(size) + " bytes)"); 
    return NULL; 
} 

// Close the file 
fclose(file); 




// Create the shader object 


// shaderType is GLenum that is set based on the file extension. I assure you it is correctly set to either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER 
GLuint shaderID = glCreateShader(shaderType); 

// If we could not create the shader object, check for OpenGL errors and return false 
if(shaderID == 0) 
{ 
    checkForErrors(); 
    Log::error("error creating shader \"" + name); 
    delete source[0]; 
    delete [] source; 
    return NULL; 
} 

// Load shader source and compile it 
glShaderSource(shaderID, 1, (const GLchar**)source, NULL); 
glCompileShader(shaderID); 

GLint success; 
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success); 
if(!success) 
{ 
    GLchar error[1024]; 
    glGetShaderInfoLog(shaderID, 1024, NULL, error); 
    Log::error("error compiling shader \"" + name + "\"\n Log:\n" + error); 
    delete source[0]; 
    delete [] source; 
    return NULL; 
} 
else 
{ 
    Log::debug("success! Loaded shader \"" + name + "\""); 
} 

// Clean up 
delete source[0]; 
delete [] source; 

nota rápida: glShaderSource - yo echo a (const GLchar **) porque GCC se queja de los punteros const to non const char; De lo contrario, creo que soy totalmente obediente.

No hay errores allí, por cierto. Los sombreadores (a continuación) compilan sin ningún error.

Vertex Shader:

void main() 
{ 
    // If I comment the line below, the link status is GL_TRUE. 
    gl_Position = vec4(1.0, 1.0, 1.0, 1.0); 
} 

Fragmento de Shader:

void main() 
{ 
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 
} 

A continuación se muestra el código que crea el programa de sombreado, se une objetos y enlaces, etc .:

// Create a new shader program 
GLuint program = glCreateProgram(); 
if(program == 0) 
{ 
    Log::error("RenderSystem::loadShaderProgram() - could not create OpenGL shader program; This one is fatal, sorry."); 
    getContext()->fatalErrorIn("RenderSystem::loadShaderProgram(shader1, shader2)", "OpenGL failed to create object using glCreateProgram()"); 
    return NULL; 
} 

// Attach shader objects to program 
glAttachShader(program, vertexShaderID); 
glAttachShader(program, fragmentShaderID); 

// Link the program 
GLint success = GL_FALSE; 
glLinkProgram(program); 
checkForErrors(); 
glGetProgramiv(program, GL_LINK_STATUS, &success); 
if(success == GL_FALSE) 
{ 
    GLchar errorLog[1024] = {0}; 
    glGetProgramInfoLog(program, 1024, NULL, errorLog); 
    Log::error(std::string() + "error linking program: " + errorLog); 
    return NULL; 
} 

success = GL_FALSE; 
glValidateProgram(program); 
glGetProgramiv(program, GL_VALIDATE_STATUS, &success); 
if(success == GL_FALSE) 
{ 
    GLchar errorLog[1024] = {0}; 
    glGetProgramInfoLog(program, 1024, NULL, errorLog); 
    checkForErrors(); 
    Log::error(std::string() + "error validating shader program; Details: " + errorLog); 
    return NULL; 
} 

Por lo general, ni siquiera llega a validar el programa ... Estoy tan frustrado con esto, es muy difícil no e vulgar.

¡Su ayuda es necesaria y cualquier ayuda es realmente apreciada!

EDITAR: Estoy ejecutando todo en Intel HD 3000 (con soporte para OpenGL hasta 3.1). Mi versión de OpenGL objetivo es 2.0.

Edit2: También me gustaría señalar que tuve algunos problemas con la lectura de los sombreadores de archivos de texto si fijo la banderas "RT" "r" o en fopen - el tamaño de lectura era más pequeño que el tamaño real en un 10 bytes (consistentemente en todos los archivos) - y feof() devolvería verdadero. Cuando cambié a lectura en binario ("rb"), el problema desapareció y los archivos se leyeron por completo. Intenté varias implementaciones alternativas y todas produjeron el mismo error durante la vinculación (e imprimí la fuente del sombreador en la consola justo después de leer el archivo para asegurar que se ve correcto, lo hace).

+1

¿Dónde está tu declaración '# version' en tu shader? –

+0

No incluí uno ... ¿podría ser eso? Lo buscaré en Google, pero si puedo, ¿cuál sería una versión de shader apropiada para el objetivo de OpenGL 2.0? – Kaa

+0

Intenté usar #version 150, #version 140 y #version 130 en tres pruebas distintas (la misma versión para ambos sombreadores), y los resultados son los mismos: el estado del enlace devuelve GL_FALSE, y no hay ningún registro de información :( – Kaa

Respuesta

14

OK, sabía cuando estaba publicando que esto sería embarazoso, pero es bastante malo: la aplicación de configuración de gráficos Intel que generalmente acompaña a un controlador Intel tiene una pestaña de configuración 3D; Ahora, la casilla de verificación "configuraciones personalizadas" no estaba marcada, pero la opción atenuada en la configuración "Procesamiento de vértices" decía "Habilitar el procesamiento de software". Aunque no estaba marcado y todo estaba atenuado, simplemente ingresé la configuración personalizada y revisé todo en "Configuración de la aplicación".

¡Eso lo arregló! ¡Todo se vincula como debería! No sé quién pensó en esa opción, ¿por qué sería útil? Es la única opción que se ve increíblemente fuera de lugar.

Pasé por varias reinstalaciones de controladores, depuración intensa e investigación de configuración, ¡tuve que especular y adivinar absolutamente todo! Terrible, no lo desearía en mis peores enemigos. Perdón por molestar a todos, pero si hay otro idiota como yo, eres bienvenido :)

Cuestiones relacionadas