Я много читал про матричные преобразования в 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, где нормально объяснено и оба подхода к пониманию указаны (двигаем точки, оставляя систему координат фиксированной / двигаем систему координат, располагая точки относительно неё).