OpenGL oświetlenie

0

Witam,

Tak się zastanawiam ostatnio, jak to jest z tymi światłami w opengl, tworze sobie sześcian z środkiem w 0.0 i boku długości 1.0. Następnie obracam go o kąt alfa i przemieszczam na pozycję (-0.8, 0.0, -3.0) i próbuje umieścić światło tak jak by się znajdowało po prawej stronie sześcianu (pozycja 0.0, 0.0, -3.0). Kiedy próbuje ten efekt uzyskać ręcznie:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();	
GLfloat position[] = { 0.0f, 0.0f, -3.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, position);

Matrix3d m1, m2, m3;
Matrix3d::transformMatrix3d(-0.8f, 0.0f, -3.0f, m1);							
Matrix3d::rotateMatrix3dY(a, m2);
Matrix3d::mul(m2, m1, m3);   // m3 = m2 * m1

	glBegin(GL_QUADS);		
		Face3d*& face = mesh1->face;
		for(unsigned int i=0; i<mesh1->count; i++) {
			Vertex3d*& vertex = face[i].vertex;
			for(unsigned int j=0; j<face[i].count; j++) {
				Vector3d& vect = vertex[j].vect;
				Vector3d tmp;
				m3->mul(vect, tmp); // tmp = vect * m3
				glColor3f(vertex[j].r, vertex[j].g, vertex[j].b);
				glVertex3f(tmp.x, tmp.y, tmp.z);
			}
		}
	glEnd();		

Wszystko działa, sam tworze macierz i wrzucam już przemnożone przez macierz wierzchołki.

Kiedy próbuje zmusić do tego samego opengl czyli dodaje linijkę glLoadMatrixf(m3->data); przed glBegin(GL_QUADS) i zamieniam glVertex3f(tmp.x, tmp.y, tmp.z); na glVertex3f(vect.x, vect.y, vect.z); światło nie zachowuje se w taki sam sposób. Wygląda to bardziej tak jak by najpierw było obliczane oświetlenie a dop potem wierzchołki były mnożone przez macierz =/
Próbowałem też glLightfv(GL_LIGHT0, GL_POSITION, position); umieścić w push/pop matrix i wewnątrz zrobić odwrotne przekształcenie tak żeby światło było przemieszczone do pozycji modelu znajdującego się w 0,0,0 ale niestety mi to nie wyszło. Da się to jakoś naprawić? czy zmuszony jestem przetwarzać wierzchołki przez CPU zamiast GPU?

0

To co chcesz zrobić to wziąć wierzchołek i najpierw go obrócić wokół (0,0,0), a następnie przesunąć o wektor (-0.8, 0, -3.0). Macierz m3 to złożenie m2 i m1 zatem po umieszczeniu wierzchołka v z jej prawej strony najpierw zostanie on zjedzony przez m1, a następnie przez m2, a to nie jest to co chciałeś (zauważ że mnożenie macierzy nie jest przemienne). Mówiąc krótko zamień miejscami m1 z m2.

0

Nie o to chodzi, obiekt obraca się tak jak tego oczekuje. Tylko oświetlenie zachowuje sie nie tak jak powinno tzn. różnie dla tych dwóch przypadków. Chce mieć obiekt, który znajduje się w jakiejś pozycji p i obraca sie o kąt alfa dookoła własnej osi Y. Ponadto oświetlenie ma się znajdować na prawo od pozycji p. Kiedy sam wyliczam obrót i przesuniecie tak jak podaje wyżej czyli podaje już pozycję sześcianu w przestrzeni jest ok. Kiedy podaje sześcian w pozycji 0,0,0 i pcham tę samą macierz przez glLoadMatrixf sześcian obraca się tak jak powinien ale oświetlenie sie nie zgadza.

0

ach i jeszcze m3 to złożenie m2 i m1 nie na odwrót.

0

Możesz mieć jednak racje co do kolejności złożenia, chyba sobie napisałem mnożenie macierzy na odwrót tzn mul mnoży nie AB tylko BA, chyba sobie pomyliłem we wzorze nie zmienia to faktu że złożenie nie jest problemem bo macierz m3 jest taka jaka powinna być ;-) Kod źródłowy zweryfikuje jak będę w domu w każdym razie nadal nie zmienia to problemu z oświetleniem.

0

Problem rozwiązany :D

Okazało się że miałem błędne założenie że OpenGl sam wylicza normalne dla prymitywów(dla każdej ściany nie wierzchołka). W błąd wprowadziło mnie to że opengl wspiera back face culling, jednak po dłuższym czasie znalazłem informacje ze opengl nie korzysta do tego z normalnych(tylko z kierunku podawania wierzchołków) i to była dla mnie dobra informacja;-) Dzieki temu doszukałem sie jeszcze takiej informacji :

OpenGL needs normals to calculate lighting equations, and it won't calculate normals for you (with the exception of evaluators). If your application doesn't call glNormal*(), then it uses the default normal of (0.0, 0.0, 1.0) at every vertex

Tak wiec samemu wyliczyłem normalne i teraz wszystko działa jak należy.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.