• Nie Znaleziono Wyników

Open GL

N/A
N/A
Protected

Academic year: 2021

Share "Open GL"

Copied!
26
0
0

Pełen tekst

(1)

OpenGL

narzędzie dla bardzo ambitnych

Robert Machejek

Instytut Informatyki Uniwersytet Śląski w Katowicach

12 grudnia 2008

(2)

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.

(3)

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.

(4)

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

(5)

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.

(6)

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]

(7)

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.

(8)

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);}

}

(9)

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 ...

(10)

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();

}

(11)

No to narysujmy tło

Na koniec wypadało by się pochwalić wynikami :D ...

(12)

No to narysujmy tło

... wiec się chwalimy

(13)

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 zdarzeniePaint.

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.

(14)

...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ą klasyMyView, odświeżamy okno a następnie obsługujemy

komunikaty okna.

(15)

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 }

(16)

rysujemy trójkącik cd..

Biorąc pod uwagę, że tym razem korzystamy z bogatej biblioteki TaoFrameworkw wyniku powyższej operacji powinniśmy otrzymać poniższy efekt

(17)

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);

}

(18)

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();

}

(19)

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 }

(20)

rysujemy kwadracik cd..

(21)

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();

}

(22)

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();

}

(23)

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(); }) }

(24)

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 ... ... ... ...

(25)

wynik końcowy wcześniejszego kodu

Czyli ładny wykresik dostaliśmy

(26)

Podsumowanie

Reasumując olbrzymią zaletą OpenGL jest wizualizacja (takie ładne wszystko). Wodą jest z całą pewnością skomplikowana składnia.

Dziękuje za uwagę

Cytaty

Powiązane dokumenty

do: przyznawania zasiłków pieniężnych, organizowania świad- czeń opiekuńczych, udzielania schronienia, pracy socjalnej, prowadzenia poradnictwa czy domów pomocy społecznej

Juist dat was immers het basis- idee van de publieke ruimte als de fysieke manifestatie van de ‘publieke sfeer’ zoals deze door Hannah Arendt en Jürgen Habermas werd gedefini- eerd:

tekst próbny - black tekst próbny - olive tekst próbny - teal tekst próbny - red tekst próbny - blue tekst próbny - maroon tekst próbny - navy tekst próbny - gray

Responsibility of States for Internationally Wrongful Acts (ILC, 2001)

As a result of conversion process all data on public procurement along with supplementing and extensible data is readily available in a convenient format and can be uniformly

Basic conditions for the success of public projects – project management specialists

Ich echa powracać miały jeszcze wielokrotnie w  ma- larskiej i scenograficznej twórczości Roszkowskiej, by z czasem zasymilować się w efektowny sposób z odkrywaną

Wobec me- tafizyki cierpienia powstan¹ zatem pytania: o jego pocz¹tek (ájñ÷Þ), przyczynê (áé##ôéïí), elementy, naturê, przeciwieñstwo, iloœæ, jakoœæ, dyspozycje,