Intro to OpenGL ES 2.0

OleksandrKozubets 317 views 38 slides Jan 16, 2018
Slide 1
Slide 1 of 38
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38

About This Presentation

Intro to OpenGL ES 2.0


Slide Content

Intro to OpenGL ES

ES = Embedded (and mobile) Systems

OpenGL ES versions
●1.x - deprecated, fixed function pipeline
●2.0 - programmable pipeline, the most widespread API
●3.0 - enhanced graphics (multiple rendering targets etc.)
○3.1 - general purpose compute (compute shaders, independent vertex and fragment shaders)
○3.2 - extensions to v.3.1 (based on Android Extension Pack)

Compatible devices
iOS

Android

OpenGL ES Version Device Distribution
2.0 37.2%
3.0 45.1%
3.1 17.7%
Device
OpenGL ES Version
2.0 3.X
iPhone X
iPhone 8/8 Plus
iPhone 7/7 Plus
iPhone 6s/6s Plus
iPhone SE
iPhone 6/6 Plus
iPhone 5s

iPhone 5/5c
iPhone 4/4s
iPhone 3GS

Fixed vs Programmable

Fixed function pipeline (OpenGL ES 1.x)
Vertices
Transform and
Lighting
Primitive
Assembly
Rasterizer
Color
Sum
Texture
Environment
Fog
Alpha
Test
Depth
Stencil
Color
Buffer
Blend
Dither Frame Buffer

Programmable pipeline (OpenGL ES 2.0)
Vertices
Vertex
Shader
Primitive
Assembly
Rasterizer
Color
Sum
Fragment
Shader
Fog
Alpha
Test
Depth
Stencil
Color
Buffer
Blend
Dither Frame Buffer

Simplest Vertex Shader Code

attribute vec4 vPosition ;

void main() {
gl_Position = vPosition;
gl_PointSize = 10.0; // Makes sense only when drawing points
}

Simplest Fragment Shader Code

precision mediump float;

void main() {
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); //Everything will be green...
}

Let’s draw!

But first we need a surface...
●GLKit framework (GLKView and GLKViewController) on iOS
●GLSurfaceView or TextureView on Android

GLSurfaceView (Android)
●Implement and set rendering callback!
●OpenGL context will be created and attached to surface for you
(still possible to create on your own)
●The rendering context stores the appropriate OpenGL ES state
(state machine)

Renderer callback (pseudocode)
glView.setRenderer(new GLSurfaceView.Renderer() {
@Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
createNative ();
}

@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
initNative(width, height);
}

@Override
public void onDrawFrame(GL10 unused) {
drawNative();
}
});

createNative()

Create vertex/fragment shader
GLuint createShader(GLenum shaderType, const char *pSource) {
GLuint shader = glCreateShader(shaderType);
if (shader) {
glShaderSource (shader, 1, &pSource, NULL);
glCompileShader (shader);
GLint compiled = 0;
glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
// Log error, clear memory...
...
}
}
return shader;
}

Create and link program
GLuint createProgram(GLuint vertexShader, GLuint fragmentShader) {
GLuint program = glCreateProgram();
if (program) {
glAttachShader (program, vertexShader);
glAttachShader (program, fragmentShader);
glLinkProgram (program);

GLint linkStatus = GL_FALSE;
glGetProgramiv (program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE) {
// Handle error
...
}
}
return program;
}

initNative(width, height)

Viewport
void initNative(int w, int h) {
// Specifies the affine transformation of x and y
// from normalized device coordinates
// to window coordinates.
glViewport(0, 0, w, h);
}

Image from https://developer.android.com/guide/topics/graphics/opengl.html#coordinate-mapping

drawNative()

Draw with shader
void drawSomething(GLuint shaderId) {
glClearColor(.0f, .0f, .0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(shaderId);

// draw with program...
...

glUseProgram(0);
}

glDrawElements
●GL_POINTS
●GL_LINE_STRIP
●GL_LINE_LOOP
●GL_LINES
●GL_TRIANGLE_STRIP
●GL_TRIANGLE_FAN
●GL_TRIANGLES
Image from https://stackoverflow.com/questions/13789269/draw-a-ring-with-different-color-sector

Draw square
GLuint vPositionHandle = glGetAttribLocation (programId, "vPosition");

static const GLfloat triangleVertices[] = {
-0.5, 0.5, 0.0f, // square left top vertex, 0 index
-0.5, -0.5, 0.0f, // square left bottom vertex, 1 index
0.5, -0.5, 0.0f, // square right bottom vertex, 2 index
0.5, 0.5, 0.0f, // square right top vertex, 3 index
};

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

glVertexAttribPointer (vPositionHandle, 3, GL_FLOAT, GL_FALSE, 0, triangleVertices);
glEnableVertexAttribArray (vPositionHandle);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);

Texturing

Texture Vertex Shader
attribute vec4 vPosition ;

attribute vec2 vTexCoord ;

varying vec2 v_TexCoordinate ;

void main() {
v_TexCoordinate = vTexCoord;
gl_Position = vPosition;
}

Texture Fragment Shader
precision mediump float;

uniform sampler2D tex ;

varying vec2 v_TexCoordinate ;

void main() {
gl_FragColor = texture2D(tex, v_TexCoordinate);
}

http://www.learnopengles.com/android-lesson-four-introducing-basic-texturing/texture-coordinates/

Set texture coordinates
GLfloat texCoords[] = {
0, 0,
0, 1,
1, 1,
1, 0
};

GLuint vTexCoordHandle;
vTexCoordHandle = glGetAttribLocation (textureShader->getId(), "vTexCoord");
glVertexAttribPointer (vTexCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
glEnableVertexAttribArray (vTexCoordHandle);

Bind texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
glUniform1i(glGetUniformLocation (programId, "tex"), 0);

Transformations

Vertex Shader
attribute vec4 vPosition ;

attribute vec4 vColor ;

varying vec4 v_Color ;

uniform mat4 uMVPMatrix ;

void main() {
v_Color = vColor;
gl_Position = uMVPMatrix * vPosition;
}

Fragment Shader
precision mediump float;

varying vec4 v_Color ;

varying vec2 v_TexCoordinate ;

void main() {
gl_FragColor = v_Color;
}

Cube vertices and indices
float d = 0.5f;
const GLfloat vertices[] = {
// near cube face
-d, d, d, // left top vertex, 0 index
-d, -d, d, // left bottom vertex, 1 index
d, -d, d, // right bottom vertex, 2 index
d, d, d, // right top vertex, 3 index

// far cube face
-d, d, -d, // left top vertex, 4 index
-d, -d, -d, // left bottom vertex, 5 index
d, -d, -d, // right bottom vertex, 6 index
d, d, -d, // right top vertex, 7 index

};



const GLubyte indices[] = {
0, 1, 2, 2, 3, 0, // front face
6, 5, 4, 4, 7, 6, // rear face
4, 0, 3, 3, 7, 4, // top face
1, 5, 6, 6, 2, 1, // bottom face
4, 5, 1, 1, 0, 4, // left face
3, 2, 6, 6, 7, 3, // right face
};

Set colors per vertex
const float colors[] = {
0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f,
};
const int componentsPerColor = 3;

GLuint colorHandle = glGetAttribLocation (programId, "vColor");
glEnableVertexAttribArray (colorHandle);
glVertexAttribPointer (colorHandle, 4, GL_FLOAT, false, componentsPerColor * 4, colors);

Set matrices
//on init...
projMatr = matr4::frustum(-aspectRatio, aspectRatio, -1, 1, 3, 7);
viewMatr = matr4::lookAt(0, 0, -4, 0, 0, 0, 0, 1, 0);


//on draw...
modelMatr = matr4::rotateX(angleX) * matr4::rotateY(angleY) * matr4::rotateZ(angleZ);
matr4 mvp = projMatr * viewMatr * modelMatr;

GLuint modelViewProjectionHandle = glGetUniformLocation (programId, "uMVPMatrix");
GL2::uniformMatrix4fv(modelViewProjectionHandle , 1, GL_FALSE, mvp.ptr());

References
1.https://www.khronos.org/opengles/sdk/docs/reference_cards/OpenGL-ES-2_0-Reference-card.pdf
2.https://www.amazon.com/OpenGL-ES-2-0-Programming-Guide-ebook/dp/B004Z6EW5O
3.https://developer.apple.com/library/content/documentation/3DDrawing/Conceptual/OpenGLES_Prog
rammingGuide/Introduction/Introduction.html
4.https://developer.android.com/training/graphics/opengl/index.html

Android sample on GitHub
https://github.com/AlexanderKozubets/opengl-sample-android

Thank you for attention!
Tags