I am working on a Qt6 application which features a QOpenGLWidget where I render using some GLSL shaders.
I try to use the Qt6 helpers and primitives for OpenGL as much as possible.
I set up my context to use OpenGL version 4.6 core and log the result with this code:
// Print OpenGL version information
qDebug().nospace().noquote() << "OpenGL actual version: " << context->format().version().first << "." << context->format().version().second;
qDebug().nospace().noquote() << "OpenGL vendor:" << QString(reinterpret_cast<const char*>(functions->glGetString(GL_VENDOR)));
qDebug().nospace().noquote() << "OpenGL renderer:" << QString(reinterpret_cast<const char*>(functions->glGetString(GL_RENDERER)));
The corresponding output looks like this:
OpenGL actual version: 4.6
OpenGL vendor:NVIDIA Corporation
OpenGL renderer:Quadro P400/PCIe/SSE2
I also log the number of available uniform locations with the following code:
// Retrieve the maximum uniform locations
GLint maxUniformLocations;
functions->glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, &maxUniformLocations);
qDebug().nospace().noquote() << "Maximum uniform locations:" << maxUniformLocations;
and it outputs:
Maximum uniform locations:65536
The code that sets uniforms run on every frame and looks like this:
//program.setUniformValue("last_draw_down", lastButtonsPressed[DRAW_BUTTON_INDEX]);
//program.setUniformValue("last_now", lastNow);
program.setUniformValue("bits_per_channel", bits_per_channel);
program.setUniformValue("brightness", brightness.value().toFloat());
program.setUniformValue("clock", static_cast<GLfloat>(now%1000)/1000.0f);
program.setUniformValue("contrast", contrast.value().toFloat());
program.setUniformValue("dithering", dithering.value().toFloat());
program.setUniformValue("is_dragging", is_dragging);
program.setUniformValue("is_draw_down", buttonsPressed[DRAW_BUTTON_INDEX]);
program.setUniformValue("is_navigation_down", buttonsPressed[NAVIGATION_BUTTON_INDEX]);
program.setUniformValue("last_dragged", last_dragged);
program.setUniformValue("last_navigation_down", lastButtonsPressed[NAVIGATION_BUTTON_INDEX]);
program.setUniformValue("modelMat", modelMat);
program.setUniformValue("now", now);
program.setUniformValue("projectionMat", projectionMat);
program.setUniformValue("resolution", size());
program.setUniformValue("texture_array", textureUnit);
program.setUniformValue("viewMat", viewMat);
As you can see there are exactly 16 uniforms set. If I add just one more uniform (for example by uncommenting one of the lines at the top), the program starts to spit the following in error output:
OpenGL Message: "GL_INVALID_OPERATION error generated. Wrong component type or count."
(I have debug enabled in my OpenGL context) It does not really matter which uniforms are enabled, just the number.
So my question is, how come I can't set more than 16 uniforms when my context clearly claims there is room for 65536 (4096 times as many)?
I don't know exactly what's wrong with your code, but I have some ideas that might help.
setUniformValuemethod does, but I guess it calls one of theglUniform*functions. According to the docs, this function won't give you an error if you use too many uniform locations. It gives you errors for example when you want to put avec4where there is only afloatin the shader. You should check these errors: https://docs.gl/gl4/glUniform#errorsMAX_VERTEX_UNIFORM_COMPONENTS(which has to be at least 1024). Avec4has 4 components amat3has 9 etc. and in a vertex shader you can only useMAX_VERTEX_UNIFORM_COMPONENTSmany uniform components. So you should check these other limits as well.glGetError, you should set up a debug message callback to get more information about the error. Here is a good tutorial: https://learnopengl.com/In-Practice/Debugging