Я испытываю следующую ошибку в GLSL.Вот фрагментный шейдер:
#version 450 core
#define DIFFUSE_TEX_UNIT 0
#define INDEX_UNIFORM_LOC 0
layout(binding = DIFFUSE_TEX_UNIT) uniform sampler2D colorTex;
#ifdef SOME_SPECIAL_CASE
layout (location = INDEX_UNIFORM_LOC) uniform uint u_blendMode;
//...more code here related to the case
#endif
//... rest of the code(not important)
Теперь, когда я компилирую этот шейдер в программу без объявления SOME_SPECIAL_CASE и все еще устанавливаю u_blendMode
равномерно во время выполнения, я получаю следующую ошибку от драйвера:
Сгенерирована ошибка GL_INVALID_OPERATION.значение недействительно;ожидается GL_INT или GL_UNSIGNED_INT64_NV.
Но я ожидаю получить ошибку, подобную этой:
GL_INVALID_OPERATION генерируется ошибка.'location' недопустимо.
Поскольку нет места с таким индексом (0), если я не установлю флаг препроцессора SOME_SPECIAL_CASE
.Затем я решил проверить, какую форму я получил, для чего требуется GL_INT
или GL_UNSIGNED_INT64_NV
, поэтому я запросил имя формы на основе его местоположения (ноль):
char buff[20];
GLsizei len = 0;
glGetActiveUniformName(prog.progHandle, 0, 20, &len, buff);
И получил имя 'colorTex', которое является именем сэмплера2D, имеющего индекс привязки DIFFUSE_TEX_UNIT
, который также равен нулю.До сих пор я считал, что единообразное расположение и точки привязки не используют одни и те же индексы, и я все еще верю, что это не так, потому что в противном случае этот шейдер при компиляции с SOME_SPECIAL_CASE
active потерпит неудачу, как и многие другие шейдеры, которые я написал через мойИстория работы. Но это выглядит очень странно, почему на единообразный индекс привязки sampler2D влияют, когда я задаю несуществующее унифицированное местоположение, и я также использую определенный тип (GLSL - uint)
glProgramUniform1ui(prog, location, (GLuint)value);
Что также не 'не соответствует типу sampler2D (так что ошибка, по крайней мере, относительно несоответствия типов).Это ошибка драйвера?
Еще одна вещь, я попытался проверить документы , действительно ли индексы привязки и местоположения действительно перекрываются, и обнаружил следующее утверждение:
Недопустимо назначать одно и то жеединое местоположение для двух униформ в одном шейдере или в одной программе.Даже если эти две униформы имеют одинаковое имя и тип и определены на разных этапах шейдера, недопустимо явно назначать им одно и то же унифицированное местоположение;возникнет ошибка компоновщика.
Это абсолютно неправильно!Я делал это годами.И попробовал это снова после прочтения этих строк.Имея одинаковую униформу, с одинаковым расположением в вершинном и фрагментном шейдерах, компилируется и работает нормально.
Моя настройка:
- NVIDIA Quadro P2000, драйвер 419.17
- OpenGL 4.5
- Windows 10 64-битная
Что касается возможности использовать одинаковую униформу в одном и том же месте, по крайней мере на графическом процессоре NVIDIA следующие компилируются и работают нормально:
Vertex shader
#version 450 core
#define MVP_UNIFORM_LOC 2
layout(location = 0) in vec2 v_Position;
layout(location = MVP_UNIFORM_LOC) uniform mat4 u_MVP;
smooth out vec2 texCoord;
void main()
{
texCoord = v_Position;
gl_Position = u_MVP * vec4(v_Position,0.0,1.0);
}
Фрагмент шейдера:
#version 450 core
#define MVP_UNIFORM_LOC 2
#define TEX_MAP_UNIT 5
layout(binding = TEX_MAP_UNIT ) uniform sampler2D texMap;
layout(location = MVP_UNIFORM_LOC) uniform mat4 u_MVP;
smooth in vec2 texCoord;
out vec4 OUTPUT;
void main()
{
vec4 tex = texture(texMap, texCoord);
OUTPUT = u_MVP * tex;
}