2016-12-13 14 views
1

Итак, я борюсь с 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% гарантировано в будущем. Я вернусь с вопросами по этим темам, как только я это выясню (:)

ответ

0

Хорошо, разобрался с https://stackoverflow.com/users/1774414/raistmaj

Оказывается width есть и в glTexStorage и glTexSubImage количество элементов в массиве, так что 1, независимо от числа компонентов.

Кроме того, glActiveTexture должна быть вызвана перед glBindTexture (Duh !!)

+0

Вы также злоупотребляете glActiveTe xture с идентификатором текстуры. OpenGL генерирует ошибку и игнорирует этот вызов. – datenwolf

+0

Что вы подразумеваете под неправильным использованием? Из-за суммы? AFAIK это довольно стандартный способ, как бы вы узнали, какая текстурная единица активируется в противном случае, если значение 'lightID' неизвестно до времени исполнения? –

+1

Что вы делаете неправильно, добавляет * текстурное имя * к 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