Вобщем пытаюсь разобраться с VBO и связкой с вершинным шейдером.
Задача состоит в том, чтоб преобразовать старый формат моделей в проге для отрисовки с использованием VBO.
Простейший случаи в 4 вершины на 2 треугольника и индексным буфером работает.
В проге происходит следующее:
Так всё выводится-рисуется. Но при попытке прописать свой атрибут например "position" в таком шейдере:
attribute vec3 position; uniform mat4 Projection; uniform mat4 ModelView; uniform mat4 Transform; void main() { gl_Position = Projection * ModelView * Transform * gl_Vertex; gl_TexCoord[0] = gl_MultiTexCoord0; }
и при попытке считать индекс этого атрибута функцией glGetAttribLocation("position");
мне возвращается -1. Почему не находит мой атрибут? Для стандартных атрибутов возвращаются нормальные индексы..
Вопрос решился при написании его тут :) При компиляции из шейдера убираются все атрибуты, которые обьявлены, но не используются, а у меня так и было.
Второй самый главный вопрос. Вот мы проиндексировали вершины по координатам, ну то-есть мы избавились от одинаковых Position. И теперь, если в нескольких треугольниках совпадает координата одной из вершин, мы просто берём её по индексу. Но как быть с одинаковыми нормалями и текстурными координатами? Например у нас куча квадратов разбросанных в пространстве, все позиции вершин разные, но текстурные координаты одни и те же, и нормаль одна и та же для всех вершин. То как я понял индексный буфер тут не поможет, и для всех этих разных позиций будет соответствовать одинаковые значения нормалей и текстурных координат, повторяющихся по всему буферу?
Чего-то я не допонимаю, как сделать индексный буфер, чтоб нормали и текстурные координаты тоже без дубликатов были. По сути получится, что вершинный буфер например на 16 вершин, а текстурный буфер должен хранить например всего 4 координаты(чтоб дубликаты не хранить). Это возможно? И как это сделать?
UVW
> Чего-то я не допонимаю, как сделать индексный буфер, чтоб нормали и текстурные координаты тоже без дубликатов были
Железка не умеет индексировать отдельные компоненты вершины. Для неё вершина - полный комплект значений всех атрибутов.
Хоть один атрибут отличается - это уже целиком другая вершина.
Поэтому ты сам должен сгенерить все вершины, состоящие из значений позиции/нормали/текстурных координат, и удалять дубликаты либо во время этого процесса, либо после.
RPGman
> Железка не умеет индексировать отдельные компоненты вершины. Для неё вершина -
> полный комплект значений всех атрибутов.
Блин, хреново то как, чёто я сразу разочаровался в индексном буфере, думал "экономия места то какая" а на самом деле бесполезняк, только место занимает. У меня в формате модели раньше все атрибуты были проиндексированы, а теперь после загрузки придётся "разворачивать" значит в обычный массив данных.. грусть-печаль.. Получается польза только для мешей с неразрывно наложенной текстурой и сглаженными нормалями..
UVW
> чёто я сразу разочаровался в индексном буфере, думал "экономия места то какая"
Кроме экономии места это ещё и экономия на обращениях к памяти и на вычислениях. Почитай про pre/post-TnL кеши.
UVW
> Блин, хреново то как
Может отдохнуть на Канарах ? :)
А я итак отдыхаю, только отдых своеобразный :) Вот, до VBO потихоньку доотдыхался, аж на мозге трещины появились)))
А если по теме вопроса, то:
glVertexAttribPointer(attr_tcoord, 2, GL_FLOAT, false, sizeof(Vertex), ???????);
Чего ему от меня надо? Буфер с чередующимися атрибутами для каждой вершины. От начала данных вершины до нужного значения отступаем 3 флоата(позиция).
Я ему даю 3*4= int 12, а он мне говорит "я это не ем, дай мне const void *.
Тогда я свою бяку ему маскирую под нямку
int offs=12;
ext->glVertexAttribPointer(attr_tcoord, 2, GL_FLOAT, false, sizeof(Vertex), (void*)&offs);
а он крашится, подавился..
И ещё вопрос, как лучше поступить для статических моделей, помещать все атрибуты в один буфер, или разместить по отдельным и все бинды в VAO?
UVW
> glVertexAttribPointer(attr_tcoord, 2, GL_FLOAT, false, sizeof(Vertex),
> ???????);
> Чего ему от меня надо?
???????????? - сюда ему надо адрес начала текстурных координат.
> Тогда я свою бяку ему маскирую под нямку
Вообще не ту нямку даешь. Он ведь не зря предупреждает.
Как было говно так и осталось, тока ты её руками перевернул.
> а он крашится, подавился..
Всё верно. Дал говно - говно получил.
Хмм.. А как вообще узнать адрес начала буфера в видеопамяти, а потом прибавив смещение до нужного атрибута дать функции?
И стоит ли так заморачиваться?(последний вопрос в моём предыдущем посте)
UVW
> А как вообще узнать адрес начала буфера в видеопамяти
Не нужен тебе этот адрес.
Раз используешь vbo, то в качестве адреса указываешь смещение от начала буфера.
Не адрес переменной, где лежит смещение, а само смещение пригоняешь к указателю, т.е. (void*)12;
В твоем случае драйвер падает, пытается читать данные за пределами vbo, т.к. пытается интерпретировать адрес переменной как смещение от начала буфера.
Даже порисовать не поленился.
Надеюсь все ясно?
Big V
> Надеюсь все ясно?
Нет, почему фон серый ? :)
Big V
> Надеюсь все ясно?
Более чем, спасибо)
Правда это я итак понял, у меня с последним параметром запарка была, знал что, но не знал как передать) смутило то, что функция не просто какой-нибудь инт потребовала, и подумал, что это число нужно как то специально подготовить, а не просто привести к void*)
innuendo
> почему фон серый
Белый - режет глаз
Черный - такого же цвета обводка
Серый - компромисс)
> Нет
А что не ясно то?
UVW
> мне возвращается -1.
> ...
> Вопрос решился при написании его тут :) При компиляции из шейдера убираются все
> атрибуты, которые обьявлены, но не используются, а у меня так и было.
http://www.gamedev.ru/code/tip/gluniformlocation_fail
:)
UVW
> attribute vec3 position;
> ...
> gl_Position = Projection * ModelView * Transform * gl_Vertex;
На всякий пожарный, у тебя vec3, а тут всё 4-компонентное, так что свою позицию тоже делай 4-компонентной (vec4, последний компонент - единица). Если из-за крайней необходимости в экономии лишних флоатов будешь писать vec3 - приводи к vec4 в шейдере.
UVW
> По сути получится, что вершинный буфер например на 16 вершин, а текстурный буфер должен хранить например всего 4 координаты(чтоб дубликаты не хранить). Это возможно? И как это сделать?
Зачем так делать? делай уникальный массив вершин с учтетом атрибутов вершин, и индекснвый буфер.
Тема в архиве.