I must admit that this is my first experience in implementing shaders, previously I only worked with a pipeline with a fixed function; however, although I am sure that everything I have done is correct - there must be a mistake.
glLinkProgram(program)
- Returns GL_FALSE
when prompted for GL_LINK_STATUS
. In addition, the information log is empty (when I request the length of the log - this is 1, which is the null terminator for documents, it checks). So there are linker errors and no logs. In addition, I just discovered that linker problems occur as soon as I use the gl_Position
variable in the vertex shader, both during assignment and when I use it for calculations. I tried all kinds of shader options, these are errors, but he could not create logs - it seems that he returns GL_FALSE
at any time gl_Position
. Interestingly, the fragment shader does not cause any problems.
Both fragments and vertex shaders compile without errors. When I introduce syntax errors, they are detected, printed, and the process is interrupted before the program is created (so it seems to be working fine). I debugged and ensured that the files loaded properly, the source was completed with zero, the sizes were correct, I checked the number of connected programs after attachment and 2 (the correct lol). It has been removed for clarity, I have a checkForErrors()
method that checks and prints opengl errors - no one has been detected.
I'm at a standstill, please help someone! Iβm losing sleep over this for 2 days ...
This is the code to load the 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;
Quick note: glShaderSource - I drop (const GLchar **) because GCC complains about const constants for non-constant char pointers; Otherwise, I believe that I completely agree.
No errors, by the way. Shaders (below) compile without errors.
Vertex Shader:
void main() {
Fragment Shader:
void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }
Below is the code that creates the shader program, attaches objects and links, 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; }
Usually it doesnβt even get to the program check ... I am so upset by this that it is very difficult not to be vulgar.
Your help is needed and any help is really appreciated!
EDIT: I run everything on Intel HD 3000 (with OpenGL support up to 3.1). My target version is OpenGL 2.0.
EDIT2: I would also like to point out that I had some problems reading shaders from text files if I set the "r" or "rt" flags to fopen - the read size was less than the actual size by about 10 bytes (consistently on all files ) - and feof () will return true. When I switched to reading in binary ("rb"), the problem disappeared and the files were read completely. I tried several alternative implementations, and they all produced the same error while linking (and I print the shader source for the console right after reading the file to make sure it looks correct.)