Movatterモバイル変換


[0]ホーム

URL:


Przejdź do zawartości
Wikipediawolna encyklopedia
Szukaj

OpenGL

Z Wikipedii, wolnej encyklopedii
OpenGL
Logo OpenGL
Logo programu
ilustracja
AutorKhronos Group
Aktualnawersja stabilna4.6
(31 lipca 2017) [±]
Platforma sprzętowaWieloplatformowe
System operacyjnyWieloplatformowe
RodzajBiblioteka programistyczna /API
Multimedia w Wikimedia Commons
Strona internetowa

OpenGL (ang. Open Graphics Library) – specyfikacjaotwartego iuniwersalnegoAPI dotworzeniagrafiki. Zestaw funkcji składa się z 250 podstawowych wywołań, umożliwiających budowanie złożonych trójwymiarowych scen z podstawowych figur geometrycznych.

Cele

[edytuj |edytuj kod]

Główny

[edytuj |edytuj kod]

Głównym celem jest tworzenie grafiki. Dzięki temu, że polecenia są realizowane przez sprzęt (GPU), tworzenie grafiki następuje szybciej niż innymi sposobami. Ten efekt nazywamyprzyspieszeniem sprzętowym.OpenGL wykorzystywany jest często przez gry komputerowe iwygaszacze ekranu, spełnia rolę analogiczną, jak konkurencyjnyDirect3D (częśćDirectX) w systemieWindows. OpenGL używają również programy do przedstawiania wyników badań naukowych,CAD, orazwirtualnej rzeczywistości.

Dodatkowy

[edytuj |edytuj kod]

OpenGL jest wykorzystywane do szybkich obliczeń (GPGPU), mimo że nie był do tego zaprojektowany.

Opis działania

[edytuj |edytuj kod]

OpenGL, podobnie jak np.X Window System, działa warchitekturzeklient-serwer. Klientem w tym przypadku jest aplikacja wykorzystująca OpenGL, która zleca operacje graficzne do wykonania, a serwerem – aktualnie używanaimplementacja OpenGL (np. w sterowniku karty graficznej). Zwykle klient i serwer znajdują się na tej samej maszynie, jednak nie jest to konieczne – biblioteka jest zaprojektowana tak, aby możliwe było np. wyświetlanie grafiki OpenGL na zdalnym terminalu. Jednocześnie dzięki zastosowaniu zunifikowanego protokołu komunikacji wyświetlanie może odbywać się na zupełnie innej platformie niż ta, na której działa aplikacja.

Jedną z podstawowych cech OpenGL jest to, że jest onmaszyną stanu (ang.state machine). Na stan OpenGL w danym momencie składa się szereg parametrów i trybów działania, które można ustawić lub zapamiętać na stosie i później odtworzyć. Ich konfiguracja będzie miała bezpośredni lub pośredni wpływ na otrzymany rezultatrenderingu. Raz ustawiony parametr lub tryb działania pozostaje zachowany aż do następnej zmiany. Przykładami takich parametrów mogą być kolor rysowania, aktualnie używanatekstura, sposób działaniabufora Z,macierz na której wykonywane są aktualnie operacje, oraz wiele innych.

Część z parametrów może być włączana lub wyłączana w sposób prosty, tzn. poprzez wywołanie funkcjiglEnable() lubglDisable(), a inne ustawiane są poprzez wykonanie powiązanych z tymi parametrami funkcji (np.glBindTexture() – ustawienie aktywnej tekstury).

Dzięki funkcjiglPushAttrib() możliwe jest zapamiętanie na stosie części lub całości aktualnego stanu OpenGL w zależności od przekazanego jej argumentu. Funkcja odwrotna, czyliglPopAttrib() nie wymaga żadnych argumentów, gdyż pobiera ze szczytustosu taki stan, jaki został wcześniej zapamiętany.

Geneza OpenGL

[edytuj |edytuj kod]

Pierwotna wersja biblioteki wyewoluowała ze stworzonej przez firmęSilicon Graphics Inc. dla jej systemów graficznych bibliotekiIRIS GL(inne języki). W chwili obecnej implementacje OpenGL można znaleźć w praktycznie wszystkich nowoczesnych platformach. W większości przypadków implementacje te rozwijane są przez producentów sprzętu graficznego. Istnieje również otwarta implementacja –Mesa, zgodna z OpenGL na poziomie kodu, która jednak ze względu na brak licencji określana jest jako „bardzo podobna”.

Do połowy 2006 rozwój OpenGL był kontrolowany przez organizacjęARB (Architectural Review Board), powołaną w 1992 i zrzeszającą 10 firm (3DLabs(inne języki),Apple,ATI,Dell, Evans & Sutherland,Hewlett-Packard,IBM,Intel,Matrox,NVIDIA,SGI,Sun Microsystems), które spotykały się raz na 3 miesiące, aby głosować i podejmować decyzje. 31 lipca 2006 komitet standaryzacyjny ARB opowiedział się w głosowaniu za wcieleniem tej organizacji do grupy roboczejKhronos, która prowadzi prace nad wieloma pokrewnymi projektami w tymOpenGL ES, co w założeniach miało uprościć formalności, przyspieszyć prace i ujednolicić dalszy rozwój tych standardów. Prawa do logo i nazwy OpenGL nadal jednak należą doSGI.

Prace nowej grupy roboczej pozytywnie wpłynęły na podejście do społecznościprogramistów OpenGL. Postawiono na intensywną współpracę, szeroki kontakt oraz częste informowanie o postępach w pracy nad nowymi rozwiązaniami. Na życzenie użytkowników zaczęto pracować nad jednolitymSDK, które ma ułatwić poznanie tej biblioteki nowym deweloperom oraz dostarczać narzędzia przydatne do analizy, budowania i optymalizacji aplikacji, które z niej korzystają.

We wrześniu 2004 ARB opublikowała specyfikację OpenGL w wersji 2.0. Kolejna wersja 2.1 ujrzała światło dzienne w sierpniu 2006 i jest już oficjalnie firmowana przezKhronos. Na rok 2007 zapowiedziano premierę dwóch kolejnych wersji OpenGL o kodowych nazwach „Longs Peak” i „Mt. Evans”. Pierwsza z nich miała być zgodna z dotychczasowymi akceleratorami wykorzystującymi standardShader Model 3.0, kolejna miała obsługiwać już tylko karty następnej generacji.

Wersje

[edytuj |edytuj kod]

Zależność między Opengl iGLSL:[1]

Wersja OpenGLWersja GLSL#version tag
1.2
2.01.10.59110
2.11.20.80120
3.01.30.10130
3.11.40.08140
3.21.50.11150
3.33.30.60330
4.04.00.90400
4.14.10.60410
4.24.20.60420
4.34.30.60430

Biblioteki pomocnicze

[edytuj |edytuj kod]

Mimo dużych możliwości, samo OpenGL jest interfejsem niskopoziomowym. Oznacza to, że zawiera ono np. funkcje rysujące pojedyncze wielokąty lub seriewielokątów albo funkcje operujące namacierzy widoku, ale już na przykład funkcje pozwalające na ustawienie obserwatora w pewnym punkcie patrzącego w inny punkt (gluLookAt), narysowanie całej sfery (gluSphere), bądź automatyczne wygenerowaniemipmap dla danejtekstury (gluBuild2DMipmaps), realizowane są za pomocą biblioteki pomocniczejGLU(inne języki) (ang.GL Utility Library).

Poza GL i GLU do wykorzystania OpenGL w aplikacji potrzebne są zwykle również inne biblioteki. Wynika to z faktu, że OpenGL zajmuje się tylko renderingiem grafiki i nie zawiera funkcji związanych z tworzeniem kontekstu graficznego, obsługą środowiska okienkowego, czy obsługą zdarzeń takich jak naciśnięcie klawisza na klawiaturze lub ruch kursora myszy. Funkcjonalność tę można dodać poprzez biblioteki, jakGLUT (ang.GL Utility Toolkit),GLUI, czy przeznaczone dla poszczególnych platformGLX (w przypadku środowiskaX Window System) lubWGL (w przypadku Windows).

Istnieje również bibliotekaSDL (ang.Simple DirectMedia Layer), realizująca funkcje podobne jak DirectX i jednocześnie umożliwiająca łatwe użycie OpenGL z jej poziomu.

Zarówno SDL, jak i GLUT dostępne są dla wielu platform, a zatem pozwalają na efektywne tworzenie przenośnych aplikacji. W przeciwieństwie do SDL klasyczny GLUT (dzieło Marka Kilgarda) nie jest już jednak rozwijany i choć pojawiają się nieoficjalne wersje typufreeglut, to rozwiązują one bardziej kwestie licencyjne niż podtrzymują rozwój tego oprogramowania.

Rozszerzenia

[edytuj |edytuj kod]

OpenGL został zaprojektowany w taki sposób, aby producenci sprzętu graficznego mogli rozszerzać jego funkcjonalność poprzez własne rozszerzenia. Rozszerzenia takie dystrybuowane są poprzez publikację zarównosterowników obsługujących dane funkcje, jak równieżplików nagłówkowych z definicjami tychże, aby z funkcji tych mogli skorzystać programiści piszącyoprogramowanie używające OpenGL.

Funkcje lub stałe występujące w rozszerzeniach oznaczane są skrótami przyporządkowanymi poszczególnym producentom (np. funkcje firmy NVIDIA oznaczane są skrótemNV). Jeśli funkcja jest używana przez więcej niż jednego producenta, oznaczana jest skrótemEXT, a w przypadku, gdy zostanie oficjalnie zaakceptowana przezArchitectural Review Board, staje się ona rozszerzeniem standardowym i otrzymuje oznaczenieARB. Później, rozszerzenie może się stać oficjalnie częścią standardu OpenGL, w kolejnej jego wersji.

Przykładowy kod

[edytuj |edytuj kod]
Potok programowalny OpenGL 3.3

Najmniejszy, najprostszy program wykorzystujący możliwości OpenGL składa się z pięciu plików. Głównego pliku programu – main.cpp, klasy wykorzystującej możliwości OpenGL (mainwindow.cpp) oraz nagłówka do tej klasy (mainwindow.h), a także dwóch plików z kodem shaderów.

Kolejność przekształceń punktów/wierzchołków

Przykład został napisany w języku C++ z wykorzystaniem bibliotekQt. Wykorzystuje onOpenGL w wersji 3.3.

Niezbędnefunkcje iklasy do napisania programu:

main:

  • QApplication,
  • Nasza nowa klasa wykorzystująca OpenGL,
  • QSurfaceFormat
  • QSufraceFormat::defaultFormat();
  • QSurfaceFormat::setProfile();
  • QSurfaceFormat::setVersion();
  • QSurfaceFormat::setDefaultFormat();

mainwindow:

1) Przygotowanie:

  • initializeOpenGLFunctions();
  • glCreateProgram();
  • glCreateShader();
  • glShaderSource();
  • glCompileShader();
  • glGetShaderiv();
  • glAttachShader();
  • glDeleteShader();
  • glGetShaderInfoLog();
  • glLinkProgram();
  • glGetProgramiv();

3) Obiekty – przygotowanie:

  • glGenVertexArray();
  • glBindVertexArray();
  • glEnableVertexAtribArray();
  • glGenBuffers();
  • glBindBuffer();
  • glBufferData();
  • glVertexAttribPointer();
  • glGenTextures();
  • glActiveTexture();
  • glBindTexture();
  • glTexImage2D()
  • glTexParameteri();

4) Opcjonalne:

  • glGenFramebuffers();
  • glBindFramebuffer();
  • glFramebufferTexture2D();
  • glCheckFramebufferStatus();

5) Rysowanie/Działanie:

  • glGetIntegerv();
  • glBindFramebuffer();
  • glViewport();
  • glClear();
  • glUseProgram();
  • glActiveTexture();
  • glBindTexture()
  • glGetUniformLocation();
  • glUniform1i();
  • glBindVertexArray();
  • glDrawArrays();

Niezbędnemakra:

  • GL_VERTEX_SHADER,
  • GL_COMPILE_STATUS,
  • GL_FRAGMENT_SHADER,
  • GL_LINK_STATUS,
  • GL_ARRAY_BUFFER,
  • GL_STATIC_DRAW,
  • GL_FALSE,
  • GL_FLOAT,
  • GL_TEXTURE0,
  • GL_TEXTURE_2D,
  • GL_RGBA,
  • GL_BGRA,
  • GL_UNSIGNED_BYTE,
  • GL_TEXTURE_MIN_FILTER,
  • GL_LINEAR,
  • GL_COLOR_BUFFER_BIT,
  • GL_TRIANGLES,

Dodatkowe makra:

  • GL_FRAMEBUFFER,,
  • GL_COLOR_ATTACHMENT0,
  • GL_DRAW_FRAMEBUFFER_BINDING,

Szczegóły na temat poszczególnych funkcji oraz makr podane są nastronie dokumentacji OpenGL.

Plikmain.cpp

#include"mainwindow.h"#include<QApplication>#include<QSurfaceFormat>intmain(intargc,char*argv[]){QApplicationa(argc,argv);QSurfaceFormatformat=QSurfaceFormat::defaultFormat();format.setProfile(QSurfaceFormat::CoreProfile);format.setVersion(3,3);QSurfaceFormat::setDefaultFormat(format);MainWindoww;w.show();returna.exec();}

Plikmainwindow.h

# ifndef MAINWINDOW_H# define MAINWINDOW_H//#include <QMainWindow>#include<QOpenGLFunctions_3_3_Core>#include<QOpenGLWidget>classMainWindow:publicQOpenGLWidget,protectedQOpenGLFunctions_3_3_Core//public QMainWindow,{//Q_OBJECTGLuintuchwytProg1;//unsigned intGLuintVertexArrayO;// Vertex Array ObjectintilWierz;//ilosc wierzcholkowGLuinttex0;public:MainWindow();~MainWindow();voidinitializeGL();voidpaintGL();voidresizeGL(intw,inth);};# endif// MAINWINDOW_H

Plikmainwindow.cpp

#include"mainwindow.h"#include<QOpenGLFunctions_3_3_Core>#include<QFile>#include<Qdebug>structvec3{floatx,y,z;};MainWindow::MainWindow()//QMainWindow(parent){}MainWindow::~MainWindow(){}voidMainWindow::initializeGL(){initializeOpenGLFunctions();qDebug()<<"initializeGL";GLintstatus;// program kopiujący teksture na ekranuchwytProg1=glCreateProgram();QFilefile("vshaderS.sh");if(file.open(QFile::ReadOnly)){QTextStreamstream(&file);std::stringvshader_zrodlo=stream.readAll().toStdString();GLuintshader=glCreateShader(GL_VERTEX_SHADER);GLchar*srcs[]={(GLchar*)vshader_zrodlo.c_str()};glShaderSource(shader,1,srcs,NULL);glCompileShader(shader);glGetShaderiv(shader,GL_COMPILE_STATUS,&status);//skompilowanyif(status==true){glAttachShader(uchwytProg1,shader);glDeleteShader(shader);}else{qDebug()<<"Shadera nie skompilowano. V";}qDebug()<<"BB"<<vshader_zrodlo.c_str();}elseqDebug()<<"Brak pliku";file.close();QFilefile2("fshaderS.sh");if(file2.open(QFile::ReadOnly)){QTextStreamstream(&file2);std::stringvshader_zrodlo=stream.readAll().toStdString();GLuintshader=glCreateShader(GL_FRAGMENT_SHADER);GLchar*srcs[]={(GLchar*)vshader_zrodlo.c_str()};glShaderSource(shader,1,srcs,NULL);glCompileShader(shader);glGetShaderiv(shader,GL_COMPILE_STATUS,&status);//skompilowanyif(status==true){glAttachShader(uchwytProg1,shader);glDeleteShader(shader);}else{qDebug()<<"Błąd komp. szhadera. F";GLcharinfoLog[10240];glGetShaderInfoLog(shader,10240,NULL,infoLog);qDebug()<<infoLog<<endl;}qDebug()<<"AA"<<srcs;}elseqDebug()<<"Brak pliku";file2.close();glLinkProgram(uchwytProg1);glGetProgramiv(uchwytProg1,GL_LINK_STATUS,&status);if(status==true){qDebug()<<"Program przygotowany";}elseqDebug()<<"Problemy z programem.";glUseProgram(uchwytProg1);GLintpolozenie=glGetUniformLocation(uchwytProg1,"textura");qDebug()<<"Polozenie, textura: "<<polozenie;// prostokat na cały ekranvec3wierzcholki[]={{-1,-1,0},{1,-1,0},//Dwa trójkąty...{1,1,0},{1,1,0},{-1,1,0},{-1,-1,0}};ilWierz=6;glGenVertexArrays(1,&VertexArrayO);glBindVertexArray(VertexArrayO);glEnableVertexAttribArray(0);//włączenie obsługi konkretnej tablicy atrybutów,//wygenerowanie nazwy bufora dla atrybutu i dodanie do mapy pod konkretnym indexemGLuintbuforVertex;glGenBuffers(1,&buforVertex);// przypisanie bufora do tablicy vaoglBindBuffer(GL_ARRAY_BUFFER,buforVertex);// stworzenie bufora i skopiowanie do niego danychglBufferData(GL_ARRAY_BUFFER,ilWierz*sizeof(vec3),wierzcholki,GL_STATIC_DRAW);// ustawienie odpowiednich typow i wielkosci bufora wierzcholkow vboglVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);glBindBuffer(GL_ARRAY_BUFFER,0);glBindVertexArray(0);glGenTextures(1,&tex0);glActiveTexture(GL_TEXTURE0);// tekstura wczytana z plikuQImageimg("lena.png");if(img.width()==0)qt_assert("QImage not loaded!",__FILE__,__LINE__);glBindTexture(GL_TEXTURE_2D,tex0);glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,img.width(),img.height(),0,GL_BGRA,GL_UNSIGNED_BYTE,img.bits());glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glBindTexture(GL_TEXTURE_2D,0);}voidMainWindow::resizeGL(intw,inth){qDebug()<<"resizeGL";}voidMainWindow::paintGL(){qDebug()<<"PaintGL – rysuje";GLuintpolozenie;/* niektore implementacje nie przypisuja domyslnego FB ekranu == 0        wtedy trzeba zapamietac samemu jego numer: */GLintscreenFB;glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING,&screenFB);qDebug()<<"Numer dla ScreenFramebuffer:  "<<screenFB;inttryb=1;if(tryb==1){// rysowanie tekstury na domyslnym FrameBufferze// glBindFramebuffer(GL_FRAMEBUFFER, 0);// lubglBindFramebuffer(GL_FRAMEBUFFER,screenFB);glViewport(0,0,width(),height());glClear(GL_COLOR_BUFFER_BIT);glUseProgram(uchwytProg1);// Ustawienie teksturypolozenie=glGetUniformLocation(uchwytProg1,"textura");if(polozenie!=-1)glUniform1i(polozenie,0);elseqDebug()<<"Brak zmiennej Uniform textura";glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D,tex0);glBindVertexArray(VertexArrayO);glDrawArrays(GL_TRIANGLES,0,ilWierz);glBindVertexArray(0);glBindTexture(GL_TEXTURE_2D,tex0);glViewport(width()/2.0,0,width()/2.0,height());glBindVertexArray(VertexArrayO);glDrawArrays(GL_TRIANGLES,0,ilWierz);glBindVertexArray(0);glUseProgram(0);}}

Plik vshader.glsl –Shader Vertexów – Shader wierzchołków:

# version 330layout(location=0)invec3VertexPosition;//atrybut zerowy,outvec2textureCoords;voidmain(){//Macierz skalowania,mat4macierz=mat4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);vec4a=vec4(VertexPosition.x,VertexPosition.y,VertexPosition.z,1);vec4b=a*macierz;// Macierz translacji – przesuwaniamat4macierzTran=mat4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);b=b*macierzTran;gl_Position=b;// lub://gl_Position = vec4(VertexPosition, 1); //-- wówczas będzie bez rotacji i bez translacjitextureCoords=VertexPosition.xy*0.5f+0.5f;}

Plik fshader.glsl –Shader Fragmentów:

# version 330//Dyrektywa informująca o wersji OpenGL'a// Zmienne wbudowane shadera:// in vec4 gl_FragCoord// in bool gl_FrontFacing// in vec2 gl_PointCoorduniformsampler2Dtekstura;invec2teksturaCoords;outvec4FragColor;//Obowiązkowa zmienna wyjściowa//fragment shader kopiujacy texele z tekstury na wyjscievoidmain(){//vec2 jest wbudowanym typem [wektor dwuelementowy]vec2tc=vec2(teksturaCoords.x,1-teksturaCoords.y);FragColor=texture(tekstura,tc);// discard; – spowoduje nie nadanie wartości danemu tekslowi, na danych współrzędnych}

Zobacz też

[edytuj |edytuj kod]

Przypisy

[edytuj |edytuj kod]
  1. OpenGL 4 Shaders Anton Gerdelan. 24 June 2014

Linki zewnętrzne

[edytuj |edytuj kod]
Źródło: „https://pl.wikipedia.org/w/index.php?title=OpenGL&oldid=78913439
Kategoria:
Ukryta kategoria:

[8]ページ先頭

©2009-2026 Movatter.jp