TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování...

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

Transcript of TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování...

Page 1: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

TAM

Ústav počítačové grafiky a multimédií

Prezentace p řednášek

Page 2: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

OpenGL ES 2.0

Grafika na mobilních za řízeních

Page 3: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 3

Motto

„If Edison had a needle to find in a haystack, hewould proceed at once with the diligence of the bee to examine straw after straw until he found the object of his search.I was a sorry witness of such doings, knowing that a little theory and calculation would have saved him ninety per cent of his labor.“

- Nikola Tesla

Page 4: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 4

Obsah:

• Úvod do OpenGL• OpenGL ES on embedded devices• Reprezentace objektů ve vertex arrays• Vertex a fragment shadery• Texturování• Framebuffer objekty• Doporučená literatura

Page 5: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 5

OpenGL

• Knihovna „Open Graphics Library“ od SGI• Dnes udržuje Khronos Group• Kreslení pomocí

– Immediate mode (glVertex3f())– Display lists (glCallLists())– Arrays (glDrawArrays())

• Fixed-function pipeline• Binding pro mnoho jazyků

– “C“/C ++– Java (JOGL)– Python (PyGL)– Další ...

Page 6: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 6

OpenGL (ES 1.0) fixed-function pipeline

Page 7: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 7

OpenGL programmable pipeline

vertex shadertesselation shadergeometry shader

fragment shadertransform feedback

Page 8: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 8

OpenGL ES 2.0 pipeline

vertex shadertesselation shadergeometry shader

fragment shadertransform feedback

Page 9: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 9

OpenGL ES on embedded devices

• Různé platformy– NVIDIA Tegra (ULP GeForce)– ARM

• Android-based devices– “C“/C ++– Java

• Apple iPhone– Objective C– Java

• Ubuntu, Win CE– “C“/C ++

Page 10: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 10

OpenGL ES bez zařízení

• Motivace– Vývojářské nástroje, možnost ladění– Snadné použití– Není potřeba mít cílové mobilní zařízení (zejména velké týmy)

• Emulace je možná na OpenGL 2.0 hardware• See (and use):

http://www.stud .fit .vutbr.cz/~xpolok 00/proj_glesemu.htm• Android emulator (pomalý)

Page 11: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 11

Inicializace OpenGL ES

• Windows CE– WGL + nativní okna– EGL

• Ubuntu– GLX + Xserver– EGL

• Android– android.opengl.GLSurfaceView (wrapper EGL)

Page 12: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 12

Inicializace OpenGL ES - Android

public class MyApp extends Activity {

GLSurfaceView mGLView;

GLSurfaceView.Renderer mRenderer = new MyRendererMyRendererMyRendererMyRenderer(this);

protected void onCreateonCreateonCreateonCreate(Bundle _instance) {

super.onCreateonCreateonCreateonCreate(_instance);

setContentViewsetContentViewsetContentViewsetContentView(R.layout.main);

setTitlesetTitlesetTitlesetTitle("OpenGL ES Hello World");

mGLView = (GLSurfaceView)findViewByIdfindViewByIdfindViewByIdfindViewById(R.id.glsv);

mGLView.setEGLContextClientVersionsetEGLContextClientVersionsetEGLContextClientVersionsetEGLContextClientVersion(2);

mGLView.setRenderersetRenderersetRenderersetRenderer(mRenderer);

}

protected void onPauseonPauseonPauseonPause()

{ super.onPauseonPauseonPauseonPause(); mGLView.onPauseonPauseonPauseonPause(); }

protected void onResumeonResumeonResumeonResume()

{ super.onResumeonResumeonResumeonResume(); mGLView.onResumeonResumeonResumeonResume(); } }

Page 13: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 13

Inicializace OpenGL ES - Android

public class MyRenderer implements GLSurfaceView.Renderer {

private int mWidth = 640, mHeight = 480;

private MyApp mContext;

public MyRendererMyRendererMyRendererMyRenderer(MyApp context)

{ supersupersupersuper(); mContext = context; }

public void onDrawFrameonDrawFrameonDrawFrameonDrawFrame(GL10 unused) {

GLES20.glViewportglViewportglViewportglViewport(0, 0, mWidth, mHeight);

GLES20.glClearColorglClearColorglClearColorglClearColor(0.0f, 0.0f, 1.0f, 1.0f);

GLES20.glClearglClearglClearglClear(GLES20.GL_COLOR_BUFFER_BIT);

// GLES20.glDoSomethingRatherInterestingglDoSomethingRatherInterestingglDoSomethingRatherInterestingglDoSomethingRatherInteresting(12345);

}

public void onSurfaceChangedonSurfaceChangedonSurfaceChangedonSurfaceChanged(GL10 gl, int w, int h)

{ mWidth = w; mHeight = h; }

public void onSurfaceCreatedonSurfaceCreatedonSurfaceCreatedonSurfaceCreated(GL10 gl, EGLConfig cfg)

{ /* perform init here */ }

}

Page 14: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 14

Inicializace OpenGL ES - Android

res.layout.main.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent">

<androidandroidandroidandroid.openglopenglopenglopengl.GLSurfaceViewGLSurfaceViewGLSurfaceViewGLSurfaceViewandroid:layout_height="match_parent"android:layout_width="match_parent"android:id="@+id/glsvglsvglsvglsv"/>

</LinearLayout>

Page 15: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 15

Inicializace OpenGL ES - Android

Page 16: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 16

Kreslení v OpenGL ES

• Nemůžeme použít immediate mode (glVertex*())• Musíme použít

– Vertex attributes– Vertex arrays– Vertex shader– Fragment shader

Page 17: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 17

Vertex attributes

• OpenGL už nemá pevně danou sémantiku vrcholových dat– Dříve byla pozice, normála, barva, sekundární barva + texcoords

• Místo toho se používají očíslované atributy

glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(uint attrib_number, // 0

uint num_dimensions, // 3

GLenum data_type, // GL_FLOAT

bool is_normalized, // false

uint stride, // 3 * sizeof(float)

const void *data) // {1, 2, 3}

glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(uint attrib_number) // 0

• V Javě je místo “const void*“ java.nio.Buffer

Page 18: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 18

Vertex arrays

• Data vrcholů musí být někde uložená• Na lepších GPU použijeme Vertex Buffer Object (VBO)

– Ten však mobilní zařízení často nemají (sdílená RAM)

• Nebo použijeme jednoduchý buffer– V “C“/C++ prostě float*– V Javě java.nio.FloatBuffer (nebo jiný typ)

final float[] data = {1, 2, 3};

FloatBuffer buff =ByteBuffer.allocateDirectallocateDirectallocateDirectallocateDirect(data.length * 4).orderorderorderorder(ByteOrder.nativeOrdernativeOrdernativeOrdernativeOrder()).asFloatBufferasFloatBufferasFloatBufferasFloatBuffer();

buff.putputputput(data); buff.positionpositionpositionposition(0);

GLES20.glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(0, 3, GLES20.GL_FLOAT,false, 3 * 4, buff);

GLES20.glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(0);

Page 19: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 19

Vertex arrays

• Když máme připravená data ve vertex bufferu, můžeme je poslat k vykreslení

glDrawArraysglDrawArraysglDrawArraysglDrawArrays(GLenum mode, // GL_TRIANGLES

uint first, // 0

uint count) // 3

• Když chceme kreslit složitější objekty kde se vrcholy opakují, přidáme druhý buffer s indexy (forma komprese)a voláme:

glDrawElementsglDrawElementsglDrawElementsglDrawElements(GLenum mode, // GL_TRIANGLESuint count, // 3

GLenum data_type, // GL_UNSIGNED_INT

const void *indices) // indexy

Page 20: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 20

Vertex arrays

• Vykreslení trojúhelníku

float buff[] = {0, .9f, 0,

.9f, -.9f, 0, -.9f, -.9f, 0};

// pozice vrcholů ve 3D

glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(0, 3,GL_FLOAT, false, 3 * 4, buff);

// pointer na data vertex atributu 0

glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(0);

// povolíme pole atributů 0

glDrawArraysglDrawArraysglDrawArraysglDrawArrays(GL_TRIANGLES, 0, 3);

// kreslíme tři vrcholy jako trojúhelník, začínáme nultým

x

y1

-1

0

(0, 0.9)

(-0.9, -0.9)

(0.9, -0.9)

Page 21: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 21

Vertex arrays

• Vykreslení čtverce

float buff[] = {

+.9f, +.9f, 0,

+.9f, -.9f, 0,

-.9f, -.9f, 0,

-.9f, +.9f, 0};

// pozice vrcholů ve 3D

glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(0, 3,GL_FLOAT, false, 3 * 4, buff); // pointer na atribut 0

glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(0); // povolíme pole atributů 0

glDrawArraysglDrawArraysglDrawArraysglDrawArrays(GL_QUADS, 0, 4);

// kreslíme 4 vrcholy jako čtverec, začínáme nultým

x

y1

-1

0

(0.9, 0.9)

(-0.9, -0.9)

(0.9, -0.9)

(-0.9, 0.9)

Page 22: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 22

Vertex arrays

• Vykreslení čtverce

float buff[] = {

+.9f, +.9f, 0,

+.9f, -.9f, 0,

-.9f, -.9f, 0,

-.9f, +.9f, 0};

// pozice vrcholů ve 3D

glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(0, 3,GL_FLOAT, false, 3 * 4, buff); // pointer na atribut 0

glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(0); // povolíme pole atributů 0

glDrawArraysglDrawArraysglDrawArraysglDrawArrays(GL_QUADS, 0, 4);

// kreslíme 4 vrcholy jako čtverec, začínáme nultým

x

y1

-1

0

(0.9, 0.9)

(-0.9, -0.9)

(0.9, -0.9)

(-0.9, 0.9)

Page 23: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 23

Vertex arrays

• Bohužel už nemáme GL_QUADS, GL_QUAD_STRIP a GL_POLYGON

• Máme GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP a GL_TRIANGLE_FAN

0

1

2

3

4

5

0

12

3

4

5

Page 24: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 24

Vertex arrays

• Vykreslení čtverce

float buff[] = {

-.9f, +.9f, 0,

+.9f, +.9f, 0,

+.9f, -.9f, 0,

+.9f, -.9f, 0,

-.9f, -.9f, 0,

-.9f, +.9f, 0};

// pozice vrcholů ve 3D

glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(0, 3,GL_FLOAT, false, 3 * 4, buff); // pointer na atribut 0

glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(0); // povolíme pole atributů 0

glDrawArraysglDrawArraysglDrawArraysglDrawArrays(GL_TRIANGLES, 0, 6);

// kreslíme 6 vrcholů jako trojúhelníky, začínáme nultým

x

y1

-1

0

(0.9, 0.9)

(-0.9, -0.9)

(0.9, -0.9)

(-0.9, 0.9)

Page 25: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 25

Vertex arrays

• Vykreslení čtverce

float buff[] = {

+.9f, +.9f, 0,

+.9f, -.9f, 0,

-.9f, -.9f, 0,

-.9f, +.9f, 0};

// pozice vrcholů ve 3D

int indices[] = {3, 0, 1, 1, 2, 3};

// permutace vrcholů, tvořící dva trojúhelníky

glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(0, 3,GL_FLOAT, false, 3 * 4, buff); // pointer na atribut 0

glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(0); // povolíme pole atributů 0

glDrawElementsglDrawElementsglDrawElementsglDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices);

// kreslíme 6 vrcholů které vybíráme ze 4 pomocí pole indices

x

y1

-1

0

(0.9, 0.9)

(-0.9, -0.9)

(0.9, -0.9)

(-0.9, 0.9)

Page 26: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 26

Vertex arrays

• Vykreslení čtverce

float buff[] = {

-.9f, -.9f, 0,

-.9f, +.9f, 0,

+.9f, -.9f, 0,

+.9f, +.9f, 0};

// pozice vrcholů ve 3D

glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(0, 3,GL_FLOAT, false, 3 * 4, buff); // pointer na atribut 0

glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(0); // povolíme pole atributů 0

glDrawArraysglDrawArraysglDrawArraysglDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// kreslíme 4 vrcholy jako tristrip, začínáme nultým

x

y1

-1

0

(0.9, 0.9)

(-0.9, -0.9)

(0.9, -0.9)

(-0.9, 0.9)

Page 27: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 27

Vertex arrays

• Vykreslení krychle

const float p_box_vertices[] = {

-1, -1, -1, +1, -1, -1,

+1, -1, +1, -1, -1, +1,

-1, +1, -1, +1, +1, -1,

+1, +1, +1, -1, +1, +1};

const unsigned int p_box_indices[] = {

0, 1, 3, 2, 6, 1, 5, 0, 4, 3, 7, 6, 4, 5};

10

23

4

5

6 5

1 0

7 6

3

4

00 1

23

4 5

67

Page 28: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 28

Vertex arrays

• Vykreslení krychle

const float p_box_vertices[] = {

-1, -1, -1, +1, -1, -1,

+1, -1, +1, -1, -1, +1,

-1, +1, -1, +1, +1, -1,

+1, +1, +1, -1, +1, +1};

const unsigned int p_box_indices[] = {

0, 1, 3, 2, 6, 1, 5, 0, 4, 3, 7, 6, 4, 5};

10

23

4

5

6 5

1 0

7 6

3

4

00 1

23

4 5

67

Page 29: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 29

Vertex Buffer Objekty (VBO)

• Paměť na GPU pro data vrcholů a indexů• Napřed je nutné buffery naplnit (box z předchozí strany)

int n_vertex_buffer, n_index_buffer;

glGenBuffersglGenBuffersglGenBuffersglGenBuffers(1, &n_vertex_buffer);

glBindBufferglBindBufferglBindBufferglBindBuffer(GL_ARRAY_BUFFER, n_vertex_buffer);

glBufferDataglBufferDataglBufferDataglBufferData(GL_ARRAY_BUFFER, sizeof(p_box_vertices), p_box_vertices, GL_STATIC_DRAW);

glGenBuffersglGenBuffersglGenBuffersglGenBuffers(1, &n_index_buffer);

glBindBufferglBindBufferglBindBufferglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, n_index_buffer);

glBufferDataglBufferDataglBufferDataglBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(p_box_indices), p_box_indices, GL_STATIC_DRAW);

Page 30: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 30

Vertex Buffer Objekty (VBO)

• Pro nastavení vertex attributů je potřeba buffer nabindovat• Adresu dat v bufferu nevíme, použijeme NULL (+ offset,

pokud je třeba)• Použít pro různé vertex atributy data z více bufferů je

dovolené, někdy i žádoucí

glBindBufferglBindBufferglBindBufferglBindBuffer(GL_ARRAY_BUFFER, n_vertex_buffer);

glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(0);

glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * sizeof(float), NULL); // NULL ukazuje na začátek VBO

// set vertex coordinate attribute

glBindBufferglBindBufferglBindBufferglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, n_index_buffer);

glDrawElementsglDrawElementsglDrawElementsglDrawElements(GL_TRIANGLE_STRIP, 14, GL_UNSIGNED_INT, NULL);

// NULL ukazuje na začátek VBO s indexy (element array)

Page 31: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 31

Vertex Array Objekty (VAO)

• VAO je objekt, který si „pamatuje“ nastavení vertex atributů• Nastavení vyrobíme takto:

int n_vao;

glGenVertexArraysglGenVertexArraysglGenVertexArraysglGenVertexArrays(1, &n_vao);

glBindVertexArrayglBindVertexArrayglBindVertexArrayglBindVertexArray(n_vao);

glBindBufferglBindBufferglBindBufferglBindBuffer(GL_ARRAY_BUFFER, n_vertex_buffer);

glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(0);

glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * 4, NULL);

glBindBufferglBindBufferglBindBufferglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, n_index_buffer);

glBindVertexArrayglBindVertexArrayglBindVertexArrayglBindVertexArray(0); // zamezíme náhodnému poškození

• A v okamžiku potřeby si ho už jen vyvoláme:

glBindVertexArrayglBindVertexArrayglBindVertexArrayglBindVertexArray(n_vao);

glDrawElementsglDrawElementsglDrawElementsglDrawElements(GL_TRIANGLE_STRIP, 14, GL_UNSIGNED_INT, NULL);

Page 32: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 32

Vertex shader

• Krátký program, který říká jak se mají interpretovat vertexatributy

• Každá instance jeden vertex dostane a jeden taky „vyplivne“

precision highp float; // specifikace přesnosti

attribute vec3 v_pos; // atributy - vstup z dat vrcholu

varying vec3 v_color; // výstup - barva vrcholu

uniform mat4 t_modelview_projection;

// parametr shaderu - transformační matice

void mainmainmainmain() {

gl_Position = t_modelview_projection * vec4vec4vec4vec4(v_pos, 1.0);

// musíme zapsat pozici

v_color = v_pos * .5 + .5;

// vymyslíme barvu vrcholu pro fragment shader

}

Page 33: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 33

Fragment shader

• Krátký program, který říká jak vypočítat z interpolovaných souřadnic barvu

• Každá instance dostane interpolované atributy pro jeden pixel a na jejich základě může spočítat barvu nebo hloubku, případně pixel zahodit (discard )

precision highp float; // specifikace přesnosti

varying vec3 v_color; // vstup z vertex shaderu

void mainmainmainmain() {

gl_FragColor = vec4vec4vec4vec4(v_color, 1.0); // zapíše výstupní barvu

}

Page 34: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 34

Práce se shadery

• Na začátku vygenerujeme shader objekty, nahrajeme do nich zdrojový kód shaderů (jako text) a zkompilujeme

int p_shader[2]; // vertex a fragment

char *p_src[2] = {ReadFileReadFileReadFileReadFile(“vs.txt“), ReadFileReadFileReadFileReadFile(“fs.txt“)};

for(int i = 0, n_temp; i < 2; ++ i) {

p_shader[i] = glCreateShaderglCreateShaderglCreateShaderglCreateShader((i == 0)?GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);

glShaderSourceglShaderSourceglShaderSourceglShaderSource(p_shader[i], 1, &p_src[i], NULL);

glCompileShaderglCompileShaderglCompileShaderglCompileShader(p_shader[i]);

glGetShaderivglGetShaderivglGetShaderivglGetShaderiv(p_shader[i], GL_COMPILE_STATUS, &n_temp);

if(n_temp != GL_TRUE)

failfailfailfail(); // chyba při kompilaci (glGetShaderInfoLogglGetShaderInfoLogglGetShaderInfoLogglGetShaderInfoLog())

freefreefreefree(p_src[i]); // !!

}

Page 35: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 35

Práce se shadery

• Vyrobíme program object a shadery k němu připojíme• Nastavíme čísla vertex atributů (propojení s proměnnými VS)• Slinkujeme program• Najdeme čísla parametrů shaderu (uniform )

int n_program_object = glCreateProgramglCreateProgramglCreateProgramglCreateProgram(), n_temp;

for(int i = 0, n_temp; i < 2; ++ i) glAttachShaderglAttachShaderglAttachShaderglAttachShader(n_program_object, p_shader[i]);

glBindAttribLocationglBindAttribLocationglBindAttribLocationglBindAttribLocation(n_program_object, 0, “v_pos“);

glLinkProgramglLinkProgramglLinkProgramglLinkProgram(n_program_object);

glGetProgramivglGetProgramivglGetProgramivglGetProgramiv(n_program_object, GL_LINK_STATUS, &n_temp);

if(n_temp != GL_TRUE)

failfailfailfail(); // chyba při linkování glGetProgramInfoLogglGetProgramInfoLogglGetProgramInfoLogglGetProgramInfoLog()

int n_mvp_uni = glGetUniformLocationglGetUniformLocationglGetUniformLocationglGetUniformLocation((((n_program_object, “t_modelview_projection“);

Page 36: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 36

Práce se shadery

• Při použití nastavíme program jako aktivní• Nastavíme hodnoty různých parametrů (uniform )

Matrix4f t_projection, t_modelview;

t_projection.PerspectivePerspectivePerspectivePerspective(90, 4.0f / 3, .01f, 1000);

t_modelview.IdentityIdentityIdentityIdentity();

t_modelview.TranslateTranslateTranslateTranslate(0, 0, -2);

t_modelview.RotateXRotateXRotateXRotateX(30 * M_PI / 180);

t_modelview.RotateYRotateYRotateYRotateY(10 * M_PI / 180);

Matrix4f t_mvp = t_projection * t_camera_matrix;

float *p_matrix = &t_mvp[0][0];

// OpenGL už nemá operace s maticemi, musíme “počítat sami“

glUseProgramglUseProgramglUseProgramglUseProgram(n_program_object);

glUniformMatrix4fvglUniformMatrix4fvglUniformMatrix4fvglUniformMatrix4fv(n_mvp_uni, 1, GL_FALSE, p_matrix);

// aktivujeme program a nastavíme matici

Page 37: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 37

Výsledek

Page 38: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 38

Textury

• Textury jsou dvourozměrné rastrové obrázky, jež lze v shaderu číst

• K texturám přistupujeme pomocí sampleru, je třeba nastavit číslo texturovací jednotky, ve které je textura nastavená

• OpenGL ES umí i 3D textury (GL_OES_texture_3D)

int n_texture;

glGenTexturesglGenTexturesglGenTexturesglGenTextures(1, &n_texture);

glBindTextureglBindTextureglBindTextureglBindTexture(GL_TEXTURE_2D, n_texture);

glTexParameteriglTexParameteriglTexParameteriglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // zapneme mipmapy (trilineární)

glTexParameteriglTexParameteriglTexParameteriglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // zapneme bilineární filtr

glTexImage2DglTexImage2DglTexImage2DglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, p_bitmap); // specifikujeme obraz

glGenerateMipmapglGenerateMipmapglGenerateMipmapglGenerateMipmap(GL_TEXTURE_2D); // spočítáme mipmapy

Page 39: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 39

Textury

• Pro texturování „tradičním“ způsobem je potřeba mít souřadnice textur (další vertex atribut)

• V shaderu ale můžeme souřadnice textury i nějak spočítat

float buff[] = {-.9f, -.9f, 0, 0, 0,

-.9f, +.9f, 0, 0, 1,

+.9f, -.9f, 0, 1, 0,

+.9f, +.9f, 0, 1, 1};

// 3D pozice vrcholů + 2D souřadnice textury (5 souřadnic)

glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(0, 3,GL_FLOAT, false, 5 * 4, buff); // pointer na atribut 0

glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(0); // povolíme pole atributů 0

glVertexAttribPointerglVertexAttribPointerglVertexAttribPointerglVertexAttribPointer(1, 2,GL_FLOAT, false, 5 * 4, buff + 3); // pointer na atribut 1

glEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArrayglEnableVertexAttribArray(1); // povolíme pole atributů 1

Page 40: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 40

Textury

• Vertex shader

precision highp float; // specifikace přesnosti

attribute vec3 v_pos;

attribute vec2 v_tex; // atributy - vstup z dat vrcholu

varying vec3 v_texcoord; // výstup - souřadnice textury

uniform mat4 t_modelview_projection;

// parametr shaderu - transformační matice

void mainmainmainmain() {

gl_Position = t_modelview_projection * vec4vec4vec4vec4(v_pos, 1.0);

// musíme zapsat pozici

v_texcoord = v_tex;

// souřadnici textury jen kopírujeme

}

Page 41: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 41

Textury

• Fragment shader

precision highp float; // specifikace přesnosti

varying vec2 v_texcoord; // vstup z vertex shaderu

uniform sampler2D n_sampler; // sampler pro čtení textury§

void mainmainmainmain() {

gl_FragColor = texture2Dtexture2Dtexture2Dtexture2D(n_sampler, v_texcoord);

// přečte texturu a zapíše ji na výstup

}

int n_sam_uni = glGetUniformLocationglGetUniformLocationglGetUniformLocationglGetUniformLocation(n_program_object, “n_sampler“); // najdi n_sampler ...

glUniform1iglUniform1iglUniform1iglUniform1i(n_sam_uni, 0);

// textura je v texturovací jednotce 0

Page 42: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 42

Výsledek

Page 43: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 43

Framebuffer objekty (FBO)

• Umožňují kreslení do textury– Různé efekty, Voda, Zrcadla– Stínové mapy

• Framebuffer objekt je „kontejner“ pro framebuffery– Renderbuffer objekt (kus paměťi pro uložení rastru)– Textura (při kreslení do textury)

• V OpenGL ES poměrně omezený– Jen jeden attachment pro color, musí být obsazený– Nejsou k dispozici formáty pro depth textury

• DokumentaceglGenFramebuffersglGenFramebuffersglGenFramebuffersglGenFramebuffers(), glGenRenderbuffersglGenRenderbuffersglGenRenderbuffersglGenRenderbuffers()

glBindFramebufferglBindFramebufferglBindFramebufferglBindFramebuffer(), glBindRenderbufferglBindRenderbufferglBindRenderbufferglBindRenderbuffer()

glRenderbufferStorageglRenderbufferStorageglRenderbufferStorageglRenderbufferStorage()

glFramebufferRenderbufferglFramebufferRenderbufferglFramebufferRenderbufferglFramebufferRenderbuffer(), glFramebufferTexture2DglFramebufferTexture2DglFramebufferTexture2DglFramebufferTexture2D()

Page 44: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 44

Framebuffer objekty (FBO)int n_fb, n_rb, n_tex;

glGenFramebuffersglGenFramebuffersglGenFramebuffersglGenFramebuffers(1, &n_fb); glGenRenderbuffersglGenRenderbuffersglGenRenderbuffersglGenRenderbuffers(1, &n_rb);

glBindFramebufferglBindFramebufferglBindFramebufferglBindFramebuffer(GL_FRAMEBUFFER, n_fb);

glBindRenderbufferglBindRenderbufferglBindRenderbufferglBindRenderbuffer(GL_RENDERBUFFER, n_rb);

glRenderbufferStorageglRenderbufferStorageglRenderbufferStorageglRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT16, 256, 256); // renderbuffer pro depth

glFramebufferRenderbufferglFramebufferRenderbufferglFramebufferRenderbufferglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, n_rb); // připojí rb

glFramebufferTexture2DglFramebufferTexture2DglFramebufferTexture2DglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, n_tex, 0); // připojí texturu

int n_status = glCheckFramebufferStatusglCheckFramebufferStatusglCheckFramebufferStatusglCheckFramebufferStatus(GL_FRAMEBUFFER);

if(n_status != GL_FRAMEBUFFER_COMPLETE)

failfailfailfail(); // zpravidla chyba programátora

glViewportglViewportglViewportglViewport(0, 0, 256, 256); // potom je třeba vrátit původní

// kreslení do textury

glFramebufferTexture2DglFramebufferTexture2DglFramebufferTexture2DglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, 0, 0); // uvolnění textury pro kreslení

Page 45: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

IVS / Urychlování výpočtů, možnosti paralelizace 45

Literatura

• NVIDIA OpenGL SDK• www.fit .vutbr.cz/~ipolok /gles /• www.fit .vutbr.cz/~ipolok /gl /• NeHe

Page 46: TAM - OpenGLipolok/tam/TAM_OpenGL_ES.pdf · Inicializace OpenGL ES - Android. IVS / Urychlování výpo čtů, možnosti paralelizace 16 Kreslení v OpenGL ES • Nem ůžeme použít

The End

Questions?