Я много читал про матричные преобразования в openGL и у меня накопились тонны негодования по тому, как они описываются.
Во-первых, почти везде сказано, что мы двигаем/вращаем объект. Но в OpenGL нет геометрических объектов, он процедурный, мы просто указываем что рисовать, и он рисует это снова и снова, не сохраняя у себя.
Во-вторых, порядок умножения, возникает много путаницы между нотацией opengl и математической и никогда непонятно, какая именно используется. Допустим такой код (старый API для простоты):
glRotatef(30, 0.0, 0.0, 1.0); //M1
glTranslatef(0.5, 0.0, 0.0); //M2
glRotatef(90, 0.0, 0.0, 1.0); //M3
Математически, я так понимаю, будет так - v' = M1*M2*M3*v, где v - точка, которую мы передвигаем, v' - её новое положение. Эти преобразования верны, если мы выполняем их относительно начальной системы координат. Но тут же пишут про реверсивный порядок, будто бы должно быть M3*M2*M1*v. Возможно кому-то удобнее так представлять - можно двигать систему координат в таком порядке и потом рисовать точку в новой системе координат вместо того, чтобы двигать точку, но математическая сторона здесь становится неясна. В OpenGL матрицы хранятся в транспонированном виде, так что в математической записи это будет верно только если представить, что все матрицы уже транспонированы, а вектор-строка стоит слева, и здесь уже совсем непонятно, что имеется в виду под записью.
В общем, подскажите где можно про всё это почитать и чтоб не возникало никакой путаницы.
FreeSlave писал: Математически, я так понимаю, будет так - v' = M1*M2*M3*v
Правильно, всё так и будет. Просто надо привыкнуть к тому, что в опенгле матрицы колумн-мажор, и (M1*M2)обычное = (M2*M1)OpenGL.
Цитата:
FreeSlave писал: если представить, что все матрицы уже транспонированы, а вектор-строка стоит слева, и здесь уже совсем непонятно, что имеется в виду под записью.
Вектор-столбец стоит справа, а матрицы перемножаются в обратном порядке, т.к. транспонированы, что ж тут непонятнова?
Если это вызывает у тебя путаницу, то почитай про glClipPlane и glLightfv(GL_POSITION), это должно гарантированно взорвать твой мозг.
__________________
Правдой дорожить, лжи не потакать,
Дальних не судить, ближним помогать,
С тишиной сойтись на исходе дня
Научи меня, Родина моя!
XaeroX, при умножении транспонированных матриц результат остается транспонированным (относительно математической записи), т.е. умножать вектор на такую матрицу было бы неправильно. Если M - результат перемножения транспонированных матриц, то запись M*v = v' некорректна. Меня это и смущает, матчасть то ясна, неясна запись, ибо непонятно когда что имеется в виду.
FreeSlave писал: Но в OpenGL нет геометрических объектов, он процедурный
Чо?
Цитата:
FreeSlave писал: он рисует это снова и снова, не сохраняя у себя.
Чтоб "сохранял у себя" используй VBO.
Цитата:
FreeSlave писал: много путаницы между нотацией opengl и математической
Нет никакой "нотации опенгл". Есть row-major и column-major организация матриц.
Я к слову, никогда в жизни не читал документации по OpenGL.
Но почему-то не имею проблем ни с клипплейнами ни с матрицами.
Наверное если бы прочитал - тоже запутался.
Дядя Миша, я имел в виду, что вместо того, чтобы удалять/создавать "объекты", мы просто решаем, что рисовать, а что нет. Есть фреймворки, где, например, можно добавить на сцену прямоугольник - он там и останется, пока его не удалишь, а в opengl мы напрямую даём команды для рисования прямоугольника. Разные подходы к описанию сцены, как-то так. В общем, лучше б было, если бы писали что-нибудь вроде "двигает координаты" вместо "двигает объект".
Таки вроде разобрался, надо было не в сторону транспонирования смотреть, а в сторону ассоциативности умножения, тогда всё ясно становится.
FreeSlave
Ага, точно. А я всегда думал, что равно. Что с дурака взять.
Добавлено 30-06-2013 в 21:33:
По правде говоря, все эти матрицы совершенно не нужны. Задача сделать матрицу вида или матрицу трансформации возникает пару-тройку раз за весь движок. Я обычно просто генерирую функцию для этих целей.
Добавлено 30-06-2013 в 21:34:
Цитата:
Дядя Миша писал: Но почему-то не имею проблем ни с клипплейнами ни с матрицами.
Потому что все проблемы с клипплейнами решил BUzer, когда мы пешком под стол ходили. И теорию объяснил, и пример кода дал.
__________________
Правдой дорожить, лжи не потакать,
Дальних не судить, ближним помогать,
С тишиной сойтись на исходе дня
Научи меня, Родина моя!
Дядя Миша писал: Проблема с клипплейном ровно одна - если не работает, то инвертировать distance. Других у меня не было.
Проблема в том, что он умножается на какую-то там матрицу, и плоскость в итоге оказывается не той, что ты хотел. Там надо уравнение плоскости хитро преобразовывать.
__________________
Правдой дорожить, лжи не потакать,
Дальних не судить, ближним помогать,
С тишиной сойтись на исходе дня
Научи меня, Родина моя!
XaeroX, даже если используется пару раз, всё равно ведь понять надо, ибо эти разы одни из самых важных
Вот, кстати, всё-таки нашёл книгу Addison Wesley - OpenGL Programming Guide, где нормально объяснено и оба подхода к пониманию указаны (двигаем точки, оставляя систему координат фиксированной / двигаем систему координат, располагая точки относительно неё).