Локальное ротационное моделирование разрывает openGL Lighting - PullRequest
1 голос
/ 06 декабря 2010

У меня проблемы с освещением OpenGL.Моя проблема заключается в следующем: когда объект имеет нулевое вращение, освещение работает хорошо, иначе освещение работает, но вращается вместе с объектом, а не остается неподвижным относительно сцены.

Звучит просто, верно?В FAQ по OpenGL есть несколько простых советов: координаты, переданные glLightfv (GL_LIGHT0, GL_POSITION ...), умножаются на текущую матрицу MODELVIEW.Так что я, должно быть, звоню не туда ... кроме меня нет.Я скопировал матрицу MODELVIEW в переменную для отладки, и она остается неизменной независимо от того, как вращается мой объект.Так что это должно быть что-то еще, но я в растерянности относительно того, что.

Я рисую модель, используя glDrawArrays, и позиционирую свою модель в мире, используя glMatrixMult, на матрице, построенной из кватерниона вращения и перевода.Все это происходит в glPushMatrix / glPopMatrix, поэтому не должно иметь побочных эффектов на свет.

Урезанная версия моего процесса рендеринга выглядит следующим образом:

//Setup our camera
glMatrixMode(GL_MODELVIEW);             
glLoadIdentity();
cameraMatrix = translate(Vector3D(Pos.mX,Pos.mY,Pos.mZ)) * camRot.QuatToMatrix();
glMultMatrixf((GLfloat*)&cameraMatrix);

//Position the light now
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat lp[4] = {lightPos.mX, lightPos.mY, lightPos.mZ, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION,(GLfloat*)  lp);

//Loop, doing this for each model: (mRot, mPos, and mi are model member variables)
matrix = translate(Vector3D(mPos.mX,mPos.mY,mPos.mZ)) * mRot.QuatToMatrix();
glPushMatrix();
glMultMatrixf((GLfloat*)&matrix);
glBindBuffer(GL_ARRAY_BUFFER, mi->mVertexBufHandle);  //Bind the model VBO.
glDrawArrays(GL_TRIANGLES, 0, mi->verts); //Draw the object
glPopMatrix();

IЯ думал, что нормалы могут быть испорчены, но когда я их выводу, они выглядят хорошо.Есть ли что-нибудь еще, что может повлиять на освещение openGL?В разделе часто задаваемых вопросов упоминается:

Если ваш источник света является частью осветительного прибора, вам также может потребоваться указать моделирующее преобразование, чтобы позиция света находилась в том же месте, что и геометрия окружающего осветителя.

Я понял, что это означает, что вам нужно перевести свет на сцену, что-то вроде легкой задачи ... но означает ли это что-то еще?

Ответы [ 3 ]

1 голос
/ 06 декабря 2010

Может быть незначительным, но в этой строке:

glLightfv(GL_LIGHT0, GL_POSITION,(GLfloat*)  &lp);

удалить & (адрес оператора). lp уже даст вам адрес массива.

1 голос
/ 22 июня 2011

Это было некоторое время назад, но в конце концов я понял проблему. Проблема, о которой я думал , была в том, что позиция света была переведена неправильно. Представьте себе: свет был расположен в 0,0,0, но затем я перевел и повернул свою сетку. Если бы это было так, мне пришлось бы поступить так, как предлагалось в других ответах, и убедиться, что я размещаю свои вызовы glLightfv в нужном месте.

Фактическая проблема оказалась гораздо проще, но гораздо коварнее. Оказывается, я неправильно установил glNormalPointer, и поэтому он получал мусорные данные. Во время отладки я рендерил нормали, чтобы убедиться, что они правильные, но при этом я рисовал их вручную на основе рассчитанных позиций. Рекомендация будущим отладчикам: при рисовании отладочной информации обычными лучами, убедитесь, что вы передаете отладочную функцию / те же данные /, что и openGL. В моем случае это означало бы наведение моей обычной функции рисования лучей glVertexPointer в то же место, что и glNormalPointer модели.

0 голосов
/ 06 декабря 2010

По сути, свет OpenGL ведет себя как вершина. Таким образом, в вашем коде он преобразуется cameraMatrix, а ваши сетки - cameraMatrix * matrix. Теперь, похоже, что и cameraMatrix, и matrix содержат mrot.QuatToMatrix(), то есть: там есть одна матрица вращения, и свет поворачивается один раз, а объекты поворачиваются дважды. Это не выглядит правильно для меня, если ваш реальный код отличается; матрица mRot, которую вы используете для каждой сетки, должна быть своей, например, mRot[meshIndex].

...