I'm writing OpenGL code for a project, using Visual Studio and C++. I have created a shader that contains a Uniform Block correctly linked and initialized in the source code. This is the source code part:
unsigned int sunLightUBO;
glGenBuffers(1, &sunLightUBO);
glBindBuffer(GL_UNIFORM_BUFFER, sunLightUBO);
glBufferData(GL_UNIFORM_BUFFER, 48, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_UNIFORM_BUFFER, 0, 12, &sunDirection);
glBufferSubData(GL_UNIFORM_BUFFER, 12, 12, &sunAmbient);
glBufferSubData(GL_UNIFORM_BUFFER, 24, 12, &sunDiffuse);
glBufferSubData(GL_UNIFORM_BUFFER, 36, 12, &sunSpecular);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
unsigned int sunLightIndex = glGetUniformBlockIndex(floor.ID, "sunLight");
glUniformBlockBinding(floor.ID, sunLightIndex, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, sunLightUBO);
While this is the part related to the shader, specifically the Fragment Shader:
layout (std140) uniform sunLight
{ //offset
vec3 direction; //0
vec3 ambient; //12
vec3 diffuse; //24
vec3 specular; //36
};
When I try to compile it gives me this error:
I've been trying to solve this problem for some time now. I tried to search all over the internet, looking for a solution, but even if they dealt with the problem of the .pdb file not loaded, they were not solutions that helped me.
I illustrate below everything I have tried:
- I activated the two servers available by default (Microsoft Symbol Servers and NuGet.org Symbol Server) and I let all the modules load without making exceptions. I also tried to set "atio6axx.dll" as the only module to load.
- Since I have an ATI Radeon video card, I added as server symbol, the one provided by AMD that is https://download.amd.com/dir/bin found on the site https://gpuopen.com/learn/amd-driver-symbol-server/. Even with this server added and activated, I tried to load all the modules and then only the one I needed (atio6axx.dll).
- I downloaded PDB Downloader at the link https://github.com/rajkumar-rangaraj/PDB-Downloader/releases/download/v1.0/PDBDownloader.exe but it didn't help because it couldn't download the file I needed.
- I manually copied the atio6axx.dll file to the same directory as the source code
If I try to remove the Uniform Block in the fragment shader, everything works fine, so surely it's because of it. I don't know what else to try, does anyone have a solution?
EDIT
I corrected the part about the offset and the memory allocated in the buffer:
unsigned int sunLightUBO;
glGenBuffers(1, &sunLightUBO);
glBindBuffer(GL_UNIFORM_BUFFER, sunLightUBO);
glBufferData(GL_UNIFORM_BUFFER, 64, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_UNIFORM_BUFFER, 0, 16, &sunDirection);
glBufferSubData(GL_UNIFORM_BUFFER, 16, 16, &sunAmbient);
glBufferSubData(GL_UNIFORM_BUFFER, 32, 16, &sunDiffuse);
glBufferSubData(GL_UNIFORM_BUFFER, 48, 16, &sunSpecular);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
unsigned int sunLightIndex = glGetUniformBlockIndex(floor.ID, "sunLight");
glUniformBlockBinding(floor.ID, sunLightIndex, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, sunLightUBO);
and
layout (std140) uniform sunLight
{ //offset
vec3 direction; //0
vec3 ambient; //16
vec3 diffuse; //32
vec3 specular; //48
};
Unfortunately, the error persists and is always the same
EDIT 2
Using the "Step Over" debug option, I found that the exception is thrown upon arriving at the line where I create the unsigned int sunLightUBO:
unsigned int sunLightUBO; <--Here the exception is thrown
glGenBuffers(1, &sunLightUBO);
glBindBuffer(GL_UNIFORM_BUFFER, sunLightUBO);
glBufferData(GL_UNIFORM_BUFFER, 48, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_UNIFORM_BUFFER, 0, 12, &sunDirection);
glBufferSubData(GL_UNIFORM_BUFFER, 12, 12, &sunAmbient);
glBufferSubData(GL_UNIFORM_BUFFER, 24, 12, &sunDiffuse);
glBufferSubData(GL_UNIFORM_BUFFER, 36, 12, &sunSpecular);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
unsigned int sunLightIndex = glGetUniformBlockIndex(floor.ID, "sunLight");
glUniformBlockBinding(floor.ID, sunLightIndex, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, sunLightUBO);
Before this line I only create and link one shader. Before that, there are all the classic lines for initializing a window with GLFW and pointers to OpenGL functions with GLAD. I also tried to initialize the variable that throws the exception, setting it equal to 0, but it doesn't change anything.
SOLUTION
After several attempts, I decided to test the project on another pc. I state that: the initial pc with which I encountered the error is an HP Pavilion dv6 6c80el which is equipped with an ATI Radeon HD 7690M XT video card and is almost 10 years old. The second pc on which I tested the project, on the other hand, is decidedly more powerful in everything and is equipped with a GTX 980.
While debugging on the second pc, I immediately noticed that the console was showing me errors in the fragment shader code, which the first pc did not show. The error was related to the syntax used inside the fragment shader main; to refer to the variables within the Uniform Block, I wrote (in my case) sunLight.direction (for example). Instead you had to write only direction. Unfortunately the console did not show me these errors in the first pc and consequently I did not insert the code regarding the main in the initial question, my mistake. In any case I don't know why the console didn't show me these errors. I think it's because my Radeon card worked differently in debugging than the NVidia GTX.
Correct the syntax, the console would start showing me errors again. Fixed these last errors, always related to the fragment shader (conversion problems from vec3 to vec4 ...), the program started correctly.
Also, to write shaders, I use a Visual Studio extension called "GLSL Language Integration". Apparently this extension fails to recognize all syntax errors of a GLSL code, because for example the fact that I wrote sunLight.direction instead of direction, did not report it to me. And as a result of this, the engine that handled syntax error checking was not working. For example, given a vec4 called vector, I could write vector.rgbdsfuiweda and it wouldn't report it to me as an error anyway. In other words, the syntax error that he could not recognize, confused the recognition of many other possible errors in the code. So you have to be very careful.