OpenGL 3.x Part 2: Textures and Objects Ingo Radax, Gnther Voglsam - - PowerPoint PPT Presentation

opengl 3 x part 2 textures and objects
SMART_READER_LITE
LIVE PREVIEW

OpenGL 3.x Part 2: Textures and Objects Ingo Radax, Gnther Voglsam - - PowerPoint PPT Presentation

OpenGL 3.x Part 2: Textures and Objects Ingo Radax, Gnther Voglsam Institute of Computer Graphics and Algorithms Vienna University of Technology Topics for today OpenGL 3.x Part 1 - Revisited Textures Framebuffer Objects Vertexbuffer


slide-1
SLIDE 1

OpenGL 3.x Part 2: Textures and Objects

Ingo Radax, Günther Voglsam

Institute of Computer Graphics and Algorithms Vienna University of Technology

slide-2
SLIDE 2

2

Topics for today OpenGL 3.x Part 1 - Revisited Textures Framebuffer Objects Vertexbuffer Objects Vertex Array Objects Uniform Buffer Objects Notes on CG2

Institute of Computer Graphics and Algorithms

slide-3
SLIDE 3

Set up OpenGL-Project

slide-4
SLIDE 4

Setup OpenGL Project

#include <GL/gl.h> // basic OpenGL

Institute of Computer Graphics and Algorithms 4

Set up a MSVC-project as explained in the C+ +-lecture Version 1:

Include OpenGL-header: Link OpenGL-library “opengl32.lib” Bind extensions manually Cumbersome!

slide-5
SLIDE 5

Setup OpenGL Project

#include <GL/glew.h> // GLEW

Institute of Computer Graphics and Algorithms 5

Better: Version 2:

Include GLEW-header: Link OpenGL-library “opengl32.lib” and “glew32.lib” Copy “glew32.dll” to bin folder U’r ready to go. 

slide-6
SLIDE 6

OpenGL-Object life-cycle revisited

slide-7
SLIDE 7

OpenGL-Object life-cycle In OpenGL, all objects, like buffers and textures, are somehow treated the same way. On object creation and initialization:

First, create a handle to the object (in OpenGL

  • ften called a name). Do this ONCE for each
  • bject.

Then, bind the object to make it current. Pass data to OpenGL. As long as the data does not change, you only have to do this ONCE. Unbind the object if not used.

Institute of Computer Graphics and Algorithms 7

slide-8
SLIDE 8

OpenGL-Object life-cycle On rendering, or whenever the object is used:

Bind it to make it current. Use it. Unbind it.

Finally, when object is not needed anymore:

Delete object. Note that in some cases you manually have to delete attached resources!

NOTE: OpenGL-objects are NOT objects in an OOP-sense!

Institute of Computer Graphics and Algorithms 8

slide-9
SLIDE 9

GLSL Shader revisited

slide-10
SLIDE 10

What shaders are

Institute of Computer Graphics and Algorithms 10

Small C-like programs executed on the graphics-hardware Replace fixed function pipeline with shaders Shader-Types

Vertex Shader (VS): per vertex operations Geometry Shader (GS): per primitive

  • perations

Fragment shader (FS): per fragment

  • perations

Used e.g. for transformations and lighting

slide-11
SLIDE 11

Shader-Execution model

11

Application Shader-Source-Code OpenGL-API OpenGL-Driver Compiler Linker Shader- Object Program- Object Graphics-Hardware compiled code executable code

Institute of Computer Graphics and Algorithms

slide-12
SLIDE 12

Hardware (GPU)

Rendering-Pipeline OpenGL 3.x Rendering-Pipeline:

12 Institute of Computer Graphics and Algorithms

Geometry Vertex- Shader Primitive Assembly Clip Project Viewport Cull Rasterize Fragment- Shader Per Fragment Operations Framebuffer Operations Framebuffer Programmable!

slide-13
SLIDE 13

Rendering-Pipeline

Institute of Computer Graphics and Algorithms 13

Remember:

The Vertex-Shader is executed ONCE per each vertex! The Fragment-Shader is executed ONCE per rasterized fragment (~ a pixel)!

A Shader-Program consists of both,

One VS One FS

slide-14
SLIDE 14

Example usage

Load shader and initialize parameter-handles Do some useful stuff like binding texture, activate texture-units, calculate and update matrices, etc. glUseProgram(programHandle); Set shader-parameters Draw geometry glUseProgram(anotherProgramHandle); ...

Institute of Computer Graphics and Algorithms 14

An application using shaders could basicially look like this:

slide-15
SLIDE 15

Textures

slide-16
SLIDE 16

Why Texturing? Idea: enhance visual appearance of plain surfaces by applying fine structured details

Institute of Computer Graphics and Algorithms 16

slide-17
SLIDE 17

Textures

Institute of Computer Graphics and Algorithms 17

// enable 2D-texturing glEnable(GL_TEXTURE_2D);

First things first:

Load image-data from a file or Generate it (i.e. procedurally)

Use Library to read data from files:

GLFW: glfw.sourceforge.net Devil: openil.sourceforge.net

Enable Texturing in OpenGL:

slide-18
SLIDE 18

Textures

Institute of Computer Graphics and Algorithms 18

GLuint textureHandle; // variable for our texture-handle // get _one_ texture-handle glGenTextures(1, &textureHandle); // bind texture glBindTexture(GL_TEXTURE_2D, textureHandle); // could also be 1D, 3D, ...

As usual in OpenGL:

Create texture-handle Bind texture-handle to make it current Pass data to OpenGL (next slide)

slide-19
SLIDE 19

Textures

Institute of Computer Graphics and Algorithms 19

int mipLevel = 0; int border = 0; int internalFormat = GL_RGBA, int width = 800; int height = 600; int format = GL_RGBA; int type = GL_UNSIGNED_BYTE; // pass data for a 2D-texture glTexImage2D(GL_TEXTURE_2D, mipLevel, internalFormat, width, height, border, format, type, data);

Use glTexImage*(...) to pass loaded image- data stored in data to OpenGL If data is a null-pointer, the needed memory

  • n the GPU will be allocated
slide-20
SLIDE 20

Textures

Institute of Computer Graphics and Algorithms 20

// unbind texture glBindTexture(GL_TEXTURE_2D, 0); ... // delete texture glDeleteTextures(1, &textureHandle);

As usual in OpenGL:

After using it, don’t forget to unbind Finally, if not needed anymore, delete the texture

slide-21
SLIDE 21

Texture Aliasing / Mipmaps

Institute of Computer Graphics and Algorithms 21

Problem: One pixel in image space covers many texels

Solution: Mipmaps

slide-22
SLIDE 22

Mip-Maps

// generate mipmaps for current bound 2D-texture glGenerateMipmap(GL_TEXTURE_2D);

Institute of Computer Graphics and Algorithms 22

(Pre-)Calculate different Levels of detail:

From original size (level 0) down to size of 1x1 pixel

After data has been passed to OpenGL:

Use glGenerateMipmap(…) to generate a set of mipmaps for currently bound texture

slide-23
SLIDE 23

Texture Parameters

Institute of Computer Graphics and Algorithms 23

// set filter-mode for currently bound 2D-texture glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);

For filter-types see specification!

Magnification-Filter: Nearest vs. Linear

slide-24
SLIDE 24

Texture Parameters

Institute of Computer Graphics and Algorithms 24

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);

Minification-Filter:

Without Mipmaps:

GL_*

With Mipmaps:

GL_*_MIPMAP_*

where * = NEAREST || LINEAR Recommended:

Mipmaps with GL_LINEAR_MIPMAP_LINEAR

slide-25
SLIDE 25

Texture Parameters

Institute of Computer Graphics and Algorithms 25

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_*, filter); // * = S || T || R

Wrap and clamp:

GL_CLAMP, GL_REPEAT, GL_CLAMP_TO_BORDER, GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT

repeat mirror/repeat clamp

border

slide-26
SLIDE 26

Passing Textures to Shader

// get location of sampler GLuint texLocation = glGetUniformLocation(programHandle, "colorTexture"); // activate the texture-unit to which the texture should be bound to glActiveTexture(GL_TEXTURE0 + textureUnit); glBindTexture(GL_TEXTURE_2D, textureHandle); // pass the texture unit (i.e., it's id) to the shader glUniform1i(texLocation, textureUnit);

Institute of Computer Graphics and Algorithms 26

Use different texture-units for different textures Use uniform sampler* variables in shader to access texture-units

slide-27
SLIDE 27

Using texture in shader

// Textures can be accessed with samplers uniform sampler2D colorTexture; // to access textures, coordinates are needed in vec2 texCoord; ... void main(void) { ... // Access texture at specified coordinates vec4 texel = texture2D(colorTexture, texCoord); ... }

Institute of Computer Graphics and Algorithms 27

slide-28
SLIDE 28

Cleaning Up If texture is not needed anymore, delete it References

OpenGL Registry, http://www.opengl.org/registry/ DGL Wiki, http://wiki.delphigl.com

Institute of Computer Graphics and Algorithms 28

glDeleteTextures(1, &texId); // delete texture

slide-29
SLIDE 29

Framebuffer Objects FBOs

slide-30
SLIDE 30

What are FBOs used for? “Normal” rendering With FBO

// GL Program

glBindBuffer(GL_ARRAY_BUFFER, vboHandle); glVertexAttribPointer(vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(vertexLocation); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboHandle) glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(vertexLocation); glBindBuffer(GL_ARRAY_BUFFER, 0) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

// GL Program

glBindBuffer(GL_ARRAY_BUFFER, vboHandle); glVertexAttribPointer(vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(vertexLocation); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboHandle) glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(vertexLocation); glBindBuffer(GL_ARRAY_BUFFER, 0) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

Screen Texture

Institute of Computer Graphics and Algorithms 30

slide-31
SLIDE 31

What are FBOs used for? Shadow Mapping Bloom HDR Motion Blur Depth of Field ...

Institute of Computer Graphics and Algorithms 31

slide-32
SLIDE 32

What is an FBO? FBO is an encapsulation of attachments Attachments can be color- or renderbuffers Renderbuffers are objects that support off- screen rendering without an assigned texture

Depth- and stencil-buffer

There can be more then one color attachment

Number depends on your HW More than one is advanced stuff

Institute of Computer Graphics and Algorithms 32

slide-33
SLIDE 33

Setting up an FBO

GLuint fbo; // this will store our fbo-name // generate fbo glGenFramebuffers(1, &fbo); // bind FBO glBindFramebuffer(GL_FRAMEBUFFER, fbo);

Generating an FBO is done as usual in OpenGL:

First generate an OpenGL-”name” Then bind it to do something with it

Institute of Computer Graphics and Algorithms 33

slide-34
SLIDE 34

Setting up a renderbuffer

GLuint depthbuffer; // this will store our db-name // create a depth-buffer glGenRenderbuffers(1, &depthbuffer); // bind our depth-buffer glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);

An FBO on it’s own isn’t much Therefore: attach renderable objects So we want to add a depth buffer Again, create name and bind it:

Institute of Computer Graphics and Algorithms 34

slide-35
SLIDE 35

Creating storage-space

// create storage for our renderbuffer glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); // attach renderbuffer to FBO glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer);

We didn’t create any storage for our render- buffer yet, so create it… …and attach it to our FBO

Institute of Computer Graphics and Algorithms 35

slide-36
SLIDE 36

Attaching a texture to the FBO

// create a texture GLuint img; glGenTextures(1, &img); glBindTexture(GL_TEXTURE_2D, img); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

To render to a texture, we first need one We create it as usual Note: width and height are the same as those for the FBO and renderbuffers!

Institute of Computer Graphics and Algorithms 36

slide-37
SLIDE 37

Attaching a texture to the FBO (cont.)

// attach texture to fbo glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, img, 0);

Simply attach the texture to the FBO

Institute of Computer Graphics and Algorithms 37

slide-38
SLIDE 38

Status checking

// fbo-creation error-checking GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { // error }

Check, if the creation worked out correctly See specification for detailed error-codes

Institute of Computer Graphics and Algorithms 38

slide-39
SLIDE 39

Rendering to texture

// bind fbo glBindFramebuffer(GL_FRAMEBUFFER, fbo); glViewport(0, 0, width, height); // clear our color- and depth-buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // render something here // unbind fbo glBindFramebuffer(GL_FRAMEBUFFER, 0);

Bind FBO – render scene – unbind FBO Note: need to set viewport for FBO!

Institute of Computer Graphics and Algorithms 39

slide-40
SLIDE 40

Using the rendered to texture

// bind texture glBindTexture(GL_TEXTURE_2D, img);

Just bind it like a regular texture Note: If you want to create MIP-maps from it, use glGenerateMipmap()! (For more see GameDev[1].)

Institute of Computer Graphics and Algorithms 40

slide-41
SLIDE 41

Cleaning up

// delete fbo glDeleteFramebuffers(1, &fbo); // delete renderbuffer glDeleteRenderbuffers(1, &depthbuffer); // delete texture glDeleteTextures(1, &img);

If FBO is not needed anymore, delete it Delete also all with the FBO associated renderbuffers and textures!

Institute of Computer Graphics and Algorithms 41

slide-42
SLIDE 42

That’s all? With an FBO, you can render into more than

  • ne texture simultaneously

For more check the tutorials at www.gamedev.net[1] about DrawBuffers References:

[1] Gamedev.net

http://www.gamedev.net/reference/programming/features/fbo1/ http://www.gamedev.net/reference/programming/features/fbo2/

Institute of Computer Graphics and Algorithms 42

slide-43
SLIDE 43

Vertexbuffer Objects VBOs

slide-44
SLIDE 44

Institute of Computer Graphics and Algorithms 44

Why use VBOs? With VBOs

Init() Load model data from file Render() Send model data to GPU Render model Init(): Load model data from file Send model data to GPU and store it in VBOs Render(): Enable VBOs Render model S L O W F A S T

Without VBOs Slow: Send model data often to GPU Fast: Send model data once to GPU Conclusion: Use VBOs

slide-45
SLIDE 45

Create VBOs Generate VBO target

GL_ARRAY_BUFFER

for vertex data: vertex position, normals, tex coords, tangent vector, ...

GL_ELEMENT_ARRAY_BUFFER

For index data

glGenBuffers(1, &vboHandle) glBindBuffer(target, vboHandle); glBufferData(target, size, data, usage)

Institute of Computer Graphics and Algorithms 45

slide-46
SLIDE 46

Create VBOs Generate VBO size

used memory of data array e.g. array_length * sizeof(float)

data

Array containing vertex data

glGenBuffers(1, &vboHandle) glBindBuffer(target, vboHandle); glBufferData(target, size, data, usage)

Institute of Computer Graphics and Algorithms 46

slide-47
SLIDE 47

Create VBOs Generate VBO usage

GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY

glGenBuffers(1, &vboHandle) glBindBuffer(target, vboHandle); glBufferData(target, size, data, usage)

Institute of Computer Graphics and Algorithms 47

slide-48
SLIDE 48

Create VBOs

GL_STREAM_... You will modify the data once, then use it once, and repeat this process many times. GL_STATIC_... You will specify the data only once, then use it many times without modifying it. GL_DYNAMIC_... You will specify or modify the data repeatedly, and use it repeatedly after each time you do this. ..._DRAW The data is generated by the application and passed to GL for rendering. ..._READ The data is generated by GL, and copied into the VBO to be used for rendering. ..._COPY The data is generated by GL, and read back by the application. It is not used by GL.

usage GL_STATIC_DRAW should be the most useful for CG2

Institute of Computer Graphics and Algorithms 48

slide-49
SLIDE 49

Using VBOs Enable VBO and connect to Shader

// first get location vertexLocation = glGetAttribLocation(programHandle, "vertex"); // activate desired VBO glBindBuffer(GL_ARRAY_BUFFER, vboHandle); // set attribute-pointer glVertexAttribPointer(vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); // finally enable attribute-array glEnableVertexAttribArray(vertexLocation);

Institute of Computer Graphics and Algorithms 49

slide-50
SLIDE 50

Using VBOs Render triangles with DrawArrays or with DrawElements (if you have indices) Disable VBOs

glDrawArrays(GL_TRIANGLES, 0, 3); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboHandle) glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(vertexLocation); glBindBuffer(GL_ARRAY_BUFFER, 0) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

Institute of Computer Graphics and Algorithms 50

slide-51
SLIDE 51

Cleaning up If VBO is not needed anymore, delete it References

OpenGL, http://www.opengl.org/wiki/Vertex_Buffer_Obj ects DGL Wiki, http://wiki.delphigl.com/index.php/Tutorial_Ver texbufferobject

Institute of Computer Graphics and Algorithms 51

glDeleteBuffers(1, &vboHandle)

slide-52
SLIDE 52

Vertex Array Objects VAOs

slide-53
SLIDE 53

Institute of Computer Graphics and Algorithms 53

Why use VAOs? With VAOs

Render() Enable vertex attribute 1 Enable vertex attribute 2 ... Enable vertex attribute n Render model Disable vertex attribute 1 Disable vertex attribute 2 ... Disable vertex attribute n Render(): Enable VAO Render model Disable VAO M A N Y O N E

Without VAOs VAOs are a collection of VBOs and attribute pointers

M A N Y O N E

slide-54
SLIDE 54

Create VAOs

// Create and Bind VAO glGenVertexArrays(1, &vaoId); glBindVertexArray(vaoId); // Bind VBO glBindBuffer(GL_ARRAY_BUFFER, vbo1Id); // Set Attribute Pointer GLint loc = glGetAttribLocation(programHandle, "attrib1"); glEnableVertexAttribArray(loc); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, 0, 0); // Continue with other VBOs/AttribPointers ... // Unbind VAO glBindVertexArray(0);

Institute of Computer Graphics and Algorithms 54

slide-55
SLIDE 55

Rendering

// Enable Shader glUseProgram(programHandle); // Bind VAO glBindVertexArray(vaoId); // Set Render Calls glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); // Unbind VAO glBindVertexArray(0); // Disable Shader glUseProgram(0);

Institute of Computer Graphics and Algorithms 55

slide-56
SLIDE 56

Notes Per combination of Shader and Model (VBOs)

  • ne VAO is needed

Don't call glBindBuffer(GL_ELEMENT_ARRAY_BUFFE R, 0); when a VAO is bound, or the VAO will loose the current set index vbo References:

OpenGL, http://www.opengl.org/registry/specs/ARB/vert ex_array_object.txt

Institute of Computer Graphics and Algorithms 56

slide-57
SLIDE 57

Uniform Buffer Objects UBOs

slide-58
SLIDE 58

Institute of Computer Graphics and Algorithms 58

Why use UBOs? With UBOs

Render() Set uniform parameter 1 Set uniform parameter 2 ... Set uniform parameter n Render model Render(): Enable UBO Pass uniform parameters at once Render model Disable UBO O N C E

Without UBOs

M A N Y

slide-59
SLIDE 59

Uniform Blocks In shaders: uniforms are grouped into blocks Blocks can have scope names

Access to uniform only via scope name

uniform MaterialBlock { vec3 ambient; vec3 diffuse; vec3 specular; float shininess; }; void main(void) {

  • ut_Color = ambient;

} uniform MaterialBlock { vec3 ambient; vec3 diffuse; vec3 specular; float shininess; } material; void main(void) {

  • ut_Color = material.ambient;

}

Institute of Computer Graphics and Algorithms 59

slide-60
SLIDE 60

Uniform Blocks (cont.) Data layout should be specified

3 layouts available: packed, shared, std140 Use std140

It is possible to choose between row-major and column-major for matrices

layout(std140) uniform MaterialBlock { vec3 ambient; vec3 diffuse; vec3 specular; float shininess; }; layout(row_major) uniform; //Row major is now the default for matrices.

Institute of Computer Graphics and Algorithms 60

slide-61
SLIDE 61

Data structure The same data structure is needed in both, the shader and the program

In the shader: uniform MaterialBlock { vec3 ambient; vec3 diffuse; vec3 specular; float shininess; }; In the program: GLfloat material[] = { 0.3f, 0.3f, 0.3f, // ambient 0.6f, 0.6f, 0.6f, // diffuse 0.1f, 0.1f, 0.1f, // specular 50 // shininess };

Institute of Computer Graphics and Algorithms 61

slide-62
SLIDE 62

Creating UBOs Start with getting an id for the UBO Then get the index of the uniform block

This index helps us to identify a block

GLuint uboId; glGenBuffers(1, &uboId); GLuint blockIdx; blockIdx = glGetUniformBlockIndex(programHandle, "MaterialBlock");

Institute of Computer Graphics and Algorithms 62

slide-63
SLIDE 63

Creating UBOs (cont.) You might wanna ask OpenGL for the size of the block The block size should be the same as the size

  • f the data structure in the program

Glint blockSize; glGetActiveUniformBlockiv(programHandle, blockIdx, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize); // Test if both data structures have the same size if( sizeof(material) != blockSize ) ERROR!

Institute of Computer Graphics and Algorithms 63

slide-64
SLIDE 64

Creating UBOs (cont.) Create the buffer Choose DYNAMIC_DRAW since uniforms might be changed

glBindBuffer(GL_UNIFORM_BUFFER, uboId); glBufferData(GL_UNIFORM_BUFFER, blockSize, NULL, GL_DYNAMIC_DRAW);

Institute of Computer Graphics and Algorithms 64

slide-65
SLIDE 65

Rendering For rendering, just pass the data to the UBO The uniform blocks will automatically get the data since they are connected with the UBO

Enable Shader Connect block/buffer to binding point (see next slide) // Bind Buffer glBindBuffer(GL_UNIFORM_BUFFER, uboId); // And pass data to UBO glBufferData(GL_UNIFORM_BUFFER, blockSize, material, GL_DYNAMIC_DRAW); Render Calls Disable Shader

Institute of Computer Graphics and Algorithms 65

slide-66
SLIDE 66

Connect to binding point At last, connect the uniform block and the uniform buffer to a binding point Binding points connect uniform blocks to uniform buffers Use different binding points for different blocks/buffers

Like you should use different texture units for different textures/samplers

GLuint bindingPoint = 0; glBindBufferBase(GL_UNIFORM_BUFFER, bindingPoint, uboId); glUniformBlockBinding(programHandle, blockIdx, bindingPoint);

Institute of Computer Graphics and Algorithms 66

slide-67
SLIDE 67

Cleaning up If UBO is not needed anymore, delete it References

OpenGL, http://www.opengl.org/registry/specs/ARB/unif

  • rm_buffer_object.txt

Institute of Computer Graphics and Algorithms 67

glDeleteBuffers(1, &uboId);

slide-68
SLIDE 68

Notes on CG2

slide-69
SLIDE 69

Notes on CG2 Textures/VBOs are mandatory You also have to implement (at least) one of the following:

FBOs VAOs UBOs

USEFUL FOR A LOT OF EFFECTS JUST 5 LINES OF CODE

Institute of Computer Graphics and Algorithms 69