OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
OpenGL
narzędzie dla bardzo ambitnych
Robert Machejek
Instytut Informatyki
Uniwersytet Śląski w Katowicach
12 grudnia 2008
Robert Machejek
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
OpenGL - co to właściwie jest?
OpenGL (ang. Open Graphics Library) - specyfikacja uniwersalnego API
do generowania grafiki. Zestaw funkcji składa się z 250 podstawowych
wywołań, umożliwiających budowanie złożonych trójwymiarowych scen z
podstawowych figur geometrycznych.
OpenGL wykorzystywany jest często przez gry komputerowe i wygaszacze
ekranu, spełnia rolę analogiczną, jak konkurencyjny Direct3D (część
DirectX) w systemie Windows firmy Microsoft. Również programy do
przedstawiania wyników badań naukowych, CAD, oraz wirtualnej
rzeczywistości używają OpenGL.
Robert Machejek
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
OpenGL - krótka historia
Troszkę historii..
1992 - powstaje wersja 1.0 specyfikacji OpenGL przenośnej między
platformami. OpenGL Architecture Review Board (SG,HP,IBM)
1995 - wersja 1.1 tej biblioteki z wieloma poprawkami
przyśpieszającymi wyświetlanie grafiki.
Robert Machejek
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
No to na pewno warte uwagi
OpenGL nie należy do języków opisu sceny. Scena tworzona jest w
OpenGL z wielokątów poprzez wywoływanie odpowiednich procedur
Języki programowania:
Pascal,C/C++,Visual Basic,Python,Java
Robert Machejek
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
Składnia - bo jak bez niej żyć
Polecenia OpenGL określane są jako funkcje lub procedury. Znaczna cześć
funkcji wykonuje te same operacje, ale różni się zbiorem argumentów.
Przyjęta konwencja nazewnictwa określa ilość i rodzaj parametrów funkcji
według poniższego schematu:
rtype Name {1|2|3|4} {b|s|i|f|d|ub|us|ui} {v}
[
args, ]Targ1, ..., TargN[, args]
gdzie poszczególne elementy oznaczają:
•
rtype - wartość zwracana przez funkcje,
•
Name - nazwa funkcji,
•
1, 2, 3, 4 - ilość argumentów funkcji,
•
b - argumenty typu GLbyte,
•
s - argumenty typu GLshort,
•
... itd... czyli najnormalniej typy danych GLfloat, GLdouble, GLubyte, GLushort,
GLuint
•
v - argument funkcji stanowi tablica wartości,
•
T arg1, ..., T argN - argumenty funkcji.
Robert Machejek
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
Typy danych - aby ładnie na różnych platformach hulało
Typ
danych
OpenGL
min.
liczba
bitów
Opisik
GLboolean
1
typ logiczny
GLbyte
8
liczba całkowita ze znakiem (U2)
GLubyte
8
liczba całkowita bez znaku
GLchar
8
ciąg znaków tekstowych
GLshort
16
liczba całkowita ze znakiem (U2)
GLushort
16
liczba całkowita bez znaku
GLint
32
liczba całkowita ze znakiem (U2)
GLuint
32
liczba całkowita bez znaku
GLsizei
32
nieujemna liczba całkowita
GLenum
32
typ wyliczeniowy całkowity
GLintptr
ptrbits
wskaźnik na liczbę całkowitą ze znakiem (U2)
GLsizeiptr
ptrbits
wskaźnik na nieujemna liczbę całkowitą
GLbitfield
32
pole bitowe
GLfloat
32
liczba zmiennoprzecinkowa
GLclampf
32
liczba zmiennoprzecinkowa z przedziału [0, 1]
GLdouble
64
liczba zmiennoprzecinkowa
GLclampd
64
liczba zmiennoprzecinkowa z przedziału [0, 1]
Robert Machejek
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
Wady a może zalety
OpenGL nie ma funkcji obsługujących operacje:
wejścia/wyjścia
interakcje z użytkownikiem
zarządzanie oknami.
Wywołania funkcji w OpenGL są zgodne z konwencją wywoływania
funkcji w języku C.
Robert Machejek
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
No to narysujmy tło
Na dobry początek tworzymy klasę MyView
public class MyView : OpenGLControl
{
public MyView() : base()
{}
public override void glDraw()
{GL.glClear(GL.GL_COLOR_BUFFER_BIT);}
protected override void InitGLContext()
{base.InitGLContext();
GL.glClearColor( 0.0f, 0.0f, 1.0f, 0.0f );}
protected override void OnSizeChanged(EventArgs e)
{base.OnSizeChanged(e);}
}
Robert Machejek
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
No to narysujmy tło
Mamy już klasę to teraz wypada konstruktor ładny napisać
public class MyView : OpenGLControl
public Form1()
{
InitializeComponent();
this.ClientSize = new System.Drawing.Size(640, 480);
// Ustawiamy rozmiar widoku
this.view = new MyView();
// Tworzymy obiekt klasy MyView
this.view.Parent = this;
// Ustawiamy rodzica na gªówne okno aplikacji
this.view.Dock = DockStyle.Fill;
// B¦dziemy wypeªnia¢ caªy okno.
}
... a jeżeli komuś się wydaje że to już koniec to zapomniał o ...
Robert Machejek
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
No to narysujmy tło
...o metodzie main klasy Form1
static void Main()
{
Form1 form = new Form1();
form.Show();
while( !form.IsDisposed )
{
form.view.glDraw();
form.Refresh();
Application.DoEvents();
}
form.Dispose();
}
Robert Machejek
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
No to narysujmy tło
Na koniec wypadało by się pochwalić wynikami :D ...
Robert Machejek
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
No to narysujmy tło
... wiec się chwalimy
Robert Machejek
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
aby nie było bo mieliśmy się czegoś nauczyć
Przywołani do porządku dowiedzmy się co te dziwne znaczki na
wcześniejszych stronach oznaczają
glDraw()
- funkcja odpowiedzialna za wy±wietlanie. Standardowo
metoda ta jest wywoªywana na zdarzenie
Paint
.
InitGLContext()
- w tej metodzie przeprowadzane s¡ wszystkie
inicjacje jak np ustawienie koloru czyszczenia bufora kolorów.
OnSizeChanged()
- metoda obsªuguj¡ca zdarzenie zmiany rozmiaru
okna..
ClientSize
- ustawiamy rozmiar po obszaru roboczego po jakim
b¦dziemy rysowa¢.
view.Parent
- ustawiamy rodzica dla na gªówne okno. Dzi¦ki temu
okre±lamy gdzie b¦dziemy rysowa¢ za pomoc¡ klasy
MyView
.
viewDock
- okre±lany sposób wypeªnienia obszaru roboczego. W tym
przypadku ustawiamy wypeªnianie caªego okna.
Robert Machejek
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
...a co namieszaliśmy w metodzie Main?
Po pierwsze usunęliśmy standardowe uruchomienie aplikacji. W tym
przypadku było to konieczne. Problem tkwi bowiem w nieustannym
odświeżaniu okna. Problem rozwiązaliśmy następująco:
tworzymy obiekt reprezentujący nasze okno głównego
wyświetlamy okno
wykonujemy pętle do momentu kiedy okno nie zostanie uznane za
niewłaściwą kontrolkę (następuje to np po wywołaniu komendy
zamknięcia aplikacji). W każdej iteracji wywołujemy metodą rysującą
klasy
MyView
, odświeżamy okno a następnie obsługujemy
komunikaty okna.
Robert Machejek
OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
rysujemy trójkącik :D
W tym celu musimy naspidać metodę
Draw()
public override void Draw()
{
#region Draw Triangle
Gl.glPushMatrix();
base.Draw();
Gl.glBegin(Gl.GL_TRIANGLES);
// Rysowanie trójk¡ta
Gl.glColor4fv(colorTop);
Gl.glVertex3f(0.0f, (oat)(+height / 2), 0.0f);
// Wierzchoªek trójk¡ta
Gl.glColor4fv(colorLeftBottom);
Gl.glVertex3f((oat)(-xSize / 2), (oat)(-height / 2), 0.0f);
// Lewy bok trójk¡ta
Gl.glColor4fv(colorRightBottom);
Gl.glVertex3f((oat)(+xSize / 2), (oat)(-height / 2), 0.0f);
// rodeczek trójk¡ta
Gl.glEnd();
// I to by byªo na tyle z trójk¡cikiem
Gl.glPopMatrix();
#endregion
}
Robert Machejek
OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
rysujemy trójkącik cd..
Biorąc pod uwagę, że tym razem korzystamy z bogatej biblioteki
TaoFramework
w wyniku powyższej operacji powinniśmy otrzymać
poniższy efekt
Robert Machejek
OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
rysujemy trójkącik cd..
Chcąc narysować kwadracik w wersji ambitniejszej wracamy do pierwszej
implementacji (niebieskie tło) i nadpisujemy klasy zgodnie ze schematem.
protected override void InitGLContext()
{ GL.glShadeModel(GL.GL_SMOOTH);
// gładkie cieniowanie
GL.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
// kolor czyszczenia bufora kolorów
GL.glClearDepth(1.0f);
// wartość wypełnienia bufora głębi
GL.glEnable(GL.GL_DEPTH_TEST);
GL.glDepthFunc(GL.GL_LEQUAL);
GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT,GL.GL_NICEST);
}
Robert Machejek
OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
rysujemy kwadracik cd..
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
// wywoªujemy metod¡ klasy bazowej
System.Drawing.Size s = Size;
// pobieramy nowy rozmiar okna
GL.glMatrixMode(GL.GL_PROJECTION);
GL.glLoadIdentity();
GL.gluPerspective(45.0f, (double)s.Width /(double) s.Height, 0.1f,
100.0f);
GL.glMatrixMode(GL.GL_MODELVIEW);
GL.glLoadIdentity();
}
Robert Machejek
OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
rysujemy kwadracik cd..
public override void glDraw()
{ GL.glClear(GL.GL_COLOR_BUFFER_BIT); GL.glClear(GL.GL_COLOR_BUFFER_BIT |
GL.GL_DEPTH_BUFFER_BIT); GL.glMatrixMode(GL.GL_MODELVIEW); GL.glLoadIdentity(); GL.glTranslatef(0.0f,0.0f,-5.0f);
GL.glRotatef(xrot,1.0f,0.0f,0.0f); // obrót po osi X xrot+=0.3f; // zwiększenie kąta obrotu po osi X GL.glRotatef(yrot,0.0f,1.0f,0.0f); // obrót po osi Y
yrot+=0.2f; // zwiększenie kąta obrotu po osi Y GL.glRotatef(zrot,0.0f,0.0f,1.0f); // obrót po osi Z zrot+=0.4f; // zwiększenie kąta obrotu po osi Z
GL.glBegin(GL.GL_QUADS); // rozpoczęcie rysowania czworoboków
GL.glColor3f(1.0f, 0.0f, 0.0f); GL.glVertex3f(1.0f,1.0f,1.0f); // deklaracja koloru i wierzchołka
GL.glColor3f(1.0f, 0.0f, 0.0f); GL.glVertex3f(-1.0f,1.0f,1.0f)
GL.glColor3f(1.0f, 0.0f, 0.0f); GL.glVertex3f(-1.0f,-1.0f,1.0f);
GL.glColor3f(1.0f, 0.0f, 0.0f); GL.glVertex3f(1.0f,-1.0f,1.0f);
GL.glColor3f(0.0f, 1.0f, 0.0f); GL.glVertex3f(-1.0f,1.0f,-1.0f);
GL.glColor3f(0.0f, 1.0f, 0.0f); GL.glVertex3f(1.0f,1.0f,-1.0f);
GL.glColor3f(0.0f, 1.0f, 0.0f); GL.glVertex3f(1.0f,-1.0f,-1.0f);
GL.glColor3f(0.0f, 1.0f, 0.0f); GL.glVertex3f(-1.0f,-1.0f,-1.0f);
GL.glColor3f(0.0f, 0.0f, 1.0f); GL.glVertex3f(1.0f,1.0f,-1.0f);
GL.glColor3f(0.0f, 0.0f, 1.0f); GL.glVertex3f(-1.0f,1.0f,-1.0f);
GL.glColor3f(0.0f, 0.0f, 1.0f); GL.glVertex3f(-1.0f,1.0f,1.0f);
GL.glColor3f(0.0f, 0.0f, 1.0f); GL.glVertex3f(1.0f,1.0f,1.0f);
GL.glColor3f(1.0f, 0.0f, 1.0f); GL.glVertex3f(1.0f,-1.0f,1.0f);
GL.glColor3f(1.0f, 0.0f, 1.0f); GL.glVertex3f(-1.0f,-1.0f,1.0f);
GL.glColor3f(1.0f, 0.0f, 1.0f); GL.glVertex3f(-1.0f,-1.0f,-1.0f);
GL.glColor3f(1.0f, 0.0f, 1.0f); GL.glVertex3f(1.0f,-1.0f,-1.0f);
GL.glColor3f(0.0f, 1.0f, 1.0f); GL.glVertex3f(1.0f,1.0f,-1.0f);
GL.glColor3f(0.0f, 1.0f, 1.0f); GL.glVertex3f(1.0f,1.0f,1.0f);
GL.glColor3f(0.0f, 1.0f, 1.0f); GL.glVertex3f(1.0f,-1.0f,1.0f);
GL.glColor3f(0.0f, 1.0f, 1.0f); GL.glVertex3f(1.0f,-1.0f,-1.0f);
GL.glColor3f(1.0f, 1.0f, 0.0f); GL.glVertex3f(-1.0f,1.0f,1.0f);
GL.glColor3f(1.0f, 1.0f, 0.0f); GL.glVertex3f(-1.0f,1.0f,-1.0f);
GL.glColor3f(1.0f, 1.0f, 0.0f); GL.glVertex3f(-1.0f,-1.0f,-1.0f);
GL.glColor3f(1.0f, 1.0f, 0.0f); GL.glVertex3f(-1.0f,-1.0f,1.0f);
GL.glEnd(); // koniec rysowania
}
Robert Machejek
OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
rysujemy kwadracik cd..
Robert Machejek
OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
ambitnego Bohachevskiego narysujmy
Zaczynamy standardowo - nadpisujemy klasy do czego zdążyliśmy się już
chyba przyzwyczaić.
protected override void InitGLContext()
{
GL.glShadeModel(GL.GL_SMOOTH); // gªadkie cieniowanie
GL.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // kolor czyszczenia bufora
kolorów
GL.glClearDepth(1.0f); // warto±¢ wypeªnienia bufora gª¦bi
GL.glEnable(GL.GL_DEPTH_TEST); // uaktywnienie testu gª¦bi
GL.glDepthFunc(GL.GL_LEQUAL); // rodzaj funkcji testuj¡cej gª¦bie
GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
BuildLists();
}
Robert Machejek
OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
ambitnego Bohachevskiego narysujmy
Nadpisujmy dalej - w końcu wersja dla ambitnych ma być
protected override void OnSizeChanged(EventArgs e)
{
{
base.OnSizeChanged(e); // wywoªujemy metod¡ klasy bazowej
System.Drawing.Size s = Size; // pobieramy nowy rozmiar okna
GL.glMatrixMode(GL.GL_PROJECTION);
GL.glLoadIdentity();
GL.gluPerspective(45.0f, (double)s.Width / (double)s.Height, 0.1f,
100.0f);
GL.glMatrixMode(GL.GL_MODELVIEW)
ustalamy widok;
GL.glLoadIdentity();
}
Robert Machejek
OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
ambitnego Bohachevskiego narysujmy
Teraz utworzymy sobie klasę którą sobie porysujemy
public void DrawGraph(int functionNumber)
{ {
float r = 0, g = 0, b = 0;
GetData(bohachevsky f1.dat); break; }
GL.glBegin(GL.GL_QUAD_STRIP);
for (int layer = 0; layer < 10; layer++)
{
for (int i = 0; i < pointCount; i++)
{
if (zTable[i] < 0)
GL.glColor3f(0.0f, 0.6f, 1.0f);
else
GL.glColor3f(0.0f, 0.3f, 1.0f);
GL.glVertex3f(xTable[i], zTable[i], yTable[i]);
GL.glVertex3f(xTable[i + layer * pointCount], zTable[i + layer * pointCount], yTable[i + layer * pointCount]);
if (i == 96)
{
i = i + 2;
GL.glEnd();
GL.glBegin(GL.GL_QUAD_STRIP);
}
{ r = r + 0.01f; g = g + 0.01f; b = b + 0.01f; }
i++;
}
}
GL.glEnd(); }) }
Robert Machejek
OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
Magiczny plik
bohachevsky f1.dat
Magiczny pliczek to nic innego jak współrzędne które posłużą do
wyrysowania funkcji oraz typ zmiennej
#x y z type -50 -50 7500 GLint
-48.9899 -50 7400.61 GLint
-47.9798 -50 7302.07 GLint
-46.9697 -50 7206.74 GLint
-45.9596 -50 7112.31 GLint
-44.9495 -50 7021.02 GLint
-43.9394 -50 6930.72 GLint
-42.9293 -50 6843.46 GLint
-41.9192 -50 6757.3 GLint
-40.9091 -50 6674.05 GLint
-39.899 -50 6592.06 GLint
-38.8889 -50 6512.8 GLint
-37.8788 -50 6434.98 GLint
... ... ... ...
-29.798 -50 5888.32 GLint
-28.7879 -50 5828.92 GLint
-27.7778 -50 5772.05 GLint
-26.7677 -50 5716.63 GLint
-25.7576 -50 5663.95 GLint
... ... ... ...
Robert Machejek
OpenGL - co? kto? kiedy?
Napiszmy pierwszy program
Napiszmy coś ambitniejszego
to jeszcze kwadracik w wersji dla ambitnych
Niedoceniani zróbmy coś ambitnego
wynik końcowy wcześniejszego kodu
Czyli ładny wykresik dostaliśmy
Robert Machejek
Podsumowanie
Reasumując olbrzymią zaletą OpenGL jest wizualizacja (takie ładne
wszystko). Wodą jest z całą pewnością skomplikowana składnia.
Dziękuje za uwagę
Robert Machejek