From: Steinar H. Gunderson Date: Sat, 8 Mar 2014 20:35:29 +0000 (+0100) Subject: Use VAOs to bind the VBOs. X-Git-Tag: 1.0~39 X-Git-Url: https://git.sesse.net/?p=movit;a=commitdiff_plain;h=d398770154ecc4bc95282dc45656789dd5686309 Use VAOs to bind the VBOs. Needed for OpenGL 3.2+ core context support. Also refactor a bit, since the amount of boilerplate was getting over the top. --- diff --git a/effect_chain.cpp b/effect_chain.cpp index c803c62..3376daa 100644 --- a/effect_chain.cpp +++ b/effect_chain.cpp @@ -1470,6 +1470,7 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height } const GLuint glsl_program_num = phases[phase]->glsl_program_num; + check_error(); glUseProgram(glsl_program_num); check_error(); @@ -1542,37 +1543,31 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height 0.0f, 1.0f }; - int position_attrib = glGetAttribLocation(glsl_program_num, "position"); - assert(position_attrib != -1); - glEnableVertexAttribArray(position_attrib); + GLuint vao; + glGenVertexArrays(1, &vao); check_error(); - glVertexAttribPointer(position_attrib, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glBindVertexArray(vao); check_error(); - int texcoord_attrib = glGetAttribLocation(glsl_program_num, "texcoord"); - if (texcoord_attrib != -1) { - glEnableVertexAttribArray(texcoord_attrib); - check_error(); - glVertexAttribPointer(texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 0, vertices); // Same as texcoords. - check_error(); - } + GLuint position_vbo = fill_vertex_attribute(glsl_program_num, "position", 2, GL_FLOAT, sizeof(vertices), vertices); + GLuint texcoord_vbo = fill_vertex_attribute(glsl_program_num, "texcoord", 2, GL_FLOAT, sizeof(vertices), vertices); // Same as vertices. glDrawArrays(GL_QUADS, 0, 4); check_error(); + cleanup_vertex_attribute(glsl_program_num, "position", position_vbo); + cleanup_vertex_attribute(glsl_program_num, "texcoord", texcoord_vbo); + glUseProgram(0); check_error(); - glDisableVertexAttribArray(position_attrib); - check_error(); - if (texcoord_attrib != -1) { - glDisableVertexAttribArray(texcoord_attrib); - check_error(); - } for (unsigned i = 0; i < phases[phase]->effects.size(); ++i) { Node *node = phases[phase]->effects[i]; node->effect->clear_gl_state(); } + + glDeleteVertexArrays(1, &vao); + check_error(); } for (map::const_iterator texture_it = output_textures.begin(); diff --git a/init.cpp b/init.cpp index 4003163..b7604e4 100644 --- a/init.cpp +++ b/init.cpp @@ -101,28 +101,23 @@ void measure_texel_subpixel_precision() 0.25f, 0.0f }; - int position_attrib = glGetAttribLocation(glsl_program_num, "position"); - assert(position_attrib != -1); - int texcoord_attrib = glGetAttribLocation(glsl_program_num, "texcoord"); - assert(texcoord_attrib != -1); - glEnableVertexAttribArray(position_attrib); + GLuint vao; + glGenVertexArrays(1, &vao); check_error(); - glVertexAttribPointer(position_attrib, 2, GL_FLOAT, GL_FALSE, 0, vertices); - check_error(); - glEnableVertexAttribArray(texcoord_attrib); - check_error(); - glVertexAttribPointer(texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 0, texcoords); + glBindVertexArray(vao); check_error(); + GLuint position_vbo = fill_vertex_attribute(glsl_program_num, "position", 2, GL_FLOAT, sizeof(vertices), vertices); + GLuint texcoord_vbo = fill_vertex_attribute(glsl_program_num, "texcoord", 2, GL_FLOAT, sizeof(texcoords), texcoords); + glDrawArrays(GL_QUADS, 0, 4); check_error(); + cleanup_vertex_attribute(glsl_program_num, "position", position_vbo); + cleanup_vertex_attribute(glsl_program_num, "texcoord", texcoord_vbo); + glUseProgram(0); check_error(); - glDisableVertexAttribArray(position_attrib); - check_error(); - glDisableVertexAttribArray(texcoord_attrib); - check_error(); // Now read the data back and see what the card did. // (We only look at the red channel; the others will surely be the same.) @@ -153,6 +148,8 @@ void measure_texel_subpixel_precision() check_error(); resource_pool.release_glsl_program(glsl_program_num); + glDeleteVertexArrays(1, &vao); + check_error(); } void measure_roundoff_problems() @@ -230,25 +227,24 @@ void measure_roundoff_problems() 0.75f, 0.0f, 0.25f, 0.0f }; - int position_attrib = glGetAttribLocation(glsl_program_num, "position"); - assert(position_attrib != -1); - int texcoord_attrib = glGetAttribLocation(glsl_program_num, "texcoord"); - assert(texcoord_attrib != -1); - glEnableVertexAttribArray(position_attrib); - check_error(); - glVertexAttribPointer(position_attrib, 2, GL_FLOAT, GL_FALSE, 0, vertices); - check_error(); - glEnableVertexAttribArray(texcoord_attrib); + + GLuint vao; + glGenVertexArrays(1, &vao); check_error(); - glVertexAttribPointer(texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 0, texcoords); + glBindVertexArray(vao); check_error(); + + GLuint position_vbo = fill_vertex_attribute(glsl_program_num, "position", 2, GL_FLOAT, sizeof(vertices), vertices); + GLuint texcoord_vbo = fill_vertex_attribute(glsl_program_num, "texcoord", 2, GL_FLOAT, sizeof(texcoords), texcoords); + glDrawArrays(GL_QUADS, 0, 4); + check_error(); + + cleanup_vertex_attribute(glsl_program_num, "position", position_vbo); + cleanup_vertex_attribute(glsl_program_num, "texcoord", texcoord_vbo); glUseProgram(0); check_error(); - glDisableVertexAttribArray(position_attrib); - check_error(); - glDisableVertexAttribArray(texcoord_attrib); // Now read the data back and see what the card did. (Ignore the last value.) // (We only look at the red channel; the others will surely be the same.) @@ -281,6 +277,8 @@ void measure_roundoff_problems() check_error(); resource_pool.release_glsl_program(glsl_program_num); + glDeleteVertexArrays(1, &vao); + check_error(); } bool check_extensions() diff --git a/util.cpp b/util.cpp index 9e18e9f..b86e3f7 100644 --- a/util.cpp +++ b/util.cpp @@ -178,4 +178,41 @@ void combine_two_samples(float w1, float w2, float *offset, float *total_weight, assert(*offset <= 1.0f); } +GLuint fill_vertex_attribute(GLuint glsl_program_num, const string &attribute_name, GLint size, GLenum type, GLsizeiptr data_size, const GLvoid *data) +{ + int attrib = glGetAttribLocation(glsl_program_num, attribute_name.c_str()); + if (attrib == -1) { + return -1; + } + + GLuint vbo; + glGenBuffers(1, &vbo); + check_error(); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + check_error(); + glBufferData(GL_ARRAY_BUFFER, data_size, data, GL_STATIC_DRAW); + check_error(); + glEnableVertexAttribArray(attrib); + check_error(); + glVertexAttribPointer(attrib, size, type, GL_FALSE, 0, BUFFER_OFFSET(0)); + check_error(); + glBindBuffer(GL_ARRAY_BUFFER, 0); + check_error(); + + return vbo; +} + +void cleanup_vertex_attribute(GLuint glsl_program_num, const string &attribute_name, GLuint vbo) +{ + int attrib = glGetAttribLocation(glsl_program_num, attribute_name.c_str()); + if (attrib == -1) { + return; + } + + glDisableVertexAttribArray(attrib); + check_error(); + glDeleteBuffers(1, &vbo); + check_error(); +} + } // namespace movit diff --git a/util.h b/util.h index f62618c..627c629 100644 --- a/util.h +++ b/util.h @@ -43,6 +43,13 @@ std::string output_glsl_mat3(const std::string &name, const Eigen::Matrix3d &m); // (estimated) squared errors of the two weights. void combine_two_samples(float w1, float w2, float *offset, float *total_weight, float *sum_sq_error); +// Create a VBO with the given data, and bind it to the vertex attribute +// with name . Returns the VBO number. +GLuint fill_vertex_attribute(GLuint glsl_program_num, const std::string &attribute_name, GLint size, GLenum type, GLsizeiptr data_size, const GLvoid *data); + +// Clean up after fill_vertex_attribute(). +void cleanup_vertex_attribute(GLuint glsl_program_num, const std::string &attribute_name, GLuint vbo); + } // namespace movit #ifdef NDEBUG