langkopf langkopf - 19 days ago 5
C++ Question

OpenGL glUniform1ui() throws GLError GL_INVALID_OPERATION

I am trying to initialize a usampler2D in my fragment Shader

uniform vec3 lightColor;

uniform usampler2D texSampler;///////////

uniform vec3 ambientLight;
uniform vec3 lightPosition;
uniform vec3 cameraPosition;


in Vertex{
vec4 rawPosition;
vec2 uv;
vec4 normal;
}vertexIn;

in InstanceData{
unsigned int textureUnitIndex;
}instance;
out vec4 color;

void main(){

vec3 normal = normalize(vec3(vertexIn.normal.x, vertexIn.normal.y, vertexIn.normal.z));
vec3 worldPosition = vec3(vertexIn.rawPosition.x, vertexIn.rawPosition.y, vertexIn.rawPosition.z);

vec3 lightVector = normalize(lightPosition - worldPosition);
vec3 cameraVector = normalize(cameraPosition - worldPosition);
vec3 halfVec = normalize(lightVector + cameraVector);

float lightAngle = clamp(dot(lightVector, normal), 0.0f, 1.0f);
float specAngle = clamp(dot(halfVec, normal), 0.0f, PI);
float specular = clamp(pow(specAngle, 128), 0.0f, 1.0f);
unsigned int index = instance.textureUnitIndex;

vec4 actColor = texture2D(texSampler, vec2(vertexIn.uv)); //////////////////////
vec4 diffuseLight = sqrt(actColor * vec4(lightColor, 1.0)) * lightAngle;
vec4 specularLight = 1.0f - (cos(vec4(lightColor, 1.0f) * specular));

color = actColor * (vec4(ambientLight, 1.0) + diffuseLight) + specularLight;// + vec4(ambientLight, 1.0f);
}


Like this

void ShaderProgram::addUniform(std::string uniformName, unsigned int uniformValue)
{
unsigned int loc = glGetUniformLocation(_programID, uniformName.c_str());
Graphic::checkOpenGLErrors("addUniform() - 1");
glUniform1ui(loc, (GLuint)uniformValue);
Graphic::checkOpenGLErrors("addUniform - 2");
}


loc turns out to be 6 and uniformValue equals 2 but checkOpenGLErrors() still throws

"OpenGL ERROR: GL_INVALID_OPERATION - At: addUniform - 2"


Is there something you need to know about initializing sampler uniforms? Because this function usually does not throw errors in this GLSL program

Thanks

Answer

You must use glUniform1i or 1iv when uploading uniforms for opaque types (including samplers). Just because the sampler uses an unsigned integer format doesn't mean the uniform call changes to match.