36
Mohammad Shaker mohammadshaker.com @ZGTRShaker 2014 OpenGL Graphics L06- PERFORMANCE

OpenGL L06-Performance

Embed Size (px)

DESCRIPTION

OpenGL L06-Performance

Citation preview

Page 1: OpenGL L06-Performance

Mohammad Shaker

mohammadshaker.com

@ZGTRShaker

2014

OpenGL Graphics

L06- PERFORMANCE

Page 2: OpenGL L06-Performance

Performance

Page 3: OpenGL L06-Performance

How can you up your OpenGL app performance?

• Different Techniques:

– Vertex buffer and vertex arrays

– Display Lists

– Frustum culling

– Other methods

Page 4: OpenGL L06-Performance

Vertex Buffer Object (VBO)Vertex Array Object (VAO)

Page 5: OpenGL L06-Performance

Vertex and Array Buffers

• Look at this,

Page 6: OpenGL L06-Performance

Vertex and Array Buffers

Good oder Bad?

Page 7: OpenGL L06-Performance

Vertex and Array Buffers

Good oder Bad?

Page 8: OpenGL L06-Performance

Vertex and Array Buffers

Page 9: OpenGL L06-Performance

Vertex and Array Buffers

Page 10: OpenGL L06-Performance

Vertex and Array Buffers

huge performance benefit!

Page 11: OpenGL L06-Performance

VBO and VAOExample: Creating Cube Using VBO and VAO

Page 12: OpenGL L06-Performance

Initializing the Cube’s Data

• We’ll build each cube face from individual triangles

• We need to determine how much storage is required:

– (6 faces)(2 triangles/face)(3 vertices/triangle)

const int NumVertices = 36;

• To simplify communicating with GLSL, we’ll use a vec4 class (implemented in

C++) similar to GLSL’s vec4 type

– We’ll also typedef it to add logical meaning:

typedef vec4 point4;typedef vec4 color4;

Page 13: OpenGL L06-Performance

Initializing the Cube’s Data

• Our cube has two attributes per vertex:

– position

– color

• We create two arrays to hold the VBO data:

point4 points[NumVertices];color4 colors[NumVertices];

Page 14: OpenGL L06-Performance

Initializing the Cube’s Data

// Vertices of a unit cube centered at origin, sides aligned with axes

point4 vertex_positions[8] = {

point4(-0.5, -0.5, 0.5, 1.0 ),

point4(-0.5, 0.5, 0.5, 1.0 ),

point4( 0.5, 0.5, 0.5, 1.0 ),

point4( 0.5, -0.5, 0.5, 1.0 ),

point4(-0.5, -0.5, -0.5, 1.0 ),

point4(-0.5, 0.5, -0.5, 1.0 ),

point4( 0.5, 0.5, -0.5, 1.0 ),

point4( 0.5, -0.5, -0.5, 1.0 )

};

// RGBA colors

color4 vertex_colors[8] = {

color4(0.0, 0.0, 0.0, 1.0 ), // black

color4(1.0, 0.0, 0.0, 1.0 ), // red

color4(1.0, 1.0, 0.0, 1.0 ), // yellow

color4(0.0, 1.0, 0.0, 1.0 ), // green

color4(0.0, 0.0, 1.0, 1.0 ), // blue

color4(1.0, 0.0, 1.0, 1.0 ), // magenta

color4(1.0, 1.0, 1.0, 1.0 ), // white

color4(0.0, 1.0, 1.0, 1.0 ) // cyan

};

Page 15: OpenGL L06-Performance

Initializing the Cube’s Data

// quad() generates two triangles for each face and assigns colors to the vertices

int Index = 0; // global variable indexing into VBO arrays

void quad(int a, int b, int c, int d )

{

colors[Index] = vertex_colors[a]; points[Index] = vertex_positions[a]; Index++;

colors[Index] = vertex_colors[b]; points[Index] = vertex_positions[b]; Index++;

colors[Index] = vertex_colors[c]; points[Index] = vertex_positions[c]; Index++;

colors[Index] = vertex_colors[a]; points[Index] = vertex_positions[a]; Index++;

colors[Index] = vertex_colors[c]; points[Index] = vertex_positions[c]; Index++;

colors[Index] = vertex_colors[d]; points[Index] = vertex_positions[d]; Index++;

}

// generate 12 triangles: 36 vertices and 36 colors

Void colorcube()

{

quad(1, 0, 3, 2);

quad(2, 3, 7, 6);

quad(3, 0, 4, 7);

quad(6, 5, 1, 2);

quad(4, 5, 6, 7);

quad(5, 4, 0, 1);

}

Page 16: OpenGL L06-Performance

Creating the VAO

• VAOs store the data of a geometric object

• Steps for using a VAO

1. Generate VAO names by calling glgenvertexarrays()

2. Bind a specific VAO for initialization by calling glbindvertexarray()

3. Update VBOs associated with this VAO

4. Bind VAO for use in rendering

• This approach allows a single function call to specify all the data for an objects

– previously, you might have needed to make many calls to make all the data current

GLuint vao; // Create a vertex array object

glGenVertexArrays(1, &vao);

glBindVertexArray(vao);

Page 17: OpenGL L06-Performance

• Vertex data must be stored in a VBO, and associated with a VAO

• The code-flow is similar to configuring a VAO:– generate VBO names by calling

glGenBuffers()

– bind a specific VBO for initialization by calling

glBindBuffer(GL_ARRAY_BUFFER, …)

– load data into VBO using

glBufferData(GL_ARRAY_BUFFER, …)

– bind VAO for use in rendering

glBindVertexArray()

Creating the VBO

GLuint buffer; // Create and initialize a buffer object

glGenBuffers(1, &buffer);

glBindBuffer(GL_ARRAY_BUFFER, buffer);

glBufferData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors), NULL, GL_STATIC_DRAW);

glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);

glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(colors), colors);

Page 18: OpenGL L06-Performance

• Vertex data must be stored in a VBO, and associated with a VAO

• The code-flow is similar to configuring a VAO:– generate VBO names by calling

glGenBuffers()

– bind a specific VBO for initialization by calling

glBindBuffer(GL_ARRAY_BUFFER, …)

– load data into VBO using

glBufferData(GL_ARRAY_BUFFER, …)

– bind VAO for use in rendering

glBindVertexArray()

Creating the VBO

GLuint buffer; // Create and initialize a buffer object

glGenBuffers(1, &buffer);

glBindBuffer(GL_ARRAY_BUFFER, buffer);

glBufferData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors), NULL, GL_STATIC_DRAW);

glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);

glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(colors), colors);

Page 19: OpenGL L06-Performance

Display ListDisplay lists allow you to define the geometry and execute them multiple times. If you plan to redraw the same geometry multiple times, this is a great way to

save performance!

Page 20: OpenGL L06-Performance

Immediate Mode versus Display Listed Rendering

• Immediate Mode Graphics

– Primitives are sent to pipeline and display right away

– No memory of graphical entities

• Display Listed Graphics

– Primitives placed in display lists

– Display lists kept on graphics server

– Can be redisplayed with different state

– Can be shared among OpenGL graphics contexts

Page 21: OpenGL L06-Performance

OpenGL Architecture

DisplayList

PolynomialEvaluator

Per VertexOperations &

PrimitiveAssembly

RasterizationPer Fragment

OperationsFrameBuffer

TextureMemory

CPU

PixelOperations

Page 22: OpenGL L06-Performance

OpenGL Architecture

DisplayList

PolynomialEvaluator

Per VertexOperations &

PrimitiveAssembly

RasterizationPer Fragment

OperationsFrameBuffer

TextureMemory

CPU

PixelOperations

Page 23: OpenGL L06-Performance

OpenGL Architecture

DisplayList

PolynomialEvaluator

Per VertexOperations &

PrimitiveAssembly

RasterizationPer Fragment

OperationsFrameBuffer

TextureMemory

CPU

PixelOperations

Page 24: OpenGL L06-Performance

Display Lists

• Not all OpenGL routines can be stored in display lists

• State changes persist, even after a display list is finished

• Display lists can call other display lists

• Display lists are not editable, but you can fake it

– make a list (A) which calls other lists (B, C, and D)

– delete and replace B, C, and D, as needed

Page 25: OpenGL L06-Performance

Display Lists and Hierarchy

• Consider model of a car

– Create display list for chassis

– Create display list for wheel

glNewList(CAR, GL_COMPILE);glCallList(CHASSIS);glTranslatef(…);glCallList(WHEEL);glTranslatef(…);glCallList(WHEEL);

…glEndList();

Page 26: OpenGL L06-Performance

Display List Examplefor Terrain Drawing

Page 27: OpenGL L06-Performance

Display List for Terrain Drawing

1. Global Scope: GLuint terrainListId;

2. InitGl():

• Generate a list:

terrainListId = glGenLists(1);

• Call the terrain drawing function that you want OpenGL to perform faster

DrawTerrain();

3. DrawTerrain():

– In the first line of this function, tell OpenGL that each instruction from now on must be located in the display list

that’s bound to terrainListId by writing:

• glNewList(terrainListId, GL_COMPILE);

– Now, write the terrain drawing algorithm

– End display list scope by calling

• glEndList();

4. In DrawGLScene() instead of calling DrawTerrain(), call the terrain list:

– glCallList(terrainListId);

Page 28: OpenGL L06-Performance

Display List for Terrain Drawing

1. Global Scope: GLuint terrainListId;

2. InitGl():

• Generate a list:

terrainListId = glGenLists(1);

• Call the terrain drawing function that you want OpenGL to perform faster

DrawTerrain();

3. DrawTerrain():

– In the first line of this function, tell OpenGL that each instruction from now on must be located in the display list

that’s bound to terrainListId by writing:

• glNewList(terrainListId, GL_COMPILE);

– Now, write the terrain drawing algorithm

– End display list scope by calling

• glEndList();

4. In DrawGLScene() instead of calling DrawTerrain(), call the terrain list:

– glCallList(terrainListId);

GLuint terrianListId;

initGL()

{ terrianListId = glGenLists(1);

DrawTerrain();

}

DrawTerrain()

{ glNewList(terrianListId, GL_COMPILE);

//Terrain Drawing Algorithm

glEndList();

}

DrawGLSene()

{ //Other Stuff

glCallList(terrianListId);

}

Page 29: OpenGL L06-Performance

Culling and Clipping

Page 30: OpenGL L06-Performance

Frustum Culling

• Create a clipping plane

– float plane [] = {A, b, C, D};

• Create a clipping plane with it

– glClipPlane(GL_CLIP_PLANE0, plane);

• Enable the clipping plane

– glEnable(GL_CLIP_PLANE0);

Page 31: OpenGL L06-Performance

Scissor Box

• Additional Clipping Test

glScissor(x, y, w, h )

• any fragments outside of box are clipped

• useful for updating a small section of a viewport

– affects glClear() operations

Page 32: OpenGL L06-Performance

General Memory Managementhttp://docs.unity3d.com/Manual/UnderstandingAutomaticMemoryManagement.html

Page 33: OpenGL L06-Performance

General Memory Management

• Avoid memory allocation in a loops

function ConcatExample(intArray: int[]) {

var line = intArray[0].ToString();

for (i = 1; i < intArray.Length; i++) {

line += ", " + intArray[i].ToString();

}

return line;

}

Page 34: OpenGL L06-Performance

General Memory Management

• Avoid memory allocation in a loops

var scoreBoard: GUIText;var score: int;

function Update() {var scoreText: String = "Score: " + score.ToString();scoreBoard.text = scoreText;

}

var scoreBoard: GUIText;var scoreText: String;var score: int;var oldScore: int;

function Update() {if (score != oldScore) {

scoreText = "Score: " + score.ToString();scoreBoard.text = scoreText;oldScore = score;

}}

Page 35: OpenGL L06-Performance

General Memory Management

• Avoid memory allocation in a loops– Assign random variables to an array.

function RandomList(numElements: int) {

var result = new float[numElements];

for (i = 0; i < numElements; i++) {

result[i] = Random.value;

}

return result;

}

function RandomList(arrayToFill: float[]) {

for (i = 0; i < arrayToFill.Length; i++) {

arrayToFill[i] = Random.value;

}

}

Page 36: OpenGL L06-Performance

General Memory Management

• Free Memory in C++ and C# (for example: arrays, images, complex objects, ..etc.)

– C++: delete keyword

– C#: enforce garbage collection cleanup