Как я фиксирую источник света в OpenGL при вращении объекта?

Python использует передачу значением, но так как все такие значения являются ссылками на объект, результирующий эффект является чем-то сродни передаче ссылкой. Однако Python программисты думают больше о том, является ли тип объекта изменяемым или неизменный . Изменяемые объекты могут быть изменены оперативные (например, словари, списки, пользовательские объекты), тогда как неизменные объекты не могут (например, целые числа, строки, кортежи).

следующий пример показывает функцию, которая передается два аргумента, неизменная строка и изменяемый список.

>>> def do_something(a, b):
...     a = "Red"
...     b.append("Blue")
... 
>>> a = "Yellow"
>>> b = ["Black", "Burgundy"]
>>> do_something(a, b)
>>> print a, b
Yellow ['Black', 'Burgundy', 'Blue']

строка a = "Red" просто создает локальное имя, a, для строкового значения "Red" и не имеет никакого эффекта на переданный - в аргументе (который теперь скрыт, поскольку a должен относиться к локальному имени с тех пор). Присвоение не является оперативной операцией, независимо от того, изменяем ли аргумент или неизменен.

b параметр является ссылкой на изменяемый объект списка, и .append(), метод выполняет оперативное расширение списка, лавирующего на новом "Blue" строковое значение.

(Поскольку строковые объекты неизменны, у них нет методов, которые поддерживают оперативные модификации.)

, Как только функция возвращается, переназначение [1 110] не имело никакого эффекта, в то время как расширение [1 111] ясно показывает семантику вызова передачи стилем ссылки.

, Как упомянуто прежде, даже если аргументом в пользу [1 112] является изменяемый тип, переназначение в функции не является оперативной операцией, и таким образом, не было бы никакого изменения в значении передаваемого аргумента:

>>> a = ["Purple", "Violet"]
>>> do_something(a, b)
>>> print a, b
['Purple', 'Violet'] ['Black', 'Burgundy', 'Blue', 'Blue']

, Если бы Вы не хотели свой список, измененный вызванной функцией, Вы вместо этого использовали бы неизменный тип "кортеж" (определенный круглыми скобками в литеральной форме, а не квадратными скобками), который не поддерживает оперативное .append() метод:

>>> a = "Yellow"
>>> b = ("Black", "Burgundy")
>>> do_something(a, b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in do_something
AttributeError: 'tuple' object has no attribute 'append'
5
задан Attila Kun 18 November 2009 в 18:09
поделиться

4 ответа

Я думаю, что изменение

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

на

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

- хорошее место для начала.

2
ответ дан 14 December 2019 в 19:17
поделиться

В часто задаваемых вопросах говорится :

Положение источника света преобразуется текущая матрица ModelView в время, когда позиция указывается с вызов glLight * ().

Другими словами, источники света не размещаются в какой-то магической статической «мировой системе координат»; они умножаются на матрицу вида модели, как и любая геометрия. Это имеет смысл; вы часто хотите, чтобы источники света были привязаны к геометрии.

Я также думаю, что ваше приложение «разрушает» матрицу вида модели; он никогда не пересчитывается с нуля. Каждый кадр следует начинать с LoadIdentity (), затем излучать источник света, затем вращать по желанию и, наконец, излучать геометрию.

0
ответ дан 14 December 2019 в 19:17
поделиться

Я также считаю, что ваше приложение "разрушает" представление модели. матрица; он никогда не пересчитывается с нуля. Вам следует начинать каждый кадр с LoadIdentity (), затем выдавать источник света, затем поверните по желанию и, наконец, испустите

Это не работает, это не работает, это не работает, lalalalalalalala, и FAQ явно неверный , простой и понятный.

Просто испускать свет. после glLoadIdentity () для получения света, привязанного к камере, будет работать в простых случаях, когда вы только перемещаете или вращаете модель вокруг начала координат. Но когда вы начинаете делать нетривиальные вещи, не относящиеся к приветливому миру, такие как вращение объекта вокруг точки, отличной от исходной (перевод (-v), поворот (угол), перевод (v)), а затем перемещение объекта так, чтобы центр вращения переносится перед камерой, затем метод «загрузить идентичность, разместить свет» начинает с впечатляющей ошибкой и таким образом, что очень сложно понять, что вообще происходит .

Нет, я не знаю решения.

1
ответ дан 14 December 2019 в 19:17
поделиться

На мой взгляд, вам следует не только вызывать glLoadIdentity () в начале процедуры рендеринга, но и нажимать и выталкивать матрицу просмотра модели.

для сцена с глобально фиксированным источником света и двумя объектами, которые независимо позиционируются и поворачиваются, этот псевдокод поможет:

glLoadIdentity();

// first object
glPushMatrix();
glTranslate(...);
glRotate(...)
glPopMatrix();

// second object
glPushMatrix();
glTranslate(...);
glRotate(...);
glPopMatrix();
0
ответ дан 14 December 2019 в 19:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: