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).
¿Dónde está tu declaración '# version' en tu shader? –
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
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