}
const GLuint glsl_program_num = phases[phase]->glsl_program_num;
+ check_error();
glUseProgram(glsl_program_num);
check_error();
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<Phase *, GLuint>::const_iterator texture_it = output_textures.begin();
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.)
check_error();
resource_pool.release_glsl_program(glsl_program_num);
+ glDeleteVertexArrays(1, &vao);
+ check_error();
}
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.)
check_error();
resource_pool.release_glsl_program(glsl_program_num);
+ glDeleteVertexArrays(1, &vao);
+ check_error();
}
bool check_extensions()
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
// (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 <attribute_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