// generate vertex array object void Mesh::generateVAO() { #if _GVRF_USE_GLES3_ GLuint tmpID; if (!vao_dirty_) { return; } deleteVaos(); if (vertices_.size() == 0 && normals_.size() == 0 && tex_coords_.size() == 0) { std::string error = "no vertex data yet, shouldn't call here. "; throw error; return; } glGenVertexArrays(1, &vaoID_); glBindVertexArray(vaoID_); glGenBuffers(1, &triangle_vboID_); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle_vboID_); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * indices_.size(), &indices_[0], GL_STATIC_DRAW); numTriangles_ = indices_.size() / 3; if (vertices_.size()) { glGenBuffers(1, &vert_vboID_); glBindBuffer(GL_ARRAY_BUFFER, vert_vboID_); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices_.size(), &vertices_[0], GL_STATIC_DRAW); GLuint vertexLoc = GLProgram::POSITION_ATTRIBUTE_LOCATION; glEnableVertexAttribArray(vertexLoc); glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0); } if (normals_.size()) { glGenBuffers(1, &norm_vboID_); glBindBuffer(GL_ARRAY_BUFFER, norm_vboID_); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * normals_.size(), &normals_[0], GL_STATIC_DRAW); GLuint normalLoc = GLProgram::NORMAL_ATTRIBUTE_LOCATION; glEnableVertexAttribArray(normalLoc); glVertexAttribPointer(normalLoc, 3, GL_FLOAT, 0, 0, 0); } if (tex_coords_.size()) { glGenBuffers(1, &tex_vboID_); glBindBuffer(GL_ARRAY_BUFFER, tex_vboID_); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * tex_coords_.size(), &tex_coords_[0], GL_STATIC_DRAW); GLuint texCoordLoc = GLProgram::TEXCOORD_ATTRIBUT_LOCATION; glEnableVertexAttribArray(texCoordLoc); glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_float_keys_.begin(); it != attribute_float_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * getFloatVector(it->second).size(), getFloatVector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 1, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_vec2_keys_.begin(); it != attribute_vec2_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * getVec2Vector(it->second).size(), getVec2Vector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 2, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_vec3_keys_.begin(); it != attribute_vec3_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * getVec3Vector(it->second).size(), getVec3Vector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 3, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_vec4_keys_.begin(); it != attribute_vec4_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec4) * getVec4Vector(it->second).size(), getVec4Vector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 4, GL_FLOAT, 0, 0, 0); } // done generation glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); vao_dirty_ = false; #endif }
// generate vertex array object void Mesh::generateVAO(Material::ShaderType key) { #if _GVRF_USE_GLES3_ GLuint tmpID; if (vao_dirty_) { deleteVaos(); } if (vaoID_map_.find(key) != vaoID_map_.end()) { // already initialized return; } if (vertices_.size() == 0 && normals_.size() == 0 && tex_coords_.size() == 0) { std::string error = "no vertex data yet, shouldn't call here. "; throw error; return; } if (vertexLoc_ == -1 && normalLoc_ == -1 && texCoordLoc_ == -1) { std::string error = "no attrib loc setup yet, please compile shader and set attribLoc first. "; throw error; return; } GLuint vaoID_ = 0; GLuint triangle_vboID_, vert_vboID_, norm_vboID_, tex_vboID_; glGenVertexArrays(1, &vaoID_); glBindVertexArray(vaoID_); glGenBuffers(1, &triangle_vboID_); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle_vboID_); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * triangles_.size(), &triangles_[0], GL_STATIC_DRAW); numTriangles_ = triangles_.size() / 3; if (vertices_.size()) { glGenBuffers(1, &vert_vboID_); glBindBuffer(GL_ARRAY_BUFFER, vert_vboID_); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices_.size(), &vertices_[0], GL_STATIC_DRAW); glEnableVertexAttribArray(getVertexLoc()); glVertexAttribPointer(getVertexLoc(), 3, GL_FLOAT, 0, 0, 0); } if (normals_.size()) { glGenBuffers(1, &norm_vboID_); glBindBuffer(GL_ARRAY_BUFFER, norm_vboID_); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * normals_.size(), &normals_[0], GL_STATIC_DRAW); glEnableVertexAttribArray(getNormalLoc()); glVertexAttribPointer(getNormalLoc(), 3, GL_FLOAT, 0, 0, 0); } if (tex_coords_.size()) { glGenBuffers(1, &tex_vboID_); glBindBuffer(GL_ARRAY_BUFFER, tex_vboID_); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * tex_coords_.size(), &tex_coords_[0], GL_STATIC_DRAW); glEnableVertexAttribArray(getTexCoordLoc()); glVertexAttribPointer(getTexCoordLoc(), 2, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_float_keys_.begin(); it != attribute_float_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * getFloatVector(it->second).size(), getFloatVector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 1, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_vec2_keys_.begin(); it != attribute_vec2_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * getVec2Vector(it->second).size(), getVec2Vector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 2, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_vec3_keys_.begin(); it != attribute_vec3_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * getVec3Vector(it->second).size(), getVec3Vector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 3, GL_FLOAT, 0, 0, 0); } for (auto it = attribute_vec4_keys_.begin(); it != attribute_vec4_keys_.end(); ++it) { glGenBuffers(1, &tmpID); glBindBuffer(GL_ARRAY_BUFFER, tmpID); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec4) * getVec4Vector(it->second).size(), getVec4Vector(it->second).data(), GL_STATIC_DRAW); glEnableVertexAttribArray(it->first); glVertexAttribPointer(it->first, 4, GL_FLOAT, 0, 0, 0); } vaoID_map_[key] = vaoID_; triangle_vboID_map_[key] = triangle_vboID_; vert_vboID_map_[key] = vert_vboID_; norm_vboID_map_[key] = norm_vboID_; tex_vboID_map_[key] = tex_vboID_; // done generation glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); vao_dirty_ = false; #endif }