Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / GLSL: о причине, по которой glGetUniformLocation() может вернуть -1 (комментарии)

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

Страницы: 1 2 Следующая »
Роман ШуваловУчастникwww11 дек. 20124:22#0
GLSL: о причине, по которой glGetUniformLocation() может вернуть -1 (комментарии)
Это сообщение сгенерировано автоматически.
NeptuneПостоялецwww11 дек. 20124:22#1
А не проще ли проверять, не равен ли location минус единице, и не вызывать glUniform* для него? Я просто написал свои функции установки юниформа в классе шейдера, которые делают эту проверку, и радуюсь.
ExecutorУдалёнwww11 дек. 20128:45#2
Проблема на ровном месте. :)

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.

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

SiPlusПостоялецwww11 дек. 20129:11#3
Вот так я делаю. Всё без каких-то там проверок нормально идет.
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;
};
gkv311Постоялецwww11 дек. 20129:53#4
ALPINE
можно, например, вписав вот такую строчку в конец фраргментного шейдера:
gl_FragColor.r += 0.000001*v_uv[0];
Она не окажет влияния на картинку, зато не даст компилятору съесть переменную. А ближе к финальной версии неиспользуемых переменных в шейдере само собой быть не должно .

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

innuendoПостоялецwww11 дек. 20129:59#5
ALPINE

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

Che@terПостоялецwww11 дек. 201212:12#6
Я так и в HLSL делаю, когда чтото тестирую.
Роман ШуваловУчастникwww11 дек. 201221:39#7
> Автор видимо предпочитает потратить кучу времени на изобретение велосипеда,
> вместо того, чтобы потратить одну минуту на чтение доки.
Автор предпочитает потратить кучу времени на выяснение обстоятельства, почему glGetError не пустой. А судя по
will be silently ignored

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

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

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

Cyber_WandererПостоялецwww28 янв. 201322:30#8
Хех, -1 выбрасывает, если запрашиванных переменных в шейдере нету. А нету их по трем причинам: 1) Шейдер не сбилдился и там нету никаких переменных вообще, в том числе и этой. 2) Шейдер сбилдился но этой переменной там нету. 3) Когда шейдер билдился эта переменная оказалась не использованной и ее выбросили ради оптимизации, соответственно ее там нету. И того "о причине, по которой glGetUniformLocation() может вернуть -1": исключительно тогда когда запрашиваемой переменной нету. А причины по которым она все же есть но куда-то пропала, можно описать отдельно. ИМХО.
Роман ШуваловУчастникwww29 янв. 20134:00#9
Cyber_Wanderer
> если запрашиванных переменных в шейдере нету. А нету их по трем причинам
А в первых двух случаях ошибок разве никаких нет? В первой уж точно должна быть - статус соответствующий будет, валидация не пройдёт. Про второй случай вот не знаю, но никто в здравом уме не будет искать отсутствующую переменную, так ведь? А вот в третьем случае однозначно не скажешь, что переменная отсутствует - ты её определил и вроде как даже использовал. А её нет. Именно из-за этого ситуация несколько сбивающая с толку и именно из-за этого я о ней и рассказал.
ExecutorУдалёнwww29 янв. 201311:47#10
ALPINE
> А вот в третьем случае однозначно не скажешь, что переменная отсутствует - ты
> её определил и вроде как даже использовал. А её нет.

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

Роман ШуваловУчастникwww29 янв. 201315:10#11
Executor
> Под использованием естественно подразумеваю влияние на вычисления.
Так я же и пишу - во время экспериментов с шейдером не углядел, что результат вычислений я случайно перезаписал константой (см. пример кода фрагментного шейдера в начале статьи). Да, факт перезаписи имеет место, да, на вычисления переменная уже не влияет. Но это не очень-то и очевидно во время работы над шейдером (комментирования кусков кода и т.д.). Далеко не сразу можно сообразить, откуда внезапно в лог вывалилось куча ошибок при том, что картинка отображается корректная.
ExecutorУдалёнwww29 янв. 201315:33#12
ALPINE
> внезапно в лог вывалилось куча ошибок

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

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

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

Роман ШуваловУчастникwww29 янв. 201315:43#13
Executor
> Каких ошибок?
При выполнении
glVertexAttribPointer(a_uv, 4, GL_FLOAT, GL_FALSE,  12 * sizeof(float), data + 4 );
получаю GL_INVALID_VALUE, поскольку a_uv = -1.
innuendoПостоялецwww29 янв. 201315:53#14
ALPINE
> получаю GL_INVALID_VALUE, поскольку a_uv = -1.

э...

Страницы: 1 2 Следующая »

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

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

2001—2018 © GameDev.ru — Разработка игр