Programowanie w systemie UNIX/c grafika/OpenGL: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
linki, interpunkcja, literówki
Linia 1:
=Definicja=
==Ścisła==
OpenGL w ścisłym znaczeniu oznacza :
* standard sposóbusposobu dostępu do karty graficznej w celu :
** tworzenia grafiki ( 2D i 3D) - główny cel <ref>[http://www.opengl-tutorial.org/ OpenGl tutorial ]</ref>
** GPGPU - używając renderowania poza ekranem ( ang. offscreen rendering) : nie wysyła danych do bufora ramki<ref>[w[W:Bufor ramki| Bufor ramki w wikipediiWikipedii]]</ref> ( ang. the frame buffer ) ale do innej części pamięci karty graficznej ( ang. the offscreen buffer )<ref>[http://www.mathematik.uni-dortmund.de/~goeddeke/gpgpu/tutorial.html GPGPU::Basic Math / FBO Tutorial
Modified from Dominik Göddeke]</ref>
* nie jest biblioteką lecz specyfikacją (API). Nie jest związane ze sprzętem i dzięki temu jest wieloplatformowe, uniwersalne i abstrakcyjne. Nie posiada kodu źródłowego
* działa w architekturze klient-serwer
* system graficzny czasu rzeczywistego) = zapewnia [[Programowanie_w_systemie_UNIX/c_grafika/OpenGL#Przyspieszanie_sprz.C4.99towe|przyspieszenie sprzętowe ( ang. hardware acceleration ) renderowania grafiki]] dzięki :
** programowaniu równoległemu ( procesor i program)
** bezpośredniemu dostępowi do karty graficznej (z pominięciem systemu operacyjnego)<ref>[http://rmantiuk.zut.edu.pl/?page_id=166index.php/gkiw/ Radosław Mantiuk - wprowadzenie do grafiki ] </ref>
 
==Praktyczna==
W potocznym i praktycznym znaczeniu OpenGlOpenGL obejmuje następujące elementy :
* sprzęt ( karta graficzna z procesorem GPU)<ref>[http://askubuntu.com/questions/72766/how-do-i-find-out-the-model-of-my-graphics-card askubuntu question: how-do-i-find-out-the-model-of-my-graphics-card]</ref>
* oprogramowanie :
** sterownik karty graficznej
** biblioteki pomocnicze
Linia 22:
= Typy kodu OpenGL =
 
[[File:Linux Graphics Stack 2013.svg|thumb|right|grafiakwgrafika w linuksie]]
Typy kodu OpenGL, podział wg :
* OS ( lokalizacja bibliotek )
* język programowania
* środowiska ( konsola / IDE )
* platforma ( OpenGL / OpenglOpenGL ES )
* wersja OpenGL :
** legacy = 1 lub 2
** modern = czyli 3 lub 4 ( [[OpenGL Shading Language|GLSL]] )
* biblioteki podstawowe i ich wersje ( Gl, Glu , GLew, .... )
* GUI lub konsola
* sprzętu ( karta graficzna / GPU)
* [[Programowanie_w_systemie_UNIX/c_grafika/OpenGL#Sterowniki_karty_graficznej|sterownika karty graficznej]] ( program i jego wersja ) i moduł jądra ( ang. kernel module )
 
 
Ponieważ prawie dowolnie można łączyć powyższe cechy ( 9) liczba możliwych kombinacji jest bardzo duża, dlatego prawie każdy poradnik, program musimy zmodyfikować do naszych warunków.
 
Dostęp do GPU:
* z poziomu X-window : DRI -> GPU ( np. Mesa 3D )
* z poziomu konsoli bez X-window : DRI -> GPU ( np. DirectFB<ref>[httphttps://directfbgithub.orgcom/DirectFB/directfb directfb]</ref> )
 
=Test=
 
==Konsolowe==
Sprawdzamy instalację za pomocą konsolowego programu glxinfo ( Mesa ) <ref>[]http://www.linuxcommand.org/man_pages/glxinfo1.html| glxinfo - linux command]</ref><ref>[http://cgit.freedesktop.org/mesa/demos/tree/src/xdemos/glxinfo.c| glxinfo code]</ref>
glxinfo
Linia 52:
lub
 
glxinfo | more
 
lub
 
glxinfo > gl.txt
 
otrzymujemy :
 
<pre>
Linia 85:
glxinfo | grep "OpenGL version"
 
przykładowy wynik :
 
OpenGL version string: 3.0 Mesa 10.3.2
 
lub :
 
lub :
 
sudo /usr/lib/nux/unity_support_test -p -f
 
Przykładowy wynik :
 
<pre>
Linia 114 ⟶ 113:
Unity 3D supported: yes
</pre>
 
 
 
===Karta graficzna ===
 
Sprawdzamy kartę i jej sterownik używając '''lspci''' :
 
lspci | grep VGA
 
 
przykładowy wynik :
 
01:00.0 VGA compatible controller: NVIDIA Corporation GK104 [GeForce GTX 770] (rev a1)
 
lub '''nvidia-smi''' :
 
 
nvidia-smi<ref>[http://stackoverflow.com/questions/13125714/how-to-get-the-nvidia-driver-version-from-the-command-line How to get the nvidia driver version from the command line ? - stackoverflow]</ref>
 
Linia 153 ⟶ 148:
</pre>
 
Za pomocą '''cat''' otrzymujemy informacje o aktualnie załadowanym module jądra (ang. the version of the currently loaded NVIDIA kernel module ) :
 
cat /proc/driver/nvidia/version
 
otrzymujemy :
 
 
NVRM version: NVIDIA UNIX x86_64 Kernel Module 319.60 Wed Sep 25 14:28:26 PDT 2013
GCC version: gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)
 
 
Za pomocą '''dkms''' :
 
dkms status
 
otrzymujemy :
 
nvidia-304-updates, 304.108, 3.11.0-15-generic, x86_64: installed
 
 
Program : nvidia-detect<ref>[https://github.com/elrepo/packages/tree/master/nvidia-detect |nvidia-detect]</ref><ref>[http://www.howtoeverything.net/linux/hardware/installing-nvidia-drivers-in-linux-mint Installing Nvidia Drivers In Linux Mint]</ref>
<ref>[http://www.howtoeverything.net/linux/hardware/installing-nvidia-drivers-in-linux-mint|Installing Nvidia Drivers In Linux Mint
 
]</ref>
 
===Przyspieszanie sprzętowe ===
Sprawdzamy czy mamy przyśpieszanie sprzętowe : <ref>[http://mgltools.scripps.edu/documentation/how-to/hardware-opengl Using hardware accelerated 3D renderer on Linux from mgltools]</ref>
 
 
glxinfo | grep renderer
 
otrzymujemy :
 
OpenGL renderer string: GeForce GTX 770/PCIe/SSE2
 
to znaczy, że mamy przyspieszanie sprzętowe. Jeśli otrzymamuy otrzymamy:
 
Mesa GLX Indirect
 
to powinnniśmypowinniśmy zainstalować odpowiednie do posiadanej karty graficznej sterowniki.
 
== Graficzne==
Linia 201 ⟶ 187:
* strona Nvidia: Smart Scan <ref>[http://www.nvidia.com/Download/Scan.aspx?lang=en-us The NVIDIA Smart Scan page (requires the latest version of Java)]</ref>
* Gpu Test <ref>[http://www.geeks3d.com/20121113/gputest-0-2-0-cross-platform-opengl-benchmark-furmark-lands-on-linux-and-os-x/ Gpu test]</ref>
* LuxRender <ref>[http://www.luxrender.net/ | LuxRender]</ref>
* w przeglądarce chrome wpisz : <code>chrome://gpu</code><ref>[http://askubuntu.com/questions/5417/how-to-get-gpu-info/692858 askubuntu question : How to get GPU info?]</ref>
 
=Błędy=
Linia 208 ⟶ 194:
== undefined reference to ==
 
Spróbujmy skompilować przeglądarkę dla programistów w Ubuntu używając komendy :
 
 
gcc v.c -lm -lGLU -lglut -Wall
 
Otrzymamy :
<pre>
v.c: In function ‘readPPM’:
Linia 224 ⟶ 208:
</pre>
 
Błąd. Kompilator nie widzi definicji procedury glDrawPixels. W ubuntuUbuntu problem rozwiązuje dodanie biblioteki GL :
 
 
gcc v.c -lm -lGL -lGLU -lglut -Wall
v.c: In function ‘readPPM’:
Linia 234 ⟶ 216:
 
 
Czasem kolejność też ma znaczenie<ref>[http://stackoverflow.com/questions/8892251/undefined-reference-to-symbol-glulookat StackOverflow : undefined reference to symbol 'gluLookAt']</ref>
 
==Różne wersje sterownika karty graficznej i modułu jądra==
 
=Elementy OpenGlOpenGL=
 
 
Linia 253 ⟶ 235:
 
==Sterownik==
 
 
===wersje===
 
Wersje :<ref>[https://developer.nvidia.com/opengl-driver OpenGlOpenGL - wsparcie przez sterowniki firmy Nvidia ( ang.)]</ref><ref>[http://stackoverflow.com/questions/12383178/how-is-mesa-different-from-opengl-drivers How is Mesa different from OpenGL drivers - Sytackoverflow Stackoverflow]</ref>
* własnościowe sterowniki ( ang. : the proprietary drivers , GPU vendor's driver, binary driver, closed source unified NVIDIA drivers )<ref>[http://zyli.republika.pl/linux/nvidia.html| Zyli : Instalacja zamkniętych (firmowych) sterowników Nvidia ]</ref>
**Nvidia<ref>[http://www.nvidia.com/object/unix.html Nvidia Unix Driver Archive]</ref>
** AMD
* otwarte sterowniki (ang. : the open source drivers )
** Nouveau: Accelerated Open Source driver for nVidia cards. <ref>[httphttps://nouveau.freedesktop.org/wiki/ Nouveau: Accelerated Open Source driver for nVidia cards]</ref>
** MESA ( sterowniki zawarte w bibliotece programistycznej )
** Intel
** ATI/AMD ( radeon, radeonhd )
 
 
Sterowniki własnościowe Nvidii powoduję konflikt ze sterownikami Nouvoux. <ref>[https://help.ubuntu.com/community/BinaryDriverHowto/Nvidia|Ubuntu Ubuntu: BinaryDriverHowto/Nvidia]</ref>
 
===Etapy instalacji ===
* dodanie kodu do drzewa (ang. add)
* kompilacja ( build)
* instalacja ( ang. install )
* ładowanie modułu do jądra (
 
===Elementy===
====kod źródłowy====
* jądra : /lib/module/kernel - version/build directory
* modułu : /usr/src/module - module-version
 
====Moduł jądra====
Linia 286 ⟶ 266:
 
 
Moduł jadra jądra:
/lib/modules/wersja_jadra/kernel/drivers/video/nvidia.ko
 
SprawdzmySprawdźmy czy mamy załadowany moduł nvidia za pomocą [[Linux/lsmod|lsmod]] :
 
 
lsmod | grep nvidia
 
przykładowy wynik :
 
nvidia 9430379 50
drm 297056 2 nvidia
 
Mamy więc próbujemy otrzymać więcej informacji o nim za pomocą [[Linux/modinfo|modinfo]] :<ref>[http://askubuntu.com/questions/251754/why-would-modinfo-say-a-module-is-not-found-when-it-appears-with-lsmod| Why would modinfo say a module is not found when it appears with lsmod ?]</ref>
 
modinfo nvidia
 
wynik :
 
ERROR: Module nvidia not found.
 
Przyczyną tego jest alias<ref>[[wW:en:alias (Unixcommand)|aliasAlias w wikipediiangielskiej angWikipedii]]</ref>. Znajdujemy właściwą nazwę :
 
 
modprobe --resolve-alias nvidia
 
wynik :
 
 
nvidia_319
 
i :
 
modinfo nvidia_319
 
Wynik :
<pre>
filename: /lib/modules/3.11.0-19-generic/updates/dkms/nvidia_319.ko
Linia 358 ⟶ 332:
 
==Biblioteki==
Pakiety : <ref>[http://stackoverflow.com/questions/859501/learning-opengl-in-ubuntu/1988688#1988688 stackoverflow question learning-opengl-in-ubuntu]</ref>
* freeglut3 freeglut3-dev
* libglew1.5 libglew1.5-dev
* libglu1-mesa, libglu1-mesa-dev, libgl1-mesa-glx , libgl1-mesa-dev
 
kompilacja :
 
gcc -lglut -lGL -lGLU -lGLEW example.c
 
W kodzie :
<source lang=c>
#include <GL/glew.h>
Linia 376 ⟶ 350:
</source>
 
Pliki nagłówkowe bibliotek :
* gl.h
* glu.h
Linia 384 ⟶ 358:
==== GL ====
 
GL = Graphic Library ( ang. ) jest to niskopoziomowa biblioteka zawierająca procedury do rysowania linii, koloru tła itp.
Otrzymujemy dostęp do OpenGL-1.1. Na więcej potrzebujemy rozszerzeń, np. za pomocą biblioteki GLEW<ref>[http://stackoverflow.com/questions/12122631/difference-between-opengl-files-glew-h-and-gl-h-glu-h Różnice między bibliotekami]</ref>
 
====GLU ====
 
GLU = Graphics Library Utility ( ang. ) jest to średniopoziomowa biblioteka pozwalająca na dostęp do macierzy, renderowania powierzchni itp.
 
===GUI===
Lekkie/ proste :
* [[Programowanie_w_systemie_UNIX/c_grafika/OpenGL/glut|GLUT / freeglut]]
 
Złożone :
* GLFW <ref>[http://www.glfw.org/ GLFW]</ref>
* GTK+
Linia 401 ⟶ 375:
* Qt
* GLUS <ref>[https://www.opengl.org/sdk/libs/GLUS/ GLUS]</ref>
 
 
====GLUT====
* GLUT
Linia 408 ⟶ 380:
====GLFW====
 
Wymagania :
* gcc
* OpenGlOpenGL ( OpenGL header packages )
* X11
* xorg-dev
Linia 417 ⟶ 389:
* cmake
 
Etapy :
* ściągnięcie kodu źródłowego biblioteki<ref>[http://www.glfw.org/download.html KOdKod żródłowy GLFW ]</ref>
* kompilacja biblioteki <ref>[http://www.glfw.org/docs/latest/compile.html Kompilacja GLFW ]</ref>
 
Linia 427 ⟶ 399:
 
 
Sprawdzamy :
sudo updatedb
locate glfw3.pc
 
przykładowy wynik :
 
 
/home/a/cn/glfw-3.0.4/src/glfw3.pc
/home/a/cn/glfw-3.0.4/src/glfw3.pc.in
Linia 456 ⟶ 426:
====SFML====
 
SFML = Simple and Fast Multimedia Library ( ang.)
 
===Rozszerzenia===
Biblioteki rozszerzeń ( ang. OpenGL Loading Library , Extension Loading Library)
* nieoficalny OpenGlOpenGL SDK <ref>[http://glsdk.sourceforge.net/ Unofficial OpenGL Software Development Kit]</ref>
* GLEW
* gl3w <ref>[http://github.com/shakesoda/gl3w gl3w]</ref>
Linia 467 ⟶ 437:
====GLEW====
 
GLEW = OpenGL Extension Wrangler Library ( ang.) jest to programistyczna biblioteka międzyplatformowa, pomagająca w odpytywaniu i ładowaniu rozszerzeń OpenGL. GLEW dostarcza efektywne mechanizmy do określania w czasie uruchamiania programu dostępnych rozszerzeń na danej platformie. Wszystkie rozszerzenia OpenGL są wylistowane w jednym pliku nagłówkowym, który z kolei jest maszynowo generowany na podstawie oficjalnej listy rozszerzeń.
 
GLEW jest napisany w ANSI C.
 
 
#include<GL/glew.h>
#include<GL/gl.h>
Linia 477 ⟶ 445:
#include<GL/glut.h>
 
Kompilacja :
 
-lGLEW -lGLU -lGL - lglut
 
GLEW zawiera dodatkowe programy konsolowe, np. : glewinfo
 
glewinfo>i.txt
 
W pliku i.txt jest informacja :
<pre>
---------------------------
Linia 498 ⟶ 466:
</pre>
 
Następnie jest lista rozszerzeń i informacja o dostępności ( OK/MISSING).
===matematyczne===
* GLM is a C++ mathematics library ( and to replace OpenGL fixed pipeline functions) for 3D software based on the OpenGL Shading Language (GLSL) specification.
 
===graficzne===
* GLI ( OpenGL Image , C++)
*
 
Linia 510 ⟶ 478:
==Pierwszy program ==
 
Konsolowy program korzystający z bibliotek GL, GLU i GLUT. Tworzy okno wypełnione czerwonym kolorem <ref>[http://www.linuxforuopensourceforu.com/2013/04/graphics-programming-in-linux/ Graphics Programming in Linux By Rajnish-Singh ] </ref>
 
<source lang=c>
Linia 555 ⟶ 523:
==GLEW==
 
Konsolowy program korzystający z glew :
 
<source lang="c">
//gcc c.c -lGLEW -lGL -lGLU -lglut
//./a.out
Linia 566 ⟶ 534:
#include<GL/glu.h>
 
void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInit(&argc, argv);
glewInit();
if ( GL_VERSION_4_0) printf("OpenGL 4.0 is supported\n");
glewInit();
if ( GL_VERSION_4_0) printf("OpenGL 4.0 is supported\n");
}
</source>
Linia 621 ⟶ 587:
</source>
 
Sprawdzamy rozszerzenia :<ref>[http://steps3d.narod.ru/tutorials/glew-tutorial.html glew tutorial - Alexey V. Boreskov]</ref>
 
<source lang=c>
Linia 698 ⟶ 664:
}
</source>
 
 
 
==Zapisywanie obrazu==
* kod (paul bourke ) <ref>[http://paulbourke.net/miscellaneous/windowdump/windowdump.c Zapisywanie obrazu z aplikacjioaplikacji OpenGlOpenGL - kod (paul bourke )]</ref>
==Przeglądarka obrazów dla programistów ==
Ten program :
* działa tylko dla legacy OpenGL API !
* otwiera binarne pliki ppm (P6) i pgm ( P5)
* wyświetla je w nowym oknie ( Glut)
* na konsoli tekstowej wyświetla :
** typ pliku,
** szerokość, wysokość,
** komentarz,
** dane punktu nad którym znajduje się mysz ( patrz procedura Motion, można to zmienić !!! )
 
Program służy do analizy plików graficznych.
Linia 1130 ⟶ 1094:
|}
 
Q : Czego lepiej używać, wymiarów typu 1.0f, -2,0f, czy wartości w pixelach 100, 550 - przy rysowaniu ?
 
A : "Używaj tego co Ci wygodniej. Większość instrukcji operujących na wierzchołkach ma wersje dla liczb całkowitych - te z przedrostkiem i, jak i zmiennoprzecinkowych - te z przedrostkiem f(float) lub d(double)).
Q : Czego lepiej używać, wymiarów typu 1.0f, -2,0f, czy wartości w pixelach 100, 550 - przy rysowaniu ?
np: glVertex2i(x,y), glVertex2f(x,y), glVertex3d(x,y,z) itd." <ref>[http://cpp0x.pl/forum/temat/?id=3091 Forum Serwisu programistycznego C i C++ : [OPENGL] glViewport a gluOtrho2d] </ref>
 
A : "Używaj tego co Ci wygodniej. Większość instrukcji operujących na wierzchołkach ma wersje dla liczb całkowitych - te z przedrostkiem i, jak i zmiennoprzecinkowych - te z przedrostkiem f(float) lub d(double)).
np: glVertex2i(x,y), glVertex2f(x,y), glVertex3d(x,y,z) itd." <ref>[http://cpp0x.pl/forum/temat/?id=3091 Forum Serwisu programistycznego C i C++ : [OPENGL] glViewport a gluOtrho2d] </ref>
 
 
Q : Gdzie definiujemy viewport ?
 
A : W 2 miejscach :
* w inicjalizacji , wtedy ma taki sam rozmiar jak całe okno
* w funkcji zmieniającej rozmiar okna ( glutReshapeFunc )
 
===Typy===
====World====
Domyślnie współrzędne okna światowego ( world) w OpenGlOpenGL mają zakres -1.0 do 1.0 :
 
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
 
 
Miejsce lewego dolnego rogu wyświetlanego obrazu :
 
glRasterPos2i(-1.0, -1.0); // in Draw procedure
Linia 1158 ⟶ 1121:
====Screen====
 
W OpenGlOpenGL mamy tu 3 elementy :
* rozdzielczość ekranu ( ang. screen )
* wielkość okna ekranu (ang. window)
* wielkość fragmentu okna ekranu gdzie jest wyświetlany obraz ( ang. viewport) <ref>[http://lmb.informatik.uni-freiburg.de/people/reisert/opengl/doc/glViewport.html glView[portglViewport] </ref><ref>[http://lazyfoo.net/tutorials/OpenGL/03_the_viewport/index.php The Viewport - Lazy Foo' Productions] </ref>
 
 
Współrzędne są liczbami całkowitymi :
 
glutInitWindowSize(2560, 1440); // screen width, screen height in poixels
Linia 1178 ⟶ 1141:
===Przeliczanie===
 
Przeliczanie współrzędnych :<ref>[ http://wwwweb.cse.ohio-state.edu/~whmin/courses/cse581-2012-winter/transformation_2D.pdf 2D Coordinate Systems and Drawing ] </ref>
* World window: W_L, W_R, W_B, W_T
* Viewport: V_L, V_R, V_B, V_T
* punkt :
** współrzędne world : (x,y)
** współrzędne viewport : (sx, sy)
 
world_height=world_width*view_port_height/view_port_width