Передать 1d текстуру в фрагментный шейдер — все нули?

Я пытаюсь передать массив int в фрагментный шейдер с помощью 1D текстуры. Хотя код компилируется и запускается, когда я смотрю на значения текстуры в шейдере, все они равны нулю!

Это код C ++, который я имею после следующих руководств:

GLuint texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0 + 5); // use the 5th since first 4 may be taken
glBindTexture  (GL_TEXTURE_1D, texture);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RED_INTEGER, myVec.size(), 0,
GL_RED_INTEGER, GL_INT, &myVec[0]);

GLint textureLoc =  glGetUniformLocation( program, "myTexture" );
glUniform1i(textureLoc, 5);

И вот как я пытаюсь получить доступ к текстуре в шейдере:

uniform sampler1D myTexture;
int dat = int(texture1D(myTexture, 0.0).r); // 0.0 is just an example
if (dat == 0) { // always true!

Я уверен, что это какая-то тривиальная ошибка с моей стороны, но я просто не могу понять это. К сожалению, я ограничен в использовании GLSL 1.20, поэтому этот синтаксис может показаться устаревшим для некоторых.

Так почему же значения текстуры в шейдере всегда равны нулю?

РЕДАКТИРОВАТЬ:

Если я заменю int на float, у меня все еще будет проблема:

std::vector <float> temp;
// fill temp...
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage1D(GL_TEXTURE_1D, 0, GL_R32F, temp.size(), 0, GL_R32F, GL_FLOAT, &temp[0]);
// ...
glUniform1f(textureLoc, 5);

На этот раз, просто читая из sampler кажется, испортить другие текстуры ..

0

Решение

Начать с, GL_RED_INTEGER неверно для внутреннего формата. я хотел бы использовать GL_R32I (32-разрядное целое число со знаком), вы также можете использовать GL_R8I или же GL_R16I в зависимости от ваших реальных требований к хранению — меньшие типы, как правило, лучше. Кроме того, не используйте sampler1D для целочисленной текстуры используйте isampler1D,

Поскольку OpenGL ES не поддерживает преобразование типов данных, когда вы используете функцию передачи пикселей (например, glTexture2D (...)), вы обычно можете найти оптимальное сочетание формата, внутреннего формата и типа в таблице, если вы просматриваете OpenGL ES документы.


Вы не можете использовать целочисленные текстуры в OpenGL 2.1, если мы вернемся к той же проблеме, что у вас была вчера с UBO. Если вы не можете получить контекст основного профиля в OS X, вы ограничены GLSL 1.2 (OpenGL 2.1). Константы для GL_R32I, GL_RED_INTEGERи т. д. будут определены, но они должны создавать GL_INVALID_ENUM ошибки во время выполнения в реализации OpenGL 2.1 OS X.

Это не означает, что вы не можете упаковать целочисленное значение в стандартную текстуру с фиксированной запятой и вернуть целочисленное значение обратно в шейдер. Если вы используете 8-битный формат для каждого компонента (например, GL_R8) вы можете хранить значения в диапазоне 0255. В вашем шейдере после поиска текстур (я бы использовал GL_NEAREST для фильтра текстуры, фильтрация действительно испортит все) вы можете умножить результат с плавающей запятой на 255,0 и бросить в int, Это далеко не идеально, но мы прекрасно обходились без целочисленных текстур в течение многих лет.

Вот модификация вашего шейдера, которая делает именно это:

#version 120

uniform sampler1D myTexture;
int dat = (int)(texture1D (myTexture, (idx + 0.5)/(float)textureWidth).r * 255.0);
if (dat == 0) { // not always true!

Предполагает GL_R8 для внутреннего формата используйте 65535.0 за GL_R16

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]