Základy programování shaderů v OpenGL Část 2 - přenos dat

Podobné dokumenty
Základy programování shaderů v OpenGL Část 2 - přenos dat

Připravil: David Procházka. Vertex Buffer Objects

Fakulta informačních technologíı. IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 1 / 38

Připravil: David Procházka. Vykreslování grafických primitiv

NPGR019. Geometry & tessellation shaders. MFF UK Praha. Vykreslování v OpenGL Tessellation shaders Geometry shaders Literatura

Fakulta informačních technologíı. Rendering Seminář 1. 1 / 28

Základy OpenGL Josef Pelikán CGG MFF UK Praha. OpenGL / 34

Připravil: David Procházka. Shadery

Základy programování shaderů v OpenGL část 1 program

Android OpenGL. Práce s texturami

TAM. Prezentace přednášek. Ústav počítačové grafiky a multimédií

27. listopadu 2013, Brno Připravil: David Procházka

Transformace (v OpenGL) příklady a knihovna GLM

Programování grafiky ÚVOD

Textury. Petr Felkel, Jaroslav Sloup a Vlastimil Havran

Android OpenGL. Pokročilé shadery

Programování grafiky ÚVOD

Hierarchický model Josef Pelikán CGG MFF UK Praha. 1 / 16

Připravil: David Procházka. Základy OpenGL

Reprezentace 3D scény

Třída DrawingTool. Obrázek 1: Prázdné okno připravené pro kreslení

Počítačová grafika 2 (POGR2)

Programování shaderů GLSL

Úvod do programovacích jazyků (Java)

Reflections, refractions, interreflections

XNA Game Studio 3.1. Tomáš Herceg Microsoft Most Valuable Professional Microsoft Student Partner

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Datové typy v Javě. Tomáš Pitner, upravil Marek Šabo

PB161 Programování v jazyce C++ Přednáška 4

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

Co je grafický akcelerátor

ak. rok 2013/2014 Michal Španěl,

Zobrazování a osvětlování

Připravil: David Procházka. Projekce

2 Grafický výstup s využitím knihovny

Jana Dannhoferová Ústav informatiky, PEF MZLU

Zdroj:

V této příloze je podrobně popsána struktura XML dokumentu s mapou (viz kapitolu 5.3), příklad tohoto XML dokumentu je na přiloženém CD v souboru

Pokročilé programování v jazyce C pro chemiky (C3220) 3D grafika v knihovně Qt

PostGIS Topology. Topologická správa vektorových dat v geodatabázi PostGIS. Martin Landa

Rastrová reprezentace

Databázové systémy Cvičení 5.2

FPC - Převodník pro čínské čtečky F17 a F18 - podrobný popis služeb a příkazů -

Programování v C++ 3, 3. cvičení

Textury v real-time grafice Josef Pelikán, MFF UK Praha Josef.Pelikan@mff.cuni.cz

8 Třídy, objekty, metody, předávání argumentů metod

SOFTWARE NA ZPRACOVÁNÍ MRAČEN BODŮ Z LASEROVÉHO SKENOVÁNÍ. Martin Štroner, Bronislav Koska 1

Převod prostorových dat katastru nemovitostí do formátu shapefile

Téma: Arkanoid. X36SOJ Strojově orientované jazyky Semestrální práce. Vypracoval: Marek Handl Datum: červen 2006

Struktura programu v době běhu

Zobrazování terénu. Abstrakt. 1. Úvod. 2. Vykreslování terénu

Základy programování (IZP)

Problém identity instancí asociačních tříd

GENEROVÁNÍ KÓDU 9. SHRNUTÍ - PŘÍKLAD POSTUPU PŘEKLADU VSTUPNÍHO PROGRAMU (ZA POUŽITÍ DOSUD ZNÁMÝCH TECHNIK)

První kroky s METEL IEC IDE

Návod k použití softwaru Solar Viewer 3D

3D akcelerátory historie a architektura

IUJCE 07/08 Přednáška č. 6

Západočeská univerzita v Plzni Fakulta aplikovaných věd Katedra informatiky a výpočetní techniky. haptického pera

Úloha 1. Text úlohy. Vyberte jednu z nabízených možností: NEPRAVDA. PRAVDA Úloha 2. Text úlohy

Programování v C++ 2, 4. cvičení

Masivně paralelní zpracování obrazu v prostředí systému VisionLab Liberec Roman Cagaš, rc@mii.cz

Úvod Typy promítání Matematický popis promítání Implementace promítání Literatura. Promítání. Pavel Strachota. FJFI ČVUT v Praze

Základy programování (IZP)

Práce s binárními soubory. Základy programování 2 Tomáš Kühr

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Tematický celek Proměnné. Proměnné slouží k dočasnému uchovávání hodnot během provádění aplikace Deklarace proměnných

Úvodem... 9 Kapitola 1 Karetních

Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole

VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ

GIS1-7. cvičení. listopad ČVUT v Praze, Fakulta stavební, katedra mapování a kartografie. Obsah. Založení nového souboru s vektorovými daty

umenugr JEDNOTKA PRO VYTVÁŘENÍ UŽIVATELSKÝCH GRAFICKÝCH MENU Příručka uživatele a programátora

MyIO - webový komunikátor

Hardware pro počítačovou grafiku NPGR019

Michal Krátký. Tvorba informačních systémů, 2008/2009. Katedra informatiky VŠB Technická univerzita Ostrava. Tvorba informačních systémů

PB161 Programování v jazyce C++ Přednáška 9

programování formulářů Windows

Osnova. GIOP a IIOP IDL IOR POA. IDL Klient Server. 2 Historie. 3 Princip a základní pojmy. 4 Implementace. 5 Aplikace CORBA

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky

Geekovo Minimum. Počítačové Grafiky. Nadpis 1 Nadpis 2 Nadpis 3. Božetěchova 2, Brno

Základy 3D modelování a animace v CGI systémech Cinema 4D C4D

Základy programování (IZP)

Databázové systémy. - SQL * definice dat * aktualizace * pohledy. Tomáš Skopal

Tabulka symbolů. Vazba (binding) Vazba - příklad. Deklarace a definice. Miroslav Beneš Dušan Kolář

Manuál k aplikaci FieldGIS v.2.27

Elektronické publikování - prezentace. 23. dubna 2009 VŠB - TUO. Beamer - grafické zpracování prezentace. Rostislav Šuta, sut017.

Vektorové grafické formáty

Obsah. Základy práce s rastry. GIS1-5. cvičení. ČVUT v Praze, Fakulta stavební, katedra mapování a kartografie

Úvod do Matlabu. Praha & EU: Investujeme do vaší budoucnosti. 1 / 24 Úvod do Matlabu

Rasterizace je proces při kterém se vektorově definovaná grafika konvertuje na. x 2 x 1

8. Zpracování dotazu. J. Zendulka: Databázové systémy 8 Zpracování dotazu 1

Generování vnitřní reprezentace programu

Přednáška. Vstup/Výstup. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Úvod do programování - Java. Cvičení č.4

Hardware pro počítačovou grafiku NPGR019

Bitové operátory a bitová pole. Úvod do programování 2 Tomáš Kühr

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

MySQL sežere vaše data

Struktura scény. Petr Felkel Katedra počítačové grafiky a interakce, ČVUT FEL místnost KN:E-413 (Karlovo náměstí, budova E)

Úvod do GIS. Prostorová data I. část. Pouze podkladová prezentace k přednáškám, nejedná se o studijní materiál pro samostatné studium.

Transkript:

Základy programování shaderů v OpenGL Část 2 - přenos dat Petr Felkel, Jaroslav Sloup Katedra počítačové grafiky a interakce, ČVUT FEL místnost KN:E-413 (Karlovo náměstí, budova E) E-mail: felkel@fel.cvut.cz Poslední změna: 10.4.2016

Obsah přednášky Minule Tok dat v OpenGL se shadery Překlad a sestavení programu Struktura programu typu shader Dnes Předávání dat a parametrů do programu typu shader Grafická primitiva Příklady zdrojových kódů pro shadery

Předávání parametrů shaderům ATRIBUTY vrcholů (vstupy VS) UNIFORM (společné proměnné) Vertex Data Vertex Shader Primitive Assembly and Rasterization Fragment Shader Blending Pixel Data Texture Store OpenGL verze 3.1

Pro každý vrchol s atributy se spustí VS Vertex Shader Vertex Data Vertex Shader T&L Cache Primitive Assembly Vertex Shader 4

Atributy vrcholu a proměnné uniform UNIFORM (společné proměnné) ATRIBUTY vrcholu 0 1 n vertex shader 0 1 n fragment shader GPU attriblocation (index vstupu VS) uniformlocation (index společné proměnné uniform) 5

Index atributu = číslo vstupu VS (opak.) V kódu VS layout (location = 0) in vec3 VertexPosition; VS OpenGL V OpenGL před gllinkprogram() in vec3 VertexPosition; glbindattriblocation(programhandle, 0, VertexPosition ); Po slinkování po gllinkprogram() in vec3 VertexPosition; vplocation = glgetattriblocation(programhandle, VertexPosition ); 6

Data v hlavní paměti versus data na GPU Bottleneck!!! [http://www.yaldex.com/game-programming/0131020099_app02lev1sec10.html] 7

Postup před vykreslením jednoho snímku Inicializace a příprava dat (1x) Nastaví se stav OpenGL Připraví se balíky dat přenos do GPU (buffery) Připraví se informace o obsahu bufferů a jejich propojení na vstupy vertex shaderů (vertex arrays) Vykreslování (např. 60x za sekundu) viz dále Smazání obrazovky Propojení vstupů VS (bind vertex array) Spustí se vykreslení (draw) 8

Příprava dat k vykreslování 1x 1. Aplikace připraví atributy pro všechny vrcholy (pozice vrcholů, normály, ) 2. Vytvoří buffer objekty (VBO, EBO, ) a předá jim data (ovladač je obvykle překopíruje do videopaměti viz dále) 3. Zjistí indexy vstupních proměnných VS (glgetattriblocation) 4. Popíše, jak jsou v bufferu atributy uloženy a propojí je se vstupy VS vertex array (VAO) 9

Příklad scény 10

Data Baked in the code: static const GLfloat g_vertex_buffer_desk[] = { -1.0f,-1.0f,-1.0f, // triangle 1 : begin -1.0f,-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // triangle 1 : end 1.0f, 1.0f,-1.0f, // triangle 2 : begin -1.0f,-1.0f,-1.0f, -1.0f, 1.0f,-1.0f, // triangle 2 : end... } or Loaded from a file 11

Buffery Atributy vrcholů a indexy VBOs + EBO Propojení atributů s vertex shaderem 0 1 n in vec3 VertexPosition; in vec3 VertexNormal; vertex shader VAOs 12

Vertex Buffery VBO1 VBO2... VBOn GL_ARRAY_BUFFER GL_ELEMENT_ARRAY_BUFFER EBO indices Propojení atributů s vertex shaderem 0 1 n in vec3 VertexPosition; in vec3 VertexNormal; vertex shader VAOs 13

Attrib locations VBO1 VBO2... VBOn EBO indices Propojení atributů s vertex shaderem 0 1 n in vec3 VertexPosition; in vec3 VertexNormal; vertex shader VAOs 14

Vertex Array Objects VBO1 VBO2 VBOn... EBO indices VAO Attrib 1 positions x,y,z Buffer ID target offset stride size type index Attrib 2 normals nx,ny,nz Buffer ID target offset stride size type index 0 1 n in vec3 VertexPosition; in vec3 VertexNormal; vertex shader... Bind VertexAttribPointer indices (0 or 1x) Buffer ID element_array Bind 15

Objekty v OpenGL OpenGL využívá princip objektů Všechny objekty mají celočíselné jméno (ID, handle, ) Pomocí něj aktivujeme příslušný objekt či jej použijeme pro připojení k jinému objektu. Z hlediska aplikace je struktura objektu neznámá Jméno slouží k předávání objektu funkcemi API buffer jako pojmenovaný blok bytů v paměti vertex array jako kolekce bufferů a stavu OpenGL spojených se vstupem vrcholů s atributy do Vertex Shaderu (jak jsou v bufferech uloženy souřadnice a atributy a jak je propojit na vstupy VS) textura shader a program 16

Práce s objekty v OpenGL Při vytváření objektu 1. glgenxxx vytvoření jmen objektů --> vždy typ GLuint 2. glbindxxx (target,) object_name 3. Copy data - např. glteximage2d, glbufferdata,,, 4. + nastavení stavu OpenGL Při použití glbindxxx (target,) object_name Pokud objekt nepotřebujeme gldelete 17

Předávání dat mezi GPU a CPU v OpenGL Probíhá prostřednictvím těchto objektů Buffer Objekty (pro vrcholy nazýváme VBO, EBO, ) Vertex Array Objekty (pro vrcholy nazýváme VAO) VBO je principiálně jen jednorozměrné pole dat / bajtů - data jsou svázána s vrcholy, - souřadnice, normály, texturovací souřadnice, VAO obsahuje jeden čí více VBOs a dává interpretační strukturu datům v nich uložených, (co který bajt znamená). Může obsahovat buffer s indexy vrcholů (EBO). 19

Další obsah přednášky Buffer objekty (VBO, EBO, ) Vertex array objekty (VAO) Použití a nastavení pro zobrazení dat 20

(Vertex) Buffer objekty Slouží k přístupu do paměti spravované OpenGL obvykle na GPU (CPU = klient, GPU = server) Je to blok bajtů bez dalších informací o jejich struktuře Typický postup vytvoření: float buffer_data [] = {-0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f}; GLuint buffer_name; // často jen buffer // slajd glgenbuffers(1, &buffer_name ); // 1 glbindbuffer(target, buffer_name ); // 2 glbufferdata(target, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW); // 3 glbindbuffer(target, 0); target je způsob interpretace bufferu, např. GL_ARRAY_BUFFER, ale další jsou GL_ELEMENT_ARRAY_BUFFER pro indexy, [Groff] GL_PIXEL_PACK_BUFFER, or GL_PIXEL_UNPACK_BUFFER pro pixely 21

Pomocná funkce na vytvoření bufferů Pro vytváření objektů bufferů se může hodit tato funkce, která vrací jméno vytvořeného bufferu static GLuint make_buffer( GLenum target, // typ bufferu GLsizei buffer_size const void *buffer_data,// void pointer ) { GLuint buffer; glgenbuffers(1, &buffer); // 1 glbindbuffer(target, buffer); // 2a glbufferdata(target, buffer_size,// 3 buffer_data, GL_STATIC_DRAW); } glbindbuffer(target, 0); // 2b return buffer; // vrací jméno bufferu - ID [Groff] 22

Buffer Objekty 1. generování jmen void Vrací glgenbuffers( n nepoužitých GLsize jmen n, bufferů GLuint * buffers); // 1 Vygeneruje n jmen bufferů, jméno je číslo typu Gluint Uloží je do pole buffers glgenbuffers(1,&buffer); // 1 Vytvoří jedno jméno bufferu void gldeletebuffers( GLsize n, const GLuint * buffers); Uvolní n jmen bufferů v poli buffers a smaže je Přesněji pokud někdo buffer používá, jen ho označí jako smazaný. Smaže se až s posledním odkazem 23

Buffer Objekty 2. propojení jména s cílem void glbindbuffer(enum target, GLuint buffer); // 2 Propojí jméno objektu buffer s OpenGL cílem target target ARRAY_BUFFER ELEMENT_ARRAY_BUFFER target se používá i jako parametr příkazů OpenGL Propojení ovlivňuje i další příkazy, které target jako parametr nemají, ale využívají jím nastaveného stavu (např. gldrawarrays pracuje s navázanými vrcholy, glvertexattribpointer nastavuje připojený buffer ve VAO) Volá se podruhé při vykreslování před použitím bufferu Propojení se zruší parametrem 0 glbindbuffer(target,0); Účel Atributy vrcholů (Vertex array) Indexy do pole vrcholů // 2b 24

Buffer Objekty 3. předání dat void glbufferdata(enum target, sizeiptr size, const void * data, enum usage); // 3 Okopíruje data z klientské paměti do paměti buffer objektu usage rada, kam data dát STATIC_... DYNAMIC_... STREAM_ _DRAW _READ _COPY Účel Data nehodláme měnit (rigidní objekty) Data budeme měnit často Data budeme měnit pravidelně (animace) CPU -> GPU GPU -> CPU GPU GPU Pro vertex a element arrays tedy typicky GL_STATIC_DRAW glbufferdata(target, buffer_size, buffer_data, GL_STATIC_DRAW); // 3 25

Vertex Array Object (VAO) Sdružuje kompletní informace o atributech vrcholů potřebné pro předávání dat vertex shaderům Připojené buffery se souřadnicemi a dalšími atributy Informace o struktuře dat v bufferech (jak jsou data v bufferech poskládána) Navázání na vstupy vertex shaderů (location) V nových verzích OpenGL je nutno VAO explicitně definovat (gen, bind, ) a před vykreslením se provede jen propojení (bind) Poznámka: v OpenGL ES a WebGL VAO není (extenze) ve starší verzi OpenGL existoval implicitní VAO s číslem 0 propojení se vstupy (glbindbuffer a glvertexattribpointer) se dělalo v metodě draw() [Groff] 26

Vertex Array Object (VAO) - vytvoření GLuint vertex_array; glgenvertexarrays( 1, &vertex_array ); // 4 glbindvertexarray( vertex_array ); // 5a // buffery s atributy vrcholů vytvořeny dříve Bind, BufferData glbindbuffer( GL_ARRAY_BUFFER, positionbuffer ); glenablevertexattribarray( pos_location ); // 6 glvertexattribpointer( pos_location, 2,GL_FLOAT, GL_FALSE,0,0);// 7 glbindbuffer( GL_ARRAY_BUFFER, colorbuffer ); glenablevertexattribarray(color_location); // 6 glvertexattribpointer(color_location,3,gl_float,gl_false,0,0); // 7 // pouze jeden buffer s indexy vrcholů! glbindbuffer( GL_ELEMENT_ARRAY_BUFFER, elementbuffernamehouse2 ); glbindvertexarray( 0 ); // 5b detach 27

Vertex Array Object 4. generování jmen void Vrací glgenvertexarrays( n nepoužitých jmen GLsize bufferů n, GLuint * arrays); // 4 Vytvoří n jmen polí v poli arrays void gldeletevertexarrays (GLsize n, const GLuint *arrays ); Uvolní n jmen polí v polí arrays a jejich obsah smaže 28

Vertex Array Objects 5. připojení void glbindvertexarray (GLuint array); // 5 Připojí pole se jménem array Při prvním volání se objekt pole vytvoří Volá se podruhé při vykreslování před použitím v poli definovaných bufferů a v nich uložených atributů vrcholů (nemá parametr target existuje jediný typ vertex array) Připojení se zruší parametrem 0 glbindvertexarray(0); // 5b 29

6. Povolení pole atributů s daným indexem (location) void glenablevertexattribarray(gluint index); // 6 Povolí atribut (location) s indexem index Každý vrchol dostane na vstup vertex shaderu jiná data odpovídající jeho umístění v bufferu void gldisablevertexattribarray(gluint index); Zakáže atribut (location) s indexem index Všechny vrcholy dostávají konstantní vstupní hodnotu Implicitně (0.0, 0.0, 0.0, 1.0) Nebo příkazem glvertexattrib*(gluint index, TYPE value); 30

6. Povolení pole atributů s daným indexem glenablevertexattribarray(location) [Craitou] 31

7. Popis pole atributů vrcholů (co je ve vertex bufferu pro location uloženo a kde) void glvertexattribpointer(gluint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer); // 7 index atributu ve vertex shaderu (location atributové proměnné) size -počet složek atributu (1, 2, 3 nebo 4) type - datový typ složek (GL_BYTE, GL_FLOAT, ) normalized převádí čísla na interval 0.0f...1.0f stride - offset mezi atributy v bufferu pointer - offset první hodnoty v rámci bufferu přetypovaný na (void *) pro data od začátku bufferu (void*)0 32

Vrcholy za sebou a na přeskáčku indices Vertices are separated attributes may be different Vertices are shared attributes must be the same [http://www.opengl-tutorial.org] 33

Shared vs Separate normals [http://www.opengl-tutorial.org] 34

[http://answers.unity3d.com/questions/441722/splitting-up-verticies.html] [http://hub.jmonkeyengine.org/t/help-understanding-vertex-normals/25827/4] 35

Postup vykreslení jednoho snímku Příprava (1x) Nastaví se stav OpenGL Připraví se balíky dat přenos do GPU (buffery) Připraví se informace o obsahu bufferů a jejich propojení na vstupy vertex shaderů (vertex arrays) Vykreslování (např. 60x za sekundu) Smazání obrazovky Propojení vstupů VS (bind vertex array) Nastavení uniform proměnných (materiál, transformace, ) Spustí se vykreslení (draw) 36

Dva způsoby vykreslování geometrických primitiv Data o vrcholech jsou uložena v buffer objektech, tj. v polích v adresovém prostoru serveru (obvykle v paměti GPU viz glbufferdata) Jedním příkazem lze vybrat část z nich a vykreslit je (např. jednu stěnu krychle) gldrawarrays() vykreslí n po sobě jdoucích vrcholů gldrawelements() vykreslí n po vrcholů na přeskáčku, podle pole indexů vrcholů Před vykreslováním je nutno informovat OpenGL o tom, jak jsou data v polích poskládána, jak jsou propojena se vstupy vertex shaderů a v jakém pořadí se budou vrcholy uložené v datech vykreslovat - to je uloženo ve Vertex Array glbindvertexarray( ) => připojit Vertex Array 37

Vykreslení n po sobě jdoucích vrcholů void gldrawarrays(glenum mode, GLint first, GLsizei count); Vykreslí count po sobě jdoucích vrcholů ze všech povolených polí Začne na vrcholu s indexem first Poslední vykreslený má index first+count-1 mode udává typ primitiva GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, first GL_TRIANGLES count mode = GL_TRIANGLES 38

Použití vertex arrays glbindvertexarray( vertex_array );// 5) gldrawarrays( GL_LINES, 3, 6 ); // od indexu 3 // 6) 6 vrcholů glbindvertexarray( 0 ); // 5) first count 0 1 2 3 4 5 6 7 8 [ 1,0, 2,0, 3,0, 0,2, 1,0, 1,0, 2,2, 2,2, 0,2,.] mode = GL_LINES 39

Vykreslení n po vrcholů napřeskáčku void gldrawelements(glenum mode, GLsizei count, GLenum type, void *indices); Vykreslí count vrcholů ze všech připojených polí ARRAY_BUFFER, jejichž indexy jsou uloženy v připojeném poli indexů ELEMENT_ARRAY_BUFFER na offsetu indices (dříve to byl opravdu odkaz na pole indexů v klientské paměti, proto se offset přetypovává na odkaz (void*) offset) type udává datový typ indexů a může nabývat hodnot GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT mode udává typ primitiva GL_POINTS, GL_LINES, mode = GL_TRIANGLES 40

ELEMENT_ARRAY_BUFFER target Bounded once per VAO stores the order of data in VBOs Bounded only, does not store the type of indices gldrawelements must provide type and offset (*indices) VAO ARRAY_BUFFER target Buffer ID array_boffset stride size type index... Bind VertexAttribPointer indices (0 or 1x) ELEMENT_ARRAY_BUFFER target Buffer ID element_array Bind 41

Souřadnicový systém v OpenGL - základy Pravotočivá souřadná soustava y axis x axis z axis Souřadnicový systém zobrazované plochy: (0,h) (w,h) Levý dolní roh obrazovky (0,0) (w,0) 42

Souřadnice vrcholů Souřadnice vrcholů Typicky se s nimi pracuje v polích vrcholů Předávají se přes ANSI C pole do tzv. vertex buffer objektů Počet složek souřadnic 2 2D souřadnice (x, y), implicitně z = 0 a w = 1 3 3D souřadnice (x, y, z), implicitně w = 1 4 homogenní souřadnice (x, y, z, w) reprezentují 3D souřadnice podle vztahu (x/w, y/w, z/w) je to vhodnější pro transformace, detaily později. Vnitřní reprezentace vrcholů v homogenních souřadnicích (x, y, z, w). specifikace (x, y, z) reprezentace (x, y, z, 1) (x, y) reprezentace (x, y, 0, 1) 43

Grafická primitiva v OpenGL GL_POINTS GL_LINES GL_LINE_STRIP GL_LINE_LOOP V5 V4 V0 V2 V4 V4 V3 V2 V2 V0 V1 GL_TRIANGLES V3 V1 V3 GL_TRIANGLE_STRIP V5 V0 GL_TRIANGLE_FAN V1 PLUS (pro geometry shader a teselace): GL_LINES_ADJACENCY GL_TRIANGLES_ADJACENCY GL_TRIANGLE_STRIP_ADJACENCY GL_PATCH_VERTICES 44

Body GL_POINTS Vrcholy jsou specifikovány v poli, vrcholů je libovolný počet Lze specifikovat velikost bodu v počtu pixelů Nezáleží tedy na vzdálenosti bodu ke kameře, velikost bodu bude vždy stejná. v0 v2 v5 v1 v4 v3 45

Velikost bodu void glpointsize(glfloat size); nastaví šířku zobrazovaných bodů v pixelech, šířka musí být větší než 0, implicitní hodnota je 1.0 Je-li však nastaveno glenable(gl_program_point_size), příkaz se ignoruje a velikost každého bodu nastavuje vertex shader v proměnné gl_pointsize Dříve možnost zapnout aliasing glenable(gl_point_smooth) Nyní všechny body jako čtverce s texturou point sprite antialiasing disabled antialiasing enabled 46

Samostatné úsečky GL_LINES Sekvence samostatných úseček Úsečka je mezi v0 a v1, mezi v2 a v3, mezi v4 a v5 atd. Je-li počet vrcholů n lichý, poslední vrchol je ignorován. v0 v2 v5 v1 v4 v3 n is 6 (even) 47

Lomená čára GL_LINE_STRIP Úsečka z v0 do v1, potom z v1 do v2, atd., konečně pak z vn-2 to vn-1 Celkem n-1 line úseček, pokud n=1, nekresli nic Nejsou stanovena žádná omezení na hodnoty vrcholů, úsečky se mohou protínat a body opakovat v0 v2 v5 v1 v4 v3 48

Uzavřená posloupnost úseček GL_LINE_LOOP Ozavřená lomená čára tj., jako GL_LINE_STRIP, plus poslední úsečka z vn-1 do v0 uzavírá smyčku v0 v2 v5 v1 v4 v3 49

Trojúhelník GL_TRIANGLES zobrazí sekvenci trojúhelníků pomocí vrcholů v0, v1, v2, pak trojúhelník v3, v4, v5, atd. Orientace je dána pořadím vrcholů, ne např. normálou. Pokud n není násobkem tří, je poslední vrchol či oba poslední dva vrcholy ignorovány v2 v3 v5 v4 v0 v1 50

TRIANGLE STRIP GL_TRIANGLE_STRIP Zobrazí sekvenci trojúhelníků o vrcholech trojúhelník v0, v1, v2, pak trojúhelník v2, v1, v3 (pozor na pořadí), pak v2, v3, v4, atd. Uspořádání vrcholů zajistí správnou orientaci každého trojúhelníku, takže je správně vykreslena k pozorovateli přivrácená část povrchů objektů n musí být větší nebo rovno třem Dochází k úspoře počtu vrcholů kolik vrcholů je potřeba na jeden trojúhelník, pokud n by bylo velké číslo? v0 v2 v4 v1 v3 v5 51

TRIANGLE FAN GL_TRIANGLE_FAN Podobné jako je GL_TRIANGLE_STRIP, ale pořadí vrcholů pro první trojúhelník je v0, v1, v2, pak trojúhelník v0, v2, v3, pak trojúhelník v0, v3, v4, atd. v4 v3 v2 v0 v1 52

PATCH Jediné vstupní primitivum pro teselační shadery N-tice vrcholů nebo řídících bodů nějaké plošky GPU pak generuje jemnější reprezentaci např. podle vzdálenosti plošky od pozorovatele (LOD) Viz 2 virchor.sourceforge.net 53

Příklady různého uložení hodnot ve VBO 1. Jeden atribut v jednom VBO 2. Dva atributy v jednom VBO za sebou 3. Dva atributy v jednom VBO prokládaně 4. Dva atributy, každý v jiném VBO 54

1. Příklad Jeden atribut v jednom VBO příprava dat static const Glfloat g_vertex_buffer_data[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f }; static const GLushort g_element_buffer_data[] = { 0,1,2,3 }; vertex_buffer = make_buffer( //souřadnice vrcholů GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data ); element_buffer = make_buffer( // indexy vrcholů GL_ELEMENT_ARRAY_BUFFER, sizeof(g_element_buffer_data), g_element_buffer_data ); [Groff] 55

1. Příklad rozvinutý make_buffer vertex_buffer = make_buffer( GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data ); Provede tedy tyto akce (bez pomocné proměnné): glgenbuffers(1, &vertex_buffer ); // 1 glbindbuffer(gl_array_buffer, vertex_buffer ); // 2a glbufferdata(gl_array_buffer, // 3 sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW ); glbindbuffer(gl_array_buffer, 0); // 2b 56

1. Příklad navázání před vykreslením pos_location = glgetattriblocation(program, "position"); glgenvertexarrays( 1, &vertex_array ); ); // 4 glbindvertexarray( vertex_array ); ); // 5 glbindbuffer(gl_array_buffer, vertex_buffer); // 2 glenablevertexattribarray(pos_location); // 6 glvertexattribpointer( // 7 pos_location, /* VS attribute index */ 2, /* size */ GL_FLOAT, /* type */ GL_FALSE, /* normalized */ sizeof(glfloat)*2, /* stride */ (void*)0 ); /* array buffer offset */ glbindbuffer(gl_element_array_buffer, element_buffer); glbindvertexarray( 0 );//4b [Groff] 57

1. Příklad - vykreslení glbindvertexarray( vertex_array ); [Groff] gldrawelements( GL_TRIANGLE_STRIP, /* mode */ 4, /* count */ GL_UNSIGNED_SHORT, /* type */ (void*)0 /* element array buffer offset */ ); glbindvertexarray(0); 58

1. Příklad tok geometrických dat na GPU Buffer Object with vertex coordinates Primitive assembly + index 0 index 1 index 2 index 3 in vec4 position; in vec4 position; in vec4 position; Přenos dat z buffer object do vertex shader Přenos dat z vertex shader do jednotky rasterizace 59

2. Příklad přidání druhého atributu v jednom VBO static const Glfloat g_vertex_buffer_data[] = { -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, vrcholy 1.0f, 1.0f 0.0f, 1.0f, 0.0f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, barvy 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, }; Doplníme proměnnou ve vertex shaderu A její navázání attributes.position = glgetattriblocation(program, "position"); // VS input attributes.color = glgetattriblocation(program, color"); // VS input [Groff] 60

2. Příklad - navázání dvou atributů za sebou glbindbuffer(gl_array_buffer, vertex_buffer); glvertexattribpointer( attributes.position, /* attribute */ 4, /* size - # components */ GL_FLOAT, /* type */ GL_FALSE, /* normalized */ sizeof(glfloat)*4, /* stride */ (void*)0 /* array buffer offset */ ); glvertexattribpointer( attributes.color, /* attribute */ 4, /* size */ GL_FLOAT, /* type */ Přeskočit 4 vrcholy GL_FALSE, /* normalized */ sizeof(glfloat)*4, /* stride */ (void*) sizeof(glfloat)*4*4 /* array buffer offset */ ); [Groff] 61

2. Předání dat vrcholu do vertex shaderu Buffer Object with vertex coordinates and color Vertex Shaders offset 0f index 0 index 1 vertexposition vertexcolor in vec4 position; in vec4 color; gl_position index 2 offset 16f index 3 index 0 vertexposition vertexcolor in vec4 position; in vec4 color; gl_position index 1 stride 4f index 2 index 3 vertexposition vertexcolor in vec4 position; in vec4 color; gl_position location 62

3. Př. Dva atributy v jednom VBO prokládaně (interleaved) static const Glfloat g_vertex_buffer_data[] = { -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, }; vrcholy barvy Prokládání je většinou ta nejrychlejší varianta Doplníme proměnnou ve vertex shaderu to je stejné A její navázání attributes.position = glgetattriblocation(program, "position"); // VS input attributes.color = glgetattriblocation(program, "color"); // VS input 63

3. Příklad - použití i druhého atributu glbindbuffer(gl_array_buffer, vertex_buffer); glvertexattribpointer( attributes.position, /* attribute */ 4, /* size */ GL_FLOAT, /* type */ GL_FALSE, /* normalized */ sizeof(glfloat)*8, /* stride */ (void*)0 /* array buffer offset */ ); glvertexattribpointer( attributes.color, /* attribute */ 4, /* size */ GL_FLOAT, /* type */ GL_FALSE, /* normalized */ sizeof(glfloat)*8, /* stride */ (void*) sizeof(glfloat)*4 /* array buffer offset */ ); [Groff] 64

4. Příklad dva atributy ve dvou VBO Příklad části programu v C++ // 1. create and bind vertex array object // variable to hold our handle to the vertex array object GLuint vaohandle; // create and bind to a vertex array object (stores the relationship between the buffers and the input attributes) glgenvertexarrays( 1, &vaohandle ); glbindvertexarray(vaohandle); // 2. set the data as arrays float positiondata[] = { -0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f, 0.0f, 0.8f, 0.0f }; float colordata[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; // coordinates of triangle vertices // colors of triangle vertices 65

4. Příklad dva atributy ve dvou VBO Příklad části programu v C++ // 3. Create and bind the buffer objects, populate them with data GLuint vbohandles[2]; glgenbuffers(2, vbohandles); GLuint positionbufferhandle = vbohandles[0]; // 0. buffer name GLuint colorbufferhandle = vbohandles[1]; // 1. buffer name // Populate the position buffer glbindbuffer(gl_array_buffer, positionbufferhandle); glbufferdata(gl_array_buffer, 9*sizeof(float), positiondata, GL_STATIC_DRAW); // Populate the color buffer glbindbuffer(gl_array_buffer, colorbufferhandle); glbufferdata(gl_array_buffer, 9*sizeof(float), colordata, GL_STATIC_DRAW); 66

4. Příklad dva atributy ve dvou VBO Příklad části programu v C++ // 4. Make connection between data on a CPU and GPU // obtain location of each attribute of given name in the shader GLint posloc = glgetattriblocation(programhandle, VertexPosition ); GLint colorloc = glgetattriblocation(programhandle, VertexColor ); // enable the vertex attribute arrays glenablevertexattribarray(posloc); // vertex position glenablevertexattribarray(colorloc); // vertex color // map attribute with index posloc to the position buffer glbindbuffer(gl_array_buffer, positionbufferhandle); glvertexattribpointer(posloc, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL); // map attribute with index colorloc to the color buffer glbindbuffer(gl_array_buffer, colorbufferhandle); glvertexattribpointer(colorloc, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL); // unbind this VAO glbindvertexarray(vaohandle); 67

4. Příklad dva atributy ve dvou VBO Příklad části programu v C++ // 5. Use the data in the application to render them // in the render function, bind to the vertex array object and call gldrawarrays to initiate rendering glbindvertexarray(vaohandle); gldrawarrays(gl_triangles, 0, 3 ); glbindvertexarray(0); 68

4. Příklad dva atributy ve dvou VBO Vertex Shaders Vertex Buffer with vertex coordinates index 0 index 1 index 2 vertexposition vertexcolor in vec4 position; in vec4 color; gl_position Vertex Buffer with vertex colors index 3 index 0 index 1 index 2 index 3 vertexposition vertexcolor vertexposition vertexcolor in vec4 position; in vec4 color; in vec4 position; in vec4 color; gl_position gl_position location 69

Zajímavé odkazy David Wolff: OpenGL 4.0 Shading Language Cookbook. Packt Publishing, 2011, ISBN 978-1-849514-76-7. Richard S. Wright, Nicholas Haemel, Graham Sellers, Benjamin Lipchak: OpenGL SuperBible: Comprehensive Tutorial and Reference. 5th ed., Addison-Wesley Professional, 2010, ISBN 0-321-71261-7. Ed Angel, Dave Shreiner: An Introduction to Modern OpenGL Programming, SIGGRAPH 2011 tutorial, http://www.daveshreiner.com/siggraph/s11/modern- OpenGL.pptx Joe Groff. An intro to modern OpenGL. Updated July 14, 2010 http://duriansoftware.com/joe/an-intro-to-modern-opengl.-table-of-contents.html Vertex Array Object na OpenGL Wiki: http://www.opengl.org/wiki/vao Vertex Specification na OpenGL Wiki: http://www.opengl.org/wiki/vertex_specification Sergiu Craitoiu: Tutorial: Modern OpenGL, OpenGL From Zero To Hero, http://in2gpu.com/opengl-3/ 71