OpenGL Geometry/Rendering Institute of Computer Graphics and Algorithms Vienna University of Technology Rendering Geometry • Old (< 2.0) way: Without VBO: Init() Load model data from file Render() Send model data to GPU Render model 16.03.2016 CGUE 2016 - Steiner/Plank 2 Rendering Geometry • Modern way Without VBO: With VBO: Init() Load model data from file Init(): Load model data from file Send model data to GPU and store it in VBOs Render() Send model data to GPU Render model Render(): Enable VBOs Render model • VBOs send data only once to the GPU -> Faster – Use VBOs wherever possible 16.03.2016 CGUE 2016 - Steiner/Plank 3 VBO • Generate VBO glGenBuffers(1, &handle); • Bind VBO and upload data glBindBuffer(target, handle); glBufferData(target, size, data, usage); • Delete VBO glDeleteBuffers(1, &handle); 16.03.2016 CGUE 2016 - Steiner/Plank 4 VBO Data Upload • Upload Data glBindBuffer(target, handle); glBufferData(target, size, data, usage); • target – GL_ARRAY_BUFFER for vertex data • Positions, Normals, UV-Coordinates – GL_ELEMENT_ARRAY_BUFFER for index data 16.03.2016 CGUE 2016 - Steiner/Plank 5 VBO Data Upload • Upload Data glBindBuffer(target, handle); glBufferData(target, size, data, usage); • size – Memory size of data array (in Bytes!!!!!) eg. array_lenght * sizeof(float) • data – Address of Data-Array 16.03.2016 CGUE 2016 - Steiner/Plank 6 VBO Data Upload • Upload Data glBindBuffer(target, handle); glBufferData(target, size, data, usage); • Usage – Spezifies how data will be used by the application – Several values possible • GL_{ACCESS_FREQUENCY}_{ACCESS_NATURE} 16.03.2016 CGUE 2016 - Steiner/Plank 7 • GL_{ACCESS_FREQUENCY}_{ACCESS_NATURE} 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. • GL_STATIC_DRAW most usefull for CGUE 16.03.2016 CGUE 2016 - Steiner/Plank 8 VAO • VAOs are a collection of VBOs and attribute pointers Render_without_VAO() Render_with_VAO(): Enable vertex attribute 1 Enable vertex attribute 2 ... Enable vertex attribute n Enable VAO Render model Disable VAO Render model Disable vertex attribute 1 Disable vertex attribute 2 ... Disable vertex attribute n 16.03.2016 CGUE 2016 - Steiner/Plank 9 VAO • Generate VAO glGenVertexArrays(1, &vao); • Bind VAO glBindVertexArray(vao); • Unbind VAO glBindVertexArray(0); • Delete VAO glDeleteVertexArrays(1, &vao); 16.03.2016 CGUE 2016 - Steiner/Plank 10 VAO – Shader Attributes • Must attach each buffer to a shader attribute – Shader in vec3 position; – Query location glGetAttribLocation(program, "position"); – Enable attribute glEnableVertexAttribArray(positionIndex); glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, 0, 0); 16.03.2016 CGUE 2016 - Steiner/Plank 11 VAO – Shader Attributes • Alternative: Specify locations in shader – Shader layout(location = 1) in vec3 pos; – No need to query location anymore – Enable attribute glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); 16.03.2016 CGUE 2016 - Steiner/Plank 12 VAO initialisation //Bind VAO glBindVertexArray(vao); //Bind VBO glBindBuffer(GL_ARRAY_BUFFER, positionBuffer); //Enable Attribute GLint positionIndex = glGetAttribLocation(program, "position"); glEnableVertexAttribArray(positionIndex); glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, 0, 0); //Bind Index Buffer glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); //Unbind VAO and VBOs glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 16.03.2016 CGUE 2016 - Steiner/Plank 13 VAO - Hints • Per combination of Shader and Model (VBOs) one VAO is needed – Also possible to fix the attribute location in shader – VAO works as long as attributes have same location • Don't call glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) when a VAO is bound, or the VAO will loose the current set index vbo 16.03.2016 CGUE 2016 - Steiner/Plank 14 VAO rendering //Activate shader glUseProgram(programHandle); //Bind VAO glBindVertexArray(vao); //Draw array glDrawArrays(GL_TRIANGLES, 0, 3); //or with index buffer glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0); //Unbind VAO glBindVertexArray(0); //Deactivate shader glUseProgram(0); 16.03.2016 CGUE 2016 - Steiner/Plank 15 DEMO 04 VBO/VAO