I am Newbie trying things with shaders, I am trying to pass a parameter passBoolean from vertex shader to a fragment shader
vertexShader.vert
:
#version 330
layout(location = 0) in vec3 pos;
out vec3 FragPos;
out float passBoolean;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
void main()
{
passBoolean=-1.0;
gl_Position = projection * view * model * vec4(pos, 1.0); // the order is important : projection-view-model
FragPos = (model * vec4(pos, 1.0)).xyz;
}
fragmentShader.frag
:
#version 330
out vec4 colour;
in float passBoolean;
void main()
{
if(passBoolean == -1.0) colour = vec4(1.0, 0.0, 0.0, 0.0);
else colour = vec4(0.7, 0.7, 0.7, 0.0);
}
I get the following error :
Error linking program: 'The shader uses varying passBoolean, but previous shader does not write to it. Out of resource error.
The vShader does write to passBoolean
, so I don’t understand the error,
is there something else to be done in the compilation side of the shaders that I am not aware of ?
is it a shader version problem ?
Which graphics driver and driver version are you using? (Sounds like Intel drivers)
Double-check that the program object you are linking contains:
- exactly the above 2 vertex and fragment shaders (compiled of course),
- only the above 2 shaders, and
- The first is created
GL_VERTEX_SHADER
and the second GL_FRAGMENT_SHADER
.
Failing that…:
- Try this on NVIDIA or AMD OpenGL drivers, instead of Intel.
- (Intel bug workaround:) Try compiling the shaders and attaching the shaders to the program object in the order: 1) VERTEX, 2) FRAGMENT.
For more insight on these last 2 suggestions, see these links:
Thanks.
I am using an Intel and an Nvidia GPU.
Nvidia driver version : 556.13
Compilation code :
void Shader::CompileShader(const char* vertexCode, const char* fragmentCode)
{
shaderID = glCreateProgram();
if (!shaderID)
{
printf("Error creating shader program!\n");
return;
}
AddShader(shaderID, vertexCode, GL_VERTEX_SHADER);
AddShader(shaderID, fragmentCode, GL_FRAGMENT_SHADER);
GLint result = 0;
GLchar eLog[1024] = { 0 };
glLinkProgram(shaderID);
glGetProgramiv(shaderID, GL_LINK_STATUS, &result);
if (!result)
{
glGetProgramInfoLog(shaderID, sizeof(eLog), NULL, eLog);
printf("Error linking program: '%s'\n", eLog);
return;
}
glValidateProgram(shaderID);
glGetProgramiv(shaderID, GL_VALIDATE_STATUS, &result);
if (!result)
{
glGetProgramInfoLog(shaderID, sizeof(eLog), NULL, eLog);
printf("Error validating program: '%s'\n", eLog);
return;
}
uniformProjection = glGetUniformLocation(shaderID, "projection");
uniformModel = glGetUniformLocation(shaderID, "model");
uniformView = glGetUniformLocation(shaderID, "view");}
Note that it works fine without the additional varying float.
I have just tested with another computer that has an NVIDIA and an AMD, it worked fine !
This must be that bug you mentioned about Intel GPUs.
How do I choose the GPU my OpenGL code uses ?
Thanks
Windows? Microsoft keeps dorking with how you set this. But what you’re looking for is the knob that selects the “High performance” GPU, not the “Power Saving” GPU.
It might be enough to make sure you have this selected:
Control Panel
→ Hardware and Sound
→ Power Options
Power Plan
= High performance
but you might need to do something awkward like this.
Just search settings for Power plan
→ Change advanced power settings
, and that’ll probably get you close.
Alternatively, check under Graphics settings
. There’s some GPU related stuff in here. But on a desktop GPU with discrete GPUs, nothing about GPU selection.
So there is no clean way of doing this other than using Vulkan (vkEnumeratePhysicalDevices) ?