ПрограммированиеФорумГрафика

GLSL: о причине, по которой glGetUniformLocation() может вернуть -1 (комментарии)

Страницы: 1 2 Следующая »
#0
4:22, 11 дек 2012

GLSL: о причине, по которой glGetUniformLocation() может вернуть -1 (комментарии)

Это сообщение сгенерировано автоматически.

#1
4:22, 11 дек 2012

А не проще ли проверять, не равен ли location минус единице, и не вызывать glUniform* для него? Я просто написал свои функции установки юниформа в классе шейдера, которые делают эту проверку, и радуюсь.

#2
8:45, 11 дек 2012

Проблема на ровном месте. :)

1) В доке написано почему glGetUniformLocation может быть -1:
This function returns -1 if name does not correspond to an active uniform variable in program

2) Не является ошибкой вызов glUniform с location -1. О чём опять же написано в доке:
If location is equal to -1, the data passed in will be silently ignored and the specified uniform variable will not be changed.

Автор видимо предпочитает потратить кучу времени на изобретение велосипеда, вместо того, чтобы потратить одну минуту на чтение доки.

#3
9:11, 11 дек 2012

Вот так я делаю. Всё без каких-то там проверок нормально идет.

GL.CreateProgram = function(identifier, uniforms, attribs, textures)
{
  var p = gl.createProgram();
  var program =
  {
    identifier: identifier,
    program: p,
    attribs: []
  };

  var vsh = gl.createShader(gl.VERTEX_SHADER);
  gl.shaderSource(vsh, document.getElementById('vsh' + identifier).text);
  gl.compileShader(vsh);
  if (gl.getShaderParameter(vsh, gl.COMPILE_STATUS) !== true)
    Sys.Error('Error compiling shader: ' + gl.getShaderInfoLog(vsh));

  var fsh = gl.createShader(gl.FRAGMENT_SHADER);
  gl.shaderSource(fsh, document.getElementById('fsh' + identifier).text);
  gl.compileShader(fsh);
  if (gl.getShaderParameter(fsh, gl.COMPILE_STATUS) !== true)
    Sys.Error('Error compiling shader: ' + gl.getShaderInfoLog(fsh));

  gl.attachShader(p, vsh);
  gl.attachShader(p, fsh);

  gl.linkProgram(p);
  if (gl.getProgramParameter(p, gl.LINK_STATUS) !== true)
    Sys.Error('Error linking program: ' + gl.getProgramInfoLog(p));

  gl.useProgram(p);
  var i;
  for (i = 0; i < uniforms.length; ++i)
    program[uniforms[i]] = gl.getUniformLocation(p, uniforms[i]);
  for (i = 0; i < attribs.length; ++i)
  {
    program.attribs[program.attribs.length] = attribs[i];
    program[attribs[i]] = gl.getAttribLocation(p, attribs[i]);
  }
  for (i = 0; i < textures.length; ++i)
  {
    program[textures[i]] = i;
    gl.uniform1i(gl.getUniformLocation(p, textures[i]), i);
  }

  GL.programs[GL.programs.length] = program;
  return program;
};

GL.UseProgram = function(identifier)
{
  var i, j;
  var program = GL.currentprogram;
  if (program != null)
  {
    if (program.identifier === identifier)
      return program;
    for (i = 0; i < program.attribs.length; ++i)
      gl.disableVertexAttribArray(program[program.attribs[i]]);
  }
  for (i = 0; i < GL.programs.length; ++i)
  {
    program = GL.programs[i];
    if (program.identifier === identifier)
    {
      GL.currentprogram = program;
      gl.useProgram(program.program);
      for (j = 0; j < program.attribs.length; ++j)
        gl.enableVertexAttribArray(program[program.attribs[j]]);
      return program;
    }
  }
};

GL.UnbindProgram = function()
{
  if (GL.currentprogram == null)
    return;
  var i;
  for (i = 0; i < GL.currentprogram.attribs.length; ++i)
    gl.disableVertexAttribArray(GL.currentprogram[GL.currentprogram.attribs[i]]);
  GL.currentprogram = null;
};
#4
9:53, 11 дек 2012

ALPINE

можно, например, вписав вот такую строчку в конец фраргментного шейдера:

gl_FragColor.r += 0.000001*v_uv[0];

Она не окажет влияния на картинку, зато не даст компилятору съесть переменную. А ближе к финальной версии неиспользуемых переменных в шейдере само собой быть не должно .

Мда... такой нелепый "хинт" - загружать шейдер вычислениями с неиспользуемой переменной - мне даже в голову не приходил :-|.
В моём "движке" ошибка выводится только для тех uniform'ов, которые должны быть железно в шейдере.
Остальные - просто засоряют лог warning'ами в дебаге (что несколько утомительно, когда одна шейдерная программа линкуется из разных кусочков и в некоторых комбинациях часть uniform'ов отбрасывается).

#5
9:59, 11 дек 2012

ALPINE

Это не наш метод :)

#6
12:12, 11 дек 2012

Я так и в HLSL делаю, когда чтото тестирую.

#7
21:39, 11 дек 2012

> Автор видимо предпочитает потратить кучу времени на изобретение велосипеда,
> вместо того, чтобы потратить одну минуту на чтение доки.
Автор предпочитает потратить кучу времени на выяснение обстоятельства, почему glGetError не пустой. А судя по

will be silently ignored

должен быть пустой. Из предположений - Valve не до конца допилили драйвер nVidia в линуксе.

> Мда... такой нелепый "хинт"
Первое, что пришло в голову. Есть идеи получше? Говорите, приму к сведению и допишу.

> А не проще ли проверять, не равен ли location минус единице
Не проще, т.к. если наткнусь на -1, то надо будет еще и отменять вызовы glEnableVertexAttribArray и так далее.

#8
22:30, 28 янв 2013

Хех, -1 выбрасывает, если запрашиванных переменных в шейдере нету. А нету их по трем причинам: 1) Шейдер не сбилдился и там нету никаких переменных вообще, в том числе и этой. 2) Шейдер сбилдился но этой переменной там нету. 3) Когда шейдер билдился эта переменная оказалась не использованной и ее выбросили ради оптимизации, соответственно ее там нету. И того "о причине, по которой glGetUniformLocation() может вернуть -1": исключительно тогда когда запрашиваемой переменной нету. А причины по которым она все же есть но куда-то пропала, можно описать отдельно. ИМХО.

#9
4:00, 29 янв 2013

Cyber_Wanderer
> если запрашиванных переменных в шейдере нету. А нету их по трем причинам
А в первых двух случаях ошибок разве никаких нет? В первой уж точно должна быть - статус соответствующий будет, валидация не пройдёт. Про второй случай вот не знаю, но никто в здравом уме не будет искать отсутствующую переменную, так ведь? А вот в третьем случае однозначно не скажешь, что переменная отсутствует - ты её определил и вроде как даже использовал. А её нет. Именно из-за этого ситуация несколько сбивающая с толку и именно из-за этого я о ней и рассказал.

#10
11:47, 29 янв 2013

ALPINE
> А вот в третьем случае однозначно не скажешь, что переменная отсутствует - ты
> её определил и вроде как даже использовал. А её нет.

Ты противоречивые вещи говоришь.
Если переменная используется, то она будет. Её нет, потому что она не используется.
Не может быть ситуации, когда ты используешь переменную, а её нет.
Под использованием естественно подразумеваю влияние на вычисления.

#11
15:10, 29 янв 2013

Executor
> Под использованием естественно подразумеваю влияние на вычисления.
Так я же и пишу - во время экспериментов с шейдером не углядел, что результат вычислений я случайно перезаписал константой (см. пример кода фрагментного шейдера в начале статьи). Да, факт перезаписи имеет место, да, на вычисления переменная уже не влияет. Но это не очень-то и очевидно во время работы над шейдером (комментирования кусков кода и т.д.). Далеко не сразу можно сообразить, откуда внезапно в лог вывалилось куча ошибок при том, что картинка отображается корректная.

#12
15:33, 29 янв 2013

ALPINE
> внезапно в лог вывалилось куча ошибок

Каких ошибок?
> Не является ошибкой вызов glUniform с location -1.

UPD: Ты же сам пишешь:
> в моём случае (Linux, nVidia, последний 310-й драйвер) Info Log пустой
А уже оказывается логи с портянками ошибок внезапно появились.

Чем тебе легче будет, что вместо -1 на неиспользуемую переменную получишь локейшен к примеру 8? Аналогично программа как работала, так и будет работать. Смысла в этих бубнах нету.

#13
15:43, 29 янв 2013

Executor
> Каких ошибок?
При выполнении

glVertexAttribPointer(a_uv, 4, GL_FLOAT, GL_FALSE,  12 * sizeof(float), data + 4 );

получаю GL_INVALID_VALUE, поскольку a_uv = -1.

#14
15:53, 29 янв 2013

ALPINE
> получаю GL_INVALID_VALUE, поскольку a_uv = -1.

э...

Страницы: 1 2 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.