Итак, я борюсь с 1D текстурами. То, что я пытаюсь достичь, это передать 3 значения float в фрагмент-шейдер в качестве uniform
. Они представляют собой светлый цвет, в попытке повторного использования одного и того же шейдера для огней n
со всеми их информационными цветами и позициями, хранящимися в текстуре. Пока, я пытаюсь передать только цвет для одного света, чтобы проверить все. Таким образом, в пиксельный шейдер у меня есть это:opengl 1D texture: fill with any float values
uniform sampler1D lightColor;
...
vec3 lc = vec3(texelFetch(lightColor, 0, 0)); // all zeroes
vec3 lc = vec3(texture(lightColor, 0, 0)); // same
Я пытался добиться его как с texelFetch
и texture
звонки внутри шейдера (либо один, либо другой), в обоих случаях не дало никаких результатов. Обратите внимание, что если я жёстко значение в затенении, как это:
vec3 lc = vec3(0.0f, 0.0f, 0.8f);
я получить ожидаемые результаты (которые отличны от нуля значения в lc
), так что я уверен, что, по крайней мере, в затенении , проблема может быть в вызовах texelFetch
или texture
.
Назад в C++ земли, код (выполняется один раз, когда мой lightManager
инициализирует) выглядит следующим образом:
GLfloat lightValues[] = { 0.8f, 0.8f, 0.8f };
GLuint lightID; // member, not a local variable.
glGenTextures(1, &lightID);
glBindTexture(GL_TEXTURE_1D, lightID);
glActiveTexture(GL_TEXTURE0 + lightID);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexStorage1D(GL_TEXTURE_1D, 1, GL_RGB32F, 1);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 3 * sizeof(GLfloat), GL_RGB, GL_FLOAT, lightValues);
glUniform1i(glGetUniformLocation(shader->program, "light"), lightID);
Ничего чрезвычайно фантазии здесь происходит (хотя, безусловно, неправильно). После прохождения таблицы 6.2 документа OpenGL для glTexStorage1D
я выбрал 1 для levels
(без MipMaps) и GL_RGB32F
для internalFormat
(так как я пытаюсь передать 3 поплавка). width
- 1, так как существует одно значение. Это должно заботиться о распределении.
Теперь, на заполнение буфера с glTexSubImage1D
, для которых я выбрать level
0 (опять же, нет мипмапов), 0 для xoffset
, для ширины трижды размера GLfloat
, GL_RGB
как формат и GLfloat
, что и type
, Наконец, фактические данные.
Несколько вещей о коде на Си ++: Я правильно установить фильтры GL_NEAREST
(так что не виновата), и я бы сказал, что равномерное расположение/подключение к Sader правильно (через glUniform1i
и glGetUniformLocation
).
Так вот приходят на мои вопросы:
- Первый и очевидный, это имеет смысл, передавая огни информации через текстуру? Шейдеры явно не могут делать такие вещи, как
lights[n]
, так какn
должно быть известно во время компиляции, поэтому текстуры приходят естественным образом, чтобы обмануть это. - Во-вторых, мое предположение верно, что размер данных может быть виновником? Я читал о полноте текстур, но, честно говоря, это было довольно коротко. Тем не менее, размер 1 текселя пахнет определенно подозрительно.
- В-третьих, вы видите что-то еще не так? В частности, с
internalFormat
,format
иtype
? - В-четвертых, любые идеи в целом почему
lc
продолжает заселяться нулями?
Спасибо!
EDIT: Я не хочу использовать такие методы, как множественное прохождение, или определить жесткий предел количества огней, передаваемых в шейдер (делая постоянным n
). Я тоже читал о некоторой возможности в OpenGL 4.2, которая мне тоже неинтересна. Я просто пытаюсь научиться с помощью имеющихся инструментов (но на 100% гарантировано в будущем. Я вернусь с вопросами по этим темам, как только я это выясню (:)
Вы также злоупотребляете glActiveTe xture с идентификатором текстуры. OpenGL генерирует ошибку и игнорирует этот вызов. – datenwolf
Что вы подразумеваете под неправильным использованием? Из-за суммы? AFAIK это довольно стандартный способ, как бы вы узнали, какая текстурная единица активируется в противном случае, если значение 'lightID' неизвестно до времени исполнения? –
Что вы делаете неправильно, добавляет * текстурное имя * к GL_TEXTURE_0. * Это не то, как это происходит! * Существует определенное количество блоков текстур (от 0 до N, N - фигура, которую вы можете запросить с помощью 'glGetInteger (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)', и она действительна для вызова 'glActiveTexture (GL_TEXTURE_0 + i) ', где i в диапазоне от 0 до N. То, что вы создаете с помощью 'glGenTextures' и связывается с' glBindTexture', является так называемым * текстурным именем *, и все в диапазоне от 1 до 2^32-1 могут использоваться как имя текстуры. – datenwolf