вершинный шейдер не работает на galaxy tab10 (tegra 2)

Я создал приложение, которое использует GLES2.0 на HTC Desire S. Оно работает на HTC, но не на вкладке Samsung Galaxy tab10.1. Программа не может быть связана (GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linOk,0) дает -1), а glGetError() выдает ошибку 1282 (недопустимая операция).

Когда я заменяю эту строку (в шейдере):

graph_coord.z = (texture2D(mytexture, graph_coord.xy / 2.0 + 0.5).r);

by

graph_coord.z = 0.2;

это работает также на вкладке галактики. Мой шейдер выглядит так:

 private final String vertexShaderCode =
"attribute vec2 coord2d;" +
"varying vec4 graph_coord;" +
"uniform mat4 texture_transform;" + 
"uniform mat4 vertex_transform;" +
"uniform sampler2D mytexture;" +
"void main(void) {" +
"  graph_coord = texture_transform * vec4(coord2d, 0, 1);" +
"  graph_coord.z = (texture2D(mytexture, graph_coord.xy / 2.0 + 0.5).r);" + 
"  gl_Position = vertex_transform * vec4(coord2d, graph_coord.z, 1);" + 
"}";

Вот где прикреплены шейдеры:

  mProgram = GLES20.glCreateProgram();             // create empty OpenGL Program
  GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
  GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
  GLES20.glLinkProgram(mProgram);                  // create OpenGL program executables
  int linOk[] = new int[1];
  GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linOk,0);

И текстура загружается здесь:

 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture_id[0]);
 GLES20.glTexImage2D(
        GLES20.GL_TEXTURE_2D,   // target
    0,                  // level, 0 = base, no minimap,
    GLES20.GL_LUMINANCE,       // internalformat
    size,                  // width
    size,                  // height
    0,                  // border, always 0 in OpenGL ES
    GLES20.GL_LUMINANCE,       // format
    GLES20.GL_UNSIGNED_BYTE,   // type
    values
 );

person vipers36    schedule 09.07.2012    source источник
comment
Вы проверили информацию о программе (см. glGetProgramiv) по той причине, что она не может быть связана? Вы проверили статус компиляции шейдера? Какая строка конкретно генерирует ошибку OpenGL?   -  person Tim    schedule 09.07.2012
comment
Спасибо за подсказку! Информационный журнал шейдера гласит: ошибка C3004: function vec4 textureD(sampler2D, vec2); не поддерживается в этом профиле   -  person vipers36    schedule 10.07.2012
comment
Если компилятор говорит, что он не поддерживается, и вы получаете 0 поддерживаемых Sampler2D при компиляции, то я полагаю, что графический процессор телефона не будет поддерживать вершинный Sampler2D, поэтому решением будет использовать try/catch и вернуться к вершинному шейдеру для телефонов, которые не играй в мяч.   -  person Pixel    schedule 26.08.2019


Ответы (2)


Похоже, это ограничение графического процессора Nvidia Tegra. Мне удалось воспроизвести ошибку на графическом процессоре Tegra 3. Несмотря на то, что поиск текстур в вершинном шейдере теоретически является частью OpenGL ES 2.0, по данным Nvidia количество текстурных блоков вершинного шейдера (GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS) для Tegra равно 0 (PDF: Разработка OpenGL ES 2.0 для платформы Tegra).

person kroneml    schedule 10.07.2012
comment
Я новичок в opengl и скопировал большую часть этого кода из учебника. Каковы обходные пути здесь? Или мне нужно применить координаты z в коде Java? Я благодарен за каждое мнение/предложение - person vipers36; 10.07.2012
comment
Я не знаю обходного пути, позволяющего читать текстуры в вершинном шейдере. Как вы получаете данные в текстуру? Я предполагаю, что вам нужно изменить свой код, чтобы ввод отправлялся в шейдер для каждой вершины (как вы предложили). Может быть, вы можете дать немного больше деталей о том, что вы хотите сделать (это своего рода рендеринг поля высоты?). - person kroneml; 10.07.2012
comment
Я следовал этому руководству, чтобы построить трехмерный график. Значения z рассчитываются с помощью функции построения графика и сохраняются в массиве, который затем используется в качестве текстуры для получения координаты z для каждого вихря) - person vipers36; 10.07.2012
comment
Я думаю, что в этом случае вы действительно должны хранить z-значения для вашего графика в массиве вершин. Я не думаю, что есть реальная (с точки зрения скорости) выгода от записи значений на ЦП и отправки их на ГП в виде текстуры по сравнению с обновлением позиций вершин. В качестве альтернативы вы также можете рассмотреть возможность оценки вашей функции на графическом процессоре (в вершинном шейдере). - person kroneml; 10.07.2012
comment
Я думаю, что основная идея учебника заключается в том, что можно иметь вершину в точке, где значение z не оценивалось в коде Java. Но мне это не очень нужно, поэтому я сделаю так, как вы предложили. Еще раз спасибо! - person vipers36; 10.07.2012

Вы должны использовать texture2DLod() вместо texture2D() для поиска текстур в вершинном шейдере.

Спецификации GLSL, раздел 8.7 Функции поиска текстур: http://www.khronos.org/files/opengles_shading_language.pdf

person keaukraine    schedule 24.01.2013
comment
Пока нельзя поставить минус, но в спецификациях НЕ это указано! В нем говорится, что функции texture2DLodX разрешены только в вершинном шейдере, там нет ничего, что говорило бы о том, что вы должны их использовать! - person Matthias Schicker; 10.02.2014
comment
Я пробовал texture2DLod, и он тоже не работает. Я тоже думаю, что это красная селедка. - person nmr; 27.01.2015