Oprogramowanie i wykorzystanie stacji roboczych Wykład 6

Transkrypt

Oprogramowanie i wykorzystanie stacji roboczych Wykład 6
Oprogramowanie i wykorzystanie
stacji roboczych
Wykład 6
Dr inż. Tomasz Olas
[email protected]
Instytut Informatyki Teoretycznej i Stosowanej
Politechnika Cz˛estochowska
Wykład 6 – p. 1/2
Wektory normalne
Wykład 6 – p. 2/2
Tworzenie wielokatów
˛
- kierunek
zgodny z ruchem
wskazówek zegara
clockwise winding (CW)
przeciwny do ruchu
wskazówek zegara
counterclockwise winding (CCW)
2
3
2
1
3
1
Wykład 6 – p. 3/2
Kierunek w OpenGL
Do określenia orientacji wielokatów
˛
w OpenGL służy funkcja:
void glFrontFace(GLenum mode)
gdzie:
mode przyjmuje wartości: GL_CW lub GL_CCW
Przykład:
// określenie, że wielokaty
˛
o kolejności kraw˛
edzi zgodnej
// z ruchem wskazówek zegara sa˛ widoczne od frontu
glFrontFace(GL_CW);
// określenie, że wielokaty
˛
o kolejności kraw˛
edzi przeciwnej
// do ruchu wskazówek zegara sa˛ widoczne od frontu
glFrontFace(GL_CCW);
Wykład 6 – p. 4/2
Tryby rysowania wielokatów
˛
Wielokaty
˛ nie musza˛ być wypełnione bieżacym
˛
kolorem.
Domyślnie wielokaty
˛ sa˛ rysowane jednolitym kolorem, można
jednak to zmienić nakazujac,
˛ aby były rysowane jedynie jako
sylwetki lub nawet jako punkty (sa˛ wtedy rysowane jedynie
wierzchołki).
glPolygonMode(GLenum face, GLenum);
gdzie:
face - Określa strone˛ wielokata,
˛ do której bedzie
˛
sie˛ odnosić dane wywołanie
funkcji:
GL_FRONT - przednia strona,
GL_BACK - tylna strona,
GL_FRONT_AND_BACK - obie strony.
mode - Określa nowy tryb rysowania. Domyślnym trybem jest GL_FILL dajacy
˛
wypełnione wielokaty.
˛ GL_LINE powoduje rysowanie jedynie sylwetek wielokatów
˛
(zewnetrznych
˛
kraw˛edzi), zaś GL_POINT powoduje rysowanie jedynie punktów w
wierzchołkach wielokata.
˛
Wykład 6 – p. 5/2
Kierunek wielokatów
˛
- przykład
void drawTriangle(int x1, int y1, int x2, int y2, int x3, int y3)
{
glBegin(GL_TRIANGLES);
glVertex3i(x1, y1, 0);
glVertex3i(x2, y2, 0);
glVertex3i(x3, y3, 0);
glEnd();
}
void MyGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
//glFrontFace(GL_CW);
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_LINE);
drawTriangle(0, 0, 1, 0, 0, 1);
drawTriangle(1, 0, 0, 1, 1, 1);
}
Wykład 6 – p. 6/2
Ukrywanie niewidocznych powierzchni
Można przyspieszyć proces renderowania poprzez
wyelminowanie wielokatów
˛
skierowanych tyłem.
// właczenie
˛
ukrywania niewidocznych wielokatów
˛
glEnable(GL_CULL_FACE);
Do określenia, które wielokaty
˛ sa˛ widoczne, a które nie służy
funkcja glFrontFace:
// określenie, że wielokaty
˛
o kolejności kraw˛
edzi zgodnej
// z ruchem wskazówek zegara sa˛ widoczne od frontu
glFrontFace(GL_CW);
˛
o kolejności kraw˛
edzi przeciwnej
// określenie, że wielokaty
// do ruchu wskazówek zegara sa˛ widoczne od frontu
glFrontFace(GL_CCW);
Wykład 6 – p. 7/2
Budowa złożonych obiektów
Wykład 6 – p. 8/2
Ograniczenia glBegin() - glEnd()
Najważniejszymi informacjami dotyczacymi
˛
wierzchołków sa˛
ich współrz˛edne określane poprzez funkcje˛ glVertex*().
Ponadto można określić dodatkowe informacje dotyczace
˛
wierzchołków, np. kolor, wektor normalny, współrz˛edne
mapowania tekstury, itp.
Funkcjami jakie moga˛ być użyte wewnatrz
˛ pary glBegin() i
glEnd() sa:
˛
glVertex*(), glColor*(), glIndex*(), glNormal*(), glTexCoord*(), glEdgeFlag*(),
glMaterial*(), glArrayElement(), glEvalCoord*(), glEvalPoint*(), glCallList(), glCallLists().
Wykład 6 – p. 9/2
Prymitywy
Wykład 6 – p. 10/2
GL_POLYGON - ograniczenia
Wszystkie wielokaty
˛ musza˛ być płaskie (wszystkie wierzchołki
wielokata
˛ musza˛ leżeć na jednej płaszczyźnie).
Krawedzie
˛
wielokata
˛ nie moga˛ sie˛ przecinać, sam zaś wielokat
˛
musi być wielokatem
˛
wypukłym (nie może posiadać żadnych
wcieć)
˛
Wykład 6 – p. 11/2
Wypełnianie wielokatów
˛
Wypełnianie wielokatów
˛
glEnable(GL_POLYGON_STIPPLE);
a nastepnie
˛
glPolygonStipple(const GLubyte *bitmap);
gdzie:
bitmap - wzorzec bitowy o wymiarach 32x32 bity (Jedynki we wzorcu sa˛
rysowane bieżacym
˛
kolorem wypełniania, zera nie sa˛ rysowane).
Wykład 6 – p. 12/2
Przesuniecie
˛
Przesuniecie
˛
jest operacja˛ przemieszczajac
˛ a˛ punkty o
określona˛ wartość w danym kierunku.
Do określenia przesuniecia
˛
należy określić wektor
przesuniecia
˛
d.
glTranslate[df](TYPE dx, TYPE dy, TYPE dz);
gdzie:
dx - współrz˛edna x wektora przesuniecia,
˛
dy - współrz˛edna y wektora przesuniecia,
˛
dz - współrz˛edna z wektora przesuniecia.
˛
Wykład 6 – p. 13/2
Skalowanie
Skalowanie powoduje zwiekszenie
˛
lub zmniejszenie obiektu
we wszystkich trzech osiach o zadane współczynniki.
Skalowanie nie musi być jednorodne. Można go użyć do
ściśniecia
˛
lub rozciagni
˛ ecia
˛
obiektu.
Do skalowania służy funkcja:
glScale[df](TYPE x, TYPE y, TYPE z);
Wykład 6 – p. 14/2
Obrót
Obrót jest dokonywany poprzez określenie kata
˛ o jaki maja˛
zostać obrócone punkty oraz wektora wyznaczajacego
˛
oś
obrotu.
glRotate[df](TYPE angle, TYPE x, TYPE y, TYPE z);
gdzie:
angle - kat
˛ obrotu w stopniach,
x, y, z - współczynniki wektora obrotu.
Obrót jest wykonywany w kierunku przeciwnym do ruchu
wskazówek zegara.
Wykład 6 – p. 15/2
Transformacje - przykład (I)
class MyGLWidget : public QGLWidget
{
public:
MyGLWidget(QWidget* parent = NULL,
const char* name = NULL);
protected:
void initializeGL();
void paintGL();
void resizeGL(int w, int h);
void keyPressEvent(QKeyEvent* event);
GLfloat zRoll;
};
Wykład 6 – p. 16/2
Transformacje - przykład (II)
void MyGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glRotatef(zRoll, 0.0f, 0.0f, 1.0f);
drawTriangle(-1, -1, 1, -1, 0, 1);
}
void MyGLWidget::keyPressEvent(QKeyEvent* event)
{
if (event->key() == Qt::Key_Left) {
zRoll -= 3.0f;
updateGL();
}
if (event->key() == Qt::Key_Right) {
zRoll += 3.0f;
updateGL();
}
}
Wykład 6 – p. 17/2
Rzutowanie równoległe
Rzutowanie równoległe jest cz˛esto używane w projektowaniu
architektonicznym i programach CAD.
W OpenGL do określenia rzutu równoległego służy funkcja
glOrtho.
glOrtho(GLdouble left, GLdouble right, GLdouble bottom,
GLdouble top, GLdouble near, GLdouble far);
Wykład 6 – p. 18/2
Rzutowanie perspektywiczne (I)
Ustalanie rzutu perspektywicznego przy użyciu funkcji
glFrustrum:
glFrustrum(GLdouble left, GLdouble right, GLdouble bottom,
GLdouble top, GLdouble near, GLdouble far);
Wykład 6 – p. 19/2
Rzutowanie perspektywiczne (II)
Ustalanie rzutu perspektywicznego przy użyciu funkcji
gluPerspective:
gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear,
GLdouble zFar);
fovy - szerokość kata
˛ widzenia w pionie (w stopniach),
aspect - używany do wyznaczenia konta widzenia w poziomie.
Wykład 6 – p. 20/2
„Pozycja kamery”
Wykład 6 – p. 21/2
Zmiana „pozycji kamery”
Do zmiany położenia „kamery” może zostać wykorzystana
transformacja:
glTranslatef(0.0, 0.0, -10.0);
rysuj_kwiatek();
Wykład 6 – p. 22/2
Funkcja gluLookAt
Funkcja gluLookAt umożliwia umieszczenie kamery w pewnym punkcie w
przestrzeni i określenie kierunku na który zwrócona jest kamera.
void gluLookAt(GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ,
GLdouble centerX, GLdouble centerY, GLdouble centerZ,
GLdouble upX, GLdouble upY, GLdouble upZ);
eyeX, eyeY, eyeZ - punkt obserwacji (współrz˛edne kamery),
centerX, centerY, centerZ - określa kierunek patrzenia (kierunek w którym
zwrócona jest kamera),
upX, upY, upZ - określa kierunek „do góry” z miejsca patrzenia.
Wykład 6 – p. 23/2
Bufor głeboko
˛
ści (I)
Gdy jest rysowany piksel przypisywana jest mu wartość
(zwana wartościa˛ z ) określajac
˛ a˛ odległość punktu tego piksel
od obserwatora. Później gdy w tym samym miejscu ekranu ma
zostać narysowany piksel, wartość z nowego piksel jest
porównywana z wartościa˛ z piksel już narysowanego. Jeżeli
jest wieksza,
˛
oznacza to, że jego punkt jest bliżej obserwatora,
wiec
˛ stary piksel jest zasłaniany przez nowy.
Wykład 6 – p. 24/2
Bufor głeboko
˛
ści (II)
Właczenie
˛
bufora głebokości:
˛
glEnable(GL_DEPTH_TEST);
Bufor głebokości
˛
musi być wyzerowany za każdym razem gdy
przystepujemy
˛
do narysowania sceny.
// Wyczyszczenie okna i bufora gł˛
ebokości
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Wykład 6 – p. 25/2
Bufor głeboko
˛
ści - przykład
glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glVertex3f(0.1f, 0.1f, 0.1f);
glVertex3f(0.5f, 0.5f, 0.1f);
glEnd();
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_TRIANGLES);
glVertex3f(0.5f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
glEnd();
Bufor głebokości
˛
wyłaczony
˛
glVertex3f(0.1f, 0.5f, 0.1f);
glVertex3f(0.5f, 0.1f, 0.1f);
glVertex3f(0.0f, 0.0f, 0.0f);
Bufor głebokości
˛
właczony
˛
Wykład 6 – p. 26/2